mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-03-21 17:25:10 -05:00
Implement Mega Stones as {key: value} pairs (#11684)
* Implement Mega Stones as pairs {key: value}
* Fix Mega Evolution check
* Add constructor guards to Dex getters
* Update config/formats.ts
---------
Co-authored-by: Kris Johnson <11083252+KrisXV@users.noreply.github.com>
This commit is contained in:
parent
ee77cf98ae
commit
684150d9d7
|
|
@ -2899,7 +2899,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
onValidateSet(set, format, setHas, teamHas) {
|
||||
if (set.item) {
|
||||
const item = this.dex.items.get(set.item);
|
||||
if (item.megaEvolves && !(this.ruleTable.has(`+item:${item.id}`) || this.ruleTable.has(`+pokemontag:mega`))) {
|
||||
if (item.megaStone && !(this.ruleTable.has(`+item:${item.id}`) || this.ruleTable.has(`+pokemontag:mega`))) {
|
||||
return [`Mega Evolution is banned.`];
|
||||
}
|
||||
if (item.zMove && !(this.ruleTable.has(`+item:${item.id}`))) {
|
||||
|
|
@ -3678,8 +3678,8 @@ export const Formats: import('../sim/dex-formats').FormatList = [
|
|||
}
|
||||
const item = this.dex.items.get(set.item);
|
||||
if (set.item && item.megaStone) {
|
||||
const megaSpecies = this.dex.species.get(Array.isArray(item.megaStone) ? item.megaStone[0] : item.megaStone);
|
||||
if (item.megaEvolves?.includes(species.baseSpecies) && megaSpecies.bst > 625) {
|
||||
const megaSpecies = this.dex.species.get(item.megaStone[species.baseSpecies]);
|
||||
if (megaSpecies.bst > 625) {
|
||||
return [
|
||||
`${set.name || set.species}'s item ${item.name} is banned.`, `(Pok\u00e9mon with a BST higher than 625 are banned)`,
|
||||
];
|
||||
|
|
|
|||
574
data/items.ts
574
data/items.ts
File diff suppressed because it is too large
Load Diff
|
|
@ -13,12 +13,10 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
masquerainite: {
|
||||
name: "Masquerainite",
|
||||
spritenum: 1,
|
||||
megaStone: "Masquerain-Mega",
|
||||
megaEvolves: "Masquerain",
|
||||
megaStone: { "Masquerain": "Masquerain-Mega" },
|
||||
itemUser: ["Masquerain"],
|
||||
onTakeItem(item, source) {
|
||||
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
|
||||
return true;
|
||||
return !item.megaStone?.[source.baseSpecies.baseSpecies];
|
||||
},
|
||||
num: -1,
|
||||
gen: 9,
|
||||
|
|
@ -59,12 +57,10 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
typhlosionite: {
|
||||
name: "Typhlosionite",
|
||||
spritenum: 1,
|
||||
megaStone: "Typhlosion-Mega",
|
||||
megaEvolves: "Typhlosion",
|
||||
megaStone: { "Typhlosion": "Typhlosion-Mega" },
|
||||
itemUser: ["Typhlosion"],
|
||||
onTakeItem(item, source) {
|
||||
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
|
||||
return true;
|
||||
return !item.megaStone?.[source.baseSpecies.baseSpecies];
|
||||
},
|
||||
num: -2,
|
||||
gen: 9,
|
||||
|
|
|
|||
|
|
@ -92,10 +92,10 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
|
|||
if (["Zacian", "Zamazenta"].includes(species.baseSpecies) && this.toID(set.item).startsWith('rusted')) {
|
||||
species = this.dex.species.get(set.species + "-Crowned");
|
||||
}
|
||||
if (set.item && this.dex.items.get(set.item).megaStone) {
|
||||
if (set.item) {
|
||||
const item = this.dex.items.get(set.item);
|
||||
if (item.megaEvolves === species.baseSpecies) {
|
||||
species = this.dex.species.get(Array.isArray(item.megaStone) ? item.megaStone[0] : item.megaStone);
|
||||
if (item.megaStone?.[species.baseSpecies]) {
|
||||
species = this.dex.species.get(item.megaStone[species.baseSpecies]);
|
||||
}
|
||||
}
|
||||
if (
|
||||
|
|
@ -123,8 +123,8 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
|
|||
}
|
||||
if (set.item) {
|
||||
const item = this.dex.items.get(set.item);
|
||||
if (item.megaEvolves === set.species) {
|
||||
godSpecies = this.dex.species.get(Array.isArray(item.megaStone) ? item.megaStone[0] : item.megaStone);
|
||||
if (item.megaStone?.[set.species]) {
|
||||
godSpecies = this.dex.species.get(item.megaStone[set.species]);
|
||||
}
|
||||
if (["Zacian", "Zamazenta"].includes(godSpecies.baseSpecies) && item.id.startsWith('rusted')) {
|
||||
godSpecies = this.dex.species.get(set.species + "-Crowned");
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
slowbronite: {
|
||||
inherit: true,
|
||||
onTakeItem(item, source) {
|
||||
if (item.megaEvolves === source.baseSpecies.name || item.megaStone === source.baseSpecies.name) return false;
|
||||
return true;
|
||||
return !item.megaStone || (!item.megaStone[source.baseSpecies.name] &&
|
||||
!Object.values(item.megaStone).includes(source.baseSpecies.name));
|
||||
},
|
||||
},
|
||||
greninjite: {
|
||||
inherit: true,
|
||||
onTakeItem(item, source) {
|
||||
if (item.megaEvolves === source.baseSpecies.name || item.megaStone === source.baseSpecies.name) return false;
|
||||
return true;
|
||||
return !item.megaStone || (!item.megaStone[source.baseSpecies.name] &&
|
||||
!Object.values(item.megaStone).includes(source.baseSpecies.name));
|
||||
},
|
||||
},
|
||||
zygardite: {
|
||||
|
|
|
|||
|
|
@ -57,23 +57,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
pokemon.baseMoves.includes(this.battle.toID(altForme.requiredMove)) && !item.zMove) {
|
||||
return altForme.name;
|
||||
}
|
||||
if (Array.isArray(item.megaEvolves)) {
|
||||
if (!Array.isArray(item.megaStone)) {
|
||||
throw new Error(`${item.name}#megaEvolves and ${item.name}#megaStone type mismatch`);
|
||||
}
|
||||
if (item.megaEvolves.length !== item.megaStone.length) {
|
||||
throw new Error(`${item.name}#megaEvolves and ${item.name}#megaStone length mismatch`);
|
||||
}
|
||||
const index = item.megaEvolves.indexOf(species.name);
|
||||
if (index < 0) return null;
|
||||
return item.megaStone[index];
|
||||
} else {
|
||||
if (item.megaEvolves === species.name) {
|
||||
if (Array.isArray(item.megaStone)) throw new Error(`${item.name}#megaEvolves and ${item.name}#megaStone type mismatch`);
|
||||
return item.megaStone;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
if (!item.megaStone) return null;
|
||||
return item.megaStone[species.name];
|
||||
},
|
||||
runMegaEvo(pokemon) {
|
||||
const speciesid = pokemon.canMegaEvo || pokemon.canUltraBurst;
|
||||
|
|
|
|||
|
|
@ -14,11 +14,9 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
name: "Flygonite",
|
||||
spritenum: 111,
|
||||
itemUser: ["Flygon"],
|
||||
megaEvolves: "Flygon",
|
||||
megaStone: "Trapinch",
|
||||
megaStone: { "Trapinch": "Flygon" },
|
||||
onTakeItem(item, source) {
|
||||
if (item.megaEvolves === source.baseSpecies.baseSpecies) return false;
|
||||
return true;
|
||||
return !item.megaStone?.[source.baseSpecies.baseSpecies];
|
||||
},
|
||||
desc: "If held by a Flygon, this item allows it to Mega Evolve in battle.",
|
||||
},
|
||||
|
|
@ -36,7 +34,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
gardevoirite: {
|
||||
inherit: true,
|
||||
itemUser: ["Ralts"],
|
||||
megaEvolves: "Ralts",
|
||||
megaStone: { "Ralts": "Gardevoir-Mega" },
|
||||
desc: "If held by a Ralts, this item allows it to Mega Evolve in battle.",
|
||||
},
|
||||
// Peary
|
||||
|
|
|
|||
|
|
@ -963,26 +963,11 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
pokemon.baseMoves.includes(this.battle.toID(altForme.requiredMove)) && !item.zMove) {
|
||||
return altForme.name;
|
||||
}
|
||||
if (!item.megaStone) return null;
|
||||
// a hacked-in Megazard X can mega evolve into Megazard Y, but not into Megazard X
|
||||
if (Array.isArray(item.megaEvolves)) {
|
||||
if (!Array.isArray(item.megaStone)) {
|
||||
throw new Error(`${item.name}#megaEvolves and ${item.name}#megaStone type mismatch`);
|
||||
}
|
||||
if (item.megaEvolves.length !== item.megaStone.length) {
|
||||
throw new Error(`${item.name}#megaEvolves and ${item.name}#megaStone length mismatch`);
|
||||
}
|
||||
// FIXME: Change to species.name when champions comes
|
||||
const index = item.megaEvolves.indexOf(species.baseSpecies);
|
||||
if (index < 0) return null;
|
||||
return item.megaStone[index];
|
||||
// FIXME: Change to species.name when champions comes
|
||||
} else {
|
||||
if (item.megaEvolves === species.baseSpecies) {
|
||||
if (Array.isArray(item.megaStone)) throw new Error(`${item.name}#megaEvolves and ${item.name}#megaStone type mismatch`);
|
||||
return item.megaStone;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
// FIXME: Change to species.name when champions comes
|
||||
const megaEvolution = item.megaStone[species.baseSpecies];
|
||||
return megaEvolution && megaEvolution !== species.name ? megaEvolution : null;
|
||||
},
|
||||
|
||||
// 1 Z per pokemon
|
||||
|
|
|
|||
|
|
@ -385,12 +385,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
if (pokemon.species.isMega) return null;
|
||||
|
||||
const item = pokemon.getItem();
|
||||
if (item.megaStone) {
|
||||
if (item.megaStone.includes(pokemon.baseSpecies.name)) return null;
|
||||
return Array.isArray(item.megaStone) ? item.megaStone[0] : item.megaStone;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
if (!item.megaStone || item.megaStone[pokemon.baseSpecies.name]) return null;
|
||||
return Object.values(item.megaStone)[0];
|
||||
},
|
||||
runMegaEvo(pokemon) {
|
||||
if (pokemon.species.isMega) return false;
|
||||
|
|
|
|||
|
|
@ -1607,8 +1607,7 @@ export class RandomGen7Teams extends RandomGen8Teams {
|
|||
if (isMonotype) {
|
||||
// Prevents Mega Evolutions from breaking the type limits
|
||||
if (itemData.megaStone) {
|
||||
const megaSpecies = this.dex.species.get(Array.isArray(itemData.megaStone) ?
|
||||
itemData.megaStone[0] : itemData.megaStone);
|
||||
const megaSpecies = this.dex.species.get(Object.values(itemData.megaStone)[0]);
|
||||
if (types.length > megaSpecies.types.length) types = [species.types[0]];
|
||||
// Only check the second type because a Mega Evolution should always share the first type with its base forme.
|
||||
if (megaSpecies.types[1] && types[1] && megaSpecies.types[1] !== types[1]) {
|
||||
|
|
|
|||
|
|
@ -1507,17 +1507,9 @@ export const Rulesets: import('../sim/dex-formats').FormatDataTable = {
|
|||
typeTable = typeTable.filter(type => species.types.includes(type));
|
||||
}
|
||||
const item = this.dex.items.get(set.item);
|
||||
if (item.megaStone) {
|
||||
if (Array.isArray(item.megaStone)) {
|
||||
const index = (item.megaEvolves as string[]).indexOf(species.name);
|
||||
if (index >= 0) {
|
||||
species = this.dex.species.get(item.megaStone[index]);
|
||||
typeTable = typeTable.filter(type => species.types.includes(type));
|
||||
}
|
||||
} else {
|
||||
species = this.dex.species.get(item.megaStone);
|
||||
typeTable = typeTable.filter(type => species.types.includes(type));
|
||||
}
|
||||
if (item.megaStone?.[species.name]) {
|
||||
species = this.dex.species.get(item.megaStone[species.name]);
|
||||
typeTable = typeTable.filter(type => species.types.includes(type));
|
||||
}
|
||||
if (item.id === "ultranecroziumz" && species.baseSpecies === "Necrozma") {
|
||||
species = this.dex.species.get("Necrozma-Ultra");
|
||||
|
|
@ -1556,17 +1548,9 @@ export const Rulesets: import('../sim/dex-formats').FormatDataTable = {
|
|||
}
|
||||
color = species.color;
|
||||
const item = this.dex.items.get(set.item);
|
||||
if (item.megaStone) {
|
||||
if (Array.isArray(item.megaStone)) {
|
||||
const index = (item.megaEvolves as string[]).indexOf(species.name);
|
||||
if (index >= 0) {
|
||||
species = this.dex.species.get(item.megaStone[index]);
|
||||
color = species.color;
|
||||
}
|
||||
} else {
|
||||
species = this.dex.species.get(item.megaStone);
|
||||
color = species.color;
|
||||
}
|
||||
if (item.megaStone?.[species.name]) {
|
||||
species = this.dex.species.get(item.megaStone[species.name]);
|
||||
color = species.color;
|
||||
}
|
||||
if (item.id === "ultranecroziumz" && species.baseSpecies === "Necrozma") {
|
||||
species = this.dex.species.get("Necrozma-Ultra");
|
||||
|
|
@ -2666,12 +2650,10 @@ export const Rulesets: import('../sim/dex-formats').FormatDataTable = {
|
|||
) {
|
||||
species = this.dex.species.get(`${species.baseSpecies}-Crowned`);
|
||||
}
|
||||
if (set.item && this.dex.items.get(set.item).megaStone) {
|
||||
if (set.item) {
|
||||
const item = this.dex.items.get(set.item);
|
||||
if (item.megaEvolves?.includes(species.name)) {
|
||||
species = this.dex.species.get(Array.isArray(item.megaEvolves) ?
|
||||
(item.megaStone as string[])[item.megaEvolves.indexOf(species.name)] :
|
||||
item.megaStone as string);
|
||||
if (item.megaStone?.[species.name]) {
|
||||
species = this.dex.species.get(item.megaStone[species.name]);
|
||||
}
|
||||
}
|
||||
if (this.ruleTable.isRestrictedSpecies(species) ||
|
||||
|
|
@ -2693,10 +2675,8 @@ export const Rulesets: import('../sim/dex-formats').FormatDataTable = {
|
|||
}
|
||||
if (set.item) {
|
||||
const item = this.dex.items.get(set.item);
|
||||
if (item.megaEvolves?.includes(set.species)) {
|
||||
godSpecies = this.dex.species.get(Array.isArray(item.megaEvolves) ?
|
||||
(item.megaStone as string[])[item.megaEvolves.indexOf(set.species)] :
|
||||
item.megaStone as string);
|
||||
if (item.megaStone?.[set.species]) {
|
||||
godSpecies = this.dex.species.get(item.megaStone[set.species]);
|
||||
}
|
||||
if (["Zacian", "Zamazenta"].includes(godSpecies.baseSpecies) && item.id.startsWith('rusted')) {
|
||||
godSpecies = this.dex.species.get(set.species + "-Crowned");
|
||||
|
|
|
|||
|
|
@ -29,14 +29,23 @@ function getMegaStone(stone: string, mod = 'gen9'): Item | null {
|
|||
id: move.id,
|
||||
name: move.name,
|
||||
fullname: move.name,
|
||||
megaEvolves: 'Rayquaza',
|
||||
megaStone: 'Rayquaza-Mega',
|
||||
megaStone: { 'Rayquaza': 'Rayquaza-Mega' },
|
||||
exists: true,
|
||||
// Adding extra values to appease typescript
|
||||
gen: 6,
|
||||
num: -1,
|
||||
effectType: 'Item',
|
||||
sourceEffect: '',
|
||||
isBerry: false,
|
||||
ignoreKlutz: false,
|
||||
isGem: false,
|
||||
isPokeball: false,
|
||||
isPrimalOrb: false,
|
||||
shortDesc: "",
|
||||
desc: "",
|
||||
isNonstandard: null,
|
||||
noCopy: false,
|
||||
affectsFainted: false,
|
||||
} as Item;
|
||||
} else {
|
||||
return null;
|
||||
|
|
@ -131,8 +140,8 @@ export const commands: Chat.ChatCommands = {
|
|||
megaSpecies = dex.species.get(forcedForme);
|
||||
baseSpecies = dex.species.get(forcedForme.split('-')[0]);
|
||||
} else {
|
||||
megaSpecies = dex.species.get(Array.isArray(stone.megaStone) ? stone.megaStone[0] : stone.megaStone);
|
||||
baseSpecies = dex.species.get(Array.isArray(stone.megaEvolves) ? stone.megaEvolves[0] : stone.megaEvolves);
|
||||
megaSpecies = dex.species.get(Object.values(stone.megaStone!)[0]);
|
||||
baseSpecies = dex.species.get(Object.keys(stone.megaStone!)[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -282,8 +291,8 @@ export const commands: Chat.ChatCommands = {
|
|||
megaSpecies = dex.species.get(forcedForme);
|
||||
baseSpecies = dex.species.get(forcedForme.split('-')[0]);
|
||||
} else {
|
||||
megaSpecies = dex.species.get(Array.isArray(aStone.megaStone) ? aStone.megaStone[0] : aStone.megaStone);
|
||||
baseSpecies = dex.species.get(Array.isArray(aStone.megaEvolves) ? aStone.megaEvolves[0] : aStone.megaEvolves);
|
||||
megaSpecies = dex.species.get(Object.values(aStone.megaStone!)[0]);
|
||||
baseSpecies = dex.species.get(Object.keys(aStone.megaStone!)[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ class SSBSetsHTML extends Chat.JSX.Component<{ target: string }> {
|
|||
<SSBInnateHTML name={setName} dex={dex} baseDex={baseDex} />
|
||||
<SSBPokemonHTML species={set.species} dex={dex} baseDex={baseDex} />
|
||||
{(!Array.isArray(set.item) && item.megaStone) && <SSBPokemonHTML
|
||||
species={Array.isArray(item.megaStone) ? item.megaStone[0] : item.megaStone} dex={dex} baseDex={baseDex}
|
||||
species={Object.values(item.megaStone)[0]} dex={dex} baseDex={baseDex}
|
||||
/>}
|
||||
{/* keys and Kennedy have an itemless forme change */}
|
||||
{['Rayquaza'].includes(set.species) && <SSBPokemonHTML species={`${set.species}-Mega`} dex={dex} baseDex={baseDex} />}
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ export function getSpeciesName(set: PokemonSet, format: Format) {
|
|||
} else if (species === "Groudon" && item.name === "Red Orb") {
|
||||
return "Groudon-Primal";
|
||||
} else if (item.megaStone) {
|
||||
return Array.isArray(item.megaStone) ? item.megaStone[0] : item.megaStone;
|
||||
return Object.values(item.megaStone)[0];
|
||||
} else if (species === "Rayquaza" && moves.includes('Dragon Ascent') && !item.zMove && megaRayquazaPossible) {
|
||||
return "Rayquaza-Mega";
|
||||
} else if (species === "Poltchageist-Artisan") { // Babymons from here on out
|
||||
|
|
|
|||
|
|
@ -1871,21 +1871,15 @@ export class BattleActions {
|
|||
pokemon.baseMoves.includes(toID(altForme.requiredMove)) && !item.zMove) {
|
||||
return altForme.name;
|
||||
}
|
||||
if (!item.megaStone) return null;
|
||||
// Temporary hardcode until generation shift
|
||||
if ((species.baseSpecies === "Floette" || species.baseSpecies === "Zygarde") && item.megaEvolves === species.name) {
|
||||
return item.megaStone as string;
|
||||
if ((species.baseSpecies === "Floette" || species.baseSpecies === "Zygarde") && item.megaStone[species.name]) {
|
||||
return item.megaStone[species.name];
|
||||
}
|
||||
// a hacked-in Megazard X can mega evolve into Megazard Y, but not into Megazard X
|
||||
if (Array.isArray(item.megaStone)) {
|
||||
// FIXME: Change to species.name when champions comes
|
||||
const index = (item.megaEvolves as string[]).indexOf(species.baseSpecies);
|
||||
if (index < 0) return null;
|
||||
return item.megaStone[index];
|
||||
// FIXME: Change to species.name when champions comes
|
||||
} else if (item.megaEvolves === species.baseSpecies && item.megaStone !== species.name) {
|
||||
return item.megaStone;
|
||||
}
|
||||
return null;
|
||||
// FIXME: Change to species.name when champions comes
|
||||
const megaEvolution = item.megaStone[species.baseSpecies];
|
||||
return megaEvolution && megaEvolution !== species.name ? megaEvolution : null;
|
||||
}
|
||||
|
||||
canUltraBurst(pokemon: Pokemon) {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ export class DexAbilities {
|
|||
}
|
||||
|
||||
getByID(id: ID): Ability {
|
||||
if (id === '') return EMPTY_ABILITY;
|
||||
if (id === '' || id === 'constructor') return EMPTY_ABILITY;
|
||||
let ability = this.abilityCache.get(id);
|
||||
if (ability) return ability;
|
||||
|
||||
|
|
|
|||
|
|
@ -665,7 +665,7 @@ export class DexConditions {
|
|||
}
|
||||
|
||||
getByID(id: ID): Condition {
|
||||
if (id === '') return EMPTY_CONDITION;
|
||||
if (id === '' || id === 'constructor') return EMPTY_CONDITION;
|
||||
|
||||
let condition = this.conditionCache.get(id);
|
||||
if (condition) return condition;
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ export class DexNatures {
|
|||
return this.getByID(toID(name));
|
||||
}
|
||||
getByID(id: ID): Nature {
|
||||
if (id === '') return EMPTY_NATURE;
|
||||
if (id === '' || id === 'constructor') return EMPTY_NATURE;
|
||||
let nature = this.natureCache.get(id);
|
||||
if (nature) return nature;
|
||||
|
||||
|
|
@ -293,7 +293,7 @@ export class DexTypes {
|
|||
}
|
||||
|
||||
getByID(id: ID): TypeInfo {
|
||||
if (id === '') return EMPTY_TYPE_INFO;
|
||||
if (id === '' || id === 'constructor') return EMPTY_TYPE_INFO;
|
||||
let type = this.typeCache.get(id);
|
||||
if (type) return type;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,17 +43,11 @@ export class Item extends BasicEffect implements Readonly<BasicEffect> {
|
|||
*/
|
||||
readonly onMemory?: string;
|
||||
/**
|
||||
* If this is a mega stone: The name (e.g. Charizard-Mega-X) of the
|
||||
* forme this allows transformation into.
|
||||
* If this is a mega stone: A pair (e.g. Charizard: Charizard-Mega-X) of the
|
||||
* forme this allows transformation from and into.
|
||||
* undefined, if not a mega stone.
|
||||
*/
|
||||
readonly megaStone?: string | string[];
|
||||
/**
|
||||
* If this is a mega stone: The name (e.g. Charizard) of the
|
||||
* forme this allows transformation from.
|
||||
* undefined, if not a mega stone.
|
||||
*/
|
||||
readonly megaEvolves?: string | string[];
|
||||
readonly megaStone?: { [megaEvolves: string]: string };
|
||||
/**
|
||||
* If this is a Z crystal: true if the Z Crystal is generic
|
||||
* (e.g. Firium Z). If species-specific, the name
|
||||
|
|
@ -116,7 +110,6 @@ export class Item extends BasicEffect implements Readonly<BasicEffect> {
|
|||
this.onDrive = data.onDrive || undefined;
|
||||
this.onMemory = data.onMemory || undefined;
|
||||
this.megaStone = data.megaStone || undefined;
|
||||
this.megaEvolves = data.megaEvolves || undefined;
|
||||
this.zMove = data.zMove || undefined;
|
||||
this.zMoveType = data.zMoveType || undefined;
|
||||
this.zMoveFrom = data.zMoveFrom || undefined;
|
||||
|
|
@ -176,7 +169,7 @@ export class DexItems {
|
|||
}
|
||||
|
||||
getByID(id: ID): Item {
|
||||
if (id === '') return EMPTY_ITEM;
|
||||
if (id === '' || id === 'constructor') return EMPTY_ITEM;
|
||||
let item = this.itemCache.get(id);
|
||||
if (item) return item;
|
||||
if (this.dex.getAlias(id)) {
|
||||
|
|
|
|||
|
|
@ -621,7 +621,7 @@ export class DexMoves {
|
|||
}
|
||||
|
||||
getByID(id: ID): Move {
|
||||
if (id === '') return EMPTY_MOVE;
|
||||
if (id === '' || id === 'constructor') return EMPTY_MOVE;
|
||||
let move = this.moveCache.get(id);
|
||||
if (move) return move;
|
||||
if (this.dex.getAlias(id)) {
|
||||
|
|
|
|||
|
|
@ -436,7 +436,7 @@ export class DexSpecies {
|
|||
}
|
||||
|
||||
getByID(id: ID): Species {
|
||||
if (id === '') return EMPTY_SPECIES;
|
||||
if (id === '' || id === 'constructor') return EMPTY_SPECIES;
|
||||
let species: Mutable<Species> | undefined = this.speciesCache.get(id);
|
||||
if (species) return species;
|
||||
|
||||
|
|
|
|||
|
|
@ -526,14 +526,8 @@ export class TeamValidator {
|
|||
|
||||
if (ruleTable.has('obtainableformes')) {
|
||||
const canMegaEvo = dex.gen <= 7 || ruleTable.has('+pokemontag:past');
|
||||
if (item.megaEvolves?.includes(species.name)) {
|
||||
if (!item.megaStone) throw new Error(`Item ${item.name} has no base form for mega evolution`);
|
||||
if (Array.isArray(item.megaEvolves)) {
|
||||
const idx = item.megaEvolves.indexOf(species.name);
|
||||
tierSpecies = dex.species.get(item.megaStone[idx]);
|
||||
} else {
|
||||
tierSpecies = dex.species.get(item.megaStone as string);
|
||||
}
|
||||
if (item.megaStone?.[species.name]) {
|
||||
tierSpecies = dex.species.get(item.megaStone[species.name]);
|
||||
} else if (item.id === 'redorb' && species.id === 'groudon') {
|
||||
tierSpecies = dex.species.get('Groudon-Primal');
|
||||
} else if (item.id === 'blueorb' && species.id === 'kyogre') {
|
||||
|
|
|
|||
|
|
@ -137,8 +137,8 @@ export class ExhaustiveRunner {
|
|||
const signatures = new Map();
|
||||
for (const id of pools.items.possible) {
|
||||
const item = dex.data.Items[id];
|
||||
if (item.megaEvolves) {
|
||||
const pokemon = toID(item.megaEvolves);
|
||||
if (item.megaStone) {
|
||||
const pokemon = toID(Object.keys(item.megaStone)[0]);
|
||||
const combo = { item: id };
|
||||
let combos = signatures.get(pokemon);
|
||||
if (!combos) {
|
||||
|
|
|
|||
|
|
@ -132,12 +132,6 @@ describe('Dex data', () => {
|
|||
const entry = Items[itemid];
|
||||
assert.equal(toID(entry.name), itemid, `Mismatched Item key "${itemid}" of "${entry.name}"`);
|
||||
assert.equal(typeof entry.num, 'number', `Item ${entry.name} should have a number`);
|
||||
if (entry.megaStone) {
|
||||
assert.equal(typeof entry.megaStone, typeof entry.megaEvolves, `Item ${entry.name} megaStone and megaEvolves should both be the same type`);
|
||||
if (Array.isArray(entry.megaStone)) {
|
||||
assert.equal(entry.megaStone.length, entry.megaEvolves.length, `Item ${entry.name} megaStone and megaEvolves arrays should be the same length`);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -312,7 +312,8 @@ function skip(dex: ModdedDex, format: Format, pokemon: string, set: DeepPartial<
|
|||
if (pokemon === 'Rayquaza-Mega') {
|
||||
return format.id.includes('ubers') || !hasMove('Dragon Ascent');
|
||||
} else {
|
||||
return dex.items.get(set.item).megaStone !== pokemon;
|
||||
const item = dex.items.get(set.item);
|
||||
return !item.megaStone || !Object.values(item.megaStone).includes(pokemon);
|
||||
}
|
||||
}
|
||||
if (pokemon === 'Necrozma-Ultra' && set.item !== 'Ultranecrozium Z') return true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user