diff --git a/build-tools/build-indexes b/build-tools/build-indexes
index 201cd2e38..4287f8bb1 100755
--- a/build-tools/build-indexes
+++ b/build-tools/build-indexes
@@ -314,8 +314,6 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
const overrideTier = {};
const metagameBans = {};
const nonstandardMoves = [];
- const gen5zuBans = {};
- const gen4puBans = {};
for (const id of pokemon) {
const species = Dex.mod(gen).species.get(id);
const baseSpecies = Dex.mod(gen).species.get(species.baseSpecies);
@@ -382,7 +380,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
if (species.tier === 'LC') return 'LC';
return 'Regular';
}
- if (isRS || isFRLG) {
+ if (isRS) {
if (species.isNonstandard) {
if (species.isNonstandard === 'Unobtainable') return 'Unreleased';
return 'Illegal';
@@ -483,20 +481,6 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
metagameBans['nationaldex35pokes'][species.id] = 1;
}
}
- if (genNum >= 5) {
- if (genNum === 5) {
- const gen5zu = Dex.formats.get(gen + 'zu');
- if (gen5zu.exists && Dex.formats.getRuleTable(gen5zu).isBannedSpecies(species)) {
- gen5zuBans[species.id] = 1;
- }
- }
- }
- if (genNum === 4) {
- const gen4pu = Dex.formats.get(gen + 'pu');
- if (gen4pu.exists && Dex.formats.getRuleTable(gen4pu).isBannedSpecies(species)) {
- gen4puBans[species.id] = 1;
- }
- }
}
nonstandardMoves.push(...Object.keys(Dex.data.Moves).filter(id => {
@@ -599,12 +583,6 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
BattleTeambuilderTable[gen].learnsets = {};
} else {
BattleTeambuilderTable[gen] = {};
- if (genNum === 5) {
- BattleTeambuilderTable[gen].gen5zuBans = gen5zuBans;
- }
- if (genNum === 4) {
- BattleTeambuilderTable[gen].gen4puBans = gen4puBans;
- }
BattleTeambuilderTable[gen].overrideTier = overrideTier;
BattleTeambuilderTable[gen].tiers = tiers;
BattleTeambuilderTable[gen].items = items;
@@ -622,15 +600,12 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
if (isVGC || isGen9BH) {
return ["Mythical", "Restricted", "Regular", "NFE", "LC"];
}
- if (isRS || isFRLG) {
+ if (isRS) {
return ["Regular", "NFE", "LC", "Uber"];
}
if (isDoubles && genNum > 4) {
return ["DUber", "(DUber)", "DOU", "DBL", "(DOU)", "DUU", "(DUU)", "New", "NFE", "LC"];
}
- if (gen === 'gen4') {
- return ["CAP", "CAP NFE", "CAP LC", "AG", "Uber", "OU", "(OU)", "UUBL", "UU", "NUBL", "NU", "NFE", "LC"];
- }
return [
"CAP", "CAP NFE", "CAP LC", "AG", "Uber", "(Uber)", "OU", "(OU)", "UUBL", "UU", "RUBL", "RU", "NUBL", "NU", "PUBL", "PU", "ZUBL", "ZU", "New", "NFE", "LC", "Unreleased",
];
@@ -990,6 +965,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
const G2Learnsets = Dex.mod('gen2').data.Learnsets;
for (const id in G2Learnsets) {
const learnset = G2Learnsets[id].learnset;
+ if (!learnset) continue;
for (const moveid in learnset) {
const gens = learnset[moveid].map(x => Number(x[0]));
const minGen = Math.min(...gens);
@@ -1006,6 +982,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
const species = Dex.mod('gen3rs').species.get(id);
if (species.isNonstandard && !['Unobtainable', 'CAP'].includes(species.isNonstandard)) continue;
const learnset = G3RSLearnsets[id].learnset;
+ if (!learnset) continue;
BattleTeambuilderTable['gen3rs'].learnsets[id] = {};
for (const moveid in learnset) {
BattleTeambuilderTable['gen3rs'].learnsets[id][moveid] = '3';
@@ -1016,6 +993,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
const species = Dex.mod('gen3frlg').species.get(id);
if (species.isNonstandard && !['Unobtainable', 'CAP'].includes(species.isNonstandard)) continue;
const learnset = G3FRLGLearnsets[id].learnset;
+ if (!learnset) continue;
BattleTeambuilderTable['gen3frlg'].learnsets[id] = {};
for (const moveid in learnset) {
BattleTeambuilderTable['gen3frlg'].learnsets[id][moveid] = '3';
@@ -1026,6 +1004,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
const species = Dex.mod('gen5bw1').species.get(id);
if (species.isNonstandard && !['Unobtainable', 'CAP'].includes(species.isNonstandard)) continue;
const learnset = G5BW1Learnsets[id].learnset;
+ if (!learnset) continue;
BattleTeambuilderTable['gen5bw1'].learnsets[id] = {};
for (const moveid in learnset) {
BattleTeambuilderTable['gen5bw1'].learnsets[id][moveid] = '5';
@@ -1039,6 +1018,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
if (!validNum) continue;
if (species.forme && !['Alola', 'Mega', 'Mega-X', 'Mega-Y', 'Starter'].includes(species.forme)) continue;
const learnset = LGLearnsets[id].learnset;
+ if (!learnset) continue;
BattleTeambuilderTable['gen7letsgo'].learnsets[id] = {};
for (const moveid in learnset) {
BattleTeambuilderTable['gen7letsgo'].learnsets[id][moveid] = '7';
@@ -1049,6 +1029,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
const species = Dex.mod('gen8bdsp').species.get(id);
if (species.isNonstandard && !['Unobtainable', 'CAP'].includes(species.isNonstandard)) continue;
const learnset = BDSPLearnsets[id].learnset;
+ if (!learnset) continue;
BattleTeambuilderTable['gen8bdsp'].learnsets[id] = {};
for (const moveid in learnset) {
BattleTeambuilderTable['gen8bdsp'].learnsets[id][moveid] = '8g';
@@ -1059,6 +1040,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
const species = Dex.mod('champions').species.get(id);
if (species.isNonstandard) continue;
const learnset = ChampionsLearnsets[id].learnset;
+ if (!learnset) continue;
BattleTeambuilderTable['champions'].learnsets[id] = {};
for (const moveid in learnset) {
BattleTeambuilderTable['champions'].learnsets[id][moveid] = '9a';
diff --git a/play.pokemonshowdown.com/js/client-teambuilder.js b/play.pokemonshowdown.com/js/client-teambuilder.js
index ba126e477..8decfa90a 100644
--- a/play.pokemonshowdown.com/js/client-teambuilder.js
+++ b/play.pokemonshowdown.com/js/client-teambuilder.js
@@ -1291,11 +1291,16 @@
if ($(window).width() < 640) this.show();
},
renderSet: function (set, i) {
+ var baseFormat = this.curTeam.format;
+ if (baseFormat.substr(-5) === 'draft') baseFormat = baseFormat.substr(0, baseFormat.length - 5);
var species = this.curTeam.dex.species.get(set.species);
- var isChampions = this.curTeam.format.includes('champions');
- var isLetsGo = this.curTeam.format.includes('letsgo');
- var isBDSP = this.curTeam.format.includes('bdsp');
- var isNatDex = this.curTeam.format.includes('nationaldex') || this.curTeam.format.includes('natdex');
+ var isChampions = baseFormat.includes('champions');
+ var isLetsGo = baseFormat.includes('letsgo');
+ var isBDSP = baseFormat.includes('bdsp');
+ var isNatDex = baseFormat.includes('nationaldex') || baseFormat.includes('natdex');
+ var isVGC = baseFormat.includes('battlespot') || baseFormat.includes('bss') ||
+ baseFormat.includes('vgc') || baseFormat.includes('battlefestival');
+ var isLC = baseFormat.startsWith('lc') || baseFormat.endsWith('lc');
var buf = '
';
if (!set.species) {
if (this.deletedSet) {
@@ -1409,16 +1414,16 @@
} else if (BattleNatures[set.nature] && BattleNatures[set.nature].minus === j) {
evBuf += '−';
}
- var highestStat = 504;
- if (j === 'hp') highestStat = 704;
- if (isChampions) {
- if (j === 'hp') highestStat = 267;
- else highestStat = 310;
+ var highestStat = j === 'hp' ? 714 : 499;
+ if (isChampions || isVGC) {
+ highestStat = j === 'hp' ? 362 : 252;
+ }
+ if (isLC) {
+ highestStat = j === 'hp' ? 45 : 29;
}
var width = stats[j] * 75 / highestStat;
- if (j === 'hp') width = stats[j] * 75 / highestStat;
if (width > 75) width = 75;
- var color = Math.floor(stats[j] * 180 / (isChampions ? 310 : 714));
+ var color = Math.floor(stats[j] * 180 / highestStat);
if (color > 360) color = 360;
var statName = this.curTeam.gen === 1 && j === 'spa' ? 'Spc' : BattleStatNames[j];
buf += ' ' + evBuf + '';
@@ -2074,8 +2079,13 @@
var stats = { hp: '', atk: '', def: '', spa: '', spd: '', spe: '' };
- var usesStatPoints = this.curTeam.format.includes('champions');
- var supportsEVs = !this.curTeam.format.includes('letsgo');
+ var baseFormat = this.curTeam.format;
+ if (baseFormat.substr(-5) === 'draft') baseFormat = baseFormat.substr(0, baseFormat.length - 5);
+ var usesStatPoints = baseFormat.includes('champions');
+ var supportsEVs = !baseFormat.includes('letsgo');
+ var isVGC = baseFormat.includes('battlespot') || baseFormat.includes('bss') ||
+ baseFormat.includes('vgc') || baseFormat.includes('battlefestival');
+ var isLC = baseFormat.startsWith('lc') || baseFormat.endsWith('lc');
// stat cell
var buf = ' ' + (usesStatPoints ? 'Points' : supportsEVs ? 'EV' : 'AV') + '';
@@ -2090,16 +2100,16 @@
} else if (BattleNatures[set.nature] && BattleNatures[set.nature].minus === stat) {
evBuf += '−';
}
- var highestStat = 504;
- if (stat === 'hp') highestStat = 704;
- if (usesStatPoints) {
- if (stat === 'hp') highestStat = 267;
- else highestStat = 310;
+ var highestStat = stat === 'hp' ? 714 : 499;
+ if (usesStatPoints || isVGC) {
+ highestStat = stat === 'hp' ? 362 : 252;
+ }
+ if (isLC) {
+ highestStat = stat === 'hp' ? 45 : 29;
}
var width = stats[stat] * 75 / highestStat;
- if (stat === 'hp') width = stats[stat] * 75 / highestStat;
if (width > 75) width = 75;
- var color = Math.floor(stats[stat] * 180 / (usesStatPoints ? 310 : 714));
+ var color = Math.floor(stats[stat] * 180 / highestStat);
if (color > 360) color = 360;
var statName = this.curTeam.gen === 1 && stat === 'spa' ? 'Spc' : BattleStatNames[stat];
buf += ' ' + evBuf + '';
@@ -2119,16 +2129,16 @@
var totalev = 0;
for (var stat in stats) {
if (stat === 'spd' && this.curTeam.gen === 1) continue;
- var highestStat = 504;
- if (stat === 'hp') highestStat = 704;
- if (usesStatPoints) {
- if (stat === 'hp') highestStat = 267;
- else highestStat = 310;
+ var highestStat = stat === 'hp' ? 714 : 499;
+ if (usesStatPoints || isVGC) {
+ highestStat = stat === 'hp' ? 362 : 252;
+ }
+ if (isLC) {
+ highestStat = stat === 'hp' ? 45 : 29;
}
var width = stats[stat] * 180 / highestStat;
- if (stat === 'hp') width = stats[stat] * 180 / highestStat;
if (width > 179) width = 179;
- var color = Math.floor(stats[stat] * 180 / (usesStatPoints ? 310 : 714));
+ var color = Math.floor(stats[stat] * 180 / highestStat);
if (color > 360) color = 360;
buf += '
';
totalev += (set.evs[stat] || 0);
@@ -2355,12 +2365,17 @@
var nature = BattleNatures[set.nature || 'Serious'];
if (!nature) nature = {};
- var usesStatPoints = this.curTeam.format.includes('champions');
- var supportsEVs = !this.curTeam.format.includes('letsgo') && !usesStatPoints;
- // var supportsAVs = !supportsEVs && this.curTeam.format.endsWith('norestrictions');
+ var baseFormat = this.curTeam.format;
+ if (baseFormat.substr(-5) === 'draft') baseFormat = baseFormat.substr(0, baseFormat.length - 5);
+ var usesStatPoints = baseFormat.includes('champions');
+ var supportsEVs = !baseFormat.includes('letsgo') && !usesStatPoints;
+ // var supportsAVs = !supportsEVs && baseFormat.endsWith('norestrictions');
var defaultEV = this.curTeam.gen <= 2 ? 252 : 0;
var maxEV = usesStatPoints ? 32 : supportsEVs ? 252 : 200;
var stepEV = supportsEVs ? 4 : 1;
+ var isVGC = baseFormat.includes('battlespot') || baseFormat.includes('bss') ||
+ baseFormat.includes('vgc') || baseFormat.includes('battlefestival');
+ var isLC = baseFormat.startsWith('lc') || baseFormat.endsWith('lc');
// label column
buf += '';
@@ -2382,16 +2397,16 @@
buf += '
';
for (var i in stats) {
stats[i] = this.getStat(i);
- var highestStat = 504;
- if (i === 'hp') highestStat = 704;
- if (usesStatPoints) {
- if (i === 'hp') highestStat = 267;
- else highestStat = 310;
+ var highestStat = i === 'hp' ? 714 : 499;
+ if (usesStatPoints || isVGC) {
+ highestStat = i === 'hp' ? 362 : 252;
+ }
+ if (isLC) {
+ highestStat = i === 'hp' ? 45 : 29;
}
var width = stats[i] * 180 / highestStat;
- if (i === 'hp') width = Math.floor(stats[i] * 180 / highestStat);
if (width > 179) width = 179;
- var color = Math.floor(stats[i] * 180 / (usesStatPoints ? 310 : 714));
+ var color = Math.floor(stats[i] * 180 / highestStat);
if (color > 360) color = 360;
buf += '
';
}
diff --git a/play.pokemonshowdown.com/src/battle-dex-search.ts b/play.pokemonshowdown.com/src/battle-dex-search.ts
index 8e4ff0cd1..25b6c2018 100644
--- a/play.pokemonshowdown.com/src/battle-dex-search.ts
+++ b/play.pokemonshowdown.com/src/battle-dex-search.ts
@@ -653,7 +653,8 @@ abstract class BattleTypedSearch
{
if (format.includes('champions')) {
this.formatType = 'champions';
this.dex = Dex.mod('champions' as ID);
- format = 'ou' as ID;
+ format = format.slice(9) as ID;
+ if (format !== 'ou') format = 'ubers' as ID;
}
if (format.startsWith('vgc')) {
this.formatType = 'doubles';
@@ -686,6 +687,7 @@ abstract class BattleTypedSearch {
if (format.includes('frlg')) {
this.formatType = 'frlg';
this.dex = Dex.mod('gen3frlg' as ID);
+ format = format.slice(4) as ID;
}
if (format === 'partnersincrime') this.formatType = 'doubles';
if (format.startsWith('ffa') || format === 'freeforall') this.formatType = 'doubles';
@@ -1036,7 +1038,7 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> {
table = table[`gen${dex.gen}`];
} else if (this.formatType === 'champions') {
table = table[`champions`];
- } else if (isVGCOrBS && !this.formatType) {
+ } else if (isVGCOrBS) {
table = table[`gen${dex.gen}vgc`];
} else if (dex.gen === 9 && isHackmons && !this.formatType) {
table = table['bh'];
@@ -1143,10 +1145,9 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> {
else if (format === 'uubl') tierSet = tierSet.slice(slices.UUBL);
else if (format === 'uu') tierSet = tierSet.slice(slices.UU);
else if (format === 'ru') tierSet = tierSet.slice(slices.RU || slices.UU);
- else if (format === 'nu') tierSet = tierSet.slice(slices.NU || slices.RU || slices.UU);
- else if (format === 'pu') tierSet = tierSet.slice(slices.PU || slices.NU);
- else if (format === 'zu' && dex.gen === 5) tierSet = tierSet.slice(slices.PU || slices.NU);
- else if (format === 'zu') tierSet = tierSet.slice(slices.ZU || slices.PU || slices.NU);
+ else if (format === 'nu') tierSet = tierSet.slice(slices.NU);
+ else if (format === 'pu') tierSet = tierSet.slice(slices.PU);
+ else if (format === 'zu') tierSet = tierSet.slice(slices.ZU);
else if (
format === 'lc' || format === 'lcuu' || format.startsWith('lc') || (format !== 'caplc' && format.endsWith('lc'))
) tierSet = tierSet.slice(slices.LC);
@@ -1236,18 +1237,6 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> {
});
}
}
- if (format === 'zu' && dex.gen === 5 && table.gen5zuBans) {
- tierSet = tierSet.filter(([type, id]) => {
- if (id in table.gen5zuBans) return false;
- return true;
- });
- }
- if (format === 'pu' && dex.gen === 4 && table.gen4puBans) {
- tierSet = tierSet.filter(([type, id]) => {
- if (id in table.gen4puBans) return false;
- return true;
- });
- }
// Filter out Gmax Pokemon from standard tier selection
if (!(/^(battlestadium|vgc|doublesubers)/g.test(format) || (format === 'doubles' && this.formatType === 'natdex'))) {
diff --git a/play.pokemonshowdown.com/src/battle-team-editor.tsx b/play.pokemonshowdown.com/src/battle-team-editor.tsx
index bb0faa4f6..eadb70245 100644
--- a/play.pokemonshowdown.com/src/battle-team-editor.tsx
+++ b/play.pokemonshowdown.com/src/battle-team-editor.tsx
@@ -118,7 +118,8 @@ export class TeamEditorState extends PSModel {
this.defaultLevel = 100;
if (
formatid.includes('vgc') || formatid.includes('bss') || formatid.includes('ultrasinnohclassic') ||
- formatid.includes('battlespot') || formatid.includes('battlestadium') || formatid.includes('battlefestival')
+ formatid.includes('battlespot') || formatid.includes('battlestadium') || formatid.includes('battlefestival') ||
+ formatid.includes('letsgo') || formatid.includes('champions')
) {
this.defaultLevel = 50;
}
@@ -2451,11 +2452,11 @@ class StatForm extends preact.Component<{
const stat = editor.getStat(statID, set, ivs[statID]);
let ev: number | string = set.evs ? (set.evs[statID] || 0) : defaultEV;
- let width = stat * 75 / 504;
- if (statID === 'hp') width = stat * 75 / 704;
- if (width > 75) width = 75;
- let hue = Math.floor(stat * 180 / 714);
- if (hue > 360) hue = 360;
+ const maxStat = statID === 'hp' ?
+ Math.floor(176 * editor.defaultLevel / 25) + 10 :
+ Math.floor(247 * editor.defaultLevel / 50) + 5;
+ const width = Math.min(stat * 75 / maxStat, 75);
+ const hue = Math.min(Math.floor(stat * 180 / maxStat), 360);
const statName = editor.gen === 1 && statID === 'spa' ? 'Spc' : BattleStatNames[statID];
if (evs && !ev && !set.evs && statID === 'hp') ev = 'EVs';
return
@@ -2715,11 +2716,12 @@ class StatForm extends preact.Component<{
plus: Dex.StatNameExceptHP | null = null;
minus: Dex.StatNameExceptHP | null = null;
renderStatbar(stat: number, statID: StatName) {
- let width = stat * 180 / 504;
- if (statID === 'hp') width = Math.floor(stat * 180 / 704);
- if (width > 179) width = 179;
- let hue = Math.floor(stat * 180 / 714);
- if (hue > 360) hue = 360;
+ const { editor } = this.props;
+ const maxStat = statID === 'hp' ?
+ Math.floor(176 * editor.defaultLevel / 25) + 10 :
+ Math.floor(247 * editor.defaultLevel / 50) + 5;
+ const width = Math.min(stat * 180 / maxStat, 180);
+ const hue = Math.min(Math.floor(stat * 180 / maxStat), 360);
return ;
diff --git a/play.pokemonshowdown.com/src/battle-tooltips.ts b/play.pokemonshowdown.com/src/battle-tooltips.ts
index 78679f35c..b13a4418b 100644
--- a/play.pokemonshowdown.com/src/battle-tooltips.ts
+++ b/play.pokemonshowdown.com/src/battle-tooltips.ts
@@ -1636,7 +1636,9 @@ export class BattleTooltips {
}
// Weather and pseudo-weather type changes.
if (move.id === 'weatherball') {
- if (value.weatherModify(0)) {
+ if (value.abilityModify(0, 'Mega Sol')) {
+ moveType = 'Fire';
+ } else if (value.weatherModify(0)) {
switch (this.battle.weather) {
case 'sunnyday':
case 'desolateland':
@@ -1656,8 +1658,6 @@ export class BattleTooltips {
moveType = 'Ice';
break;
}
- } else if (value.abilityModify(0, 'Mega Sol')) {
- moveType = 'Fire';
}
}
if (move.id === 'terrainpulse' && pokemon.isGrounded(serverPokemon)) {
@@ -2143,7 +2143,7 @@ export class BattleTooltips {
value.set(move.accuracy as number);
if (move.id === 'hurricane' || move.id === 'thunder') {
- if (value.tryAbility('Mega Sol')) value.set(50, 'Mega Sol');
+ if (value.tryAbility('Mega Sol')) value.set(50, 'Mega Sol'); // TODO check implementation
if (value.tryWeather('Sunny Day')) value.set(50, 'Sunny Day');
if (value.tryWeather('Desolate Land')) value.set(50, 'Desolate Land');
}
@@ -2276,8 +2276,7 @@ export class BattleTooltips {
}
}
if (move.id === 'weatherball') {
- value.abilityModify(2, "Mega Sol");
- if (this.battle.weather !== 'deltastream') {
+ if (!value.abilityModify(2, "Mega Sol") && this.battle.weather !== 'deltastream') {
value.weatherModify(2);
}
}