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

Teambuilder: Update popular items for gen 9 & add doubles support #2321

Merged
merged 10 commits into from
Feb 26, 2025
52 changes: 43 additions & 9 deletions build-tools/build-indexes
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
} else if (isDoubles) {
BattleTeambuilderTable[gen + 'doubles'] = {};
BattleTeambuilderTable[gen + 'doubles'].tiers = tiers;
BattleTeambuilderTable[gen + 'doubles'].items = items;
BattleTeambuilderTable[gen + 'doubles'].overrideTier = overrideTier;
BattleTeambuilderTable[gen + 'doubles'].formatSlices = formatSlices;
} else if (isGen9BH) {
Expand Down Expand Up @@ -685,40 +686,73 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
if (banlist.isBanned('item:' + item.id)) continue;
}
switch (id) {
case 'leftovers':
case 'lifeorb':
// mainstays
case 'choiceband':
case 'choicescarf':
case 'choicespecs':
case 'eviolite':
greatItems.push(id);
break;
// great everywhere but metronome
case 'leftovers':
case 'lifeorb':
case 'choicescarf':
case 'assaultvest':
case 'focussash':
case 'powerherb':
case 'rockyhelmet':
if (!isMetBattle) greatItems.push(id);
else goodItems.push(id);
break;
// just singles
case 'airballoon':
case 'loadeddice':
case 'heavydutyboots':
case 'expertbelt':
case 'salacberry':
greatItems.push(id);
if (isDoubles || isMetBattle) goodItems.push(id);
else greatItems.push(id);
break;
// just doubles
case 'safetygoggles':
case 'ejectbutton':
case 'ejectpack':
if (isDoubles) greatItems.push(id);
else goodItems.push(id);
break;
// doubles + metronome
case 'covertcloak':
case 'clearamulet':
case 'weaknesspolicy':
if (isDoubles || isMetBattle) greatItems.push(id);
else goodItems.push(id);
break;
// metronome only
case 'mirrorherb':
if (isMetBattle) greatItems.push(id);
else goodItems.push(id);
break;
// generation specific
case 'mentalherb':
if (genNum > 4) greatItems.push(id);
if (isMetBattle) goodItems.push(id);
else if (genNum > 4) greatItems.push(id);
else poorItems.push(id);
break;
case 'lumberry':
if (genNum === 2 || genNum > 6) goodItems.push(id);
else greatItems.push(id);
break;
case 'sitrusberry':
if (genNum > 6) goodItems.push(id);
else if (genNum > 3 && genNum < 7) greatItems.push(id);
if (genNum > 3 && (genNum < 7 || isDoubles)) greatItems.push(id);
else if (genNum > 6) goodItems.push(id);
else poorItems.push(id);
break;
case 'aguavberry':
case 'figyberry':
case 'iapapaberry':
case 'magoberry':
case 'wikiberry':
if (genNum >= 7) greatItems.push(id);
if (genNum === 7) greatItems.push(id);
else if (genNum >= 8) goodItems.push(id);
else poorItems.push(id);
break;
case 'berryjuice':
Expand All @@ -744,8 +778,8 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
case 'blueorb':
case 'redorb':
case 'souldew':
// falls through
// Other
// fallsthrough
case 'stick':
case 'thickclub':
case 'lightball':
Expand Down
2 changes: 2 additions & 0 deletions play.pokemonshowdown.com/src/battle-dex-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,7 @@ export class Species implements Effect {
readonly evoMove: string;
readonly evoItem: string;
readonly evoCondition: string;
readonly nfe: boolean;
readonly requiredItems: readonly string[];
readonly tier: string;
readonly isTotem: boolean;
Expand Down Expand Up @@ -1550,6 +1551,7 @@ export class Species implements Effect {
this.evoMove = data.evoMove || '';
this.evoItem = data.evoItem || '';
this.evoCondition = data.evoCondition || '';
this.nfe = data.nfe || false;
this.requiredItems = data.requiredItems || (data.requiredItem ? [data.requiredItem] : []);
this.tier = data.tier || '';

Expand Down
52 changes: 34 additions & 18 deletions play.pokemonshowdown.com/src/battle-dex-search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,9 @@
results = [...this.baseResults];
illegalResults = null;
}
if (this.defaultFilter) {
results = this.defaultFilter(results);
}

if (sortCol) {
results = results.filter(([rowType]) => rowType === this.searchType);
Expand Down Expand Up @@ -888,6 +891,7 @@
abstract getDefaultResults(): SearchRow[];
abstract getBaseResults(): SearchRow[];
abstract filter(input: SearchRow, filters: string[][]): boolean;
defaultFilter?(input: SearchRow[]): SearchRow[];
abstract sort(input: SearchRow[], sortCol: string, reverseSort?: boolean): SearchRow[];
}

Expand Down Expand Up @@ -1278,7 +1282,9 @@
} else if (this.formatType === 'bw1') {
table = table['gen5bw1'];
} else if (this.formatType === 'natdex') {
table = table[`gen${this.dex.gen}natdex`];
table = table['gen' + this.dex.gen + 'natdex'];

Check failure on line 1285 in play.pokemonshowdown.com/src/battle-dex-search.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

Operands of '+' operations must be a number or string, allowing a string + `any`. Got `string` + `number`
} else if (this.formatType?.endsWith('doubles')) { // no natdex/bdsp doubles support
table = table['gen' + this.dex.gen + 'doubles'];

Check failure on line 1287 in play.pokemonshowdown.com/src/battle-dex-search.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

Operands of '+' operations must be a number or string, allowing a string + `any`. Got `string` + `number`
} else if (this.formatType === 'metronome') {
table = table[`gen${this.dex.gen}metronome`];
} else if (this.dex.gen < 9) {
Expand All @@ -1300,32 +1306,42 @@
const speciesName = this.dex.species.get(this.species).name;
const results = this.getDefaultResults();
const speciesSpecific: SearchRow[] = [];
const abilitySpecific: SearchRow[] = [];
const abilityItem = {
protosynthesis: 'boosterenergy',
quarkdrive: 'boosterenegy',
// poisonheal: 'toxicorb',
// toxicboost: 'toxicorb',
// flareboost: 'flameorb',
}[toID(this.set?.ability) as string];
for (const row of results) {
if (row[0] !== 'item') continue;
if (this.dex.items.get(row[1]).itemUser?.includes(speciesName)) {
speciesSpecific.push(row);
}
const item = this.dex.items.get(row[1]);
if (item.itemUser?.includes(speciesName)) speciesSpecific.push(row);
if (abilityItem === item.id) abilitySpecific.push(row);
}
if (speciesSpecific.length) {
return [
results.unshift(
['header', "Specific to " + speciesName],
...speciesSpecific,
...results,
];
...speciesSpecific
);
}
if (abilitySpecific.length) {
results.unshift(
['header', "Specific to " + this.set!.ability],

Check failure on line 1331 in play.pokemonshowdown.com/src/battle-dex-search.ts

View workflow job for this annotation

GitHub Actions / build (22.x)

Invalid operand for a '+' operation. Operands must each be a number or string, allowing a string + `any`. Got `string | undefined`
...abilitySpecific
);
}
return results;
}
filter(row: SearchRow, filters: string[][]) {
if (!filters) return true;
if (row[0] !== 'ability') return true;
const ability = this.dex.abilities.get(row[1]);
for (const [filterType, value] of filters) {
switch (filterType) {
case 'pokemon':
if (!Dex.hasAbility(this.dex.species.get(value), ability.name)) return false;
break;
}
override defaultFilter(results: SearchRow[]) {
if (this.species && !this.dex.species.get(this.species).nfe) {
results.splice(results.findIndex(row => row[1] === 'eviolite'), 1);
return results;
}
return results;
}
filter(row: SearchRow, filters: string[][]) {
return true;
}
sort(results: SearchRow[], sortCol: string | null, reverseSort?: boolean): SearchRow[] {
Expand Down
12 changes: 12 additions & 0 deletions play.pokemonshowdown.com/src/battle-dex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,12 @@ export const Dex = new class implements ModdedDex {
if (!data.tier && data.baseSpecies && toID(data.baseSpecies) !== id) {
data.tier = this.species.get(data.baseSpecies).tier;
}
data.nfe = data.id === 'dipplin' || !!(data as Species).evos?.some(evo => {
const evoSpecies = this.species.get(evo);
return !evoSpecies.isNonstandard || evoSpecies.isNonstandard === data.isNonstandard ||
// Pokemon with Hisui evolutions
evoSpecies.isNonstandard === "Unobtainable";
});
species = new Species(id, name, data);
window.BattlePokedex[id] = species;
}
Expand Down Expand Up @@ -1064,6 +1070,12 @@ export class ModdedDex {
data.tier = this.species.get(data.baseSpecies).tier;
}
if (data.gen > this.gen) data.tier = 'Illegal';
data.nfe = data.id === 'dipplin' || !!data.evos?.some(evo => {
const evoSpecies = this.species.get(evo);
return !evoSpecies.isNonstandard || evoSpecies.isNonstandard === data.isNonstandard ||
// Pokemon with Hisui evolutions
evoSpecies.isNonstandard === "Unobtainable";
});

const species = new Species(id, name, data);
this.cache.Species[id] = species;
Expand Down
9 changes: 1 addition & 8 deletions play.pokemonshowdown.com/src/battle-tooltips.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1192,14 +1192,7 @@ export class BattleTooltips {
speedModifiers.push(1.5);
}
}
const isNFE = this.battle.dex.species.get(serverPokemon.speciesForme).evos?.some(evo => {
const evoSpecies = this.battle.dex.species.get(evo);
return !evoSpecies.isNonstandard ||
evoSpecies.isNonstandard === this.battle.dex.species.get(serverPokemon.speciesForme)?.isNonstandard ||
// Pokemon with Hisui evolutions
evoSpecies.isNonstandard === "Unobtainable";
});
if (item === 'eviolite' && (isNFE || this.battle.dex.species.get(serverPokemon.speciesForme).id === 'dipplin')) {
if (item === 'eviolite' && this.battle.dex.species.get(serverPokemon.speciesForme).nfe) {
stats.def = Math.floor(stats.def * 1.5);
stats.spd = Math.floor(stats.spd * 1.5);
}
Expand Down
Loading