Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow PP Ups to be edited #2222

Draft
wants to merge 27 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d7d2acb
Allow PP Ups to be edited
dot-Comfey Feb 11, 2024
1c898cd
Less ugly CSS
dot-Comfey Feb 11, 2024
d05cf8c
Moves and PP Ups on the same line
dot-Comfey Feb 12, 2024
03b84b4
Remove debugs
dot-Comfey Feb 12, 2024
de525ec
Show move PP
dot-Comfey Feb 16, 2024
ab6c6de
Update client-teambuilder.js
dot-Comfey Feb 16, 2024
65137bf
Remove UI
dot-Comfey Feb 16, 2024
db511a6
Merge branch 'smogon:master' into moveppups
dot-Comfey Oct 12, 2024
c815bbc
A little less ugly export formatting
dot-Comfey Oct 12, 2024
b696d2d
Update play.pokemonshowdown.com/js/storage.js
KrisXV Oct 12, 2024
06dcea9
Update storage.js
dot-Comfey Oct 12, 2024
b3615d7
Fix unpacking
dot-Comfey Oct 13, 2024
8feea82
Update panel-teamdropdown.tsx
dot-Comfey Oct 13, 2024
2aa94bb
Change PP Ups display in packed format
dot-Comfey Oct 15, 2024
bf8f4e4
Format errors
dot-Comfey Oct 15, 2024
243b92f
Update storage.js
dot-Comfey Oct 15, 2024
fcad12c
Merge branch 'master' into moveppups
Zarel Mar 1, 2025
c6c4da7
Update for modern lint rules
Zarel Mar 1, 2025
86a1dec
Add PP Ups to Details
dot-Comfey Mar 1, 2025
9e83c61
Update client-teambuilder.js
dot-Comfey Mar 1, 2025
22d4d67
Trump Card exception
dot-Comfey Mar 1, 2025
3954c8c
Reset PP Ups if move is not Trump Card
dot-Comfey Mar 1, 2025
f9ad0e9
Don't update PP Ups of other moves when selecting a new move
dot-Comfey Mar 1, 2025
fd46b5c
Update unpack format
dot-Comfey Mar 2, 2025
0cb6b1a
Fix crash in unpacking
dot-Comfey Mar 2, 2025
9fb4586
Default Trump Card PP Ups to 0 everywhere
dot-Comfey Mar 12, 2025
dfa1776
Update storage.js
dot-Comfey Mar 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions play.pokemonshowdown.com/js/client-teambuilder.js
Original file line number Diff line number Diff line change
@@ -1374,10 +1374,10 @@
// moves
if (!set.moves) set.moves = [];
buf += '<div class="setcol setcol-moves"><div class="setcell"><label>Moves</label>';
buf += '<input type="text" name="move1" class="textbox chartinput" value="' + BattleLog.escapeHTML(set.moves[0]) + '" autocomplete="off" /></div>';
buf += '<div class="setcell"><input type="text" name="move2" class="textbox chartinput" value="' + BattleLog.escapeHTML(set.moves[1]) + '" autocomplete="off" /></div>';
buf += '<div class="setcell"><input type="text" name="move3" class="textbox chartinput" value="' + BattleLog.escapeHTML(set.moves[2]) + '" autocomplete="off" /></div>';
buf += '<div class="setcell"><input type="text" name="move4" class="textbox chartinput" value="' + BattleLog.escapeHTML(set.moves[3]) + '" autocomplete="off" /></div>';
for (var i = 0; i <= 3; i++) {
if (i > 0) buf += '<div class="setcell">';
buf += '<input type="text" name="move' + (i + 1) + '" class="textbox chartinput" value="' + BattleLog.escapeHTML(set.moves[i]) + '" autocomplete="off" /></div>';
}
buf += '</div>';

// stats
@@ -2926,6 +2926,19 @@
buf += '</div></div>';
}

for (var i = 0; i <= 3; i++) {
buf += '<div class="formrow"><label class="formlabel" title="Move ' + (i + 1) + ' PP Ups">Move ' + (i + 1) + ' PP Ups:</label><div>';
var defaultPPUps = toID(set.moves[i]) === 'trumpcard' ? 0 : 3;
var movePPUps = defaultPPUps;
if (set.movePPUps && !isNaN(set.movePPUps[i])) movePPUps = set.movePPUps[i];
buf += '<select name="move' + i + 'ppups" class="button">';
for (var j = 0; j <= 3; j++) {
buf += '<option value="' + j + '" ' + (movePPUps === j ? 'selected' : '') + '>' + j + '</option>';
}
buf += '</select>';
buf += '</div></div>';
}

buf += '</form>';
if (species.cosmeticFormes) {
buf += '<button class="altform button">Change sprite</button>';
@@ -3008,6 +3021,13 @@
delete set.teraType;
}

// PP Ups
for (var i = 0; i <= 3; i++) {
if (!set.movePPUps) set.movePPUps = [];
var PPUps = this.$chart.find('select[name=move' + i + 'ppups]').val();
set.movePPUps[i] = parseInt(PPUps);
}

// update details cell
var buf = '';
var GenderChart = {
@@ -3354,13 +3374,15 @@
this.unChooseMove(this.curSet.moves[0]);
this.curSet.moves[0] = val;
this.chooseMove(val);
this.setPPUps(val, 0);
if (selectNext) this.$('input[name=move2]').select();
break;
case 'move2':
if (!this.curSet.moves[0]) this.curSet.moves[0] = '';
this.unChooseMove(this.curSet.moves[1]);
this.curSet.moves[1] = val;
this.chooseMove(val);
this.setPPUps(val, 1);
if (selectNext) this.$('input[name=move3]').select();
break;
case 'move3':
@@ -3369,6 +3391,7 @@
this.unChooseMove(this.curSet.moves[2]);
this.curSet.moves[2] = val;
this.chooseMove(val);
this.setPPUps(val, 2);
if (selectNext) this.$('input[name=move4]').select();
break;
case 'move4':
@@ -3378,6 +3401,7 @@
this.unChooseMove(this.curSet.moves[3]);
this.curSet.moves[3] = val;
this.chooseMove(val);
this.setPPUps(val, 3);
if (selectNext) {
this.stats();
this.$('button.setstats').focus();
@@ -3571,6 +3595,15 @@
this.updateSetTop();
if (selectNext) this.$(set.item || !this.$('input[name=item]').length ? (this.$('input[name=ability]').length ? 'input[name=ability]' : 'input[name=move1]') : 'input[name=item]').select();
},
setPPUps: function (move, slot) {
var set = this.curSet;
if (!set.movePPUps) set.movePPUps = [];
if (toID(move) === 'trumpcard') {
set.movePPUps[slot] = 0;
} else {
set.movePPUps[slot] = 3;
}
},

/*********************************************************
* Utility functions
84 changes: 75 additions & 9 deletions play.pokemonshowdown.com/js/storage.js
Original file line number Diff line number Diff line change
@@ -802,14 +802,23 @@ Storage.packTeam = function (team) {
// ability
buf += '|' + toID(set.ability);

// moves
buf += '|';
// moves and PP Ups
var moves = '|';
var PPUps = '';
if (set.moves) for (var j = 0; j < set.moves.length; j++) {
var moveid = toID(set.moves[j]);
if (j && !moveid) continue;
buf += (j ? ',' : '') + moveid;
moves += (j ? ',' : '') + moveid;
if (moveid.substr(0, 11) === 'hiddenpower' && moveid.length > 11) hasHP = true;
PPUps += (j ? ',' : ';');
if (set.movePPUps) {
var defaultPPUps = toID(set.moves[j]) === 'trumpcard' ? 0 : 3;
var PPUp = isNaN(set.movePPUps[j]) ? defaultPPUps : set.movePPUps[j];
if (PPUp !== defaultPPUps) PPUps += set.movePPUps[j].toString();
}
}
if (PPUps.length === set.moves.length) PPUps = '';
buf += moves + PPUps;

// nature
buf += '|' + (set.nature || '');
@@ -882,7 +891,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 = {};
@@ -912,10 +921,30 @@ 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);
if (j < 0) return null;
set.movePPUps = buf.substring(i, j).split(',');
for (var index = 0; index < set.movePPUps.length; index++) {
var defaultPPUps = toID(set.moves[index]) === 'trumpcard' ? 0 : 3;
set.movePPUps[index] = parseInt(set.movePPUps[index], 10);
if (isNaN(set.movePPUps[index])) set.movePPUps[index] = defaultPPUps;
}
i = j + 1;
} else {
set.movePPUps = [];
for (var index = 0; index < set.moves.length; index++) {
set.movePPUps[index] = toID(set.moves[index]) === 'trumpcard' ? 0 : 3;
}
}

// nature
j = buf.indexOf('|', i);
set.nature = buf.substring(i, j);
@@ -999,7 +1028,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 = {};
@@ -1028,12 +1057,35 @@ 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++) {
var defaultPPUps = toID(set.moves[index]) === 'trumpcard' ? 0 : 3;
set.movePPUps[index] = parseInt(set.movePPUps[index], 10);
if (isNaN(set.movePPUps[index])) set.movePPUps[index] = defaultPPUps;
}
i = j + 1;
} else {
set.movePPUps = [];
for (var index = 0; index < set.moves.length; index++) {
set.movePPUps[index] = toID(set.moves[index]) === 'trumpcard' ? 0 : 3;
}
}

// nature
j = buf.indexOf('|', i);
set.nature = buf.substring(i, j);
@@ -1343,7 +1395,16 @@ 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);
var defaultPPUps = toID(moveAndPPUps[0]) === 'trumpcard' ? 0 : 3;
if (isNaN(moveAndPPUps[1])) {
curSet.movePPUps.push(defaultPPUps);
} else {
curSet.movePPUps.push(parseInt(moveAndPPUps[1], 10));
}
}
}
if (teams && teams.length && typeof teams[teams.length - 1].team !== 'string') {
@@ -1492,7 +1553,12 @@ Storage.exportTeam = function (team, gen, hidestats) {
move = move.substr(0, 13) + '[' + move.substr(13) + ']';
}
if (move) {
text += '- ' + move + " \n";
text += '- ' + move;
var defaultPPUps = toID(move) === 'trumpcard' ? 0 : 3;
if (curSet.movePPUps && !isNaN(curSet.movePPUps[j]) && curSet.movePPUps[j] !== defaultPPUps) {
text += " (PP Ups: " + curSet.movePPUps[j] + ")";
}
text += " \n";
}
}
text += "\n";
2 changes: 2 additions & 0 deletions play.pokemonshowdown.com/src/battle-dex.ts
Original file line number Diff line number Diff line change
@@ -60,6 +60,8 @@ export declare namespace Dex {
/** 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 */
57 changes: 40 additions & 17 deletions play.pokemonshowdown.com/src/panel-teamdropdown.tsx
Original file line number Diff line number Diff line change
@@ -33,18 +33,21 @@ export class PSTeambuilder {
id = toID(set.ability);
buf += `|${id || '-'}`;

// moves
buf += '|';
if (set.moves) {
for (let j = 0; j < set.moves.length; j++) {
let moveid = toID(set.moves[j]);
if (j && !moveid) continue;
buf += `${j ? ',' : ''}${moveid}`;
if (moveid.substr(0, 11) === 'hiddenpower' && moveid.length > 11) {
hasHP = moveid.slice(11);
}
// moves and PP Ups
let moves = '|';
let PPUps = '';
if (set.moves) for (let j = 0; j < set.moves.length; j++) {
const moveid = toID(set.moves[j]);
if (j && !moveid) continue;
moves += (j ? ',' : '') + moveid;
PPUps += (j ? ',' : ';');
const defaultPPUps = toID(set.moves[j]) === 'trumpcard' ? 0 : 3;
if (set.movePPUps && (set.movePPUps[j] ?? defaultPPUps) !== defaultPPUps) {
PPUps += set.movePPUps[j].toString();
}
}
if (PPUps.length === set.moves.length) PPUps = '';
buf += moves + PPUps;

// nature
buf += `|${set.nature || ''}`;
@@ -133,11 +136,21 @@ export 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) {
const movePPUps = PPUps.split(',');
for (let i = 0; i < set.moves.length; i++) {
const defaultPPUps = toID(set.moves[i]) === 'trumpcard' ? 0 : 3;
if (!set.movePPUps) set.movePPUps = [];
set.movePPUps.push(movePPUps[i] ? parseInt(movePPUps[i]) : defaultPPUps);
}
}

// nature
set.nature = parts[5] as Dex.NatureName;
if (set.nature as any === 'undefined') set.nature = undefined;
@@ -217,14 +230,20 @@ export 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}]`;
}
const defaultPPUps = toID(move) === 'trumpcard' ? 0 : 3;
if ((set.movePPUps?.[i] ?? defaultPPUps) !== defaultPPUps) {
PPUps = ` (PP Ups: ${set.movePPUps![i]})`;
}
if (move) {
text += `- ${move} \n`;
text += `- ${move}${PPUps} \n`;
}
}
}
@@ -388,9 +407,10 @@ export class PSTeambuilder {
if (line !== 'undefined') set.nature = line as Dex.NatureName;
} else if (line.startsWith('-') || line.startsWith('~')) {
line = line.slice(line.charAt(1) === ' ' ? 2 : 1);
if (line.startsWith('Hidden Power [')) {
const hpType = line.slice(14, -1) as Dex.TypeName;
line = 'Hidden Power ' + hpType;
let [move, PPUps] = line.split(' (PP Ups: ');
if (move.startsWith('Hidden Power [')) {
const hpType = move.slice(14, -1) as Dex.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 || {};
@@ -399,6 +419,9 @@ export class PSTeambuilder {
}
}
}
if (!set.movePPUps) set.movePPUps = [];
const defaultPPUps = toID(move) === 'trumpcard' ? 0 : 3;
set.movePPUps.push(parseInt(PPUps?.charAt(0)) ?? defaultPPUps);
if (line === 'Frustration' && set.happiness === undefined) {
set.happiness = 0;
}
6 changes: 3 additions & 3 deletions play.pokemonshowdown.com/style/client.css
Original file line number Diff line number Diff line change
@@ -2859,12 +2859,12 @@ a.ilink.yours {
}

.detailsform .formrow {
padding-left: 100px;
padding-left: 150px;
}
.detailsform .formrow .formlabel {
float: left;
margin-left: -100px;
width: 110px;
margin-left: -150px;
width: 165px;
text-align: right;
}
.changeform i {