diff --git a/app.js b/app.js index 3ef7fb65d1..35f6697432 100644 --- a/app.js +++ b/app.js @@ -40,6 +40,8 @@ * @license MIT license */ +'use strict'; + /********************************************************* * Make sure we have everything set up correctly *********************************************************/ @@ -56,10 +58,10 @@ function runNpm(command) { process.exit(0); } -var isLegacyEngine = !(''.includes); +const isLegacyEngine = !(''.includes); -var fs = require('fs'); -var path = require('path'); +const fs = require('fs'); +const path = require('path'); try { require('sugar'); if (isLegacyEngine) require('es6-shim'); @@ -101,7 +103,7 @@ if (Config.watchconfig) { // Autoconfigure the app when running in cloud hosting environments: try { - var cloudenv = require('cloud-env'); + let cloudenv = require('cloud-env'); Config.bindaddress = cloudenv.get('IP', Config.bindaddress || ''); Config.port = cloudenv.get('PORT', Config.port); } catch (e) {} @@ -168,14 +170,14 @@ global.Cidr = require('./cidr.js'); if (Config.crashguard) { // graceful crash - allow current battles to finish before restarting - var lastCrash = 0; + let lastCrash = 0; process.on('uncaughtException', function (err) { - var dateNow = Date.now(); - var quietCrash = require('./crashlogger.js')(err, 'The main process', true); + let dateNow = Date.now(); + let quietCrash = require('./crashlogger.js')(err, 'The main process', true); quietCrash = quietCrash || ((dateNow - lastCrash) <= 1000 * 60 * 5); lastCrash = Date.now(); if (quietCrash) return; - var stack = ("" + err.stack).escapeHTML().split("\n").slice(0, 2).join("
"); + let stack = ("" + err.stack).escapeHTML().split("\n").slice(0, 2).join("
"); if (Rooms.lobby) { Rooms.lobby.addRaw('
THE SERVER HAS CRASHED: ' + stack + '
Please restart the server.
'); Rooms.lobby.addRaw('
You will not be able to talk in the lobby or start new battles until the server restarts.
'); @@ -200,8 +202,8 @@ global.TeamValidator = require('./team-validator.js'); fs.readFile(path.resolve(__dirname, 'config/ipbans.txt'), function (err, data) { if (err) return; data = ('' + data).split("\n"); - var rangebans = []; - for (var i = 0; i < data.length; i++) { + let rangebans = []; + for (let i = 0; i < data.length; i++) { data[i] = data[i].split('#')[0].trim(); if (!data[i]) continue; if (data[i].includes('/')) { diff --git a/battle-engine.js b/battle-engine.js index 75fe7d811a..82480e6287 100644 --- a/battle-engine.js +++ b/battle-engine.js @@ -10,6 +10,8 @@ * @license MIT license */ +'use strict'; + require('sugar'); if (!''.includes) require('es6-shim'); @@ -19,7 +21,7 @@ if (Config.crashguard) { // graceful crash - allow current battles to finish before restarting process.on('uncaughtException', function (err) { require('./crashlogger.js')(err, 'A simulator process', true); - /* var stack = ("" + err.stack).escapeHTML().split("\n").slice(0, 2).join("
"); + /* let stack = ("" + err.stack).escapeHTML().split("\n").slice(0, 2).join("
"); if (Rooms.lobby) { Rooms.lobby.addRaw('
THE SERVER HAS CRASHED: ' + stack + '
Please restart the server.
'); Rooms.lobby.addRaw('
You will not be able to talk in the lobby or start new battles until the server restarts.
'); @@ -49,9 +51,9 @@ global.toId = function (text) { global.Tools = require('./tools.js').includeMods(); -var Battle, BattleSide, BattlePokemon; +let Battle, BattleSide, BattlePokemon; -var Battles = Object.create(null); +let Battles = Object.create(null); require('./repl.js').start('battle-engine-', process.pid, function (cmd) { return eval(cmd); }); @@ -59,25 +61,25 @@ require('./repl.js').start('battle-engine-', process.pid, function (cmd) { retur // another process. process.on('message', function (message) { //console.log('CHILD MESSAGE RECV: "' + message + '"'); - var nlIndex = message.indexOf("\n"); - var more = ''; + let nlIndex = message.indexOf("\n"); + let more = ''; if (nlIndex > 0) { more = message.substr(nlIndex + 1); message = message.substr(0, nlIndex); } - var data = message.split('|'); + let data = message.split('|'); if (data[1] === 'init') { if (!Battles[data[0]]) { try { Battles[data[0]] = Battle.construct(data[0], data[2], data[3]); } catch (err) { - var stack = err.stack + '\n\n' + + let stack = err.stack + '\n\n' + 'Additional information:\n' + 'message = ' + message; - var fakeErr = {stack: stack}; + let fakeErr = {stack: stack}; if (!require('./crashlogger.js')(fakeErr, 'A battle')) { - var ministack = ("" + err.stack).escapeHTML().split("\n").slice(0, 2).join("
"); + let ministack = ("" + err.stack).escapeHTML().split("\n").slice(0, 2).join("
"); process.send(data[0] + '\nupdate\n|html|
A BATTLE PROCESS HAS CRASHED: ' + ministack + '
'); } else { process.send(data[0] + '\nupdate\n|html|
The battle crashed!
Don\'t worry, we\'re working on fixing it.
'); @@ -88,33 +90,33 @@ process.on('message', function (message) { if (Battles[data[0]] && Battles[data[0]].destroy) { Battles[data[0]].destroy(); } else { - var stack = '\n\n' + + let stack = '\n\n' + 'Additional information:\n' + 'message = ' + message; - var fakeErr = {stack: stack}; + let fakeErr = {stack: stack}; require('./crashlogger.js')(fakeErr, 'A battle'); } delete Battles[data[0]]; } else { - var battle = Battles[data[0]]; + let battle = Battles[data[0]]; if (battle) { - var prevRequest = battle.currentRequest; - var prevRequestDetails = battle.currentRequestDetails || ''; + let prevRequest = battle.currentRequest; + let prevRequestDetails = battle.currentRequestDetails || ''; try { battle.receive(data, more); } catch (err) { - var stack = err.stack + '\n\n' + + let stack = err.stack + '\n\n' + 'Additional information:\n' + 'message = ' + message + '\n' + 'currentRequest = ' + prevRequest + '\n\n' + 'Log:\n' + battle.log.join('\n').replace(/\n\|split\n[^\n]*\n[^\n]*\n[^\n]*\n/g, '\n'); - var fakeErr = {stack: stack}; + let fakeErr = {stack: stack}; require('./crashlogger.js')(fakeErr, 'A battle'); - var logPos = battle.log.length; + let logPos = battle.log.length; battle.add('html', '
The battle crashed
You can keep playing but it might crash again.
'); - var nestedError; + let nestedError; try { battle.makeRequest(prevRequest, prevRequestDetails); } catch (e) { @@ -142,7 +144,7 @@ BattlePokemon = (function () { this.side = side; this.battle = side.battle; - var pokemonScripts = this.battle.data.Scripts.pokemon; + let pokemonScripts = this.battle.data.Scripts.pokemon; if (pokemonScripts) Object.merge(this, pokemonScripts); if (typeof set === 'string') set = {name: set}; @@ -173,7 +175,7 @@ BattlePokemon = (function () { this.level = this.battle.clampIntRange(set.forcedLevel || set.level || 100, 1, 9999); - var genders = {M:'M', F:'F'}; + let genders = {M:'M', F:'F'}; this.gender = this.template.gender || genders[set.gender] || (Math.random() * 2 < 1 ? 'M' : 'F'); if (this.gender === 'N') this.gender = ''; this.happiness = typeof set.happiness === 'number' ? this.battle.clampIntRange(set.happiness, 0, 255) : 255; @@ -202,7 +204,7 @@ BattlePokemon = (function () { this.types = this.baseTemplate.types; this.typesData = []; - for (var i = 0, l = this.types.length; i < l; i++) { + for (let i = 0, l = this.types.length; i < l; i++) { this.typesData.push({ type: this.types[i], suppressed: false, @@ -211,8 +213,8 @@ BattlePokemon = (function () { } if (this.set.moves) { - for (var i = 0; i < this.set.moves.length; i++) { - var move = this.battle.getMove(this.set.moves[i]); + for (let i = 0; i < this.set.moves.length; i++) { + let move = this.battle.getMove(this.set.moves[i]); if (!move.id) continue; if (move.id === 'hiddenpower') { if (!this.set.ivs || Object.values(this.set.ivs).every(31)) { @@ -242,32 +244,32 @@ BattlePokemon = (function () { if (!this.set.ivs) { this.set.ivs = {hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31}; } - var stats = {hp: 31, atk: 31, def: 31, spe: 31, spa: 31, spd: 31}; - for (var i in stats) { + let stats = {hp: 31, atk: 31, def: 31, spe: 31, spa: 31, spd: 31}; + for (let i in stats) { if (!this.set.evs[i]) this.set.evs[i] = 0; if (!this.set.ivs[i] && this.set.ivs[i] !== 0) this.set.ivs[i] = 31; } - for (var i in this.set.evs) { + for (let i in this.set.evs) { this.set.evs[i] = this.battle.clampIntRange(this.set.evs[i], 0, 255); } - for (var i in this.set.ivs) { + for (let i in this.set.ivs) { this.set.ivs[i] = this.battle.clampIntRange(this.set.ivs[i], 0, 31); } - var hpTypes = ['Fighting', 'Flying', 'Poison', 'Ground', 'Rock', 'Bug', 'Ghost', 'Steel', 'Fire', 'Water', 'Grass', 'Electric', 'Psychic', 'Ice', 'Dragon', 'Dark']; + let hpTypes = ['Fighting', 'Flying', 'Poison', 'Ground', 'Rock', 'Bug', 'Ghost', 'Steel', 'Fire', 'Water', 'Grass', 'Electric', 'Psychic', 'Ice', 'Dragon', 'Dark']; if (this.battle.gen && this.battle.gen === 2) { // Gen 2 specific Hidden Power check. IVs are still treated 0-31 so we get them 0-15 - var atkDV = Math.floor(this.set.ivs.atk / 2); - var defDV = Math.floor(this.set.ivs.def / 2); - var speDV = Math.floor(this.set.ivs.spe / 2); - var spcDV = Math.floor(this.set.ivs.spa / 2); + let atkDV = Math.floor(this.set.ivs.atk / 2); + let defDV = Math.floor(this.set.ivs.def / 2); + let speDV = Math.floor(this.set.ivs.spe / 2); + let spcDV = Math.floor(this.set.ivs.spa / 2); this.hpType = hpTypes[4 * (atkDV % 4) + (defDV % 4)]; this.hpPower = Math.floor((5 * ((spcDV >> 3) + (2 * (speDV >> 3)) + (4 * (defDV >> 3)) + (8 * (atkDV >> 3))) + (spcDV > 2 ? 3 : spcDV)) / 2 + 31); } else { // Hidden Power check for gen 3 onwards - var hpTypeX = 0, hpPowerX = 0; - var i = 1; - for (var s in stats) { + let hpTypeX = 0, hpPowerX = 0; + let i = 1; + for (let s in stats) { hpTypeX += i * (this.set.ivs[s] % 2); hpPowerX += i * (Math.floor(this.set.ivs[s] / 2) % 2); i *= 2; @@ -283,10 +285,10 @@ BattlePokemon = (function () { // This is used in gen 1 only, here to avoid code repetition. // Only declared if gen 1 to avoid declaring an object we aren't going to need. if (this.battle.gen === 1) this.modifiedStats = {atk:0, def:0, spa:0, spd:0, spe:0}; - for (var statName in this.baseStats) { - var stat = this.template.baseStats[statName]; + for (let statName in this.baseStats) { + let stat = this.template.baseStats[statName]; stat = Math.floor(Math.floor(2 * stat + this.set.ivs[statName] + Math.floor(this.set.evs[statName] / 4)) * this.level / 100 + 5); - var nature = this.battle.getNature(this.set.nature); + let nature = this.battle.getNature(this.set.nature); if (statName === nature.plus) stat *= 1.1; if (statName === nature.minus) stat *= 0.9; this.baseStats[statName] = Math.floor(stat); @@ -338,10 +340,10 @@ BattlePokemon = (function () { BattlePokemon.prototype.speed = 0; BattlePokemon.prototype.toString = function () { - var fullname = this.fullname; + let fullname = this.fullname; if (this.illusion) fullname = this.illusion.fullname; - var positionList = 'abcdef'; + let positionList = 'abcdef'; if (this.isActive) return fullname.substr(0, 2) + positionList[this.position] + fullname.substr(2); return fullname; }; @@ -353,7 +355,7 @@ BattlePokemon = (function () { BattlePokemon.prototype.update = function (init) { this.trapped = this.maybeTrapped = false; this.maybeDisabled = false; - for (var i in this.moveset) { + for (let i in this.moveset) { if (this.moveset[i]) this.moveset[i].disabled = false; } if (init) return; @@ -373,8 +375,8 @@ BattlePokemon = (function () { } if (this.template.num === 493) { // Arceus formes - var item = Tools.getItem(this.item); - var targetForme = (item && item.onPlate ? 'Arceus-' + item.onPlate : 'Arceus'); + let item = Tools.getItem(this.item); + let targetForme = (item && item.onPlate ? 'Arceus-' + item.onPlate : 'Arceus'); if (this.template.species !== targetForme) { this.formeChange(targetForme); this.battle.add('-formechange', this, targetForme); @@ -384,16 +386,16 @@ BattlePokemon = (function () { if (this.runImmunity('trapped')) this.battle.runEvent('MaybeTrapPokemon', this); // Disable the faculty to cancel switches if a foe may have a trapping ability - for (var i = 0; i < this.battle.sides.length; ++i) { - var side = this.battle.sides[i]; + for (let i = 0; i < this.battle.sides.length; ++i) { + let side = this.battle.sides[i]; if (side === this.side) continue; - for (var j = 0; j < side.active.length; ++j) { - var pokemon = side.active[j]; + for (let j = 0; j < side.active.length; ++j) { + let pokemon = side.active[j]; if (!pokemon || pokemon.fainted) continue; - var template = (pokemon.illusion || pokemon).template; + let template = (pokemon.illusion || pokemon).template; if (!template.abilities) continue; - for (var k in template.abilities) { - var ability = template.abilities[k]; + for (let k in template.abilities) { + let ability = template.abilities[k]; if (ability === pokemon.ability) { // This event was already run above so we don't need // to run it again. @@ -420,15 +422,15 @@ BattlePokemon = (function () { if (statName === 'hp') return this.maxhp; // please just read .maxhp directly // base stat - var stat = this.stats[statName]; + let stat = this.stats[statName]; // stat boosts // boost = this.boosts[statName]; - var boosts = {}; + let boosts = {}; boosts[statName] = boost; boosts = this.battle.runEvent('ModifyBoost', this, null, null, boosts); boost = boosts[statName]; - var boostTable = [1, 1.5, 2, 2.5, 3, 3.5, 4]; + let boostTable = [1, 1.5, 2, 2.5, 3, 3.5, 4]; if (boost > 6) boost = 6; if (boost < -6) boost = -6; if (boost >= 0) { @@ -452,13 +454,13 @@ BattlePokemon = (function () { if (statName === 'hp') return this.maxhp; // please just read .maxhp directly // base stat - var stat = this.stats[statName]; + let stat = this.stats[statName]; // stat boosts if (!unboosted) { - var boosts = this.battle.runEvent('ModifyBoost', this, null, null, Object.clone(this.boosts)); - var boost = boosts[statName]; - var boostTable = [1, 1.5, 2, 2.5, 3, 3.5, 4]; + let boosts = this.battle.runEvent('ModifyBoost', this, null, null, Object.clone(this.boosts)); + let boost = boosts[statName]; + let boostTable = [1, 1.5, 2, 2.5, 3, 3.5, 4]; if (boost > 6) boost = 6; if (boost < -6) boost = -6; if (boost >= 0) { @@ -470,7 +472,7 @@ BattlePokemon = (function () { // stat modifier effects if (!unmodified) { - var statTable = {atk:'Atk', def:'Def', spa:'SpA', spd:'SpD', spe:'Spe'}; + let statTable = {atk:'Atk', def:'Def', spa:'SpA', spd:'SpD', spe:'Spe'}; stat = this.battle.runEvent('Modify' + statTable[statName], this, null, null, stat); } if (this.battle.getStatCallback) { @@ -479,15 +481,15 @@ BattlePokemon = (function () { return stat; }; BattlePokemon.prototype.getWeight = function () { - var weight = this.template.weightkg; + let weight = this.template.weightkg; weight = this.battle.runEvent('ModifyWeight', this, null, null, weight); if (weight < 0.1) weight = 0.1; return weight; }; BattlePokemon.prototype.getMoveData = function (move) { move = this.battle.getMove(move); - for (var i = 0; i < this.moveset.length; i++) { - var moveData = this.moveset[i]; + for (let i = 0; i < this.moveset.length; i++) { + let moveData = this.moveset[i]; if (moveData.id === move.id) { return moveData; } @@ -495,21 +497,21 @@ BattlePokemon = (function () { return null; }; BattlePokemon.prototype.getMoveTargets = function (move, target) { - var targets = []; + let targets = []; switch (move.target) { case 'all': case 'foeSide': case 'allySide': case 'allyTeam': if (!move.target.startsWith('foe')) { - for (var i = 0; i < this.side.active.length; i++) { + for (let i = 0; i < this.side.active.length; i++) { if (this.side.active[i] && !this.side.active[i].fainted) { targets.push(this.side.active[i]); } } } if (!move.target.startsWith('ally')) { - for (var i = 0; i < this.side.foe.active.length; i++) { + for (let i = 0; i < this.side.foe.active.length; i++) { if (this.side.foe.active[i] && !this.side.foe.active[i].fainted) { targets.push(this.side.foe.active[i]); } @@ -519,13 +521,13 @@ BattlePokemon = (function () { case 'allAdjacent': case 'allAdjacentFoes': if (move.target === 'allAdjacent') { - for (var i = 0; i < this.side.active.length; i++) { + for (let i = 0; i < this.side.active.length; i++) { if (this.side.active[i] && this.battle.isAdjacent(this, this.side.active[i])) { targets.push(this.side.active[i]); } } } - for (var i = 0; i < this.side.foe.active.length; i++) { + for (let i = 0; i < this.side.foe.active.length; i++) { if (this.side.foe.active[i] && this.battle.isAdjacent(this, this.side.foe.active[i])) { targets.push(this.side.foe.active[i]); } @@ -545,7 +547,7 @@ BattlePokemon = (function () { if (move.pressureTarget) { // At the moment, this is the only supported target. if (move.pressureTarget === 'foeSide') { - for (var i = 0; i < this.side.foe.active.length; i++) { + for (let i = 0; i < this.side.foe.active.length; i++) { if (this.side.foe.active[i] && !this.side.foe.active[i].fainted) { targets.push(this.side.foe.active[i]); } @@ -563,7 +565,7 @@ BattlePokemon = (function () { }; BattlePokemon.prototype.deductPP = function (move, amount, source) { move = this.battle.getMove(move); - var ppData = this.getMoveData(move); + let ppData = this.getMoveData(move); if (!ppData) return false; ppData.used = true; if (!ppData.pp) return false; @@ -573,8 +575,8 @@ BattlePokemon = (function () { ppData.pp = 0; } if (ppData.virtual) { - var foeActive = this.side.foe.active; - for (var i = 0; i < foeActive.length; i++) { + let foeActive = this.side.foe.active; + for (let i = 0; i < foeActive.length; i++) { if (foeActive[i].isStale >= 2) { if (move.selfSwitch) this.isStalePPTurns++; return true; @@ -599,7 +601,7 @@ BattlePokemon = (function () { }; }; BattlePokemon.prototype.getLockedMove = function () { - var lockedMove = this.battle.runEvent('LockMove', this); + let lockedMove = this.battle.runEvent('LockMove', this); if (lockedMove === true) lockedMove = false; return lockedMove; }; @@ -614,10 +616,10 @@ BattlePokemon = (function () { id: 'recharge' }]; } - var moves = []; - var hasValidMove = false; - for (var i = 0; i < this.moveset.length; i++) { - var move = this.moveset[i]; + let moves = []; + let hasValidMove = false; + for (let i = 0; i < this.moveset.length; i++) { + let move = this.moveset[i]; if (lockedMove) { if (lockedMove === move.id) { return [{ @@ -632,7 +634,7 @@ BattlePokemon = (function () { } else if (!move.disabled || move.disabled === 'hidden' && restrictData) { hasValidMove = true; } - var moveName = move.move; + let moveName = move.move; if (move.id === 'hiddenpower') { moveName = 'Hidden Power ' + this.hpType; if (this.battle.gen < 6) moveName += ' ' + this.hpPower; @@ -657,12 +659,12 @@ BattlePokemon = (function () { return []; }; BattlePokemon.prototype.getRequestData = function () { - var lockedMove = this.getLockedMove(); + let lockedMove = this.getLockedMove(); // Information should be restricted for the last active Pokémon - var isLastActive = this.isLastActive(); - var moves = this.getMoves(lockedMove, isLastActive); - var data = {moves: moves.length ? moves : [{move: 'Struggle', id: 'struggle'}]}; + let isLastActive = this.isLastActive(); + let moves = this.getMoves(lockedMove, isLastActive); + let data = {moves: moves.length ? moves : [{move: 'Struggle', id: 'struggle'}]}; if (isLastActive) { if (this.maybeDisabled) { @@ -682,23 +684,23 @@ BattlePokemon = (function () { BattlePokemon.prototype.isLastActive = function () { if (!this.isActive) return false; - var allyActive = this.side.active; - for (var i = this.position + 1; i < allyActive.length; i++) { + let allyActive = this.side.active; + for (let i = this.position + 1; i < allyActive.length; i++) { if (allyActive[i] && !allyActive.fainted) return false; } return true; }; BattlePokemon.prototype.positiveBoosts = function () { - var boosts = 0; - for (var i in this.boosts) { + let boosts = 0; + for (let i in this.boosts) { if (this.boosts[i] > 0) boosts += this.boosts[i]; } return boosts; }; BattlePokemon.prototype.boostBy = function (boost) { - var changed = false; - for (var i in boost) { - var delta = boost[i]; + let changed = false; + for (let i in boost) { + let delta = boost[i]; this.boosts[i] += delta; if (this.boosts[i] > 6) { delta -= this.boosts[i] - 6; @@ -714,13 +716,13 @@ BattlePokemon = (function () { return changed; }; BattlePokemon.prototype.clearBoosts = function () { - for (var i in this.boosts) { + for (let i in this.boosts) { this.boosts[i] = 0; } this.update(); }; BattlePokemon.prototype.setBoost = function (boost) { - for (var i in boost) { + for (let i in boost) { this.boosts[i] = boost[i]; } this.update(); @@ -728,7 +730,7 @@ BattlePokemon = (function () { BattlePokemon.prototype.copyVolatileFrom = function (pokemon) { this.clearVolatile(); this.boosts = pokemon.boosts; - for (var i in pokemon.volatiles) { + for (let i in pokemon.volatiles) { if (this.battle.getEffect(i).noCopy) continue; // shallow clones this.volatiles[i] = Object.clone(pokemon.volatiles[i]); @@ -740,12 +742,12 @@ BattlePokemon = (function () { } pokemon.clearVolatile(); this.update(); - for (var i in this.volatiles) { + for (let i in this.volatiles) { this.battle.singleEvent('Copy', this.getVolatile(i), this.volatiles[i], this); } }; BattlePokemon.prototype.transformInto = function (pokemon, user, effect) { - var template = pokemon.template; + let template = pokemon.template; if (pokemon.fainted || pokemon.illusion || (pokemon.volatiles['substitute'] && this.battle.gen >= 5)) { return false; } @@ -757,14 +759,14 @@ BattlePokemon = (function () { } this.transformed = true; this.typesData = []; - for (var i = 0, l = pokemon.typesData.length; i < l; i++) { + for (let i = 0, l = pokemon.typesData.length; i < l; i++) { this.typesData.push({ type: pokemon.typesData[i].type, suppressed: false, isAdded: pokemon.typesData[i].isAdded }); } - for (var statName in this.stats) { + for (let statName in this.stats) { this.stats[statName] = pokemon.stats[statName]; } this.moveset = []; @@ -772,9 +774,9 @@ BattlePokemon = (function () { this.set.ivs = (this.battle.gen >= 5 ? this.set.ivs : pokemon.set.ivs); this.hpType = (this.battle.gen >= 5 ? this.hpType : pokemon.hpType); this.hpPower = (this.battle.gen >= 5 ? this.hpPower : pokemon.hpPower); - for (var i = 0; i < pokemon.moveset.length; i++) { - var moveData = pokemon.moveset[i]; - var moveName = moveData.move; + for (let i = 0; i < pokemon.moveset.length; i++) { + let moveData = pokemon.moveset[i]; + let moveName = moveData.move; if (moveData.id === 'hiddenpower') { moveName = 'Hidden Power ' + this.hpType; } @@ -790,7 +792,7 @@ BattlePokemon = (function () { }); this.moves.push(toId(moveName)); } - for (var j in pokemon.boosts) { + for (let j in pokemon.boosts) { this.boosts[j] = pokemon.boosts[j]; } if (effect) { @@ -811,7 +813,7 @@ BattlePokemon = (function () { this.types = template.types; this.typesData = []; this.types = template.types; - for (var i = 0, l = this.types.length; i < l; i++) { + for (let i = 0, l = this.types.length; i < l; i++) { this.typesData.push({ type: this.types[i], suppressed: false, @@ -819,12 +821,12 @@ BattlePokemon = (function () { }); } if (!dontRecalculateStats) { - for (var statName in this.stats) { - var stat = this.template.baseStats[statName]; + for (let statName in this.stats) { + let stat = this.template.baseStats[statName]; stat = Math.floor(Math.floor(2 * stat + this.set.ivs[statName] + Math.floor(this.set.evs[statName] / 4)) * this.level / 100 + 5); // nature - var nature = this.battle.getNature(this.set.nature); + let nature = this.battle.getNature(this.set.nature); if (statName === nature.plus) stat *= 1.1; if (statName === nature.minus) stat *= 0.9; this.baseStats[statName] = this.stats[statName] = Math.floor(stat); @@ -852,8 +854,8 @@ BattlePokemon = (function () { }; if (this.battle.gen === 1 && this.baseMoves.indexOf('mimic') >= 0 && !this.transformed) { - var moveslot = this.baseMoves.indexOf('mimic'); - var mimicPP = this.moveset[moveslot] ? this.moveset[moveslot].pp : 16; + let moveslot = this.baseMoves.indexOf('mimic'); + let mimicPP = this.moveset[moveslot] ? this.moveset[moveslot].pp : 16; this.moveset = this.baseMoveset.slice(); this.moveset[moveslot].pp = mimicPP; } else { @@ -868,7 +870,7 @@ BattlePokemon = (function () { this.set.ivs = this.baseIvs; this.hpType = this.baseHpType; this.hpPower = this.baseHpPower; - for (var i in this.volatiles) { + for (let i in this.volatiles) { if (this.volatiles[i].linkedStatus) { this.volatiles[i].linkedPokemon.removeVolatile(this.volatiles[i].linkedStatus); } @@ -891,7 +893,7 @@ BattlePokemon = (function () { BattlePokemon.prototype.hasType = function (type) { if (!type) return false; if (Array.isArray(type)) { - for (var i = 0; i < type.length; i++) { + for (let i = 0; i < type.length; i++) { if (this.hasType(type[i])) return true; } } else { @@ -905,7 +907,7 @@ BattlePokemon = (function () { // actually setting of this.fainted comes later when the // faint queue is resolved. if (this.fainted || this.faintQueued) return 0; - var d = this.hp; + let d = this.hp; this.hp = 0; this.switchFlag = false; this.faintQueued = true; @@ -940,7 +942,7 @@ BattlePokemon = (function () { BattlePokemon.prototype.hasMove = function (moveid) { moveid = toId(moveid); if (moveid.substr(0, 11) === 'hiddenpower') moveid = 'hiddenpower'; - for (var i = 0; i < this.moveset.length; i++) { + for (let i = 0; i < this.moveset.length; i++) { if (moveid === this.battle.getMove(this.moveset[i].move).id) { return moveid; } @@ -1018,8 +1020,8 @@ BattlePokemon = (function () { } if (this.status === status.id) return false; - var prevStatus = this.status; - var prevStatusData = this.statusData; + let prevStatus = this.status; + let prevStatusData = this.statusData; if (status.id && !this.battle.runEvent('SetStatus', this, source, sourceEffect, status)) { this.battle.debug('set status [' + status.id + '] interrupted'); return false; @@ -1059,7 +1061,7 @@ BattlePokemon = (function () { if (!this.hp || !this.isActive) return false; if (!this.item) return false; - var id = toId(item); + let id = toId(item); if (id && this.item !== id) return false; if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect; @@ -1084,7 +1086,7 @@ BattlePokemon = (function () { if (!this.isActive) return false; if (!this.item) return false; - var id = toId(item); + let id = toId(item); if (id && this.item !== id) return false; if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect; @@ -1121,7 +1123,7 @@ BattlePokemon = (function () { if (toId(this.ability) === 'multitype') return false; if (source && toId(source.ability) === 'multitype') return false; } - var item = this.getItem(); + let item = this.getItem(); if (this.battle.runEvent('TakeItem', this, source, null, item)) { this.item = ''; this.itemData = {id: '', target: this}; @@ -1150,7 +1152,7 @@ BattlePokemon = (function () { }; BattlePokemon.prototype.hasItem = function (item) { if (this.ignoringItem()) return false; - var ownItem = this.item; + let ownItem = this.item; if (!Array.isArray(item)) { return ownItem === toId(item); } @@ -1162,7 +1164,7 @@ BattlePokemon = (function () { BattlePokemon.prototype.setAbility = function (ability, source, effect, noForce) { if (!this.hp) return false; ability = this.battle.getAbility(ability); - var oldAbility = this.ability; + let oldAbility = this.ability; if (noForce && oldAbility === ability.id) { return false; } @@ -1181,7 +1183,7 @@ BattlePokemon = (function () { }; BattlePokemon.prototype.hasAbility = function (ability) { if (this.ignoringAbility()) return false; - var ownAbility = this.ability; + let ownAbility = this.ability; if (!Array.isArray(ability)) { return ownAbility === toId(ability); } @@ -1194,7 +1196,7 @@ BattlePokemon = (function () { return this.battle.getNature(this.set.nature); }; BattlePokemon.prototype.addVolatile = function (status, source, sourceEffect, linkedStatus) { - var result; + let result; status = this.battle.getEffect(status); if (!this.hp && !status.affectsFainted) return false; if (this.battle.event) { @@ -1253,8 +1255,8 @@ BattlePokemon = (function () { status = this.battle.getEffect(status); if (!this.volatiles[status.id]) return false; this.battle.singleEvent('End', status, this.volatiles[status.id], this); - var linkedPokemon = this.volatiles[status.id].linkedPokemon; - var linkedStatus = this.volatiles[status.id].linkedStatus; + let linkedPokemon = this.volatiles[status.id].linkedPokemon; + let linkedStatus = this.volatiles[status.id].linkedStatus; delete this.volatiles[status.id]; if (linkedPokemon && linkedPokemon.volatiles[linkedStatus]) { linkedPokemon.removeVolatile(linkedStatus); @@ -1265,21 +1267,21 @@ BattlePokemon = (function () { // "static" function BattlePokemon.getHealth = function (side) { if (!this.hp) return '0 fnt'; - var hpstring; + let hpstring; if ((side === true) || (this.side === side) || this.battle.getFormat().debug || this.battle.reportExactHP) { hpstring = '' + this.hp + '/' + this.maxhp; } else { - var ratio = this.hp / this.maxhp; + let ratio = this.hp / this.maxhp; if (this.battle.reportPercentages) { // HP Percentage Mod mechanics - var percentage = Math.ceil(ratio * 100); + let percentage = Math.ceil(ratio * 100); if ((percentage === 100) && (ratio < 1.0)) { percentage = 99; } hpstring = '' + percentage + '/100'; } else { // In-game accurate pixel health mechanics - var pixels = Math.floor(ratio * 48) || 1; + let pixels = Math.floor(ratio * 48) || 1; hpstring = '' + pixels + '/48'; if ((pixels === 9) && (ratio > 0.2)) { hpstring += 'y'; // force yellow HP bar @@ -1317,8 +1319,8 @@ BattlePokemon = (function () { return true; }; BattlePokemon.prototype.getTypes = function (getAll) { - var types = []; - for (var i = 0, l = this.typesData.length; i < l; i++) { + let types = []; + for (let i = 0, l = this.typesData.length; i < l; i++) { if (getAll || !this.typesData[i].suppressed) { types.push(this.typesData[i].type); } @@ -1335,7 +1337,7 @@ BattlePokemon = (function () { if (this.volatiles['fly'] || this.volatiles['bounce'] || this.volatiles['skydrop'] || this.volatiles['dive'] || this.volatiles['dig'] || this.volatiles['phantomforce'] || this.volatiles['shadowforce']) { return true; } - for (var i = 0; i < this.side.foe.active.length; i++) { + for (let i = 0; i < this.side.foe.active.length; i++) { if (this.side.foe.active[i].volatiles['skydrop'] && this.side.foe.active[i].volatiles['skydrop'].source === this) { return true; } @@ -1343,10 +1345,10 @@ BattlePokemon = (function () { return false; }; BattlePokemon.prototype.runEffectiveness = function (move) { - var totalTypeMod = 0; - var types = this.getTypes(); - for (var i = 0; i < types.length; i++) { - var typeMod = this.battle.getEffectiveness(move, types[i]); + let totalTypeMod = 0; + let types = this.getTypes(); + for (let i = 0; i < types.length; i++) { + let typeMod = this.battle.getEffectiveness(move, types[i]); typeMod = this.battle.singleEvent('Effectiveness', move, null, types[i], move, null, typeMod); totalTypeMod += this.battle.runEvent('Effectiveness', this, types[i], move, typeMod); } @@ -1367,7 +1369,7 @@ BattlePokemon = (function () { } return false; } - var immunity = this.battle.runEvent('Immunity', this, null, null, type); + let immunity = this.battle.runEvent('Immunity', this, null, null, type); if (!immunity) { this.battle.debug('artificial immunity'); if (message && immunity !== null) { @@ -1388,7 +1390,7 @@ BattlePokemon = (function () { BattleSide = (function () { function BattleSide(name, battle, n, team) { - var sideScripts = battle.data.Scripts.side; + let sideScripts = battle.data.Scripts.side; if (sideScripts) Object.merge(this, sideScripts); this.getChoice = (this.getChoice || BattleSide.getChoice).bind(this); @@ -1412,12 +1414,12 @@ BattleSide = (function () { } this.team = this.battle.getTeam(this, team); - for (var i = 0; i < this.team.length && i < 6; i++) { + for (let i = 0; i < this.team.length && i < 6; i++) { //console.log("NEW POKEMON: " + (this.team[i] ? this.team[i].name : '[unidentified]')); this.pokemon.push(new BattlePokemon(this.team[i], this)); } this.pokemonLeft = this.pokemon.length; - for (var i = 0; i < this.pokemon.length; i++) { + for (let i = 0; i < this.pokemon.length; i++) { this.pokemon[i].position = i; } } @@ -1438,13 +1440,13 @@ BattleSide = (function () { return this.id + ': ' + this.name; }; BattleSide.prototype.getData = function () { - var data = { + let data = { name: this.name, id: this.id, pokemon: [] }; - for (var i = 0; i < this.pokemon.length; i++) { - var pokemon = this.pokemon[i]; + for (let i = 0; i < this.pokemon.length; i++) { + let pokemon = this.pokemon[i]; data.pokemon.push({ ident: pokemon.fullname, details: pokemon.details, @@ -1472,11 +1474,11 @@ BattleSide = (function () { return data; }; BattleSide.prototype.randomActive = function () { - var actives = this.active.filter(function (active) { + let actives = this.active.filter(function (active) { return active && !active.fainted; }); if (!actives.length) return null; - var i = Math.floor(Math.random() * actives.length); + let i = Math.floor(Math.random() * actives.length); return actives[i]; }; BattleSide.prototype.addSideCondition = function (status, source, sourceEffect) { @@ -1518,16 +1520,16 @@ BattleSide = (function () { return true; }; BattleSide.prototype.send = function () { - var parts = Array.prototype.slice.call(arguments); - var functions = parts.map(function (part) { + let parts = Array.prototype.slice.call(arguments); + let functions = parts.map(function (part) { return typeof part === 'function'; }); - var sideUpdate = []; + let sideUpdate = []; if (functions.indexOf(true) < 0) { sideUpdate.push('|' + parts.join('|')); } else { - var line = ''; - for (var j = 0; j < parts.length; ++j) { + let line = ''; + for (let j = 0; j < parts.length; ++j) { line += '|'; if (functions[j]) { line += parts[j](this); @@ -1552,15 +1554,15 @@ BattleSide = (function () { return; } - var decisions = []; + let decisions = []; switch (this.currentRequest) { case 'move': - for (var i = 0; i < this.active.length; i++) { - var pokemon = this.active[i]; + for (let i = 0; i < this.active.length; i++) { + let pokemon = this.active[i]; if (!pokemon || pokemon.fainted) continue; - var lockedMove = pokemon.getLockedMove(); + let lockedMove = pokemon.getLockedMove(); if (lockedMove) { decisions.push({ choice: 'move', @@ -1571,9 +1573,9 @@ BattleSide = (function () { continue; } - var moveid = 'struggle'; - var moves = pokemon.getMoves(); - for (var j = 0; j < moves.length; j++) { + let moveid = 'struggle'; + let moves = pokemon.getMoves(); + for (let j = 0; j < moves.length; j++) { if (moves[j].disabled) continue; moveid = moves[j].id; break; @@ -1587,26 +1589,26 @@ BattleSide = (function () { } break; - case 'switch': - var canSwitchOut = []; - for (var i = 0; i < this.active.length; i++) { + case 'switch': { + let canSwitchOut = []; + for (let i = 0; i < this.active.length; i++) { if (this.active[i] && this.active[i].switchFlag) canSwitchOut.push(i); } - var canSwitchIn = []; - for (var i = this.active.length; i < this.pokemon.length; i++) { + let canSwitchIn = []; + for (let i = this.active.length; i < this.pokemon.length; i++) { if (this.pokemon[i] && !this.pokemon[i].fainted) canSwitchIn.push(i); } - var willPass = canSwitchOut.splice(Math.min(canSwitchOut.length, canSwitchIn.length)); - for (var i = 0; i < canSwitchOut.length; i++) { + let willPass = canSwitchOut.splice(Math.min(canSwitchOut.length, canSwitchIn.length)); + for (let i = 0; i < canSwitchOut.length; i++) { decisions.push({ choice: this.foe.currentRequest === 'switch' ? 'instaswitch' : 'switch', pokemon: this.active[canSwitchOut[i]], target: this.pokemon[canSwitchIn[i]] }); } - for (var i = 0; i < willPass.length; i++) { + for (let i = 0; i < willPass.length; i++) { decisions.push({ choice: 'pass', pokemon: this.active[willPass[i]], @@ -1614,6 +1616,7 @@ BattleSide = (function () { }); } break; + } case 'teampreview': decisions.push({ @@ -1630,12 +1633,12 @@ BattleSide = (function () { // deallocate ourself // deallocate children and get rid of references to them - for (var i = 0; i < this.pokemon.length; i++) { + for (let i = 0; i < this.pokemon.length; i++) { if (this.pokemon[i]) this.pokemon[i].destroy(); this.pokemon[i] = null; } this.pokemon = null; - for (var i = 0; i < this.active.length; i++) { + for (let i = 0; i < this.active.length; i++) { this.active[i] = null; } this.active = null; @@ -1654,23 +1657,23 @@ BattleSide = (function () { })(); Battle = (function () { - var Battle = {}; + let Battle = {}; Battle.construct = (function () { - var battleProtoCache = {}; + let battleProtoCache = {}; return function (roomid, formatarg, rated) { - var battle = Object.create((function () { + let battle = Object.create((function () { if (battleProtoCache[formatarg] !== undefined) { return battleProtoCache[formatarg]; } // Scripts overrides Battle overrides Scripts overrides Tools - var tools = Tools.mod(formatarg); - var proto = Object.create(tools); - for (var i in Battle.prototype) { + let tools = Tools.mod(formatarg); + let proto = Object.create(tools); + for (let i in Battle.prototype) { proto[i] = Battle.prototype[i]; } - var battle = Object.create(proto); + let battle = Object.create(proto); tools.install(battle); return (battleProtoCache[formatarg] = battle); })()); @@ -1687,7 +1690,7 @@ Battle = (function () { Battle.prototype = {}; Battle.prototype.init = function (roomid, formatarg, rated) { - var format = Tools.getFormat(formatarg); + let format = Tools.getFormat(formatarg); this.log = []; this.sides = [null, null]; @@ -1760,7 +1763,7 @@ Battle = (function () { /* Battle.prototype.random = function (m, n) { this.seed = (this.seed * 0x41C64E6D + 0x6073) >>> 0; // truncate the result to the last 32 bits - var result = this.seed >>> 16; // the first 16 bits of the seed are the random value + let result = this.seed >>> 16; // the first 16 bits of the seed are the random value m = Math.floor(m); n = Math.floor(n); return (m ? (n ? (result % (n - m)) + m : result % m) : result / 0x10000); @@ -1778,7 +1781,7 @@ Battle = (function () { Battle.prototype.random = function (m, n) { this.seed = this.nextFrame(); // Advance the RNG - var result = (this.seed[0] << 16 >>> 0) + this.seed[1]; // Use the upper 32 bits + let result = (this.seed[0] << 16 >>> 0) + this.seed[1]; // Use the upper 32 bits m = Math.floor(m); n = Math.floor(n); result = (m ? (n ? Math.floor(result * (n - m) / 0x100000000) + m : Math.floor(result * m / 0x100000000)) : result / 0x100000000); @@ -1787,9 +1790,9 @@ Battle = (function () { }; Battle.prototype.nextFrame = function (n) { - var seed = this.seed; + let seed = this.seed; n = n || 1; - for (var frame = 0; frame < n; ++frame) { + for (let frame = 0; frame < n; ++frame) { // The RNG is a Linear Congruential Generator (LCG) in the form: x_{n + 1} = (a x_n + c) % m // Where: x_0 is the seed, x_n is the random number after n iterations, // a = 0x5D588B656C078965, c = 0x00269EC3 and m = 2^64 @@ -1815,20 +1818,20 @@ Battle = (function () { // This is all ignoring overflow/carry because that cannot be shown in a pseudo-mathematical equation. // The below code implements a optimised version of that equation while also checking for overflow/carry. - var a = [0x5D58, 0x8B65, 0x6C07, 0x8965]; - var c = [0, 0, 0x26, 0x9EC3]; + let a = [0x5D58, 0x8B65, 0x6C07, 0x8965]; + let c = [0, 0, 0x26, 0x9EC3]; - var nextSeed = [0, 0, 0, 0]; - var carry = 0; + let nextSeed = [0, 0, 0, 0]; + let carry = 0; - for (var cN = seed.length - 1; cN >= 0; --cN) { + for (let cN = seed.length - 1; cN >= 0; --cN) { nextSeed[cN] = carry; carry = 0; - var aN = seed.length - 1; - var seedN = cN; + let aN = seed.length - 1; + let seedN = cN; for (; seedN < seed.length; --aN, ++seedN) { - var nextWord = a[aN] * seed[seedN]; + let nextWord = a[aN] * seed[seedN]; carry += nextWord >>> 16; nextSeed[cN] += nextWord & 0xFFFF; } @@ -1851,7 +1854,7 @@ Battle = (function () { return false; } if (status.id) { - var result = this.runEvent('SetWeather', source, source, status); + let result = this.runEvent('SetWeather', source, source, status); if (!result) { if (result === false) { if (sourceEffect && sourceEffect.weather) { @@ -1864,11 +1867,11 @@ Battle = (function () { } } if (this.weather && !status.id) { - var oldstatus = this.getWeather(); + let oldstatus = this.getWeather(); this.singleEvent('End', oldstatus, this.weatherData, this); } - var prevWeather = this.weather; - var prevWeatherData = this.weatherData; + let prevWeather = this.weather; + let prevWeatherData = this.weatherData; this.weather = status.id; this.weatherData = {id: status.id}; if (source) { @@ -1900,7 +1903,7 @@ Battle = (function () { return this.weather; }; Battle.prototype.isWeather = function (weather, target) { - var ourWeather = this.effectiveWeather(target); + let ourWeather = this.effectiveWeather(target); if (!Array.isArray(weather)) { return ourWeather === toId(weather); } @@ -1917,11 +1920,11 @@ Battle = (function () { if (this.terrain === status.id) return false; if (this.terrain && !status.id) { - var oldstatus = this.getTerrain(); + let oldstatus = this.getTerrain(); this.singleEvent('End', oldstatus, this.terrainData, this); } - var prevTerrain = this.terrain; - var prevTerrainData = this.terrainData; + let prevTerrain = this.terrain; + let prevTerrainData = this.terrainData; this.terrain = status.id; this.terrainData = {id: status.id}; if (source) { @@ -1953,7 +1956,7 @@ Battle = (function () { return this.terrain; }; Battle.prototype.isTerrain = function (terrain, target) { - var ourTerrain = this.effectiveTerrain(target); + let ourTerrain = this.effectiveTerrain(target); if (!Array.isArray(terrain)) { return ourTerrain === toId(terrain); } @@ -2007,9 +2010,9 @@ Battle = (function () { return (this.activePokemon && this.activePokemon.isActive && !this.activePokemon.ignoringAbility() && this.activePokemon.getAbility().stopAttackEvents); }; Battle.prototype.suppressingWeather = function () { - var pokemon; - for (var i = 0; i < this.sides.length; i++) { - for (var j = 0; j < this.sides[i].active.length; j++) { + let pokemon; + for (let i = 0; i < this.sides.length; i++) { + for (let j = 0; j < this.sides[i].active.length; j++) { pokemon = this.sides[i].active[j]; if (pokemon && !pokemon.ignoringAbility() && pokemon.getAbility().suppressWeather) { return true; @@ -2044,12 +2047,12 @@ Battle = (function () { }; Battle.prototype.update = function () { - var actives = this.p1.active; - for (var i = 0; i < actives.length; i++) { + let actives = this.p1.active; + for (let i = 0; i < actives.length; i++) { if (actives[i]) actives[i].update(); } actives = this.p2.active; - for (var i = 0; i < actives.length; i++) { + for (let i = 0; i < actives.length; i++) { if (actives[i]) actives[i].update(); } }; @@ -2085,17 +2088,17 @@ Battle = (function () { return Math.random() - 0.5; }; Battle.prototype.getResidualStatuses = function (thing, callbackType) { - var statuses = this.getRelevantEffectsInner(thing || this, callbackType || 'residualCallback', null, null, false, true, 'duration'); + let statuses = this.getRelevantEffectsInner(thing || this, callbackType || 'residualCallback', null, null, false, true, 'duration'); statuses.sort(Battle.comparePriority); //if (statuses[0]) this.debug('match ' + (callbackType || 'residualCallback') + ': ' + statuses[0].status.id); return statuses; }; Battle.prototype.eachEvent = function (eventid, effect, relayVar) { - var actives = []; + let actives = []; if (!effect && this.effect) effect = this.effect; - for (var i = 0; i < this.sides.length; i++) { - var side = this.sides[i]; - for (var j = 0; j < side.active.length; j++) { + for (let i = 0; i < this.sides.length; i++) { + let side = this.sides[i]; + for (let j = 0; j < side.active.length; j++) { if (side.active[j]) actives.push(side.active[j]); } } @@ -2105,18 +2108,18 @@ Battle = (function () { } return Math.random() - 0.5; }); - for (var i = 0; i < actives.length; i++) { + for (let i = 0; i < actives.length; i++) { if (actives[i].isStarted) { this.runEvent(eventid, actives[i], null, effect, relayVar); } } }; Battle.prototype.residualEvent = function (eventid, relayVar) { - var statuses = this.getRelevantEffectsInner(this, 'on' + eventid, null, null, false, true, 'duration'); + let statuses = this.getRelevantEffectsInner(this, 'on' + eventid, null, null, false, true, 'duration'); statuses.sort(Battle.comparePriority); while (statuses.length) { - var statusObj = statuses.shift(); - var status = statusObj.status; + let statusObj = statuses.shift(); + let status = statusObj.status; if (statusObj.thing.fainted) continue; if (statusObj.statusData && statusObj.statusData.duration) { statusObj.statusData.duration--; @@ -2141,7 +2144,7 @@ Battle = (function () { } //this.add('Event: ' + eventid + ' (depth ' + this.eventDepth + ')'); effect = this.getEffect(effect); - var hasRelayVar = true; + let hasRelayVar = true; if (relayVar === undefined) { relayVar = true; hasRelayVar = false; @@ -2165,16 +2168,16 @@ Battle = (function () { } if (effect['on' + eventid] === undefined) return relayVar; - var parentEffect = this.effect; - var parentEffectData = this.effectData; - var parentEvent = this.event; + let parentEffect = this.effect; + let parentEffectData = this.effectData; + let parentEvent = this.event; this.effect = effect; this.effectData = effectData; this.event = {id: eventid, target: target, source: source, effect: sourceEffect}; this.eventDepth++; - var args = [target, source, sourceEffect]; + let args = [target, source, sourceEffect]; if (hasRelayVar) args.unshift(relayVar); - var returnVal; + let returnVal; if (typeof effect['on' + eventid] === 'function') { returnVal = effect['on' + eventid].apply(this, args); } else { @@ -2301,10 +2304,10 @@ Battle = (function () { throw new Error("Stack overflow"); } if (!target) target = this; - var statuses = this.getRelevantEffects(target, 'on' + eventid, 'onSource' + eventid, source); - var hasRelayVar = true; + let statuses = this.getRelevantEffects(target, 'on' + eventid, 'onSource' + eventid, source); + let hasRelayVar = true; effect = this.getEffect(effect); - var args = [target, source, effect]; + let args = [target, source, effect]; //console.log('Event: ' + eventid + ' (depth ' + this.eventDepth + ') t:' + target.id + ' s:' + (!source || source.id) + ' e:' + effect.id); if (relayVar === undefined || relayVar === null) { relayVar = true; @@ -2313,16 +2316,16 @@ Battle = (function () { args.unshift(relayVar); } - var parentEvent = this.event; + let parentEvent = this.event; this.event = {id: eventid, target: target, source: source, effect: effect, modifier: 1}; this.eventDepth++; if (onEffect && 'on' + eventid in effect) { statuses.unshift({status: effect, callback: effect['on' + eventid], statusData: {}, end: null, thing: target}); } - for (var i = 0; i < statuses.length; i++) { - var status = statuses[i].status; - var thing = statuses[i].thing; + for (let i = 0; i < statuses.length; i++) { + let status = statuses[i].status; + let thing = statuses[i].thing; //this.debug('match ' + eventid + ': ' + status.id + ' ' + status.effectType); if (status.effectType === 'Status' && thing.status !== status.id) { // it's changed; call it off @@ -2330,7 +2333,7 @@ Battle = (function () { } if (status.effectType === 'Ability' && this.suppressingAttackEvents() && this.activePokemon !== thing) { // ignore attacking events - var AttackingEvents = { + let AttackingEvents = { BeforeMove: 1, BasePower: 1, Immunity: 1, @@ -2376,10 +2379,10 @@ Battle = (function () { this.debug(eventid + ' handler suppressed by Air Lock'); continue; } - var returnVal; + let returnVal; if (typeof statuses[i].callback === 'function') { - var parentEffect = this.effect; - var parentEffectData = this.effectData; + let parentEffect = this.effect; + let parentEffectData = this.effectData; this.effect = statuses[i].status; this.effectData = statuses[i].statusData; this.effectData.target = thing; @@ -2411,10 +2414,10 @@ Battle = (function () { return relayVar; }; Battle.prototype.resolveLastPriority = function (statuses, callbackType) { - var order = false; - var priority = 0; - var subOrder = 0; - var status = statuses[statuses.length - 1]; + let order = false; + let priority = 0; + let subOrder = 0; + let status = statuses[statuses.length - 1]; if (status.status[callbackType + 'Order']) { order = status.status[callbackType + 'Order']; } @@ -2431,18 +2434,18 @@ Battle = (function () { }; // bubbles up to parents Battle.prototype.getRelevantEffects = function (thing, callbackType, foeCallbackType, foeThing) { - var statuses = this.getRelevantEffectsInner(thing, callbackType, foeCallbackType, foeThing, true, false); + let statuses = this.getRelevantEffectsInner(thing, callbackType, foeCallbackType, foeThing, true, false); statuses.sort(Battle.comparePriority); //if (statuses[0]) this.debug('match ' + callbackType + ': ' + statuses[0].status.id); return statuses; }; Battle.prototype.getRelevantEffectsInner = function (thing, callbackType, foeCallbackType, foeThing, bubbleUp, bubbleDown, getAll) { if (!callbackType || !thing) return []; - var statuses = []; - var status; + let statuses = []; + let status; if (thing.sides) { - for (var i in this.pseudoWeather) { + for (let i in this.pseudoWeather) { status = this.getPseudoWeather(i); if (status[callbackType] !== undefined || (getAll && thing.pseudoWeather[i][getAll])) { statuses.push({status: status, callback: status[callbackType], statusData: this.pseudoWeather[i], end: this.removePseudoWeather, thing: thing}); @@ -2465,9 +2468,9 @@ Battle = (function () { this.resolveLastPriority(statuses, callbackType); } if (this.events && this.events[callbackType] !== undefined) { - var handler, statusData; - for (var i = 0; i < this.events[callbackType].length; i++) { - handler = this.events[callbackType][i]; + for (let i = 0; i < this.events[callbackType].length; i++) { + let handler = this.events[callbackType][i]; + let statusData; switch (handler.target.effectType) { case 'Format': statusData = this.formatData; @@ -2483,7 +2486,7 @@ Battle = (function () { } if (thing.pokemon) { - for (var i in thing.sideConditions) { + for (let i in thing.sideConditions) { status = thing.getSideCondition(i); if (status[callbackType] !== undefined || (getAll && thing.sideConditions[i][getAll])) { statuses.push({status: status, callback: status[callbackType], statusData: thing.sideConditions[i], end: thing.removeSideCondition, thing: thing}); @@ -2493,7 +2496,7 @@ Battle = (function () { if (foeCallbackType) { statuses = statuses.concat(this.getRelevantEffectsInner(thing.foe, foeCallbackType, null, null, false, false, getAll)); if (foeCallbackType.substr(0, 5) === 'onFoe') { - var eventName = foeCallbackType.substr(5); + let eventName = foeCallbackType.substr(5); statuses = statuses.concat(this.getRelevantEffectsInner(thing.foe, 'onAny' + eventName, null, null, false, false, getAll)); statuses = statuses.concat(this.getRelevantEffectsInner(thing, 'onAny' + eventName, null, null, false, false, getAll)); } @@ -2502,7 +2505,7 @@ Battle = (function () { statuses = statuses.concat(this.getRelevantEffectsInner(this, callbackType, null, null, true, false, getAll)); } if (bubbleDown) { - for (var i = 0; i < thing.active.length; i++) { + for (let i = 0; i < thing.active.length; i++) { statuses = statuses.concat(this.getRelevantEffectsInner(thing.active[i], callbackType, null, null, false, true, getAll)); } } @@ -2513,12 +2516,12 @@ Battle = (function () { //this.debug(JSON.stringify(thing)); return statuses; } - var status = thing.getStatus(); + status = thing.getStatus(); if (status[callbackType] !== undefined || (getAll && thing.statusData[getAll])) { statuses.push({status: status, callback: status[callbackType], statusData: thing.statusData, end: thing.clearStatus, thing: thing}); this.resolveLastPriority(statuses, callbackType); } - for (var i in thing.volatiles) { + for (let i in thing.volatiles) { status = thing.getVolatile(i); if (status[callbackType] !== undefined || (getAll && thing.volatiles[i][getAll])) { statuses.push({status: status, callback: status[callbackType], statusData: thing.volatiles[i], end: thing.removeVolatile, thing: thing}); @@ -2544,9 +2547,9 @@ Battle = (function () { if (foeThing && foeCallbackType && foeCallbackType.substr(0, 8) !== 'onSource') { statuses = statuses.concat(this.getRelevantEffectsInner(foeThing, foeCallbackType, null, null, false, false, getAll)); } else if (foeCallbackType) { - var foeActive = thing.side.foe.active; - var allyActive = thing.side.active; - var eventName = ''; + let foeActive = thing.side.foe.active; + let allyActive = thing.side.active; + let eventName = ''; if (foeCallbackType.substr(0, 8) === 'onSource') { eventName = foeCallbackType.substr(8); if (foeThing) { @@ -2557,17 +2560,17 @@ Battle = (function () { } if (foeCallbackType.substr(0, 5) === 'onFoe') { eventName = foeCallbackType.substr(5); - for (var i = 0; i < allyActive.length; i++) { + for (let i = 0; i < allyActive.length; i++) { if (!allyActive[i] || allyActive[i].fainted) continue; statuses = statuses.concat(this.getRelevantEffectsInner(allyActive[i], 'onAlly' + eventName, null, null, false, false, getAll)); statuses = statuses.concat(this.getRelevantEffectsInner(allyActive[i], 'onAny' + eventName, null, null, false, false, getAll)); } - for (var i = 0; i < foeActive.length; i++) { + for (let i = 0; i < foeActive.length; i++) { if (!foeActive[i] || foeActive[i].fainted) continue; statuses = statuses.concat(this.getRelevantEffectsInner(foeActive[i], 'onAny' + eventName, null, null, false, false, getAll)); } } - for (var i = 0; i < foeActive.length; i++) { + for (let i = 0; i < foeActive.length; i++) { if (!foeActive[i] || foeActive[i].fainted) continue; statuses = statuses.concat(this.getRelevantEffectsInner(foeActive[i], foeCallbackType, null, null, false, false, getAll)); } @@ -2594,15 +2597,15 @@ Battle = (function () { * order, and subOrder for the evend handler as needed (undefined keys will use default values) */ Battle.prototype.on = function (eventid, target /*[, priority], callback*/) { - if (!eventid) throw TypeError("Event handlers must have an event to listen to"); - if (!target) throw TypeError("Event handlers must have a target"); - if (arguments.length < 3) throw TypeError("Event handlers must have a callback"); + if (!eventid) throw new TypeError("Event handlers must have an event to listen to"); + if (!target) throw new TypeError("Event handlers must have a target"); + if (arguments.length < 3) throw new TypeError("Event handlers must have a callback"); if (target.effectType !== 'Format') { - throw TypeError("" + target.effectType + " targets are not supported at this time"); + throw new TypeError("" + target.effectType + " targets are not supported at this time"); } - var callback, priority, order, subOrder; + let callback, priority, order, subOrder; if (arguments.length === 3) { callback = arguments[2]; priority = 0; @@ -2610,7 +2613,7 @@ Battle = (function () { subOrder = 0; } else { callback = arguments[3]; - var data = arguments[2]; + let data = arguments[2]; if (typeof data === 'object') { priority = data['priority'] || 0; order = data['order'] || false; @@ -2622,9 +2625,9 @@ Battle = (function () { } } - var eventHandler = {callback: callback, target: target, priority: priority, order: order, subOrder: subOrder}; + let eventHandler = {callback: callback, target: target, priority: priority, order: order, subOrder: subOrder}; - var callbackType = 'on' + eventid; + let callbackType = 'on' + eventid; if (!this.events) this.events = {}; if (this.events[callbackType] === undefined) { this.events[callbackType] = [eventHandler]; @@ -2634,12 +2637,12 @@ Battle = (function () { }; Battle.prototype.getPokemon = function (id) { if (typeof id !== 'string') id = id.id; - for (var i = 0; i < this.p1.pokemon.length; i++) { - var pokemon = this.p1.pokemon[i]; + for (let i = 0; i < this.p1.pokemon.length; i++) { + let pokemon = this.p1.pokemon[i]; if (pokemon.id === id) return pokemon; } - for (var i = 0; i < this.p2.pokemon.length; i++) { - var pokemon = this.p2.pokemon[i]; + for (let i = 0; i < this.p2.pokemon.length; i++) { + let pokemon = this.p2.pokemon[i]; if (pokemon.id === id) return pokemon; } return null; @@ -2658,17 +2661,16 @@ Battle = (function () { this.update(); // default to no request - var p1request = null; - var p2request = null; + let p1request = null; + let p2request = null; this.p1.currentRequest = ''; this.p2.currentRequest = ''; + let switchTable = []; switch (type) { - case 'switch': - var switchTable = []; - var active; - for (var i = 0, l = this.p1.active.length; i < l; i++) { - active = this.p1.active[i]; + case 'switch': { + for (let i = 0, l = this.p1.active.length; i < l; i++) { + let active = this.p1.active[i]; switchTable.push(!!(active && active.switchFlag)); } if (switchTable.any(true)) { @@ -2676,8 +2678,8 @@ Battle = (function () { p1request = {forceSwitch: switchTable, side: this.p1.getData(), rqid: this.rqid}; } switchTable = []; - for (var i = 0, l = this.p2.active.length; i < l; i++) { - active = this.p2.active[i]; + for (let i = 0, l = this.p2.active.length; i < l; i++) { + let active = this.p2.active[i]; switchTable.push(!!(active && active.switchFlag)); } if (switchTable.any(true)) { @@ -2685,6 +2687,7 @@ Battle = (function () { p2request = {forceSwitch: switchTable, side: this.p2.getData(), rqid: this.rqid}; } break; + } case 'teampreview': this.add('teampreview' + (requestDetails ? '|' + requestDetails : '')); @@ -2694,10 +2697,9 @@ Battle = (function () { p2request = {teamPreview: true, side: this.p2.getData(), rqid: this.rqid}; break; - default: - var activeData; + default: { this.p1.currentRequest = 'move'; - activeData = this.p1.active.map(function (pokemon) { + let activeData = this.p1.active.map(function (pokemon) { if (pokemon) return pokemon.getRequestData(); }); p1request = {active: activeData, side: this.p1.getData(), rqid: this.rqid}; @@ -2710,8 +2712,10 @@ Battle = (function () { break; } + } + if (this.p1 && this.p2) { - var inactiveSide = -1; + let inactiveSide = -1; if (p1request && !p2request) { inactiveSide = 0; } else if (!p1request && p2request) { @@ -2784,14 +2788,14 @@ Battle = (function () { Battle.prototype.switchIn = function (pokemon, pos) { if (!pokemon || pokemon.isActive) return false; if (!pos) pos = 0; - var side = pokemon.side; + let side = pokemon.side; if (pos >= side.active.length) { throw new Error("Invalid switch position"); } if (side.active[pos]) { - var oldActive = side.active[pos]; + let oldActive = side.active[pos]; if (this.cancelMove(oldActive)) { - for (var i = 0; i < side.foe.active.length; i++) { + for (let i = 0; i < side.foe.active.length; i++) { if (side.foe.active[i].isStale >= 2) { oldActive.isStaleCon++; oldActive.isStaleSource = 'drag'; @@ -2807,7 +2811,7 @@ Battle = (function () { pokemon.isActive = true; this.runEvent('BeforeSwitchIn', pokemon); if (side.active[pos]) { - var oldActive = side.active[pos]; + let oldActive = side.active[pos]; oldActive.isActive = false; oldActive.isStarted = false; oldActive.usedItemThisTurn = false; @@ -2820,7 +2824,7 @@ Battle = (function () { } side.active[pos] = pokemon; pokemon.activeTurns = 0; - for (var m in pokemon.moveset) { + for (let m in pokemon.moveset) { pokemon.moveset[m].used = false; } this.add('switch', pokemon, pokemon.getDetails); @@ -2828,9 +2832,9 @@ Battle = (function () { this.insertQueue({pokemon: pokemon, choice: 'runSwitch'}); }; Battle.prototype.canSwitch = function (side) { - var canSwitchIn = []; - for (var i = side.active.length; i < side.pokemon.length; i++) { - var pokemon = side.pokemon[i]; + let canSwitchIn = []; + for (let i = side.active.length; i < side.pokemon.length; i++) { + let pokemon = side.pokemon[i]; if (!pokemon.fainted) { canSwitchIn.push(pokemon); } @@ -2838,9 +2842,9 @@ Battle = (function () { return canSwitchIn.length; }; Battle.prototype.getRandomSwitchable = function (side) { - var canSwitchIn = []; - for (var i = side.active.length; i < side.pokemon.length; i++) { - var pokemon = side.pokemon[i]; + let canSwitchIn = []; + for (let i = side.active.length; i < side.pokemon.length; i++) { + let pokemon = side.pokemon[i]; if (!pokemon.fainted) { canSwitchIn.push(pokemon); } @@ -2852,12 +2856,12 @@ Battle = (function () { }; Battle.prototype.dragIn = function (side, pos) { if (pos >= side.active.length) return false; - var pokemon = this.getRandomSwitchable(side); + let pokemon = this.getRandomSwitchable(side); if (!pos) pos = 0; if (!pokemon || pokemon.isActive) return false; this.runEvent('BeforeSwitchIn', pokemon); if (side.active[pos]) { - var oldActive = side.active[pos]; + let oldActive = side.active[pos]; if (!oldActive.hp) { return false; } @@ -2874,7 +2878,7 @@ Battle = (function () { side.pokemon[pokemon.position] = pokemon; side.pokemon[oldActive.position] = oldActive; if (this.cancelMove(oldActive)) { - for (var i = 0; i < side.foe.active.length; i++) { + for (let i = 0; i < side.foe.active.length; i++) { if (side.foe.active[i].isStale >= 2) { oldActive.isStaleCon++; oldActive.isStaleSource = 'drag'; @@ -2888,7 +2892,7 @@ Battle = (function () { pokemon.isActive = true; pokemon.activeTurns = 0; if (this.gen === 2) pokemon.draggedIn = this.turn; - for (var m in pokemon.moveset) { + for (let m in pokemon.moveset) { pokemon.moveset[m].used = false; } this.add('drag', pokemon, pokemon.getDetails); @@ -2910,12 +2914,12 @@ Battle = (function () { if (slot >= pokemon.side.active.length) { throw new Error("Invalid swap position"); } - var target = pokemon.side.active[slot]; + let target = pokemon.side.active[slot]; if (slot !== 1 && (!target || target.fainted)) return false; this.add('swap', pokemon, slot, attributes || ''); - var side = pokemon.side; + let side = pokemon.side; side.pokemon[pokemon.position] = target; side.pokemon[slot] = pokemon; side.active[pokemon.position] = side.pokemon[pokemon.position]; @@ -2929,11 +2933,11 @@ Battle = (function () { }; Battle.prototype.nextTurn = function () { this.turn++; - var allStale = true; - var oneStale = false; - for (var i = 0; i < this.sides.length; i++) { - for (var j = 0; j < this.sides[i].active.length; j++) { - var pokemon = this.sides[i].active[j]; + let allStale = true; + let oneStale = false; + for (let i = 0; i < this.sides.length; i++) { + for (let j = 0; j < this.sides[i].active.length; j++) { + let pokemon = this.sides[i].active[j]; if (!pokemon) continue; pokemon.moveThisTurn = ''; pokemon.usedItemThisTurn = false; @@ -3006,12 +3010,12 @@ Battle = (function () { this.sides[i].faintedLastTurn = this.sides[i].faintedThisTurn; this.sides[i].faintedThisTurn = false; } - var banlistTable = this.getFormat().banlistTable; + let banlistTable = this.getFormat().banlistTable; if (banlistTable && 'Rule:endlessbattleclause' in banlistTable) { if (oneStale) { - var activationWarning = '
If all active Pokémon go in an endless loop, Endless Battle Clause will activate.'; + let activationWarning = '
If all active Pokémon go in an endless loop, Endless Battle Clause will activate.'; if (allStale) activationWarning = ''; - var loopReason = ''; + let loopReason = ''; switch (oneStale.isStaleSource) { case 'struggle': loopReason = ": it isn't losing HP from Struggle"; @@ -3041,10 +3045,10 @@ Battle = (function () { } if (allStale) { this.add('message', "All active Pok\u00e9mon are in an endless loop. Endless Battle Clause activated!"); - var leppaPokemon = null; - for (var i = 0; i < this.sides.length; i++) { - for (var j = 0; j < this.sides[i].pokemon.length; j++) { - var pokemon = this.sides[i].pokemon[j]; + let leppaPokemon = null; + for (let i = 0; i < this.sides.length; i++) { + for (let j = 0; j < this.sides[i].pokemon.length; j++) { + let pokemon = this.sides[i].pokemon[j]; if (toId(pokemon.set.item) === 'leppaberry') { if (leppaPokemon) { leppaPokemon = null; // both sides have Leppa @@ -3076,9 +3080,9 @@ Battle = (function () { if (this.gameType === 'triples' && this.sides.map('pokemonLeft').count(1) === this.sides.length) { // If both sides have one Pokemon left in triples and they are not adjacent, they are both moved to the center. - var center = false; - for (var i = 0; i < this.sides.length; i++) { - for (var j = 0; j < this.sides[i].active.length; j++) { + let center = false; + for (let i = 0; i < this.sides.length; i++) { + for (let j = 0; j < this.sides[i].active.length; j++) { if (!this.sides[i].active[j] || this.sides[i].active[j].fainted) continue; if (this.sides[i].active[j].position === 1) break; this.swapPosition(this.sides[i].active[j], 1, '[silent]'); @@ -3119,7 +3123,7 @@ Battle = (function () { this.add('gametype', this.gameType); this.add('gen', this.gen); - var format = this.getFormat(); + let format = this.getFormat(); Tools.mod(format.mod).getBanlistTable(format); // fill in format ruleset this.add('tier', format.name); @@ -3128,7 +3132,7 @@ Battle = (function () { } this.add('seed', Battle.logReplay.bind(this, this.startingSeed.join(','))); if (format && format.ruleset) { - for (var i = 0; i < format.ruleset.length; i++) { + for (let i = 0; i < format.ruleset.length; i++) { this.addPseudoWeather(format.ruleset[i]); } } @@ -3154,14 +3158,14 @@ Battle = (function () { if (!target.isActive) return false; effect = this.getEffect(effect); boost = this.runEvent('Boost', target, source, effect, Object.clone(boost)); - var success = false; - var boosted = false; - for (var i in boost) { - var currentBoost = {}; + let success = false; + let boosted = false; + for (let i in boost) { + let currentBoost = {}; currentBoost[i] = boost[i]; if (boost[i] !== 0 && target.boostBy(currentBoost)) { success = true; - var msg = '-boost'; + let msg = '-boost'; if (boost[i] < 0) { msg = '-unboost'; boost[i] = -boost[i]; @@ -3226,7 +3230,7 @@ Battle = (function () { if (damage !== 0) damage = this.clampIntRange(damage, 1); damage = target.damage(damage, source, effect); if (source) source.lastDamage = damage; - var name = effect.fullname; + let name = effect.fullname; if (name === 'tox') name = 'psn'; switch (effect.id) { case 'partiallytrapped': @@ -3344,13 +3348,13 @@ Battle = (function () { return ((previousMod * nextMod + 2048) >> 12) / 4096; // M'' = ((M * M') + 0x800) >> 12 }; Battle.prototype.chainModify = function (numerator, denominator) { - var previousMod = Math.floor(this.event.modifier * 4096); + let previousMod = Math.floor(this.event.modifier * 4096); if (numerator.length) { denominator = numerator[1]; numerator = numerator[0]; } - var nextMod = 0; + let nextMod = 0; if (this.event.ceilModifier) { nextMod = Math.ceil(numerator * 4096 / (denominator || 1)); } else { @@ -3368,7 +3372,7 @@ Battle = (function () { denominator = numerator[1]; numerator = numerator[0]; } - var modifier = Math.floor(numerator * 4096 / denominator); + let modifier = Math.floor(numerator * 4096 / denominator); return Math.floor((value * modifier + 2048 - 1) / 4096); }; Battle.prototype.getCategory = function (move) { @@ -3409,12 +3413,12 @@ Battle = (function () { move = {}; } if (!move.type) move.type = '???'; - var type = move.type; + let type = move.type; // '???' is typeless damage: used for Struggle and Confusion etc - var category = this.getCategory(move); - var defensiveCategory = move.defensiveCategory || category; + let category = this.getCategory(move); + let defensiveCategory = move.defensiveCategory || category; - var basePower = move.basePower; + let basePower = move.basePower; if (move.basePowerCallback) { basePower = move.basePowerCallback.call(this, pokemon, target, move); } @@ -3424,7 +3428,7 @@ Battle = (function () { } basePower = this.clampIntRange(basePower, 1); - var critMult; + let critMult; if (this.gen <= 5) { move.critRatio = this.clampIntRange(move.critRatio, 0, 5); critMult = [0, 16, 8, 4, 3, 2]; @@ -3450,28 +3454,28 @@ Battle = (function () { if (!basePower) return 0; basePower = this.clampIntRange(basePower, 1); - var level = pokemon.level; + let level = pokemon.level; - var attacker = pokemon; - var defender = target; - var attackStat = category === 'Physical' ? 'atk' : 'spa'; - var defenseStat = defensiveCategory === 'Physical' ? 'def' : 'spd'; - var statTable = {atk:'Atk', def:'Def', spa:'SpA', spd:'SpD', spe:'Spe'}; - var attack; - var defense; + let attacker = pokemon; + let defender = target; + let attackStat = category === 'Physical' ? 'atk' : 'spa'; + let defenseStat = defensiveCategory === 'Physical' ? 'def' : 'spd'; + let statTable = {atk:'Atk', def:'Def', spa:'SpA', spd:'SpD', spe:'Spe'}; + let attack; + let defense; - var atkBoosts = move.useTargetOffensive ? defender.boosts[attackStat] : attacker.boosts[attackStat]; - var defBoosts = move.useSourceDefensive ? attacker.boosts[defenseStat] : defender.boosts[defenseStat]; + let atkBoosts = move.useTargetOffensive ? defender.boosts[attackStat] : attacker.boosts[attackStat]; + let defBoosts = move.useSourceDefensive ? attacker.boosts[defenseStat] : defender.boosts[defenseStat]; - var ignoreNegativeOffensive = !!move.ignoreNegativeOffensive; - var ignorePositiveDefensive = !!move.ignorePositiveDefensive; + let ignoreNegativeOffensive = !!move.ignoreNegativeOffensive; + let ignorePositiveDefensive = !!move.ignorePositiveDefensive; if (move.crit) { ignoreNegativeOffensive = true; ignorePositiveDefensive = true; } - var ignoreOffensive = !!(move.ignoreOffensive || (ignoreNegativeOffensive && atkBoosts < 0)); - var ignoreDefensive = !!(move.ignoreDefensive || (ignorePositiveDefensive && defBoosts > 0)); + let ignoreOffensive = !!(move.ignoreOffensive || (ignoreNegativeOffensive && atkBoosts < 0)); + let ignoreDefensive = !!(move.ignoreDefensive || (ignorePositiveDefensive && defBoosts > 0)); if (ignoreOffensive) { this.debug('Negating (sp)atk boost/penalty.'); @@ -3499,11 +3503,11 @@ Battle = (function () { defense = this.runEvent('Modify' + statTable[defenseStat], defender, attacker, move, defense); //int(int(int(2 * L / 5 + 2) * A * P / D) / 50); - var baseDamage = Math.floor(Math.floor(Math.floor(2 * level / 5 + 2) * basePower * attack / defense) / 50) + 2; + 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) { - var spreadModifier = move.spreadModifier || 0.75; + let spreadModifier = move.spreadModifier || 0.75; this.debug('Spread modifier: ' + spreadModifier); baseDamage = this.modify(baseDamage, spreadModifier); } @@ -3534,14 +3538,14 @@ Battle = (function () { if (move.typeMod > 0) { if (!suppressMessages) this.add('-supereffective', target); - for (var i = 0; i < move.typeMod; i++) { + for (let i = 0; i < move.typeMod; i++) { baseDamage *= 2; } } if (move.typeMod < 0) { if (!suppressMessages) this.add('-resisted', target); - for (var i = 0; i > move.typeMod; i--) { + for (let i = 0; i > move.typeMod; i--) { baseDamage = Math.floor(baseDamage / 2); } } @@ -3575,13 +3579,13 @@ Battle = (function () { * Returns whether a proposed target for a move is valid. */ Battle.prototype.validTargetLoc = function (targetLoc, source, targetType) { - var numSlots = source.side.active.length; + let numSlots = source.side.active.length; if (!Math.abs(targetLoc) && Math.abs(targetLoc) > numSlots) return false; - var sourceLoc = -(source.position + 1); - var isFoe = (targetLoc > 0); - var isAdjacent = (isFoe ? Math.abs(-(numSlots + 1 - targetLoc) - sourceLoc) <= 1 : Math.abs(targetLoc - sourceLoc) === 1); - var isSelf = (sourceLoc === targetLoc); + let sourceLoc = -(source.position + 1); + let isFoe = (targetLoc > 0); + let isAdjacent = (isFoe ? Math.abs(-(numSlots + 1 - targetLoc) - sourceLoc) <= 1 : Math.abs(targetLoc - sourceLoc) === 1); + let isSelf = (sourceLoc === targetLoc); switch (targetType) { case 'randomNormal': @@ -3609,8 +3613,8 @@ Battle = (function () { return this.validTargetLoc(this.getTargetLoc(target, source), source, targetType); }; Battle.prototype.getTarget = function (decision) { - var move = this.getMove(decision.move); - var target; + let move = this.getMove(decision.move); + let target; if ((move.target !== 'randomNormal') && this.validTargetLoc(decision.targetLoc, decision.pokemon, move.target)) { if (decision.targetLoc > 0) { @@ -3649,7 +3653,7 @@ Battle = (function () { move = this.getMove(move); if (move.target === 'adjacentAlly') { - var adjacentAllies = [pokemon.side.active[pokemon.position - 1], pokemon.side.active[pokemon.position + 1]].filter(function (active) { + let adjacentAllies = [pokemon.side.active[pokemon.position - 1], pokemon.side.active[pokemon.position + 1]].filter(function (active) { return active && !active.fainted; }); if (adjacentAllies.length) return adjacentAllies[Math.floor(Math.random() * adjacentAllies.length)]; @@ -3660,9 +3664,9 @@ Battle = (function () { } if (pokemon.side.active.length > 2) { if (move.target === 'adjacentFoe' || move.target === 'normal' || move.target === 'randomNormal') { - var foeActives = pokemon.side.foe.active; - var frontPosition = foeActives.length - 1 - pokemon.position; - var adjacentFoes = foeActives.slice(frontPosition < 1 ? 0 : frontPosition - 1, frontPosition + 2).filter(function (active) { + let foeActives = pokemon.side.foe.active; + let frontPosition = foeActives.length - 1 - pokemon.position; + let adjacentFoes = foeActives.slice(frontPosition < 1 ? 0 : frontPosition - 1, frontPosition + 2).filter(function (active) { return active && !active.fainted; }); if (adjacentFoes.length) return adjacentFoes[Math.floor(Math.random() * adjacentFoes.length)]; @@ -3689,7 +3693,7 @@ Battle = (function () { if (lastFirst) { this.faintQueue.unshift(this.faintQueue.pop()); } - var faintData; + let faintData; while (this.faintQueue.length) { faintData = this.faintQueue.shift(); if (!faintData.target.fainted) { @@ -3709,10 +3713,10 @@ Battle = (function () { this.queue = []; } else if (this.gen <= 3 && this.gameType === 'singles') { // in gen 3 or earlier, fainting in singles skips to residuals - for (var i = 0; i < this.p1.active.length; i++) { + for (let i = 0; i < this.p1.active.length; i++) { this.cancelMove(this.p1.active[i]); } - for (var i = 0; i < this.p2.active.length; i++) { + for (let i = 0; i < this.p2.active.length; i++) { this.cancelMove(this.p2.active[i]); } } @@ -3736,7 +3740,7 @@ Battle = (function () { if (!decision.side && decision.pokemon) decision.side = decision.pokemon.side; if (!decision.choice && decision.move) decision.choice = 'move'; if (!decision.priority && decision.priority !== 0) { - var priorities = { + let priorities = { 'beforeTurn': 100, 'beforeTurnMove': 99, 'switch': 7, @@ -3763,7 +3767,7 @@ Battle = (function () { if (!decision.speed && decision.pokemon && decision.pokemon.isActive) decision.speed = decision.pokemon.speed; } if (decision.move) { - var target; + let target; if (!decision.targetPosition) { target = this.resolveTarget(decision.pokemon, decision.move); @@ -3773,7 +3777,7 @@ Battle = (function () { decision.move = this.getMoveCopy(decision.move); if (!decision.priority) { - var priority = decision.move.priority; + let priority = decision.move.priority; priority = this.runEvent('ModifyPriority', decision.pokemon, target, decision.move, priority); decision.priority = priority; // In Gen 6, Quick Guard blocks moves with artificially enhanced priority. @@ -3787,7 +3791,7 @@ Battle = (function () { }; Battle.prototype.addQueue = function (decision) { if (Array.isArray(decision)) { - for (var i = 0; i < decision.length; i++) { + for (let i = 0; i < decision.length; i++) { this.addQueue(decision[i]); } return; @@ -3801,14 +3805,14 @@ Battle = (function () { }; Battle.prototype.insertQueue = function (decision) { if (Array.isArray(decision)) { - for (var i = 0; i < decision.length; i++) { + for (let i = 0; i < decision.length; i++) { this.insertQueue(decision[i]); } return; } this.resolvePriority(decision); - for (var i = 0; i <= this.queue.length; i++) { + for (let i = 0; i <= this.queue.length; i++) { if (i === this.queue.length) { this.queue.push(decision); break; @@ -3823,7 +3827,7 @@ Battle = (function () { if (!source) source = this.event.source; if (!sourceEffect) sourceEffect = this.effect; } - for (var i = 0; i < this.queue.length; i++) { + for (let i = 0; i < this.queue.length; i++) { if (this.queue[i] === decision) { this.queue.splice(i, 1); break; @@ -3833,7 +3837,7 @@ Battle = (function () { this.queue.unshift(decision); }; Battle.prototype.willAct = function () { - for (var i = 0; i < this.queue.length; i++) { + for (let i = 0; i < this.queue.length; i++) { if (this.queue[i].choice === 'move' || this.queue[i].choice === 'switch' || this.queue[i].choice === 'instaswitch' || this.queue[i].choice === 'shift') { return this.queue[i]; } @@ -3841,7 +3845,7 @@ Battle = (function () { return null; }; Battle.prototype.willMove = function (pokemon) { - for (var i = 0; i < this.queue.length; i++) { + for (let i = 0; i < this.queue.length; i++) { if (this.queue[i].choice === 'move' && this.queue[i].pokemon === pokemon) { return this.queue[i]; } @@ -3849,8 +3853,8 @@ Battle = (function () { return null; }; Battle.prototype.cancelDecision = function (pokemon) { - var success = false; - for (var i = 0; i < this.queue.length; i++) { + let success = false; + for (let i = 0; i < this.queue.length; i++) { if (this.queue[i].pokemon === pokemon) { this.queue.splice(i, 1); i--; @@ -3860,7 +3864,7 @@ Battle = (function () { return success; }; Battle.prototype.cancelMove = function (pokemon) { - for (var i = 0; i < this.queue.length; i++) { + for (let i = 0; i < this.queue.length; i++) { if (this.queue[i].choice === 'move' && this.queue[i].pokemon === pokemon) { this.queue.splice(i, 1); return true; @@ -3869,7 +3873,7 @@ Battle = (function () { return false; }; Battle.prototype.willSwitch = function (pokemon) { - for (var i = 0; i < this.queue.length; i++) { + for (let i = 0; i < this.queue.length; i++) { if ((this.queue[i].choice === 'switch' || this.queue[i].choice === 'instaswitch') && this.queue[i].pokemon === pokemon) { return this.queue[i]; } @@ -3877,13 +3881,11 @@ Battle = (function () { return false; }; Battle.prototype.runDecision = function (decision) { - var pokemon; - // returns whether or not we ended in a callback switch (decision.choice) { - case 'start': + case 'start': { // I GIVE UP, WILL WRESTLE WITH EVENT SYSTEM LATER - var format = this.getFormat(); + let format = this.getFormat(); if (format.onBegin) format.onBegin.call(this); @@ -3896,22 +3898,24 @@ Battle = (function () { } this.add('start'); - for (var pos = 0; pos < this.p1.active.length; pos++) { + for (let pos = 0; pos < this.p1.active.length; pos++) { this.switchIn(this.p1.pokemon[pos], pos); } - for (var pos = 0; pos < this.p2.active.length; pos++) { + for (let pos = 0; pos < this.p2.active.length; pos++) { this.switchIn(this.p2.pokemon[pos], pos); } - for (var pos = 0; pos < this.p1.pokemon.length; pos++) { - pokemon = this.p1.pokemon[pos]; + for (let pos = 0; pos < this.p1.pokemon.length; pos++) { + let pokemon = this.p1.pokemon[pos]; this.singleEvent('Start', this.getEffect(pokemon.species), pokemon.speciesData, pokemon); } - for (var pos = 0; pos < this.p2.pokemon.length; pos++) { - pokemon = this.p2.pokemon[pos]; + for (let pos = 0; pos < this.p2.pokemon.length; pos++) { + let pokemon = this.p2.pokemon[pos]; this.singleEvent('Start', this.getEffect(pokemon.species), pokemon.speciesData, pokemon); } this.midTurn = true; break; + } + case 'move': if (!decision.pokemon.isActive) return false; if (decision.pokemon.fainted) return false; @@ -3920,22 +3924,24 @@ Battle = (function () { case 'megaEvo': if (decision.pokemon.canMegaEvo) this.runMegaEvo(decision.pokemon); break; - case 'beforeTurnMove': + case 'beforeTurnMove': { if (!decision.pokemon.isActive) return false; if (decision.pokemon.fainted) return false; this.debug('before turn callback: ' + decision.move.id); - var target = this.getTarget(decision); + let target = this.getTarget(decision); if (!target) return false; decision.move.beforeTurnCallback.call(this, decision.pokemon, target); break; + } + case 'event': this.runEvent(decision.event, decision.pokemon); break; - case 'team': - var len = decision.side.pokemon.length; - var newPokemon = [null, null, null, null, null, null].slice(0, len); - for (var j = 0; j < len; j++) { - var i = decision.team[j]; + case 'team': { + let len = decision.side.pokemon.length; + let newPokemon = [null, null, null, null, null, null].slice(0, len); + for (let j = 0; j < len; j++) { + let i = decision.team[j]; newPokemon[j] = decision.side.pokemon[i]; newPokemon[j].position = j; } @@ -3943,6 +3949,8 @@ Battle = (function () { // we return here because the update event would crash since there are no active pokemon yet return; + } + case 'pass': if (!decision.priority || decision.priority <= 101) return; if (decision.pokemon) { @@ -3953,7 +3961,7 @@ Battle = (function () { case 'switch': if (decision.pokemon) { decision.pokemon.beingCalledBack = true; - var lastMove = this.getMove(decision.pokemon.lastMove); + let lastMove = this.getMove(decision.pokemon.lastMove); if (lastMove.selfSwitch !== 'copyvolatile') { this.runEvent('BeforeSwitchOut', decision.pokemon); if (this.gen >= 5) { @@ -3991,8 +3999,8 @@ Battle = (function () { break; } if (decision.choice === 'switch' && decision.pokemon.activeTurns === 1) { - var foeActive = decision.pokemon.side.foe.active; - for (var i = 0; i < foeActive.length; i++) { + let foeActive = decision.pokemon.side.foe.active; + for (let i = 0; i < foeActive.length; i++) { if (foeActive[i].isStale >= 2) { decision.pokemon.isStaleCon++; decision.pokemon.isStaleSource = 'switch'; @@ -4013,13 +4021,13 @@ Battle = (function () { } delete decision.pokemon.draggedIn; break; - case 'shift': + case 'shift': { if (!decision.pokemon.isActive) return false; if (decision.pokemon.fainted) return false; decision.pokemon.activeTurns--; this.swapPosition(decision.pokemon, 1); - var foeActive = decision.pokemon.side.foe.active; - for (var i = 0; i < foeActive.length; i++) { + let foeActive = decision.pokemon.side.foe.active; + for (let i = 0; i < foeActive.length; i++) { if (foeActive[i].isStale >= 2) { decision.pokemon.isStaleCon++; decision.pokemon.isStaleSource = 'switch'; @@ -4027,6 +4035,8 @@ Battle = (function () { } } break; + } + case 'beforeTurn': this.eachEvent('BeforeTurn'); break; @@ -4039,7 +4049,7 @@ Battle = (function () { // phazing (Roar, etc) - var self = this; + let self = this; function checkForceSwitchFlag(a) { if (!a) return false; if (a.hp && a.forceSwitchFlag) { @@ -4070,8 +4080,8 @@ Battle = (function () { function hasSwitchFlag(a) { return a ? a.switchFlag : false; } function removeSwitchFlag(a) { if (a) a.switchFlag = false; } - var p1switch = this.p1.active.any(hasSwitchFlag); - var p2switch = this.p2.active.any(hasSwitchFlag); + let p1switch = this.p1.active.any(hasSwitchFlag); + let p2switch = this.p2.active.any(hasSwitchFlag); if (p1switch && !this.canSwitch(this.p1)) { this.p1.active.forEach(removeSwitchFlag); @@ -4108,7 +4118,7 @@ Battle = (function () { } while (this.queue.length) { - var decision = this.queue.shift(); + let decision = this.queue.shift(); this.runDecision(decision); @@ -4140,7 +4150,7 @@ Battle = (function () { * turn if all required choices have been made. */ Battle.prototype.choose = function (sideid, choice, rqid) { - var side = null; + let side = null; if (sideid === 'p1' || sideid === 'p2') side = this[sideid]; // This condition should be impossible because the sideid comes // from our forked process and if the player id were invalid, we would @@ -4169,9 +4179,9 @@ Battle = (function () { } }; Battle.prototype.commitDecisions = function () { - var oldQueue = this.queue; + let oldQueue = this.queue; this.queue = []; - for (var i = 0; i < this.sides.length; i++) { + for (let i = 0; i < this.sides.length; i++) { this.sides[i].resolveDecision(); if (this.sides[i].decision === true) continue; this.addQueue(this.sides[i].decision); @@ -4192,7 +4202,7 @@ Battle = (function () { this.go(); }; Battle.prototype.undoChoice = function (sideid) { - var side = null; + let side = null; if (sideid === 'p1' || sideid === 'p2') side = this[sideid]; // The following condition can never occur for the reasons given in // the choose() function above. @@ -4214,42 +4224,42 @@ Battle = (function () { * Choice validation is also done here. */ Battle.prototype.parseChoice = function (choices, side) { - var prevSwitches = {}; + let prevSwitches = {}; if (!side.currentRequest) return true; if (typeof choices === 'string') choices = choices.split(','); - var decisions = []; - var len = choices.length; + let decisions = []; + let len = choices.length; if (side.currentRequest !== 'teampreview') len = side.active.length; - var isDefault; - var choosableTargets = {normal:1, any:1, adjacentAlly:1, adjacentAllyOrSelf:1, adjacentFoe:1}; + let isDefault; + let choosableTargets = {normal:1, any:1, adjacentAlly:1, adjacentAllyOrSelf:1, adjacentFoe:1}; - var freeSwitchCount = {'switch':0, 'pass':0}; + let freeSwitchCount = {'switch':0, 'pass':0}; if (side.currentRequest === 'switch') { - var canSwitch = side.active.filter(function (mon) {return mon && mon.switchFlag;}).length; + let canSwitch = side.active.filter(function (mon) {return mon && mon.switchFlag;}).length; freeSwitchCount['switch'] = Math.min(canSwitch, side.pokemon.slice(side.active.length).filter(function (mon) {return !mon.fainted;}).length); freeSwitchCount['pass'] = canSwitch - freeSwitchCount['switch']; } - for (var i = 0; i < len; i++) { - var choice = (choices[i] || '').trim(); + for (let i = 0; i < len; i++) { + let choice = (choices[i] || '').trim(); - var data = ''; - var firstSpaceIndex = choice.indexOf(' '); + let data = ''; + let firstSpaceIndex = choice.indexOf(' '); if (firstSpaceIndex >= 0) { data = choice.substr(firstSpaceIndex + 1).trim(); choice = choice.substr(0, firstSpaceIndex).trim(); } - var pokemon = side.pokemon[i]; + let pokemon = side.pokemon[i]; switch (side.currentRequest) { case 'teampreview': if (choice !== 'team' || i > 0) return false; break; - case 'move': + case 'move': { if (i >= side.active.length) return false; if (!pokemon || pokemon.fainted) { decisions.push({ @@ -4257,7 +4267,7 @@ Battle = (function () { }); continue; } - var lockedMove = pokemon.getLockedMove(); + let lockedMove = pokemon.getLockedMove(); if (lockedMove) { decisions.push({ choice: 'move', @@ -4269,9 +4279,9 @@ Battle = (function () { } if (isDefault || choice === 'default') { isDefault = true; - var moves = pokemon.getMoves(); - var moveid = 'struggle'; - for (var j = 0; j < moves.length; j++) { + let moves = pokemon.getMoves(); + let moveid = 'struggle'; + for (let j = 0; j < moves.length; j++) { if (moves[j].disabled) continue; moveid = moves[j].id; break; @@ -4291,6 +4301,8 @@ Battle = (function () { data = '1'; } break; + } + case 'switch': if (i >= side.active.length) return false; if (!side.active[i] || !side.active[i].switchFlag) { @@ -4310,21 +4322,20 @@ Battle = (function () { } switch (choice) { - case 'team': - var pokemonLength = side.pokemon.length; + case 'team': { + let pokemonLength = side.pokemon.length; if (!data || data.length > pokemonLength) return false; - var dataArr = [0, 1, 2, 3, 4, 5].slice(0, pokemonLength); - var slotMap = dataArr.slice(); // Inverse of `dataArr` (slotMap[dataArr[x]] === x) - var tempSlot; + let dataArr = [0, 1, 2, 3, 4, 5].slice(0, pokemonLength); + let slotMap = dataArr.slice(); // Inverse of `dataArr` (slotMap[dataArr[x]] === x) - for (var j = 0; j < data.length; j++) { - var slot = parseInt(data.charAt(j), 10) - 1; + for (let j = 0; j < data.length; j++) { + let slot = parseInt(data.charAt(j), 10) - 1; if (slotMap[slot] < j) return false; if (isNaN(slot) || slot < 0 || slot >= pokemonLength) return false; // Keep track of team order so far - tempSlot = dataArr[j]; + let tempSlot = dataArr[j]; dataArr[j] = slot; dataArr[slotMap[slot]] = tempSlot; @@ -4339,6 +4350,7 @@ Battle = (function () { team: dataArr }); break; + } case 'switch': if (i > side.active.length || i > side.pokemon.length) continue; @@ -4375,7 +4387,7 @@ Battle = (function () { side.emitCallback('trapped', i); return false; } else if (side.pokemon[i].maybeTrapped) { - var finalDecision = true; + let finalDecision = true; decisions.finalDecision = decisions.finalDecision || side.pokemon[i].isLastActive(); } } @@ -4404,10 +4416,10 @@ Battle = (function () { }); break; - case 'move': - var moveid = ''; - var targetLoc = 0; - var pokemon = side.pokemon[i]; + case 'move': { + let moveid = ''; + let targetLoc = 0; + pokemon = side.pokemon[i]; if (data.substr(-2) === ' 1') targetLoc = 1; if (data.substr(-2) === ' 2') targetLoc = 2; @@ -4431,10 +4443,10 @@ Battle = (function () { * If the move is not found, the decision is invalid without requiring further inspection. */ - var requestMoves = pokemon.getRequestData().moves; + let requestMoves = pokemon.getRequestData().moves; if (data.search(/^[0-9]+$/) >= 0) { // parse a one-based move index - var moveIndex = parseInt(data, 10) - 1; + let moveIndex = parseInt(data, 10) - 1; if (!requestMoves[moveIndex]) { this.debug("Can't use an unexpected move"); return false; @@ -4450,8 +4462,8 @@ Battle = (function () { if (moveid.substr(0, 11) === 'hiddenpower') { moveid = 'hiddenpower'; } - var isValidMove = false; - for (var j = 0; j < requestMoves.length; j++) { + let isValidMove = false; + for (let j = 0; j < requestMoves.length; j++) { if (requestMoves[j].id !== moveid) continue; if (!targetLoc && side.active.length > 1 && requestMoves[j].target in choosableTargets) { this.debug("Can't use the move without a target"); @@ -4471,7 +4483,7 @@ Battle = (function () { * which could be unknown for the client. */ - var moves = pokemon.getMoves(); + let moves = pokemon.getMoves(); if (!moves.length) { // Override decision and use Struggle if there are no enabled moves with PP if (this.gen <= 4) side.send('-activate', pokemon, 'move: Struggle'); @@ -4479,8 +4491,8 @@ Battle = (function () { } else { // At least a move is valid. Check if the chosen one is. // This may include Struggle in Hackmons. - var isEnabled = false; - for (var j = 0; j < moves.length; j++) { + let isEnabled = false; + for (let j = 0; j < moves.length; j++) { if (moves[j].id !== moveid) continue; if (!moves[j].disabled) { isEnabled = true; @@ -4489,7 +4501,7 @@ Battle = (function () { } if (!isEnabled) { // request a different choice - var sourceEffect = pokemon.disabledMoves[moveid] && pokemon.disabledMoves[moveid].sourceEffect; + let sourceEffect = pokemon.disabledMoves[moveid] && pokemon.disabledMoves[moveid].sourceEffect; side.emitCallback('cant', pokemon, sourceEffect ? sourceEffect.fullname : '', moveid); return false; } @@ -4507,6 +4519,7 @@ Battle = (function () { move: moveid }); break; + } case 'pass': if (i > side.active.length || i > side.pokemon.length) continue; @@ -4527,18 +4540,18 @@ Battle = (function () { return decisions; }; Battle.prototype.add = function () { - var parts = Array.prototype.slice.call(arguments); - var functions = parts.map(function (part) { + let parts = Array.prototype.slice.call(arguments); + let functions = parts.map(function (part) { return typeof part === 'function'; }); if (functions.indexOf(true) < 0) { this.log.push('|' + parts.join('|')); } else { this.log.push('|split'); - var sides = [null, this.sides[0], this.sides[1], true]; - for (var i = 0; i < sides.length; ++i) { - var line = ''; - for (var j = 0; j < parts.length; ++j) { + let sides = [null, this.sides[0], this.sides[1], true]; + for (let i = 0; i < sides.length; ++i) { + let line = ''; + for (let j = 0; j < parts.length; ++j) { line += '|'; if (functions[j]) { line += parts[j](sides[i]); @@ -4599,7 +4612,7 @@ Battle = (function () { }; Battle.prototype.rename = function (slot, name, avatar) { if (slot === 'p1' || slot === 'p2') { - var side = this[slot]; + let side = this[slot]; side.name = name; if (avatar) side.avatar = avatar; this.add('player', slot, name, side.avatar); @@ -4607,7 +4620,7 @@ Battle = (function () { }; Battle.prototype.leave = function (slot) { if (slot === 'p1' || slot === 'p2') { - var side = this[slot]; + let side = this[slot]; if (!side) { console.log('**** ' + slot + ' tried to leave before it was possible in ' + this.id); require('./crashlogger.js')({stack: '**** ' + slot + ' tried to leave before it was possible in ' + this.id}, 'A simulator process'); @@ -4633,11 +4646,11 @@ Battle = (function () { // This function is called by this process's 'message' event. Battle.prototype.receive = function (data, more) { this.messageLog.push(data.join(' ')); - var logPos = this.log.length; - var alreadyEnded = this.ended; + let logPos = this.log.length; + let alreadyEnded = this.ended; switch (data[1]) { - case 'join': - var team = null; + case 'join': { + let team = ''; try { if (more) team = Tools.fastUnpackTeam(more); } catch (e) { @@ -4646,6 +4659,7 @@ Battle = (function () { } this.join(data[2], data[3], data[4], team); break; + } case 'rename': this.rename(data[2], data[3], data[4]); @@ -4672,13 +4686,13 @@ Battle = (function () { this.undoChoice(data[2]); break; - case 'eval': - var battle = this; - var p1 = this.p1; - var p2 = this.p2; - var p1active = p1 ? p1.active[0] : null; - var p2active = p2 ? p2.active[0] : null; - var target = data.slice(2).join('|').replace(/\f/g, '\n'); + case 'eval': { + let battle = this; + let p1 = this.p1; + let p2 = this.p2; + let p1active = p1 ? p1.active[0] : null; + let p2active = p2 ? p2.active[0] : null; + let target = data.slice(2).join('|').replace(/\f/g, '\n'); this.add('', '>>> ' + target); try { this.add('', '<<< ' + eval(target)); @@ -4688,11 +4702,15 @@ Battle = (function () { break; } + default: + // unhandled + } + this.sendUpdates(logPos, alreadyEnded); }; Battle.prototype.sendUpdates = function (logPos, alreadyEnded) { if (this.p1 && this.p2) { - var inactiveSide = -1; + let inactiveSide = -1; if (!this.p1.isActive && this.p2.isActive) { inactiveSide = 0; } else if (this.p1.isActive && !this.p2.isActive) { @@ -4711,7 +4729,7 @@ Battle = (function () { if (this.log.length > logPos) { if (alreadyEnded !== undefined && this.ended && !alreadyEnded) { if (this.rated || Config.logchallenges) { - var log = { + let log = { seed: this.startingSeed, turns: this.turn, p1: this.p1.name, @@ -4734,13 +4752,13 @@ Battle = (function () { // deallocate ourself // deallocate children and get rid of references to them - for (var i = 0; i < this.sides.length; i++) { + for (let i = 0; i < this.sides.length; i++) { if (this.sides[i]) this.sides[i].destroy(); this.sides[i] = null; } this.p1 = null; this.p2 = null; - for (var i = 0; i < this.queue.length; i++) { + for (let i = 0; i < this.queue.length; i++) { delete this.queue[i].pokemon; delete this.queue[i].side; this.queue[i] = null; diff --git a/chat-plugins/info.js b/chat-plugins/info.js index b3079f355c..0d593f24f4 100644 --- a/chat-plugins/info.js +++ b/chat-plugins/info.js @@ -10,9 +10,11 @@ * @license MIT license */ +'use strict'; + const RESULTS_MAX_LENGTH = 10; -var commands = exports.commands = { +let commands = exports.commands = { ip: 'whois', rooms: 'whois', @@ -21,16 +23,16 @@ var commands = exports.commands = { whoare: 'whois', whois: function (target, room, user, connection, cmd) { if (room.id === 'staff' && !this.canBroadcast()) return; - var targetUser = this.targetUserOrSelf(target, user.group === ' '); + let targetUser = this.targetUserOrSelf(target, user.group === ' '); if (!targetUser) { return this.errorReply("User " + this.targetUsername + " not found."); } - var showAll = (cmd === 'ip' || cmd === 'whoare' || cmd === 'alt' || cmd === 'alts'); + let showAll = (cmd === 'ip' || cmd === 'whoare' || cmd === 'alt' || cmd === 'alts'); if (showAll && !user.confirmed && targetUser !== user) { return this.errorReply("/alts - Access denied."); } - var buf = '' + targetUser.group + '' + Tools.escapeHTML(targetUser.name) + ' ' + (!targetUser.connected ? ' (offline)' : ''); + let buf = '' + targetUser.group + '' + Tools.escapeHTML(targetUser.name) + ' ' + (!targetUser.connected ? ' (offline)' : ''); if (Config.groups[targetUser.group] && Config.groups[targetUser.group].name) { buf += "
" + Config.groups[targetUser.group].name + " (" + targetUser.group + ")"; } @@ -40,14 +42,14 @@ var commands = exports.commands = { if (!targetUser.registered) { buf += "
(Unregistered)"; } - var publicrooms = ""; - var hiddenrooms = ""; - var privaterooms = ""; - for (var i in targetUser.roomCount) { + let publicrooms = ""; + let hiddenrooms = ""; + let privaterooms = ""; + for (let i in targetUser.roomCount) { if (i === 'global') continue; - var targetRoom = Rooms.get(i); + let targetRoom = Rooms.get(i); - var output = (targetRoom.auth && targetRoom.auth[targetUser.userid] ? targetRoom.auth[targetUser.userid] : '') + '' + i + ''; + let output = (targetRoom.auth && targetRoom.auth[targetUser.userid] ? targetRoom.auth[targetUser.userid] : '') + '' + i + ''; if (targetRoom.isPrivate === true) { if (targetRoom.modjoin === '~') continue; if (privaterooms) privaterooms += " | "; @@ -67,12 +69,12 @@ var commands = exports.commands = { } buf += '
'; if (user.can('alts', targetUser) || user.can('alts') && user === targetUser) { - var alts = targetUser.getAlts(true); - var output = Object.keys(targetUser.prevNames).join(", "); + let alts = targetUser.getAlts(true); + let output = Object.keys(targetUser.prevNames).join(", "); if (output) buf += "
Previous names: " + Tools.escapeHTML(output); - for (var j = 0; j < alts.length; ++j) { - var targetAlt = Users.get(alts[j]); + for (let j = 0; j < alts.length; ++j) { + let targetAlt = Users.get(alts[j]); if (!targetAlt.named && !targetAlt.connected) continue; if (targetAlt.group === '~' && user.group !== '~') continue; @@ -99,7 +101,7 @@ var commands = exports.commands = { } } if ((user.can('ip', targetUser) || user === targetUser)) { - var ips = Object.keys(targetUser.ips); + let ips = Object.keys(targetUser.ips); buf += "
IP" + ((ips.length > 1) ? "s" : "") + ": " + ips.join(", ") + (user.group !== ' ' && targetUser.latestHost ? "
Host: " + Tools.escapeHTML(targetUser.latestHost) : ""); } @@ -111,9 +113,9 @@ var commands = exports.commands = { } if (user.can('alts', targetUser) || (room.isPrivate !== true && user.can('mute', targetUser, room) && targetUser.userid in room.users)) { - var bannedFrom = ""; - for (var i = 0; i < Rooms.global.chatRooms.length; i++) { - var thisRoom = Rooms.global.chatRooms[i]; + let bannedFrom = ""; + for (let i = 0; i < Rooms.global.chatRooms.length; i++) { + let thisRoom = Rooms.global.chatRooms[i]; if (!thisRoom || thisRoom.isPrivate === true) continue; if (thisRoom.bannedIps && (targetUser.latestIp in thisRoom.bannedIps || targetUser.userid in thisRoom.bannedUsers)) { if (bannedFrom) bannedFrom += ", "; @@ -131,7 +133,7 @@ var commands = exports.commands = { if (!target) return this.parse('/help host'); if (!this.can('rangeban')) return; if (!/[0-9.]+/.test(target)) return this.errorReply('You must pass a valid IPv4 IP to /host.'); - var self = this; + let self = this; Dnsbl.reverse(target, function (err, hosts) { self.sendReply('IP ' + target + ': ' + (hosts ? hosts[0] : 'NULL')); }); @@ -144,15 +146,15 @@ var commands = exports.commands = { ipsearch: function (target, room, user, connection, cmd) { if (!target.trim()) return this.parse('/help ipsearch'); if (!this.can('rangeban')) return; - var results = []; + let results = []; - var isAll = (cmd === 'ipsearchall'); + let isAll = (cmd === 'ipsearchall'); if (/[a-z]/.test(target)) { // host this.sendReply("Users with host " + target + ":"); - for (var userid in Users.users) { - var curUser = Users.users[userid]; + for (let userid in Users.users) { + let curUser = Users.users[userid]; if (!curUser.latestHost || !curUser.latestHost.endsWith(target)) continue; if (results.push((curUser.connected ? " \u25C9 " : " \u25CC ") + " " + curUser.name) > 100 && !isAll) { return this.sendReply("More than 100 users match the specified IP range. Use /ipsearchall to retrieve the full list."); @@ -162,8 +164,8 @@ var commands = exports.commands = { // IP range this.sendReply("Users in IP range " + target + ":"); target = target.slice(0, -1); - for (var userid in Users.users) { - var curUser = Users.users[userid]; + for (let userid in Users.users) { + let curUser = Users.users[userid]; if (!curUser.latestIp.startsWith(target)) continue; if (results.push((curUser.connected ? " \u25C9 " : " \u25CC ") + " " + curUser.name) > 100 && !isAll) { return this.sendReply("More than 100 users match the specified IP range. Use /ipsearchall to retrieve the full list."); @@ -171,8 +173,8 @@ var commands = exports.commands = { } } else { this.sendReply("Users with IP " + target + ":"); - for (var userid in Users.users) { - var curUser = Users.users[userid]; + for (let userid in Users.users) { + let curUser = Users.users[userid]; if (curUser.latestIp === target) { results.push((curUser.connected ? " \u25C9 " : " \u25CC ") + " " + curUser.name); } @@ -194,7 +196,7 @@ var commands = exports.commands = { if (!this.targetUser) { return this.errorReply("User " + this.targetUsername + " not found."); } - var targetRoom = (target ? Rooms.search(target) : room); + let targetRoom = (target ? Rooms.search(target) : room); if (!targetRoom) { return this.errorReply("Room " + target + " not found."); } @@ -213,12 +215,12 @@ var commands = exports.commands = { data: function (target, room, user, connection, cmd) { if (!this.canBroadcast()) return; - var buffer = ''; - var targetId = toId(target); + let buffer = ''; + let targetId = toId(target); if (!targetId) return this.parse('/help data'); if (targetId === '' + parseInt(targetId)) { - for (var p in Tools.data.Pokedex) { - var pokemon = Tools.getTemplate(p); + for (let p in Tools.data.Pokedex) { + let pokemon = Tools.getTemplate(p); if (pokemon.num === parseInt(target)) { target = pokemon.species; targetId = pokemon.id; @@ -226,17 +228,17 @@ var commands = exports.commands = { } } } - var newTargets = Tools.dataSearch(target); - var showDetails = (cmd === 'dt' || cmd === 'details'); + let newTargets = Tools.dataSearch(target); + let showDetails = (cmd === 'dt' || cmd === 'details'); if (newTargets && newTargets.length) { - for (var i = 0; i < newTargets.length; ++i) { + for (let i = 0; i < newTargets.length; ++i) { if (newTargets[i].id !== targetId && !Tools.data.Aliases[targetId] && !i) { buffer = "No Pok\u00e9mon, item, move, ability or nature named '" + target + "' was found. Showing the data of '" + newTargets[0].name + "' instead.\n"; } if (newTargets[i].searchType === 'nature') { buffer += "" + newTargets[i].name + " nature: "; if (newTargets[i].plus) { - var statNames = {'atk': "Attack", 'def': "Defense", 'spa': "Special Attack", 'spd': "Special Defense", 'spe': "Speed"}; + let statNames = {'atk': "Attack", 'def': "Defense", 'spa': "Special Attack", 'spd': "Special Defense", 'spe': "Speed"}; buffer += "+10% " + statNames[newTargets[i].plus] + ", -10% " + statNames[newTargets[i].minus] + "."; } else { buffer += "No effect."; @@ -251,12 +253,12 @@ var commands = exports.commands = { } if (showDetails) { - var details; - var isSnatch = false; - var isMirrorMove = false; + let details; + let isSnatch = false; + let isMirrorMove = false; if (newTargets[0].searchType === 'pokemon') { - var pokemon = Tools.getTemplate(newTargets[0].name); - var weighthit = 20; + let pokemon = Tools.getTemplate(newTargets[0].name); + let weighthit = 20; if (pokemon.weightkg >= 200) { weighthit = 120; } else if (pokemon.weightkg >= 100) { @@ -285,7 +287,7 @@ var commands = exports.commands = { }).join(", "); } } else if (newTargets[0].searchType === 'move') { - var move = Tools.getMove(newTargets[0].name); + let move = Tools.getMove(newTargets[0].name); details = { "Priority": move.priority, "Gen": move.gen @@ -323,7 +325,7 @@ var commands = exports.commands = { 'all': "All Pok\u00e9mon" }[move.target] || "Unknown"; } else if (newTargets[0].searchType === 'item') { - var item = Tools.getItem(newTargets[0].name); + let item = Tools.getItem(newTargets[0].name); details = { "Gen": item.gen }; @@ -372,20 +374,20 @@ var commands = exports.commands = { if (!this.canBroadcast()) return; if (!target) return this.parse('/help dexsearch'); - var searches = []; - var allTiers = {'uber':1, 'ou':1, 'bl':1, 'uu':1, 'bl2':1, 'ru':1, 'bl3':1, 'nu':1, 'bl4':1, 'pu':1, 'nfe':1, 'lc uber':1, 'lc':1, 'cap':1}; - var allColours = {'green':1, 'red':1, 'blue':1, 'white':1, 'brown':1, 'yellow':1, 'purple':1, 'pink':1, 'gray':1, 'black':1}; - var allStats = {'hp':1, 'atk':1, 'def':1, 'spa':1, 'spd':1, 'spe':1, 'bst':1}; - var showAll = false; - var megaSearch = null; - var capSearch = null; - var randomOutput = 0; + let searches = []; + let allTiers = {'uber':1, 'ou':1, 'bl':1, 'uu':1, 'bl2':1, 'ru':1, 'bl3':1, 'nu':1, 'bl4':1, 'pu':1, 'nfe':1, 'lc uber':1, 'lc':1, 'cap':1}; + let allColours = {'green':1, 'red':1, 'blue':1, 'white':1, 'brown':1, 'yellow':1, 'purple':1, 'pink':1, 'gray':1, 'black':1}; + let allStats = {'hp':1, 'atk':1, 'def':1, 'spa':1, 'spd':1, 'spe':1, 'bst':1}; + let showAll = false; + let megaSearch = null; + let capSearch = null; + let randomOutput = 0; - var self = this; - var validParameter = function (cat, param, isNotSearch) { - var catCount = 0; - for (var h = 0; h < searches.length; h++) { - var group = searches[h]; + let self = this; + let validParameter = function (cat, param, isNotSearch) { + let catCount = 0; + for (let h = 0; h < searches.length; h++) { + let group = searches[h]; if (group[cat][param] === undefined) continue; if (group[cat][param] === isNotSearch) { self.sendReplyBox("A search cannot both include and exclude '" + param + "'."); @@ -397,20 +399,20 @@ var commands = exports.commands = { return true; }; - var andGroups = target.split(','); - for (var i = 0; i < andGroups.length; i++) { - var orGroup = {abilities: {}, tiers: {}, colors: {}, gens: {}, moves: {}, types: {}, stats: {}, skip: false}; - var parameters = andGroups[i].split("|"); + let andGroups = target.split(','); + for (let i = 0; i < andGroups.length; i++) { + let orGroup = {abilities: {}, tiers: {}, colors: {}, gens: {}, moves: {}, types: {}, stats: {}, skip: false}; + let parameters = andGroups[i].split("|"); if (parameters.length > 4) return this.sendReply("No more than 3 alternatives for each parameter may be used."); - for (var j = 0; j < parameters.length; j++) { - var isNotSearch = false; + for (let j = 0; j < parameters.length; j++) { + let isNotSearch = false; target = parameters[j].trim().toLowerCase(); if (target.charAt(0) === '!') { isNotSearch = true; target = target.substr(1); } - var targetAbility = Tools.getAbility(target); + let targetAbility = Tools.getAbility(target); if (targetAbility.exists) { if (!validParameter("abilities", targetAbility, isNotSearch)) return; orGroup.abilities[targetAbility] = !isNotSearch; @@ -435,7 +437,7 @@ var commands = exports.commands = { } if (target.substr(0, 3) === 'gen' && Number.isInteger(parseFloat(target.substr(3)))) target = target.substr(3).trim(); - var targetInt = parseInt(target); + let targetInt = parseInt(target); if (0 < targetInt && targetInt < 7) { if (!validParameter("gens", target, isNotSearch)) return; orGroup.gens[target] = !isNotSearch; @@ -466,11 +468,11 @@ var commands = exports.commands = { if (target === 'recovery') { if (parameters.length > 1) return this.sendReplyBox("The parameter 'recovery' cannot have alternative parameters"); - var recoveryMoves = ["recover", "roost", "moonlight", "morningsun", "synthesis", "milkdrink", "slackoff", "softboiled", "wish", "healorder"]; - for (var k = 0; k < recoveryMoves.length; k++) { + let recoveryMoves = ["recover", "roost", "moonlight", "morningsun", "synthesis", "milkdrink", "slackoff", "softboiled", "wish", "healorder"]; + for (let k = 0; k < recoveryMoves.length; k++) { if (!validParameter("moves", recoveryMoves[k], isNotSearch)) return; if (isNotSearch) { - var bufferObj = {moves: {}}; + let bufferObj = {moves: {}}; bufferObj.moves[recoveryMoves[k]] = false; searches.push(bufferObj); } else { @@ -483,13 +485,13 @@ var commands = exports.commands = { if (target === 'priority') { if (parameters.length > 1) return this.sendReplyBox("The parameter 'priority' cannot have alternative parameters"); - for (var move in Tools.data.Movedex) { - var moveData = Tools.getMove(move); + for (let move in Tools.data.Movedex) { + let moveData = Tools.getMove(move); if (moveData.category === "Status" || moveData.id === "bide") continue; if (moveData.priority > 0) { if (!validParameter("moves", move, isNotSearch)) return; if (isNotSearch) { - var bufferObj = {moves: {}}; + let bufferObj = {moves: {}}; bufferObj.moves[move] = false; searches.push(bufferObj); } else { @@ -501,14 +503,14 @@ var commands = exports.commands = { break; } - var targetMove = Tools.getMove(target); + let targetMove = Tools.getMove(target); if (targetMove.exists) { if (!validParameter("moves", targetMove.id, isNotSearch)) return; orGroup.moves[targetMove.id] = !isNotSearch; continue; } - var typeIndex = target.indexOf(' type'); + let typeIndex = target.indexOf(' type'); if (typeIndex >= 0) { target = target.charAt(0).toUpperCase() + target.substring(1, typeIndex); if (target in Tools.data.TypeChart) { @@ -518,7 +520,7 @@ var commands = exports.commands = { } } - var inequality = target.search(/>|<|=/); + let inequality = target.search(/>|<|=/); if (inequality >= 0) { if (isNotSearch) return this.sendReplyBox("You cannot use the negation symbol '!' in stat ranges."); if (target.charAt(inequality + 1) === '=') { @@ -526,9 +528,9 @@ var commands = exports.commands = { } else { inequality = target.charAt(inequality); } - var inequalityOffset = (inequality.charAt(1) === '=' ? 0 : -1); - var targetParts = target.replace(/\s/g, '').split(inequality); - var num, stat, direction; + let inequalityOffset = (inequality.charAt(1) === '=' ? 0 : -1); + let targetParts = target.replace(/\s/g, '').split(inequality); + let num, stat, direction; if (!isNaN(targetParts[0])) { // e.g. 100 < spe num = parseFloat(targetParts[0]); @@ -572,33 +574,33 @@ var commands = exports.commands = { if (showAll && searches.length === 0 && megaSearch === null) return this.sendReplyBox("No search parameters other than 'all' were found. Try '/help dexsearch' for more information on this command."); - var dex = {}; - for (var pokemon in Tools.data.Pokedex) { - var template = Tools.getTemplate(pokemon); - var megaSearchResult = (megaSearch === null || (megaSearch === true && template.isMega) || (megaSearch === false && !template.isMega)); + let dex = {}; + for (let pokemon in Tools.data.Pokedex) { + let template = Tools.getTemplate(pokemon); + let megaSearchResult = (megaSearch === null || (megaSearch === true && template.isMega) || (megaSearch === false && !template.isMega)); if (template.tier !== 'Unreleased' && template.tier !== 'Illegal' && (template.tier !== 'CAP' || capSearch) && megaSearchResult) { dex[pokemon] = template; } } - var learnSetsCompiled = false; + let learnSetsCompiled = false; //ensure searches with the least alternatives are run first searches.sort(function (a, b) { - var aCount = 0, bCount = 0; - for (var cat in a) { + let aCount = 0, bCount = 0; + for (let cat in a) { if (typeof a[cat] === "object") aCount += Object.size(a[cat]); } - for (var cat in b) { + for (let cat in b) { if (typeof b[cat] === "object") bCount += Object.size(b[cat]); } return aCount - bCount; }); - for (var group = 0; group < searches.length; group++) { - var alts = searches[group]; + for (let group = 0; group < searches.length; group++) { + let alts = searches[group]; if (alts.skip) continue; - for (var mon in dex) { - var matched = false; + for (let mon in dex) { + let matched = false; if (Object.size(alts.gens) > 0) { if (alts.gens[dex[mon].gen] || (Object.count(alts.gens, false) > 0 && alts.gens[dex[mon].gen] !== false)) continue; @@ -614,7 +616,7 @@ var commands = exports.commands = { alts.tiers[dex[mon].tier.toLowerCase()] !== false)) continue; } - for (var type in alts.types) { + for (let type in alts.types) { if (dex[mon].types.indexOf(type) >= 0 === alts.types[type]) { matched = true; break; @@ -622,7 +624,7 @@ var commands = exports.commands = { } if (matched) continue; - for (var ability in alts.abilities) { + for (let ability in alts.abilities) { if (alts.abilities[ability] === (Object.count(dex[mon].abilities, ability) > 0)) { matched = true; break; @@ -630,10 +632,10 @@ var commands = exports.commands = { } if (matched) continue; - for (var stat in alts.stats) { - var monStat = 0; + for (let stat in alts.stats) { + let monStat = 0; if (stat === 'bst') { - for (var monStats in dex[mon].baseStats) { + for (let monStats in dex[mon].baseStats) { monStat += dex[mon].baseStats[monStats]; } } else { @@ -661,14 +663,14 @@ var commands = exports.commands = { if (matched) continue; if (!learnSetsCompiled) { - for (var mon2 in dex) { - var template = dex[mon2]; + for (let mon2 in dex) { + let template = dex[mon2]; if (!template.learnset) template = Tools.getTemplate(template.baseSpecies); if (!template.learnset) continue; - var fullLearnset = template.learnset; + let fullLearnset = template.learnset; while (template.prevo) { template = Tools.getTemplate(template.prevo); - for (var move in template.learnset) { + for (let move in template.learnset) { if (!fullLearnset[move]) fullLearnset[move] = template.learnset[move]; } } @@ -677,8 +679,8 @@ var commands = exports.commands = { learnSetsCompiled = true; } - for (var move in alts.moves) { - var canLearn = (dex[mon].learnset.sketch && ['chatter', 'struggle', 'magikarpsrevenge'].indexOf(move) < 0) || dex[mon].learnset[move]; + for (let move in alts.moves) { + let canLearn = (dex[mon].learnset.sketch && ['chatter', 'struggle', 'magikarpsrevenge'].indexOf(move) < 0) || dex[mon].learnset[move]; if ((canLearn && alts.moves[move]) || (alts.moves[move] === false && !canLearn)) { matched = true; break; @@ -690,8 +692,8 @@ var commands = exports.commands = { } } - var results = []; - for (var mon in dex) { + let results = []; + for (let mon in dex) { if (dex[mon].baseSpecies && results.indexOf(dex[mon].baseSpecies) >= 0) continue; results.push(dex[mon].species); } @@ -700,7 +702,7 @@ var commands = exports.commands = { results = results.randomize().slice(0, randomOutput); } - var resultsStr = this.broadcasting ? "" : ("" + Tools.escapeHTML(message) + ":
"); + let resultsStr = this.broadcasting ? "" : ("" + Tools.escapeHTML(message) + ":
"); if (results.length > 1) { if (showAll || results.length <= RESULTS_MAX_LENGTH + 5) { results.sort(); @@ -729,12 +731,12 @@ var commands = exports.commands = { rollpokemon: 'randompokemon', randpoke: 'randompokemon', randompokemon: function (target, room, user, connection, cmd, message) { - var targets = target.split(","); - var targetsBuffer = []; - var qty; - for (var i = 0; i < targets.length; i++) { + let targets = target.split(","); + let targetsBuffer = []; + let qty; + for (let i = 0; i < targets.length; i++) { if (!targets[i]) continue; - var num = Number(targets[i]); + let num = Number(targets[i]); if (Number.isInteger(num)) { if (qty) return this.errorReply("Only specify the number of Pok\u00e9mon once."); qty = num; @@ -758,27 +760,27 @@ var commands = exports.commands = { if (!this.canBroadcast()) return; if (!target) return this.parse('/help movesearch'); - var targets = target.split(','); - var searches = {}; - var allCategories = {'physical':1, 'special':1, 'status':1}; - var allProperties = {'basePower':1, 'accuracy':1, 'priority':1, 'pp':1}; - var allFlags = {'authentic':1, 'bite':1, 'bullet':1, 'contact':1, 'defrost':1, 'powder':1, 'pulse':1, 'punch':1, 'secondary':1, 'snatch':1, 'sound':1}; - var allStatus = {'psn':1, 'tox':1, 'brn':1, 'par':1, 'frz':1, 'slp':1}; - var allVolatileStatus = {'flinch':1, 'confusion':1, 'partiallytrapped':1}; - var allBoosts = {'hp':1, 'atk':1, 'def':1, 'spa':1, 'spd':1, 'spe':1, 'accuracy':1, 'evasion':1}; - var showAll = false; - var lsetData = {}; - var targetMon = ''; + let targets = target.split(','); + let searches = {}; + let allCategories = {'physical':1, 'special':1, 'status':1}; + let allProperties = {'basePower':1, 'accuracy':1, 'priority':1, 'pp':1}; + let allFlags = {'authentic':1, 'bite':1, 'bullet':1, 'contact':1, 'defrost':1, 'powder':1, 'pulse':1, 'punch':1, 'secondary':1, 'snatch':1, 'sound':1}; + let allStatus = {'psn':1, 'tox':1, 'brn':1, 'par':1, 'frz':1, 'slp':1}; + let allVolatileStatus = {'flinch':1, 'confusion':1, 'partiallytrapped':1}; + let allBoosts = {'hp':1, 'atk':1, 'def':1, 'spa':1, 'spd':1, 'spe':1, 'accuracy':1, 'evasion':1}; + let showAll = false; + let lsetData = {}; + let targetMon = ''; - for (var i = 0; i < targets.length; i++) { - var isNotSearch = false; + for (let i = 0; i < targets.length; i++) { + let isNotSearch = false; target = targets[i].toLowerCase().trim(); if (target.charAt(0) === '!') { isNotSearch = true; target = target.substr(1); } - var typeIndex = target.indexOf(' type'); + let typeIndex = target.indexOf(' type'); if (typeIndex >= 0) { target = target.charAt(0).toUpperCase() + target.substring(1, typeIndex); if (!(target in Tools.data.TypeChart)) return this.sendReplyBox("Type '" + Tools.escapeHTML(target) + "' not found."); @@ -819,7 +821,7 @@ var commands = exports.commands = { continue; } - var template = Tools.getTemplate(target); + let template = Tools.getTemplate(target); if (template.exists) { if (Object.size(lsetData) !== 0) return this.sendReplyBox("A search can only include one Pok\u00e9mon learnset."); if (!template.learnset) template = Tools.getTemplate(template.baseSpecies); @@ -827,19 +829,19 @@ var commands = exports.commands = { targetMon = template.name; while (template.prevo) { template = Tools.getTemplate(template.prevo); - for (var move in template.learnset) { + for (let move in template.learnset) { if (!lsetData[move]) lsetData[move] = template.learnset[move]; } } continue; } - var inequality = target.search(/>|<|=/); + let inequality = target.search(/>|<|=/); if (inequality >= 0) { if (isNotSearch) return this.sendReplyBox("You cannot use the negation symbol '!' in quality ranges."); inequality = target.charAt(inequality); - var targetParts = target.replace(/\s/g, '').split(inequality); - var numSide, propSide, direction; + let targetParts = target.replace(/\s/g, '').split(inequality); + let numSide, propSide, direction; if (!isNaN(targetParts[0])) { numSide = 0; propSide = 1; @@ -859,7 +861,7 @@ var commands = exports.commands = { } else { return this.sendReplyBox("No value given to compare with '" + Tools.escapeHTML(target) + "'."); } - var prop = targetParts[propSide]; + let prop = targetParts[propSide]; switch (toId(targetParts[propSide])) { case 'basepower': prop = 'basePower'; break; case 'bp': prop = 'basePower'; break; @@ -884,7 +886,7 @@ var commands = exports.commands = { } if (target.substr(0, 8) === 'priority') { - var sign = ''; + let sign = ''; target = target.substr(8).trim(); if (target === "+") { sign = 'greater'; @@ -923,7 +925,7 @@ var commands = exports.commands = { continue; } - var oldTarget = target; + let oldTarget = target; if (target.charAt(target.length - 1) === 's') target = target.substr(0, target.length - 1); switch (target) { case 'toxic': target = 'tox'; break; @@ -956,23 +958,23 @@ var commands = exports.commands = { if (showAll && Object.size(searches) === 0 && !targetMon) return this.sendReplyBox("No search parameters other than 'all' were found. Try '/help movesearch' for more information on this command."); - var dex = {}; + let dex = {}; if (targetMon) { - for (var move in lsetData) { + for (let move in lsetData) { dex[move] = Tools.getMove(move); } } else { - for (var move in Tools.data.Movedex) { + for (let move in Tools.data.Movedex) { dex[move] = Tools.getMove(move); } delete dex.magikarpsrevenge; } - for (var search in searches) { + for (let search in searches) { switch (search) { case 'type': case 'category': - for (var move in dex) { + for (let move in dex) { if (searches[search][String(dex[move][search])] === false || Object.count(searches[search], true) > 0 && !searches[search][String(dex[move][search])]) { delete dex[move]; @@ -981,8 +983,8 @@ var commands = exports.commands = { break; case 'flags': - for (var flag in searches[search]) { - for (var move in dex) { + for (let flag in searches[search]) { + for (let move in dex) { if (flag !== 'secondary') { if ((!dex[move].flags[flag] && searches[search][flag]) || (dex[move].flags[flag] && !searches[search][flag])) delete dex[move]; } else { @@ -997,15 +999,15 @@ var commands = exports.commands = { break; case 'recovery': - for (var move in dex) { - var hasRecovery = (dex[move].drain || dex[move].flags.heal); + for (let move in dex) { + let hasRecovery = (dex[move].drain || dex[move].flags.heal); if ((!hasRecovery && searches[search]) || (hasRecovery && !searches[search])) delete dex[move]; } break; case 'property': - for (var prop in searches[search]) { - for (var move in dex) { + for (let prop in searches[search]) { + for (let move in dex) { if (typeof searches[search][prop].less === "number") { if (dex[move][prop] === true) { delete dex[move]; @@ -1031,8 +1033,8 @@ var commands = exports.commands = { break; case 'boost': - for (var boost in searches[search]) { - for (var move in dex) { + for (let boost in searches[search]) { + for (let move in dex) { if (dex[move].boosts) { if ((dex[move].boosts[boost] > 0 && searches[search][boost]) || (dex[move].boosts[boost] < 1 && !searches[search][boost])) continue; @@ -1047,8 +1049,8 @@ var commands = exports.commands = { case 'status': case 'volatileStatus': - for (var searchStatus in searches[search]) { - for (var move in dex) { + for (let searchStatus in searches[search]) { + for (let move in dex) { if (dex[move][search] !== searchStatus) { if (!dex[move].secondaries) { if (!dex[move].secondary) { @@ -1058,8 +1060,8 @@ var commands = exports.commands = { (dex[move].secondary[search] === searchStatus && !searches[search][searchStatus])) delete dex[move]; } } else { - var hasSecondary = false; - for (var i = 0; i < dex[move].secondaries.length; i++) { + let hasSecondary = false; + for (let i = 0; i < dex[move].secondaries.length; i++) { if (dex[move].secondaries[i][search] === searchStatus) hasSecondary = true; } if ((!hasSecondary && searches[search][searchStatus]) || (hasSecondary && !searches[search][searchStatus])) delete dex[move]; @@ -1076,12 +1078,12 @@ var commands = exports.commands = { } } - var results = []; - for (var move in dex) { + let results = []; + for (let move in dex) { results.push(dex[move].name); } - var resultsStr = ""; + let resultsStr = ""; if (targetMon) { resultsStr += "Matching moves found in learnset for " + targetMon + ":
"; } else { @@ -1113,7 +1115,7 @@ var commands = exports.commands = { if (!target) return this.parse('/help itemsearch'); if (!this.canBroadcast()) return; - var showAll = false; + let showAll = false; target = target.trim(); if (target.substr(target.length - 5) === ', all' || target.substr(target.length - 4) === ',all') { @@ -1122,13 +1124,13 @@ var commands = exports.commands = { } target = target.toLowerCase().replace('-', ' ').replace(/[^a-z0-9.\s\/]/g, ''); - var rawSearch = target.split(' '); - var searchedWords = []; - var foundItems = []; + let rawSearch = target.split(' '); + let searchedWords = []; + let foundItems = []; //refine searched words - for (var i = 0; i < rawSearch.length; i++) { - var newWord = rawSearch[i].trim(); + for (let i = 0; i < rawSearch.length; i++) { + let newWord = rawSearch[i].trim(); if (isNaN(newWord)) newWord = newWord.replace('.', ''); switch (newWord) { // words that don't really help identify item removed to speed up search @@ -1199,11 +1201,11 @@ var commands = exports.commands = { if (searchedWords.length === 0) return this.sendReplyBox("No distinguishing words were used. Try a more specific search."); if (searchedWords.indexOf('fling') >= 0) { - var basePower = 0; - var effect; + let basePower = 0; + let effect; - for (var k = 0; k < searchedWords.length; k++) { - var wordEff = ""; + for (let k = 0; k < searchedWords.length; k++) { + let wordEff = ""; switch (searchedWords[k]) { case 'burn': case 'burns': case 'brn': wordEff = 'brn'; break; @@ -1230,8 +1232,8 @@ var commands = exports.commands = { } } - for (var n in Tools.data.Items) { - var item = Tools.getItem(n); + for (let n in Tools.data.Items) { + let item = Tools.getItem(n); if (!item.fling) continue; if (basePower && effect) { @@ -1245,10 +1247,10 @@ var commands = exports.commands = { } if (foundItems.length === 0) return this.sendReplyBox('No items inflict ' + basePower + 'bp damage when used with Fling.'); } else if (target.search(/natural ?gift/i) >= 0) { - var basePower = 0; - var type = ""; + let basePower = 0; + let type = ""; - for (var k = 0; k < searchedWords.length; k++) { + for (let k = 0; k < searchedWords.length; k++) { searchedWords[k] = searchedWords[k].capitalize(); if (searchedWords[k] in Tools.data.TypeChart) { if (type) return this.sendReplyBox("Only specify natural gift type once."); @@ -1262,8 +1264,8 @@ var commands = exports.commands = { } } - for (var n in Tools.data.Items) { - var item = Tools.getItem(n); + for (let n in Tools.data.Items) { + let item = Tools.getItem(n); if (!item.isBerry) continue; if (basePower && type) { @@ -1276,19 +1278,19 @@ var commands = exports.commands = { } if (foundItems.length === 0) return this.sendReplyBox('No berries inflict ' + basePower + 'bp damage when used with Natural Gift.'); } else { - var bestMatched = 0; - for (var n in Tools.data.Items) { - var item = Tools.getItem(n); - var matched = 0; + let bestMatched = 0; + for (let n in Tools.data.Items) { + let item = Tools.getItem(n); + let matched = 0; // splits words in the description into a toId()-esk format except retaining / and . in numbers - var descWords = item.desc; + let descWords = item.desc; // add more general quantifier words to descriptions if (/[1-9\.]+x/.test(descWords)) descWords += ' increases'; if (item.isBerry) descWords += ' berry'; descWords = descWords.replace(/super[\-\s]effective/g, 'supereffective'); descWords = descWords.toLowerCase().replace('-', ' ').replace(/[^a-z0-9\s\/]/g, '').replace(/(\D)\./, function (p0, p1) { return p1; }).split(' '); - for (var k = 0; k < searchedWords.length; k++) { + for (let k = 0; k < searchedWords.length; k++) { if (descWords.indexOf(searchedWords[k]) >= 0) matched++; } @@ -1297,16 +1299,16 @@ var commands = exports.commands = { } // iterate over found items again to make sure they all are the best match - for (var l = 0; l < foundItems.length; l++) { - var item = Tools.getItem(foundItems[l]); - var matched = 0; - var descWords = item.desc; + for (let l = 0; l < foundItems.length; l++) { + let item = Tools.getItem(foundItems[l]); + let matched = 0; + let descWords = item.desc; if (/[1-9\.]+x/.test(descWords)) descWords += ' increases'; if (item.isBerry) descWords += ' berry'; descWords = descWords.replace(/super[\-\s]effective/g, 'supereffective'); descWords = descWords.toLowerCase().replace('-', ' ').replace(/[^a-z0-9\s\/]/g, '').replace(/(\D)\./, function (p0, p1) { return p1; }).split(' '); - for (var k = 0; k < searchedWords.length; k++) { + for (let k = 0; k < searchedWords.length; k++) { if (descWords.indexOf(searchedWords[k]) >= 0) matched++; } @@ -1317,7 +1319,7 @@ var commands = exports.commands = { } } - var resultsStr = this.broadcasting ? "" : ("" + Tools.escapeHTML(message) + ":
"); + let resultsStr = this.broadcasting ? "" : ("" + Tools.escapeHTML(message) + ":
"); if (foundItems.length > 0) { if (showAll || foundItems.length <= RESULTS_MAX_LENGTH + 5) { foundItems.sort(); @@ -1349,13 +1351,13 @@ var commands = exports.commands = { if (!this.canBroadcast()) return; - var lsetData = {set:{}}; - var targets = target.split(','); - var template = Tools.getTemplate(targets[0]); - var move = {}; - var problem; - var format = {rby:'gen1ou', gsc:'gen2ou', adv:'gen3ou', dpp:'gen4ou', bw2:'gen5ou'}[cmd.substring(0, 3)]; - var all = (cmd === 'learnall'); + let lsetData = {set:{}}; + let targets = target.split(','); + let template = Tools.getTemplate(targets[0]); + let move = {}; + let problem; + let format = {rby:'gen1ou', gsc:'gen2ou', adv:'gen3ou', dpp:'gen4ou', bw2:'gen5ou'}[cmd.substring(0, 3)]; + let all = (cmd === 'learnall'); if (cmd === 'learn5') lsetData.set.level = 5; if (cmd === 'g6learn') lsetData.format = {noPokebank: true}; @@ -1367,7 +1369,7 @@ var commands = exports.commands = { return this.errorReply("You must specify at least one move."); } - for (var i = 1, len = targets.length; i < len; ++i) { + for (let i = 1, len = targets.length; i < len; ++i) { move = Tools.getMove(targets[i]); if (!move.exists) { return this.errorReply("Move '" + move.id + "' not found."); @@ -1375,18 +1377,18 @@ var commands = exports.commands = { problem = TeamValidator.checkLearnsetSync(format, move, template.species, lsetData); if (problem) break; } - var buffer = template.name + (problem ? " can't learn " : " can learn ") + (targets.length > 2 ? "these moves" : move.name); + let buffer = template.name + (problem ? " can't learn " : " can learn ") + (targets.length > 2 ? "these moves" : move.name); if (format) buffer += ' on ' + cmd.substring(0, 3).toUpperCase(); if (!problem) { - var sourceNames = {E:"egg", S:"event", D:"dream world"}; + let sourceNames = {E:"egg", S:"event", D:"dream world"}; if (lsetData.sources || lsetData.sourcesBefore) buffer += " only when obtained from: