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