Fix teambuilder support for OMs (#2598)
Some checks failed
Node.js CI / build (22.x) (push) Has been cancelled

* battle-dex-search.ts: Fix natdex OMs pulling from SV OMs

* Fix Teambuilder Support For OMs

* National Dex OMs merging the rulesets for their SV counterparts

* Bans via required abilities and items never being checked

* Bans via required abilities not being implemented properly
* mega rayquaza clause being wastefully checked over and over again

* Tables in natdex now omit the 'natdex' part of the format to be consistent with battle-dex-search.ts

* Synced meta tables in build-indexes and battle-dex-search.ts

* Apply suggestions from code review

---------

Co-authored-by: Kris Johnson <11083252+KrisXV@users.noreply.github.com>
This commit is contained in:
Zachary Perlmutter 2026-01-19 00:27:52 -08:00 committed by GitHub
parent d72c511186
commit 4428a1444c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 35 deletions

View File

@ -433,36 +433,41 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
if (genNum >= 6) {
for (const meta of [
'1v1', '2v2doubles', 'lcuu', 'freeforall', 'ubersuu', 'almostanyability', 'balancedhackmons', 'godlygift', 'mixandmega', 'sharedpower', 'stabmons',
'12switch', '350cup', 'alphabetcup', 'badnboosted', 'battlefields', 'biomechmons', 'camomons', 'categoryswap',
'convergence', 'crossevolution', 'ferventimpersonation', 'foresighters', 'formemons', 'fortemons', 'franticfusions',
'12switch', '350cup', 'alphabetcup', 'badnboosted', 'battlefields', 'biomechmons', 'camomons', 'categoryswap', 'categoryswap',
'convergence', 'crossevolution', 'categoryswap', 'ferventimpersonation', 'foresighters', 'formemons', 'fortemons', 'franticfusions',
'fullpotential', 'inheritance', 'inverse', 'natureswap', 'partnersincrime', 'passiveaggressive', 'pokebilities',
'pokemoves', 'relayrace', 'revelationmons', 'sharingiscaring', 'teradonation', 'teraoverride', 'thecardgame',
'thelosersgame', 'trademarked', 'triples', 'typesplit', 'voltturnmayhem', 'nationaldexubersuu', 'nationaldex1v1',
'nationaldexaaa', 'nationaldexbh', 'nationaldexgodlygift', 'nationaldexstabmons', 'tiershift',
'thelosersgame', 'trademarked', 'triples', 'typesplit', 'voltturnmayhem',
'aaa', 'bh', // natdex abbreviations
'tiershift',
]) {
const format = Dex.formats.get(gen + meta);
if (format.exists && Dex.formats.getRuleTable(format).isBannedSpecies(species)) {
if (!metagameBans[meta]) metagameBans[meta] = {};
if (Dex.formats.getRuleTable(format).has('megarayquazaclause')) {
metagameBans[meta]['megarayquazaclause'] = 1;
}
if (species.requiredItems && species.requiredItems.length) {
for (const itemName of species.requiredItems) {
const format = Dex.formats.get(`${gen}${isNatDex ? 'nationaldex' : ''}${meta}`);
if (!format.exists) continue;
const ruleTable = Dex.formats.getRuleTable(format);
let banned = ruleTable.isBannedSpecies(species);
if (!banned) {
const requiredItems = species.requiredItems;
if (requiredItems && requiredItems.length) {
for (const itemName of requiredItems) {
const item = Dex.items.get(itemName);
if (item.itemUser && item.itemUser.includes(species.name) &&
Dex.formats.getRuleTable(format).isBanned('item:' + item.id)) {
metagameBans[meta][species.id] = 1;
}
if (item.megaStone && Object.values(item.megaStone).includes(species.name) &&
Dex.formats.getRuleTable(format).isBanned('item:' + item.id)) {
metagameBans[meta][species.id] = 1;
if (((item.itemUser && item.itemUser.includes(species.name)) ||
(item.megaStone && Object.values(item.megaStone).includes(species.name))
) && ruleTable.isBanned('item:' + item.id)) {
banned = true;
break;
}
}
}
if (species.requiredAbility) {
const ability = Dex.items.get(species.requiredAbility);
if (Dex.formats.getRuleTable(format).isBanned('ability:' + ability.id)) {
metagameBans[meta][species.id] = 1;
}
if (!banned && species.requiredAbility) {
const ability = Dex.abilities.get(species.requiredAbility);
banned = ruleTable.isBanned('ability:' + ability.id);
}
if (banned) {
if (!metagameBans[meta]) {
metagameBans[meta] = {};
if (ruleTable.has('megarayquazaclause')) {
metagameBans[meta]['megarayquazaclause'] = 1;
}
}
metagameBans[meta][species.id] = 1;

View File

@ -1155,22 +1155,19 @@ class BattlePokemonSearch extends BattleTypedSearch<'pokemon'> {
];
}
const customBanlists = [
'1v1', '2v2doubles', 'lcuu', 'freeforall', 'ubersuu', 'almostanyability', 'balancedhackmons', 'godlygift', 'mixandmega',
'sharedpower', 'stabmons', '12switch', '350cup', 'alphabetcup', 'badnboosted', 'battlefields', 'biomechmons', 'camomons',
'categoryswap', 'convergence', 'crossevolution', 'fervetimpersonation', 'foresighters', 'formemons', 'fortemons',
'franticfusions', 'fullpotential', 'inheritance', 'inverse', 'natureswap', 'partnersincrime', 'passiveaggressive',
'pokebilities', 'pokemoves', 'relayrace', 'revelationmons', 'sharingiscaring', 'teradonation', 'teraoverride', 'thecardgame',
'thelosersgame', 'trademarked', 'triples', 'typesplit', 'voltturnmayhem', 'nationaldexubersuu', 'nationaldex1v1',
'nationaldexaaa', 'nationaldexbh', 'nationaldexgodlygift', 'nationaldexstabmons', 'tiershift',
'1v1', '2v2doubles', 'lcuu', 'freeforall', 'ubersuu', 'almostanyability', 'balancedhackmons', 'godlygift', 'mixandmega', 'sharedpower', 'stabmons',
'12switch', '350cup', 'alphabetcup', 'badnboosted', 'battlefields', 'biomechmons', 'camomons', 'categoryswap', 'categoryswap',
'convergence', 'crossevolution', 'categoryswap', 'ferventimpersonation', 'foresighters', 'formemons', 'fortemons', 'franticfusions',
'fullpotential', 'inheritance', 'inverse', 'natureswap', 'partnersincrime', 'passiveaggressive', 'pokebilities',
'pokemoves', 'relayrace', 'revelationmons', 'sharingiscaring', 'teradonation', 'teraoverride', 'thecardgame',
'thelosersgame', 'trademarked', 'triples', 'typesplit', 'voltturnmayhem',
'aaa', 'bh', // natdex abbreviations
'tiershift',
];
if (dex.gen >= 6) {
if (
(customBanlists.includes(format) && table.metagameBans?.[format]) ||
(this.formatType === 'natdex' && customBanlists.includes('nationaldex' + format) &&
table.metagameBans?.['nationaldex' + format])) {
if (customBanlists.includes(format) && table.metagameBans?.[format]) {
tierSet = tierSet.filter(([type, id]) => {
if (id in table.metagameBans[format]) return false;
if (this.formatType === 'natdex' && id in table.metagameBans['nationaldex' + format]) return false;
if (!this.formatType && dex.gen === 9 &&
'miraidon' in table.metagameBans[format] &&
'calyrexshadow' in table.metagameBans[format] &&