diff --git a/play.pokemonshowdown.com/js/client-teambuilder.js b/play.pokemonshowdown.com/js/client-teambuilder.js index fd2593e4fd..98decadcbf 100644 --- a/play.pokemonshowdown.com/js/client-teambuilder.js +++ b/play.pokemonshowdown.com/js/client-teambuilder.js @@ -1375,10 +1375,10 @@ // moves if (!set.moves) set.moves = []; buf += '
'; - buf += '
'; - buf += '
'; - buf += '
'; - buf += '
'; + for (var i = 0; i <= 3; i++) { + if (i > 0) buf += '
'; + buf += '
'; + } buf += '
'; // stats diff --git a/play.pokemonshowdown.com/js/storage.js b/play.pokemonshowdown.com/js/storage.js index 8ca36a79bf..e0f02a3529 100644 --- a/play.pokemonshowdown.com/js/storage.js +++ b/play.pokemonshowdown.com/js/storage.js @@ -812,6 +812,20 @@ Storage.packTeam = function (team) { if (moveid.substr(0, 11) === 'hiddenpower' && moveid.length > 11) hasHP = true; } + // move PP ups + if (set.movePPUps) { + var PPUps = ''; + var showPPUps = false; + for (var j = 0; j < set.movePPUps.length; j++) { + if (j) PPUps += ','; + if (set.movePPUps[j] < 3) { + PPUps += set.movePPUps[j]; + showPPUps = true; + } + } + if (showPPUps) buf += ';' + PPUps; + } + // nature buf += '|' + (set.nature || ''); @@ -883,7 +897,7 @@ Storage.fastUnpackTeam = function (buf) { if (!buf) return []; var team = []; - var i = 0, j = 0; + var i = 0, j = 0, k = 0; while (true) { var set = {}; @@ -913,10 +927,23 @@ Storage.fastUnpackTeam = function (buf) { i = j + 1; // moves - j = buf.indexOf('|', i); + j = buf.indexOf(';', i); + k = buf.indexOf('|', i); + if (j < 0 || j > k) j = k; set.moves = buf.substring(i, j).split(','); i = j + 1; + // move PP ups + if (buf.charAt(j) === ';') { + j = buf.indexOf('|', i); + set.movePPUps = buf.substring(i, j).split(','); + for (var index = 0; index < set.movePPUps.length; index++) { + set.movePPUps[index] = parseInt(set.movePPUps[index], 10); + if (!set.movePPUps[index]) set.movePPUps[index] = 3; + } + i = j + 1; + } + // nature j = buf.indexOf('|', i); set.nature = buf.substring(i, j); @@ -1000,7 +1027,7 @@ Storage.unpackTeam = function (buf) { if (!buf) return []; var team = []; - var i = 0, j = 0; + var i = 0, j = 0, k = 0; while (true) { var set = {}; @@ -1029,12 +1056,29 @@ Storage.unpackTeam = function (buf) { i = j + 1; // moves - j = buf.indexOf('|', i); + j = buf.indexOf(';', i); + k = buf.indexOf('|', i); + if (j < 0 || j > k) { + j = k; + if (j < 0) return null; + } set.moves = buf.substring(i, j).split(',').map(function (moveid) { return Dex.moves.get(moveid).name; }); i = j + 1; + // move PP ups + if (buf.charAt(j) === ';') { + j = buf.indexOf('|', i); + if (j < 0) return null; + set.movePPUps = buf.substring(i, j).split(','); + for (var index = 0; index < set.movePPUps.length; index++) { + set.movePPUps[index] = parseInt(set.movePPUps[index], 10); + if (isNaN(set.movePPUps[index])) set.movePPUps[index] = 3; + } + i = j + 1; + } + // nature j = buf.indexOf('|', i); set.nature = buf.substring(i, j); @@ -1344,7 +1388,15 @@ Storage.importTeam = function (buffer, teams) { if (line === 'Frustration' && curSet.happiness === undefined) { curSet.happiness = 0; } - curSet.moves.push(line); + var moveAndPPUps = line.split(' (PP Ups: ', 2); + curSet.moves.push(moveAndPPUps[0]); + if (!curSet.movePPUps) curSet.movePPUps = []; + if (moveAndPPUps[1]) moveAndPPUps[1] = moveAndPPUps[1].charAt(0); + if (isNaN(moveAndPPUps[1])) { + curSet.movePPUps.push(3); + } else { + curSet.movePPUps.push(parseInt(moveAndPPUps[1], 10)); + } } } if (teams && teams.length && typeof teams[teams.length - 1].team !== 'string') { @@ -1493,7 +1545,11 @@ Storage.exportTeam = function (team, gen, hidestats) { move = move.substr(0, 13) + '[' + move.substr(13) + ']'; } if (move) { - text += '- ' + move + " \n"; + text += '- ' + move; + if (curSet.movePPUps && !isNaN(curSet.movePPUps[j]) && curSet.movePPUps[j] < 3) { + text += " (PP Ups: " + curSet.movePPUps[j] + ")"; + } + text += " \n"; } } text += "\n"; diff --git a/play.pokemonshowdown.com/src/battle-tooltips.ts b/play.pokemonshowdown.com/src/battle-tooltips.ts index ebeb171361..4e8a748dc7 100644 --- a/play.pokemonshowdown.com/src/battle-tooltips.ts +++ b/play.pokemonshowdown.com/src/battle-tooltips.ts @@ -2517,6 +2517,8 @@ interface PokemonSet { /** Defaults to no ability (error in Gen 3+) */ ability?: string; moves: string[]; + /** Defaults to 3 */ + movePPUps?: number[]; /** Defaults to no nature (error in Gen 3+) */ nature?: NatureName; /** Defaults to random legal gender, NOT subject to gender ratios */ diff --git a/play.pokemonshowdown.com/src/panel-teamdropdown.tsx b/play.pokemonshowdown.com/src/panel-teamdropdown.tsx index 0794f16cab..e343bc2674 100644 --- a/play.pokemonshowdown.com/src/panel-teamdropdown.tsx +++ b/play.pokemonshowdown.com/src/panel-teamdropdown.tsx @@ -41,6 +41,14 @@ class PSTeambuilder { } } + if (set.movePPUps && set.movePPUps.some(n => n < 3)) { + const PPUps = set.movePPUps.map(n => { + if (n === 3) return ''; + return n.toString(); + }); + buf += ';' + PPUps.join(','); + } + // nature buf += '|' + (set.nature || ''); @@ -140,11 +148,19 @@ class PSTeambuilder { species.abilities[parts[3] as '0' || '0'] || (parts[3] === '' ? '' : '!!!ERROR!!!') : Dex.abilities.get(parts[3]).name; - // moves - set.moves = parts[4].split(',').map(moveid => + // moves and PP ups + const [moves, PPUps] = parts[4].split(';', 2); + set.moves = moves.split(',').map(moveid => Dex.moves.get(moveid).name ); + if (PPUps) { + set.movePPUps = PPUps.split(',').map(n => { + if (!n) return 3; + return parseInt(n, 10); + }); + } + // nature set.nature = parts[5] as NatureName; if (set.nature as any === 'undefined') set.nature = undefined; @@ -224,14 +240,19 @@ class PSTeambuilder { text += `Ability: ${set.ability} \n`; } if (set.moves) { - for (let move of set.moves) { + for (let i = 0; i < set.moves.length; i++) { + let move = set.moves[i]; + let PPUps = ``; if (move.substr(0, 13) === 'Hidden Power ') { const hpType = move.slice(13); move = move.slice(0, 13); move = `${move}[${hpType}]`; } + if (set.movePPUps && !isNaN(set.movePPUps[i]) && set.movePPUps[i] < 3) { + PPUps = ` (PP Ups: ${set.movePPUps[i]})`; + } if (move) { - text += `- ${move} \n`; + text += `- ${move}${PPUps} \n`; } } } @@ -395,9 +416,10 @@ class PSTeambuilder { if (line !== 'undefined') set.nature = line as NatureName; } else if (line.charAt(0) === '-' || line.charAt(0) === '~') { line = line.slice(line.charAt(1) === ' ' ? 2 : 1); - if (line.startsWith('Hidden Power [')) { - const hpType = line.slice(14, -1) as TypeName; - line = 'Hidden Power ' + hpType; + let [move, PPUps] = line.split(' (PP Ups: '); + if (move.startsWith('Hidden Power [')) { + const hpType = move.slice(14, -1) as TypeName; + move = 'Hidden Power ' + hpType; if (!set.ivs && Dex.types.isName(hpType)) { set.ivs = {hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31}; const hpIVs = Dex.types.get(hpType).HPivs || {}; @@ -406,6 +428,8 @@ class PSTeambuilder { } } } + if (!set.movePPUps) set.movePPUps = []; + set.movePPUps.push(parseInt(PPUps?.charAt(0), 10) || 3); if (line === 'Frustration' && set.happiness === undefined) { set.happiness = 0; }