Rename Template to Species (#1484)

This commit is contained in:
Kris Johnson 2020-03-26 00:29:05 -06:00 committed by GitHub
parent a89429f9ec
commit f21bfe7f6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 412 additions and 411 deletions

View File

@ -174,7 +174,7 @@ function requireNoCache(pathSpec) {
}
}
for (const id in Dex.data.Pokedex) {
const name = Dex.data.Pokedex[id].species;
const name = Dex.data.Pokedex[id].name;
generateAlias(id, name, 'pokemon');
}
for (const id in Dex.data.Movedex) {
@ -228,7 +228,7 @@ function requireNoCache(pathSpec) {
const id = entry[0];
let name = '';
switch (entry[1]) {
case 'pokemon': name = Dex.getTemplate(id).species; break;
case 'pokemon': name = Dex.getSpecies(id).name; break;
case 'move': name = Dex.getMove(id).name; break;
case 'item': name = Dex.getItem(id).name; break;
case 'ability': name = Dex.getAbility(id).name; break;
@ -302,92 +302,92 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
const zuBans = {};
const nfeBans = {};
for (const id of pokemon) {
const template = Dex.mod(gen).getTemplate(id);
if (template.gen > genNum) continue;
const species = Dex.mod(gen).getSpecies(id);
if (species.gen > genNum) continue;
const tier = (() => {
if (isNatDex) {
let tier = template.tier;
if (template.tier === 'Illegal' || template.isNonstandard === 'Past' || template.isUnreleased === 'Past') tier = Dex.mod('gen7').getTemplate(template.species).tier;
let tier = species.tier;
if (species.tier === 'Illegal' || species.isNonstandard === 'Past' || species.isUnreleased === 'Past') tier = Dex.mod('gen7').getSpecies(species.name).tier;
let banlist = Dex.getFormat('gen8nationaldex').banlist;
if (
banlist.includes(template.species) ||
banlist.includes(template.species + '-Base') ||
banlist.includes(template.baseSpecies) ||
['Zygarde-Complete', 'Necrozma-Ultra'].includes(template.species)
banlist.includes(species.name) ||
banlist.includes(species.name + '-Base') ||
banlist.includes(species.baseSpecies) ||
['Zygarde-Complete', 'Necrozma-Ultra'].includes(species.name)
) {
tier = 'Uber';
if (template.species === 'Eternatus-Eternamax') tier = 'Illegal';
if (species.name === 'Eternatus-Eternamax') tier = 'Illegal';
return tier;
} else if (tier === 'Uber' && !template.isGigantamax) { // This check is for Pokemon tiered as Uber but aren't in the banlist for National Dex
} else if (tier === 'Uber' && !species.isGigantamax) { // This check is for Pokemon tiered as Uber but aren't in the banlist for National Dex
tier = 'OU';
return tier;
}
if (['Meltan', 'Melmetal'].includes(template.species)) tier = 'OU';
if (template.isGigantamax) tier = 'Uber';
if (['Meltan', 'Melmetal'].includes(species.name)) tier = 'OU';
if (species.isGigantamax) tier = '(Uber)';
return tier;
}
if (isMetBattle) {
let tier = template.tier;
if (template.isNonstandard) {
if (template.isNonstandard === 'Past') {
tier = Dex.mod('gen7').getTemplate(template.species).tier;
let tier = species.tier;
if (species.isNonstandard) {
if (species.isNonstandard === 'Past') {
tier = Dex.mod('gen7').getSpecies(species.name).tier;
} else {
tier = 'OU';
}
}
if (template.tier === 'CAP LC') tier = 'LC';
if (template.tier === 'CAP NFE') tier = 'NFE';
if (template.tier === 'CAP') tier = 'OU';
if (template.isUnreleased) {
if (template.isUnreleased === 'Past') {
tier = Dex.mod('gen7').getTemplate(template.species).tier;
if (species.tier === 'CAP LC') tier = 'LC';
if (species.tier === 'CAP NFE') tier = 'NFE';
if (species.tier === 'CAP') tier = 'OU';
if (species.isUnreleased) {
if (species.isUnreleased === 'Past') {
tier = Dex.mod('gen7').getSpecies(species.name).tier;
} else {
tier = 'Unreleased';
}
}
let banlist = Dex.getFormat('gen8metronomebattle').banlist;
let bst = 0;
for (const stat of Object.values(template.baseStats)) {
for (const stat of Object.values(species.baseStats)) {
bst += stat;
}
if (bst > 625) tier = 'Illegal';
if (banlist.includes(template.species) || banlist.includes(template.species + '-Base')) tier = 'Illegal';
if (template.types.includes('Steel')) tier = 'Illegal';
if (banlist.includes(species.name) || banlist.includes(species.name + '-Base')) tier = 'Illegal';
if (species.types.includes('Steel')) tier = 'Illegal';
return tier;
}
if (isLetsGo) {
let baseTemplate = Dex.mod(gen).getTemplate(template.baseSpecies);
let validNum = (baseTemplate.num <= 151 && baseTemplate.num >= 1) || [808, 809].includes(baseTemplate.num);
let baseSpecies = Dex.mod(gen).getSpecies(species.baseSpecies);
let validNum = (baseSpecies.num <= 151 && species.num >= 1) || [808, 809].includes(baseSpecies.num);
if (!validNum) return 'Illegal';
if (template.forme && !['Alola', 'Mega', 'Mega-X', 'Mega-Y', 'Starter'].includes(template.forme)) return 'Illegal';
return template.tier;
if (species.forme && !['Alola', 'Mega', 'Mega-X', 'Mega-Y', 'Starter'].includes(species.forme)) return 'Illegal';
return species.tier;
}
if (isVGC) {
if (template.tier === 'NFE') return 'NFE';
if (template.tier === 'LC') return 'NFE';
if (template.tier === 'Illegal' || template.tier === 'Unreleased') return 'Illegal';
if (restrictedLegends.includes(template.species) || restrictedLegends.includes(template.baseSpecies)) {
if (species.tier === 'NFE') return 'NFE';
if (species.tier === 'LC') return 'NFE';
if (species.tier === 'Illegal' || species.tier === 'Unreleased') return 'Illegal';
if (restrictedLegends.includes(species.name) || restrictedLegends.includes(species.baseSpecies)) {
return 'Restricted Legendary';
}
if (mythicals.includes(template.species) || mythicals.includes(template.baseSpecies)) {
if (mythicals.includes(species.name) || mythicals.includes(species.baseSpecies)) {
return 'Mythical';
}
return 'Regular';
}
if (template.tier === 'CAP' || template.tier === 'CAP NFE' || template.tier === 'CAP LC') {
return template.tier;
if (species.tier === 'CAP' || species.tier === 'CAP NFE' || species.tier === 'CAP LC') {
return species.tier;
}
if (isDoubles) {
return template.doublesTier;
return species.doublesTier;
}
return template.tier;
return species.tier;
})();
overrideTier[template.speciesid] = tier;
if (template.forme) {
overrideTier[species.id] = tier;
if (species.forme) {
if (
[
'Aegislash', 'Castform', 'Cherrim', 'Cramorant', 'Eiscue', 'Meloetta', 'Mimikyu', 'Minior', 'Morpeko', 'Wishiwashi',
].includes(template.baseSpecies) || template.forme.includes('Totem') || template.forme.includes('Zen')
].includes(species.baseSpecies) || species.forme.includes('Totem') || species.forme.includes('Zen')
) {
continue;
}
@ -413,24 +413,24 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
if (genNum >= 7) {
let banlist = Dex.getFormat(gen + 'zu').banlist;
for (const ban of banlist) {
let baseTemplate = Dex.mod(gen).getTemplate(ban.endsWith('-Base') ? ban.slice(0, -5) : ban);
if (!baseTemplate.exists) continue;
let baseSpecies = Dex.mod(gen).getSpecies(ban.endsWith('-Base') ? ban.slice(0, -5) : ban);
if (!baseSpecies.exists) continue;
const tierRank = {AG:1, Uber:1, OU:1, UUBL:1, UU:1, RUBL:1, RU:1, NUBL:1, NU:1, PUBL:1, PU:1, "(PU)":0, NFE:0, "LC Uber":0, LC:0};
let baseTier = baseTemplate.tier;
let baseTier = baseSpecies.tier;
if (baseTier !== "(PU)" && baseTier in tierRank && tierRank[baseTier] > 0) continue;
zuBans[baseTemplate.speciesid] = 1;
zuBans[baseSpecies.id] = 1;
}
}
if (genNum >= 8) {
let banlist = Dex.getFormat(gen + 'nfe').banlist;
for (const ban of banlist) {
let baseTemplate = Dex.mod(gen).getTemplate(ban.endsWith('-Base') ? ban.slice(0, -5) : ban);
if (!baseTemplate.exists) continue;
let baseSpecies = Dex.mod(gen).getSpecies(ban.endsWith('-Base') ? ban.slice(0, -5) : ban);
if (!baseSpecies.exists) continue;
const tierRank = {AG:1, Uber:1, OU:1, UUBL:1, UU:1, RUBL:1, RU:1, NUBL:1, NU:1, PUBL:1, PU:1, "(PU)":1, NFE:0, "LC Uber":0, LC:0};
let baseTier = baseTemplate.tier;
let baseTier = baseSpecies.tier;
if (!['NFE', 'LC Uber', 'LC'].includes(baseTier) && baseTier in tierRank && tierRank[baseTier] > 0) continue;
nfeBans[baseTemplate.speciesid] = 1;
nfeBans[baseSpecies.id] = 1;
}
}
}
@ -808,11 +808,11 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
}
const LGLearnsets = Dex.mod('letsgo').data.Learnsets;
for (const id in LGLearnsets) {
const template = Dex.mod('letsgo').getTemplate(id);
const baseTemplate = Dex.mod('letsgo').getTemplate(template.baseSpecies);
const validNum = (baseTemplate.num <= 151 && baseTemplate.num >= 1) || [808, 809].includes(baseTemplate.num);
const species = Dex.mod('letsgo').getSpecies(id);
const baseSpecies = Dex.mod('letsgo').getSpecies(species.baseSpecies);
const validNum = (baseSpecies.num <= 151 && baseSpecies.num >= 1) || [808, 809].includes(baseSpecies.num);
if (!validNum) continue;
if (template.forme && !['Alola', 'Mega', 'Mega-X', 'Mega-Y', 'Starter'].includes(template.forme)) continue;
if (species.forme && !['Alola', 'Mega', 'Mega-X', 'Mega-Y', 'Starter'].includes(species.forme)) continue;
const learnset = LGLearnsets[id].learnset;
BattleTeambuilderTable['letsgo'].learnsets[id] = {};
for (const moveid in learnset) {
@ -859,7 +859,7 @@ process.stdout.write("Building `data/teambuilder-tables.js`... ");
overrideHiddenAbility[id] = pastEntry.abilities['H'];
}
// in the gen 3 dex, Pokemon already have the abilities that were added in gen 4
const hasAbilityFromNewerGen = Dex.getTemplate(id).gen <= genNum && Dex.getAbility(pastEntry.abilities['1']).gen > genNum;
const hasAbilityFromNewerGen = Dex.getSpecies(id).gen <= genNum && Dex.getAbility(pastEntry.abilities['1']).gen > genNum;
if ((!pastEntry.abilities['1'] && nowEntry.abilities['1']) || hasAbilityFromNewerGen) {
removeSecondAbility[id] = true;
}

View File

@ -64,7 +64,7 @@ function updateLearnsets(callback) {
if (b.num <= 0 && a.num > 0) return 1;
if (a.num <= 0 && b.num <= 0) return b.num - a.num;
return a.num - b.num;
}).map(template => toID(template.species));
}).map(species => toID(species.name));
for (const speciesid of pokemonList) {
const entry = newLearnsetsG6[speciesid];

View File

@ -43,14 +43,14 @@ function sizeObj(path) {
function updateSizes() {
for (let baseid in Dex.data.Pokedex) {
let template = Dex.getTemplate(baseid);
for (let formid of [''].concat(template.otherForms || [])) {
let spriteid = template.spriteid;
if (formid) spriteid += '-' + formid.slice(template.id.length);
let species = Dex.getSpecies(baseid);
for (let formid of [''].concat(species.cosmeticFormes || [])) {
let spriteid = species.spriteid;
if (formid) spriteid += '-' + formid.slice(species.id.length);
let id = toID(spriteid);
{
let row = {num: template.num};
let row = {num: species.num};
const frontSize = sizeObj('sprites/ani/' + spriteid + '.gif');
if (frontSize) row.front = frontSize;
const frontSizeF = sizeObj('sprites/ani/' + spriteid + '-f.gif');
@ -65,7 +65,7 @@ function updateSizes() {
}
{
let g5row = {num: template.num};
let g5row = {num: species.num};
const frontSize = sizeObj('sprites/gen5ani/' + spriteid + '.gif');
if (frontSize) g5row.front = frontSize;
const frontSizeF = sizeObj('sprites/gen5ani/' + spriteid + '-f.gif');

View File

@ -193,7 +193,7 @@
switch (args[0]) {
case 'trapped':
requestData.trapped = true;
var pokeName = pokemon.side.n === 0 ? BattleLog.escapeHTML(pokemon.name) : "The opposing " + (this.battle.ignoreOpponent || this.battle.ignoreNicks ? pokemon.species : BattleLog.escapeHTML(pokemon.name));
var pokeName = pokemon.side.n === 0 ? BattleLog.escapeHTML(pokemon.name) : "The opposing " + (this.battle.ignoreOpponent || this.battle.ignoreNicks ? pokemon.cosmeticFormeName : BattleLog.escapeHTML(pokemon.name));
this.battle.activityQueue.push('|message|' + pokeName + ' is trapped and cannot switch!');
break;
case 'cant':
@ -570,7 +570,7 @@
} else if (!pokemon || pokemon.fainted) {
targetMenus[0] += '<button name="chooseMoveTarget" value="' + (i + 1) + '"><span class="picon" style="' + Dex.getPokemonIcon('missingno') + '"></span></button> ';
} else {
targetMenus[0] += '<button name="chooseMoveTarget" value="' + (i + 1) + '" class="has-tooltip" data-tooltip="' + BattleLog.escapeHTML(tooltipArgs) + '"><span class="picon" style="' + Dex.getPokemonIcon(pokemon) + '"></span>' + (this.battle.ignoreOpponent || this.battle.ignoreNicks ? pokemon.species : BattleLog.escapeHTML(pokemon.name)) + '<span class="' + pokemon.getHPColorClass() + '"><span style="width:' + (Math.round(pokemon.hp * 92 / pokemon.maxhp) || 1) + 'px"></span></span>' + (pokemon.status ? '<span class="status ' + pokemon.status + '"></span>' : '') + '</button> ';
targetMenus[0] += '<button name="chooseMoveTarget" value="' + (i + 1) + '" class="has-tooltip" data-tooltip="' + BattleLog.escapeHTML(tooltipArgs) + '"><span class="picon" style="' + Dex.getPokemonIcon(pokemon) + '"></span>' + (this.battle.ignoreOpponent || this.battle.ignoreNicks ? pokemon.cosmeticFormeName : BattleLog.escapeHTML(pokemon.name)) + '<span class="' + pokemon.getHPColorClass() + '"><span style="width:' + (Math.round(pokemon.hp * 92 / pokemon.maxhp) || 1) + 'px"></span></span>' + (pokemon.status ? '<span class="status ' + pokemon.status + '"></span>' : '') + '</button> ';
}
}
for (var i = 0; i < myActive.length; i++) {

View File

@ -1105,7 +1105,7 @@
if ($(window).width() < 640) this.show();
},
renderSet: function (set, i) {
var template = Dex.getTemplate(set.species);
var species = Dex.getSpecies(set.species);
var isLetsGo = this.curTeam.format.startsWith('gen7letsgo');
var isNatDex = this.curTeam.format.includes('nationaldex');
var buf = '<li value="' + i + '">';
@ -1120,13 +1120,13 @@
}
buf += '<div class="setmenu"><button name="copySet"><i class="fa fa-files-o"></i>Copy</button> <button name="importSet"><i class="fa fa-upload"></i>Import/Export</button> <button name="moveSet"><i class="fa fa-arrows"></i>Move</button> <button name="deleteSet"><i class="fa fa-trash"></i>Delete</button></div>';
buf += '<div class="setchart-nickname">';
buf += '<label>Nickname</label><input type="text" name="nickname" class="textbox" value="' + BattleLog.escapeHTML(set.name || '') + '" placeholder="' + BattleLog.escapeHTML(template.baseSpecies) + '" />';
buf += '<label>Nickname</label><input type="text" name="nickname" class="textbox" value="' + BattleLog.escapeHTML(set.name || '') + '" placeholder="' + BattleLog.escapeHTML(species.baseSpecies) + '" />';
buf += '</div>';
buf += '<div class="setchart" style="' + Dex.getTeambuilderSprite(set, this.curTeam.gen) + ';">';
// icon
buf += '<div class="setcol setcol-icon">';
if (template.otherForms && template.baseSpecies !== 'Unown') {
if (species.cosmeticFormes && species.baseSpecies !== 'Unown') {
buf += '<div class="setcell-sprite changeform"><i class="fa fa-caret-down"></i></div>';
} else {
buf += '<div class="setcell-sprite"></div>';
@ -1144,7 +1144,7 @@
};
buf += '<span class="detailcell detailcell-first"><label>Level</label>' + (set.level || 100) + '</span>';
if (this.curTeam.gen > 1) {
buf += '<span class="detailcell"><label>Gender</label>' + GenderChart[set.gender || template.gender || 'N'] + '</span>';
buf += '<span class="detailcell"><label>Gender</label>' + GenderChart[set.gender || species.gender || 'N'] + '</span>';
if (isLetsGo) {
buf += '<span class="detailcell"><label>Happiness</label>' + (typeof set.happiness === 'number' ? set.happiness : 70) + '</span>';
} else if (this.curTeam.gen < 8 || isNatDex) {
@ -1172,9 +1172,9 @@
buf += itemicon;
buf += '</div>';
buf += '<div class="setcell setcell-typeicons">';
var types = template.types;
var types = species.types;
var table = (this.curTeam.gen < 7 ? BattleTeambuilderTable['gen' + this.curTeam.gen] : null);
if (table && template.id in table.overrideType) types = table.overrideType[template.id].split('/');
if (table && species.id in table.overrideType) types = table.overrideType[species.id].split('/');
if (types) {
for (var i = 0; i < types.length; i++) buf += Dex.getTypeIcon(types[i]);
}
@ -1390,11 +1390,11 @@
var buf = '';
for (var i = 0; i < this.clipboardCount(); i++) {
var res = this.clipboard[i];
var pokemon = Dex.getTemplate(res.species);
var species = Dex.getSpecies(res.name);
buf += '<div class="result" data-id="' + i + '">';
buf += '<div class="section"><span class="icon" style="' + Dex.getPokemonIcon(res.species) + '"></span>';
buf += '<span class="species">' + (pokemon.species === pokemon.baseSpecies ? pokemon.species : (pokemon.baseSpecies + '-<small>' + pokemon.species.substr(pokemon.baseSpecies.length + 1) + '</small>')) + '</span></div>';
buf += '<div class="section"><span class="icon" style="' + Dex.getPokemonIcon(res.name) + '"></span>';
buf += '<span class="species">' + (species.name === species.baseSpecies ? species.name : (species.baseSpecies + '-<small>' + species.name.substr(species.baseSpecies.length + 1) + '</small>')) + '</span></div>';
buf += '<div class="section"><span class="ability-item">' + (res.ability || '<i>No ability</i>') + '<br />' + (res.item || '<i>No item</i>') + '</span></div>';
buf += '<div class="section no-border">';
for (var j = 0; j < 4; j++) {
@ -1678,9 +1678,9 @@
buf += '<button disabled="disabled" class="addpokemon" aria-label="Add Pok&eacute;mon"><i class="fa fa-plus"></i></button> ';
isAdd = true;
} else if (i == this.curSetLoc) {
buf += '<button disabled="disabled" class="pokemon">' + pokemonicon + BattleLog.escapeHTML(set.name || Dex.getTemplate(set.species).baseSpecies || '<i class="fa fa-plus"></i>') + '</button> ';
buf += '<button disabled="disabled" class="pokemon">' + pokemonicon + BattleLog.escapeHTML(set.name || Dex.getSpecies(set.species).baseSpecies || '<i class="fa fa-plus"></i>') + '</button> ';
} else {
buf += '<button name="selectPokemon" value="' + i + '" class="pokemon">' + pokemonicon + BattleLog.escapeHTML(set.name || Dex.getTemplate(set.species).baseSpecies) + '</button> ';
buf += '<button name="selectPokemon" value="' + i + '" class="pokemon">' + pokemonicon + BattleLog.escapeHTML(set.name || Dex.getSpecies(set.species).baseSpecies) + '</button> ';
}
}
if (this.curSetList.length < 6 && !isAdd) {
@ -1864,15 +1864,15 @@
plus: '',
minus: '',
smogdexLink: function (template) {
var template = Dex.getTemplate(template);
smogdexLink: function (s) {
var species = Dex.getSpecies(s);
var format = this.curTeam && this.curTeam.format;
var smogdexid = toID(template.baseSpecies);
var smogdexid = toID(species.baseSpecies);
if (template.speciesid === 'meowstic') {
if (species.id === 'meowstic') {
smogdexid = 'meowstic-m';
} else if (template.forme) {
switch (template.baseSpecies) {
} else if (species.forme) {
switch (species.baseSpecies) {
case 'Alcremie':
case 'Basculin':
case 'Burmy':
@ -1896,7 +1896,7 @@
case 'Vivillon':
break;
default:
smogdexid += '-' + toID(template.forme);
smogdexid += '-' + toID(species.forme);
break;
}
}
@ -1922,9 +1922,9 @@
updateStatForm: function (setGuessed) {
var buf = '';
var set = this.curSet;
var template = Dex.forGen(this.curTeam.gen).getTemplate(this.curSet.species);
var species = Dex.forGen(this.curTeam.gen).getSpecies(this.curSet.species);
var baseStats = template.baseStats;
var baseStats = species.baseStats;
buf += '<div class="resultheader"><h3>EVs</h3></div>';
buf += '<div class="statform">';
@ -1936,7 +1936,7 @@
var guessedMinus = guess.minusStat;
buf += '<p class="suggested"><small>Guessed spread:';
if (role === '?') {
buf += ' (Please choose 4 moves to get a guessed spread) (<a target="_blank" href="' + this.smogdexLink(template) + '">Smogon&nbsp;analysis</a>)</small></p>';
buf += ' (Please choose 4 moves to get a guessed spread) (<a target="_blank" href="' + this.smogdexLink(species) + '">Smogon&nbsp;analysis</a>)</small></p>';
} else {
buf += ' </small><button name="setStatFormGuesses">' + role + ': ';
for (var i in BattleStatNames) {
@ -1947,7 +1947,7 @@
}
if (guessedPlus && guessedMinus) buf += ' (+' + BattleStatNames[guessedPlus] + ', -' + BattleStatNames[guessedMinus] + ')';
else buf = buf.slice(0, -3);
buf += '</button><small> (<a target="_blank" href="' + this.smogdexLink(template) + '">Smogon&nbsp;analysis</a>)</small></p>';
buf += '</button><small> (<a target="_blank" href="' + this.smogdexLink(species) + '">Smogon&nbsp;analysis</a>)</small></p>';
// buf += ' <small>(' + role + ' | bulk: phys ' + Math.round(guess.moveCount.physicalBulk/1000) + ' + spec ' + Math.round(guess.moveCount.specialBulk/1000) + ' = ' + Math.round(guess.moveCount.bulk/1000) + ')</small>';
}
@ -2445,7 +2445,7 @@
var set = this.curSet;
var isLetsGo = this.curTeam.format.startsWith('gen7letsgo');
var isNatDex = this.curTeam.gen === 8 && this.curTeam.format.includes('nationaldex');
var template = Dex.getTemplate(set.species);
var species = Dex.getSpecies(set.species);
if (!set) return;
buf += '<div class="resultheader"><h3>Details</h3></div>';
buf += '<form class="detailsform">';
@ -2454,9 +2454,9 @@
if (this.curTeam.gen > 1) {
buf += '<div class="formrow"><label class="formlabel">Gender:</label><div>';
if (template.gender && this.curTeam.format.indexOf('hackmons') < 0) {
if (species.gender && this.curTeam.format.indexOf('hackmons') < 0) {
var genderTable = {'M': "Male", 'F': "Female", 'N': "Genderless"};
buf += genderTable[template.gender];
buf += genderTable[species.gender];
} else {
buf += '<label><input type="radio" name="gender" value="M"' + (set.gender === 'M' ? ' checked' : '') + ' /> Male</label> ';
buf += '<label><input type="radio" name="gender" value="F"' + (set.gender === 'F' ? ' checked' : '') + ' /> Female</label> ';
@ -2502,7 +2502,7 @@
}
buf += '</form>';
if (template.otherForms && template.baseSpecies !== 'Unown') {
if (species.cosmeticFormes && species.baseSpecies !== 'Unown') {
buf += '<button class="altform">Change sprite</button>';
}
@ -3004,8 +3004,8 @@
},
setPokemon: function (val, selectNext) {
var set = this.curSet;
var template = Dex.forGen(this.curTeam.gen).getTemplate(val);
if (!template.exists || set.species === template.species) {
var species = Dex.forGen(this.curTeam.gen).getSpecies(val);
if (!species.exists || set.species === species.name) {
if (selectNext) this.$('input[name=item]').select();
return;
}
@ -3028,15 +3028,15 @@
}
}
if (set.gender) delete set.gender;
if (template.gender && template.gender !== 'N') set.gender = template.gender;
if (species.gender && species.gender !== 'N') set.gender = species.gender;
if (set.happiness) delete set.happiness;
if (set.shiny) delete set.shiny;
if (this.curTeam.format.indexOf('hackmons') < 0) {
set.item = (template.requiredItem || '');
set.item = (species.requiredItem || '');
} else {
set.item = '';
}
set.ability = template.abilities['0'];
set.ability = species.abilities['0'];
set.moves = [];
set.evs = {};
@ -3070,13 +3070,13 @@
// do this after setting set.evs because it's assumed to exist
// after getStat is run
var template = Dex.forGen(this.curTeam.gen).getTemplate(set.species);
if (!template.exists) return 0;
var species = Dex.forGen(this.curTeam.gen).getSpecies(set.species);
if (!species.exists) return 0;
if (!set.level) set.level = 100;
if (typeof set.ivs[stat] === 'undefined') set.ivs[stat] = 31;
var baseStat = template.baseStats[stat];
var baseStat = species.baseStats[stat];
var iv = (set.ivs[stat] || 0);
if (this.curTeam.gen <= 2) iv &= 30;
var ev = set.evs[stat];
@ -3174,14 +3174,14 @@
this.room = data.room;
this.curSet = data.curSet;
this.chartIndex = data.index;
var template = Dex.getTemplate(this.curSet.species);
var baseid = toID(template.baseSpecies);
var forms = [baseid].concat(template.otherForms);
var species = Dex.getSpecies(this.curSet.species);
var baseid = toID(species.baseSpecies);
var forms = [baseid].concat(species.cosmeticFormes);
var spriteDir = Dex.resourcePrefix + 'sprites/';
var spriteSize = 96;
var spriteDim = 'width: 96px; height: 96px;';
var gen = {1:'gen1', 2:'gen2', 3:'gen3', 4:'gen4', 5:'gen5', 6:'dex', 7:'dex', 8:'dex'}[Math.max(this.room.curTeam.gen, template.gen)];
var gen = {1:'gen1', 2:'gen2', 3:'gen3', 4:'gen4', 5:'gen5', 6:'dex', 7:'dex', 8:'dex'}[Math.max(this.room.curTeam.gen, species.gen)];
if (Dex.prefs('nopastgens')) gen = 'dex';
if (Dex.prefs('bwgfx') && gen === 'dex') gen = 'gen5';
spriteDir += gen;
@ -3201,7 +3201,7 @@
var offset = '-' + (((i - 1) % 7) * spriteSize) + 'px -' + (Math.floor((i - 1) / 7) * spriteSize) + 'px';
buf += '<button name="setForm" value="' + form + '" style="';
buf += 'background-position:' + offset + '; background: url(' + spriteDir + '/' + baseid + (form ? '-' + formid : '') + '.png) no-repeat; ' + spriteDim + '"';
buf += (form === template.form || (form === '' && !template.form) ? ' class="cur"' : '') + '></button>';
buf += (form === species.form || (form === '' && !species.form) ? ' class="cur"' : '') + '></button>';
}
buf += '</div>';
@ -3210,11 +3210,11 @@
this.$el.html(buf).css({'max-width': (4 + spriteSize) * width, 'height': 42 + (4 + spriteSize) * height});
},
setForm: function (form) {
var template = Dex.getTemplate(this.curSet.species);
if (form && form !== template.form) {
this.curSet.species = Dex.getTemplate(template.baseSpecies + form).species;
var species = Dex.getSpecies(this.curSet.species);
if (form && form !== species.form) {
this.curSet.species = Dex.getSpecies(species.baseSpecies + form).species;
} else if (!form) {
this.curSet.species = template.baseSpecies;
this.curSet.species = species.baseSpecies;
}
this.close();
if (this.room.curSet) {

View File

@ -544,7 +544,7 @@
for (var i = 0; i < this.filters.length; i++) {
var text = this.filters[i][1];
if (this.filters[i][0] === 'move') text = Dex.getMove(text).name;
if (this.filters[i][0] === 'pokemon') text = Dex.getTemplate(text).name;
if (this.filters[i][0] === 'pokemon') text = Dex.getSpecies(text).name;
buf += '<button class="filter" value="' + BattleLog.escapeHTML(this.filters[i].join(':')) + '">' + text + ' <i class="fa fa-times-circle"></i></button> ';
}
if (!q) buf += '<small style="color: #888">(backspace = delete filter)</small>';
@ -570,22 +570,22 @@
var genChar = '' + this.gen;
var dex = Dex.mod('gen' + genChar);
for (var id in BattlePokedex) {
var template = dex.getTemplate(id);
if (template.exists === false) continue;
var species = dex.getSpecies(id);
if (species.exists === false) continue;
for (var i = 0; i < filters.length; i++) {
if (filters[i][0] === 'type') {
var type = filters[i][1];
if (template.types[0] !== type && template.types[1] !== type) break;
if (species.types[0] !== type && species.types[1] !== type) break;
} else if (filters[i][0] === 'egggroup') {
var egggroup = filters[i][1];
if (!template.eggGroups) continue;
if (template.eggGroups[0] !== egggroup && template.eggGroups[1] !== egggroup) break;
if (!species.eggGroups) continue;
if (species.eggGroups[0] !== egggroup && species.eggGroups[1] !== egggroup) break;
} else if (filters[i][0] === 'tier') {
var tier = filters[i][1];
if (template.tier !== tier) break;
if (species.tier !== tier) break;
} else if (filters[i][0] === 'ability') {
var ability = filters[i][1];
if (!Dex.hasAbility(template, ability)) break;
if (!Dex.hasAbility(species, ability)) break;
} else if (filters[i][0] === 'move') {
var learned = false;
var learnsetid = this.nextLearnsetid(id);
@ -645,10 +645,10 @@
}
if (learnsetid === 'lycanrocdusk' || (speciesid === 'rockruff' && learnsetid === 'rockruff')) return 'rockruffdusk';
var template = BattlePokedex[learnsetid];
if (!template) return '';
if (template.prevo) return template.prevo;
if (template.inheritsFrom) return template.inheritsFrom;
var species = BattlePokedex[learnsetid];
if (!species) return '';
if (species.prevo) return species.prevo;
if (species.inheritsFrom) return species.inheritsFrom;
return '';
};
Search.prototype.filteredMoves = function () {
@ -811,7 +811,7 @@
if (isMetBattle) this.mod = 'natdex';
var requirePentagon = (format === 'battlespotsingles' || format === 'battledoubles' || format.slice(0, 3) === 'vgc');
var requireGalar = (format.indexOf('battlestadium') >= 0 || (format.slice(0, 3) === 'vgc' && this.gen === 8));
var template;
var species;
var isBH = (format === 'balancedhackmons' || format === 'bh');
this.resultSet = null;
this.defaultResultSet = null;
@ -923,30 +923,30 @@
break;
case 'ability':
template = Dex.forGen(this.gen).getTemplate(set.species);
species = Dex.forGen(this.gen).getSpecies(set.species);
var abilitySet = [['header', "Abilities"]];
if (template.isMega) {
abilitySet.unshift(['html', '<p>Will be <strong>' + BattleLog.escapeHTML(template.abilities['0']) + '</strong> after Mega Evolving.</p>']);
template = Dex.getTemplate(template.baseSpecies);
if (species.isMega) {
abilitySet.unshift(['html', '<p>Will be <strong>' + BattleLog.escapeHTML(species.abilities['0']) + '</strong> after Mega Evolving.</p>']);
species = Dex.getSpecies(species.baseSpecies);
}
abilitySet.push(['ability', toID(template.abilities['0'])]);
if (template.abilities['1']) {
abilitySet.push(['ability', toID(template.abilities['1'])]);
abilitySet.push(['ability', toID(species.abilities['0'])]);
if (species.abilities['1']) {
abilitySet.push(['ability', toID(species.abilities['1'])]);
}
if (template.abilities['H']) {
if (species.abilities['H']) {
abilitySet.push(['header', "Hidden Ability"]);
abilitySet.push(['ability', toID(template.abilities['H'])]);
abilitySet.push(['ability', toID(species.abilities['H'])]);
}
if (template.abilities['S']) {
if (species.abilities['S']) {
abilitySet.push(['header', "Special Event Ability"]);
abilitySet.push(['ability', toID(template.abilities['S'])]);
abilitySet.push(['ability', toID(species.abilities['S'])]);
}
if (format === 'almostanyability' || isBH || isMetBattle) {
template = Dex.getTemplate(set.species);
species = Dex.getSpecies(set.species);
var abilities = [];
if (template.isMega) {
if (format === 'almostanyability') abilitySet.unshift(['html', '<p>Will be <strong>' + BattleLog.escapeHTML(template.abilities['0']) + '</strong> after Mega Evolving.</p>']);
// template is unused after this, so no need to replace
if (species.isMega) {
if (format === 'almostanyability') abilitySet.unshift(['html', '<p>Will be <strong>' + BattleLog.escapeHTML(species.abilities['0']) + '</strong> after Mega Evolving.</p>']);
// species is unused after this, so no need to replace
}
for (var i in BattleAbilities) {
if (BattleAbilities[i].isNonstandard) continue;
@ -977,8 +977,8 @@
break;
case 'move':
template = Dex.getTemplate(set.species);
var learnsetid = this.nextLearnsetid(template.id);
species = Dex.getSpecies(set.species);
var learnsetid = this.nextLearnsetid(species.id);
var moves = [];
var sMoves = [];
var sketch = false;
@ -1005,7 +1005,7 @@
}
}
}
learnsetid = this.nextLearnsetid(learnsetid, template.id);
learnsetid = this.nextLearnsetid(learnsetid, species.id);
}
if (isMetBattle) moves = ['metronome'];
if (sketch || isBH) {
@ -1049,31 +1049,31 @@
if (format === 'stabmons') {
for (var i in BattleMovedex) {
var types = [];
var baseTemplate = Dex.getTemplate(template.baseSpecies);
for (var j = 0; j < template.types.length; j++) {
if (template.battleOnly) continue;
types.push(template.types[j]);
var baseSpecies = Dex.getSpecies(species.baseSpecies);
for (var j = 0; j < species.types.length; j++) {
if (species.battleOnly) continue;
types.push(species.types[j]);
}
if (template.prevo) {
for (var j = 0; j < Dex.getTemplate(template.prevo).types.length; j++) {
types.push(Dex.getTemplate(template.prevo).types[j]);
if (species.prevo) {
for (var j = 0; j < Dex.getSpecies(species.prevo).types.length; j++) {
types.push(Dex.getSpecies(species.prevo).types[j]);
}
}
if (Dex.getTemplate(template.prevo).prevo) {
for (var j = 0; j < Dex.getTemplate(Dex.getTemplate(template.prevo).prevo).types.length; j++) {
types.push(Dex.getTemplate(Dex.getTemplate(template.prevo).prevo).types[j]);
if (Dex.getSpecies(species.prevo).prevo) {
for (var j = 0; j < Dex.getSpecies(Dex.getSpecies(species.prevo).prevo).types.length; j++) {
types.push(Dex.getSpecies(Dex.getSpecies(species.prevo).prevo).types[j]);
}
}
if (template.battleOnly) template = baseTemplate;
if (baseTemplate.otherFormes) {
for (var j = 0; j < baseTemplate.types.length; j++) {
if (template.forme.indexOf('Alola') >= 0 || template.forme.indexOf('Galar') >= 0 || template.baseSpecies === 'Wormadam') continue;
types.push(baseTemplate.types[j]);
if (species.battleOnly) species = baseSpecies;
if (baseSpecies.otherFormes) {
for (var j = 0; j < baseSpecies.types.length; j++) {
if (species.forme.indexOf('Alola') >= 0 || species.forme.indexOf('Galar') >= 0 || species.baseSpecies === 'Wormadam') continue;
types.push(baseSpecies.types[j]);
}
for (var j = 0; j < baseTemplate.otherFormes.length; j++) {
var forme = Dex.getTemplate(baseTemplate.otherFormes[j]);
for (var j = 0; j < baseSpecies.otherFormes.length; j++) {
var forme = Dex.getSpecies(baseSpecies.otherFormes[j]);
for (var h = 0; h < forme.types.length; h++) {
if (template.forme.indexOf('Alola') >= 0 || template.forme.indexOf('Galar') >= 0 || forme.baseSpecies === 'Wormadam' || forme.battleOnly) continue;
if (species.forme.indexOf('Alola') >= 0 || species.forme.indexOf('Galar') >= 0 || forme.baseSpecies === 'Wormadam' || forme.battleOnly) continue;
types.push(forme.types[h]);
}
}
@ -1117,7 +1117,7 @@
var id = moves[i];
var isViable = BattleMovedex[id] && BattleMovedex[id].isViable;
if (id === 'aerialace') isViable = (toID(set.species) in {scyther:1, aerodactylmega:1, kricketune:1});
if (id === 'ancientpower') isViable = (toID(set.ability) === 'technician' || (toID(set.ability) === 'serenegrace') || (template.types.indexOf('rock') > 0 && moves.indexOf('powergem') < 0));
if (id === 'ancientpower') isViable = (toID(set.ability) === 'technician' || (toID(set.ability) === 'serenegrace') || (species.types.indexOf('rock') > 0 && moves.indexOf('powergem') < 0));
if (id === 'aurawheel') isViable = (toID(set.species).startsWith('morpeko'));
if (id === 'bellydrum') isViable = (toID(set.species) in {azumarill:1, linoone:1, slurpuff:1});
if (id === 'blizzard') isViable = (toID(set.ability) === 'snowwarning');
@ -1127,19 +1127,19 @@
if (id === 'drainingkiss') isViable = (toID(set.ability) === 'triage');
if (id === 'dynamicpunch') isViable = (toID(set.ability) === 'noguard');
if (id === 'electroball') isViable = (toID(set.ability) === 'surgesurfer');
if (id === 'gyroball') isViable = (template.baseStats.spe <= 60);
if (id === 'headbutt') isViable = (toID(set.ability) === 'serenegrace' && template.types.indexOf('normal') > 0);
if (id === 'gyroball') isViable = (species.baseStats.spe <= 60);
if (id === 'headbutt') isViable = (toID(set.ability) === 'serenegrace' && species.types.indexOf('normal') > 0);
if (id === 'heartswap') isViable = (toID(set.species) === 'magearna');
if (id === 'hiddenpowerelectric') isViable = (moves.indexOf('thunderbolt') < 0);
if (id === 'hiddenpowerfighting') isViable = (moves.indexOf('aurasphere') < 0 && moves.indexOf('focusblast') < 0);
if (id === 'hiddenpowerfire') isViable = (moves.indexOf('flamethrower') < 0);
if (id === 'hiddenpowergrass') isViable = (moves.indexOf('energyball') < 0 && moves.indexOf('gigadrain') < 0);
if (id === 'hiddenpowerice') isViable = (moves.indexOf('icebeam') < 0 && template.id !== 'xerneas');
if (id === 'hiddenpowerice') isViable = (moves.indexOf('icebeam') < 0 && species.id !== 'xerneas');
if (id === 'hyperspacefury') isViable = (toID(set.species) === 'hoopaunbound');
if (id === 'hypnosis') isViable = ((this.gen < 4 && moves.indexOf('sleeppowder') < 0) || (toID(set.species) === 'darkrai'));
if (id === 'icywind') isViable = (toID(set.species).substr(0, 6) === 'keldeo');
if (id === 'infestation') isViable = (toID(set.species) === 'shuckle');
if (id === 'irontail') isViable = ((template.types.indexOf('steel') > 0 && moves.indexOf('ironhead') < 0) || ((template.types.indexOf('dark') > 0 || template.types.indexOf('dragon') > 0) && moves.indexOf('ironhead') < 0 && moves.indexOf('gunkshot') < 0));
if (id === 'irontail') isViable = ((species.types.indexOf('steel') > 0 && moves.indexOf('ironhead') < 0) || ((species.types.indexOf('dark') > 0 || species.types.indexOf('dragon') > 0) && moves.indexOf('ironhead') < 0 && moves.indexOf('gunkshot') < 0));
if (id === 'jumpkick') isViable = (moves.indexOf('highjumpkick') < 0);
if (id === 'leechlife') isViable = (this.gen > 6);
if (id === 'petaldance') isViable = (toID(set.ability) === 'owntempo');
@ -1147,15 +1147,15 @@
if (id === 'rocktomb') isViable = (toID(set.species) === 'groudon' || toID(set.ability) === 'technician');
if (id === 'selfdestruct') isViable = (this.gen < 5 && moves.indexOf('explosion') < 0);
if (id === 'skyattack') isViable = (toID(set.species) === 'hawlucha');
if (id === 'smackdown') isViable = (template.types.indexOf('ground') > 0);
if (id === 'smartstrike') isViable = (template.types.indexOf('steel') > 0 && moves.indexOf('ironhead') < 0);
if (id === 'smackdown') isViable = (species.types.indexOf('ground') > 0);
if (id === 'smartstrike') isViable = (species.types.indexOf('steel') > 0 && moves.indexOf('ironhead') < 0);
if (id === 'solarbeam' || id === 'solarblade') isViable = ['desolateland', 'drought', 'chlorophyll'].includes(toID(set.ability));
if (id === 'stompingtantrum') isViable = ((moves.indexOf('earthquake') < 0 && moves.indexOf('drillrun') < 0) || (toID(set.ability) === 'toughclaws' && moves.indexOf('drillrun') < 0 && moves.indexOf('earthquake') < 0));
if (id === 'storedpower') isViable = (toID(set.species) in {necrozma:1, espeon:1, sigilyph:1});
if (id === 'stunspore') isViable = (moves.indexOf('thunderwave') < 0);
if (id === 'teleport') isViable = (this.gen > 7);
if (id === 'thunder') isViable = (toID(set.ability) === 'drizzle' || (toID(set.ability) === 'primordialsea') || (toID(set.species) === 'xerneas'));
if (id === 'trickroom') isViable = (template.baseStats.spe <= 100);
if (id === 'trickroom') isViable = (species.baseStats.spe <= 100);
if (id === 'waterpulse') isViable = (toID(set.ability) === 'megalauncher' && moves.indexOf('originpulse') < 0);
if (format === 'mixandmega') {
if (id === 'blizzard') isViable = (toID(set.item) === 'abomasite' || toID(set.item) === 'pidgeotite');
@ -1265,7 +1265,7 @@
return this.renderMoveSortRow();
case 'pokemon':
var pokemon = BattlePokedex[id];
if (!pokemon) pokemon = BattlePokedex[toID(Dex.getTemplate(id).baseSpecies)];
if (!pokemon) pokemon = BattlePokedex[toID(Dex.getSpecies(id).baseSpecies)];
return this.renderPokemonRow(pokemon, matchStart, matchLength, errorMessage, attrs);
case 'move':
var move = BattleMovedex[id];
@ -1418,7 +1418,7 @@
// abilities
if (gen >= 3) {
var abilities = Dex.forGen(gen).getTemplate(id).abilities;
var abilities = Dex.forGen(gen).getSpecies(id).abilities;
if (abilities['1']) {
buf += '<span class="col twoabilitycol">' + abilities['0'] + '<br />' +
abilities['1'] + '</span>';

View File

@ -806,9 +806,9 @@ Storage.fastUnpackTeam = function (buf) {
// ability
j = buf.indexOf('|', i);
var ability = buf.substring(i, j);
var template = Dex.getTemplate(set.species);
if (template.baseSpecies === 'Zygarde' && ability === 'H') ability = 'Power Construct';
set.ability = (template.abilities && ['', '0', '1', 'H', 'S'].includes(ability) ? template.abilities[ability] || '!!!ERROR!!!' : ability);
var species = Dex.getSpecies(set.species);
if (species.baseSpecies === 'Zygarde' && ability === 'H') ability = 'Power Construct';
set.ability = (species.abilities && ['', '0', '1', 'H', 'S'].includes(ability) ? species.abilities[ability] || '!!!ERROR!!!' : ability);
i = j + 1;
// moves
@ -909,7 +909,7 @@ Storage.unpackTeam = function (buf) {
// species
j = buf.indexOf('|', i);
set.species = Dex.getTemplate(buf.substring(i, j)).species || set.name;
set.species = Dex.getSpecies(buf.substring(i, j)).species || set.name;
i = j + 1;
// item
@ -920,8 +920,8 @@ Storage.unpackTeam = function (buf) {
// ability
j = buf.indexOf('|', i);
var ability = Dex.getAbility(buf.substring(i, j)).name;
var template = Dex.getTemplate(set.species);
set.ability = (template.abilities && ability in {'':1, 0:1, 1:1, H:1} ? template.abilities[ability || '0'] : ability);
var species = Dex.getSpecies(set.species);
set.ability = (species.abilities && ability in {'':1, 0:1, 1:1, H:1} ? species.abilities[ability || '0'] : ability);
i = j + 1;
// moves
@ -1144,11 +1144,11 @@ Storage.importTeam = function (buffer, teams) {
var parenIndex = line.lastIndexOf(' (');
if (line.substr(line.length - 1) === ')' && parenIndex !== -1) {
line = line.substr(0, line.length - 1);
curSet.species = Dex.getTemplate(line.substr(parenIndex + 2)).species;
curSet.species = Dex.getSpecies(line.substr(parenIndex + 2)).species;
line = line.substr(0, parenIndex);
curSet.name = line;
} else {
curSet.species = Dex.getTemplate(line).species;
curSet.species = Dex.getSpecies(line).species;
curSet.name = '';
}
} else if (line.substr(0, 7) === 'Trait: ') {

View File

@ -133,26 +133,26 @@ function resolvePokemon($pokemon)
}
$lastPokemon = $pokemon;
if ($GLOBALS['BattlePokemon'][getSpecies($pokemon)]['number'] >= 494)
if ($GLOBALS['BattlePokemon'][getCosmeticFormeName($pokemon)]['number'] >= 494)
{
$GLOBALS['gen'] = 5;
}
if ($GLOBALS['BattlePokemon'][getSpecies($pokemon)]['number'] >= 387 && $GLOBALS['gen'] < 4)
if ($GLOBALS['BattlePokemon'][getCosmeticFormeName($pokemon)]['number'] >= 387 && $GLOBALS['gen'] < 4)
{
$GLOBALS['gen'] = 4;
}
if ($GLOBALS['BattlePokemon'][getSpecies($pokemon)]['number'] >= 252 && $GLOBALS['gen'] < 4)
if ($GLOBALS['BattlePokemon'][getCosmeticFormeName($pokemon)]['number'] >= 252 && $GLOBALS['gen'] < 4)
{
$GLOBALS['gen'] = 3;
}
if ($GLOBALS['BattlePokemon'][getSpecies($pokemon)]['number'] >= 152 && $GLOBALS['gen'] < 4)
if ($GLOBALS['BattlePokemon'][getCosmeticFormeName($pokemon)]['number'] >= 152 && $GLOBALS['gen'] < 4)
{
$GLOBALS['gen'] = 2;
}
return $pokemon;
}
function getSpecies($pokemon)
function getCosmeticFormeName($pokemon)
{
global $currentpokemon;
if ($currentpokemon[$pokemon]) $pokemon = $currentpokemon[$pokemon];

View File

@ -2238,6 +2238,7 @@ const BattleMoveAnims: AnimTable = {
}, 'decel', 'fade');
},
},
craftyshield: {
anim: BattleOtherAnims.selfstatus.anim,
},
@ -30831,6 +30832,7 @@ BattleMoveAnims['gravapple'] = {anim: BattleMoveAnims['energyball'].anim};
BattleMoveAnims['spiritbreak'] = {anim: BattleMoveAnims['moonblast'].anim};
BattleMoveAnims['lifedew'] = {anim: BattleMoveAnims['bubblebeam'].anim};
BattleMoveAnims['obstruct'] = {anim: BattleMoveAnims['kingsshield'].anim};
BattleMoveAnims['maxguard'] = {anim: BattleMoveAnims['banefulbunker'].anim};
BattleMoveAnims['falsesurrender'] = {anim: BattleMoveAnims['feintattack'].anim};
BattleMoveAnims['meteorassault'] = {anim: BattleMoveAnims['aurasphere'].anim};
BattleMoveAnims['eternabeam'] = {anim: BattleMoveAnims['roaroftime'].anim};

View File

@ -96,7 +96,7 @@ class BattleScene {
if (!pokemonId) return '';
if (battle.ignoreNicks || battle.ignoreOpponent) {
const pokemon = battle.getPokemon(pokemonId);
if (pokemon) return pokemon.species;
if (pokemon) return pokemon.cosmeticFormeName;
}
if (!pokemonId.startsWith('p1') && !pokemonId.startsWith('p2')) return '???pokemon:' + pokemonId + '???';
if (pokemonId.charAt(3) === ':') return pokemonId.slice(4).trim();
@ -585,9 +585,9 @@ class BattleScene {
getDetailsText(pokemon: Pokemon) {
let name = pokemon.side?.n &&
(this.battle.ignoreOpponent || this.battle.ignoreNicks) ? pokemon.species : pokemon.name;
if (name !== pokemon.species) {
name += ' (' + pokemon.species + ')';
(this.battle.ignoreOpponent || this.battle.ignoreNicks) ? pokemon.cosmeticFormeName : pokemon.name;
if (name !== pokemon.cosmeticFormeName) {
name += ' (' + pokemon.cosmeticFormeName + ')';
}
if (pokemon === pokemon.side.active[0]) {
name += ' (active)';
@ -622,10 +622,10 @@ class BattleScene {
let hasIllusion = false;
if (speciesOverage) {
for (let i = 0; i < side.pokemon.length; i++) {
const species = side.pokemon[i].getBaseTemplate().baseSpecies;
const species = side.pokemon[i].getBaseSpecies().baseSpecies;
if (speciesOverage && speciesTable.includes(species)) {
for (const sidebarIcon of sidebarIcons) {
if (side.pokemon[sidebarIcon[1]!].getBaseTemplate().baseSpecies === species) {
if (side.pokemon[sidebarIcon[1]!].getBaseSpecies().baseSpecies === species) {
sidebarIcon[0] = 'pokemon-illusion';
}
}
@ -724,8 +724,8 @@ class BattleScene {
let lombreCount = 0;
for (let i = 0; i < side.pokemon.length; i++) {
let pokemon = side.pokemon[i];
if (pokemon.species === 'Ludicolo') ludicoloCount++;
if (pokemon.species === 'Lombre') lombreCount++;
if (pokemon.cosmeticFormeName === 'Ludicolo') ludicoloCount++;
if (pokemon.cosmeticFormeName === 'Lombre') lombreCount++;
let spriteData = Dex.getSpriteData(pokemon, siden, {
gen: this.gen,
@ -742,7 +742,7 @@ class BattleScene {
x = 48 + 100 + 50 * i;
}
if (textBuf) textBuf += ' / ';
textBuf += pokemon.species;
textBuf += pokemon.cosmeticFormeName;
let url = spriteData.url;
// if (this.paused) url.replace('/xyani', '/xy').replace('.gif', '.png');
buf += '<img src="' + url + '" width="' + spriteData.w + '" height="' + spriteData.h + '" style="position:absolute;top:' + Math.floor(y - spriteData.h / 2) + 'px;left:' + Math.floor(x - spriteData.w / 2) + 'px" />';
@ -2266,7 +2266,7 @@ class PokemonSprite extends Sprite {
this.cryurl = sp.cryurl;
if (!this.scene.animating) return;
let speciesid = toID(pokemon.getSpecies());
let speciesid = toID(pokemon.getCosmeticFormeName());
let doCry = false;
const scene = this.scene;
if (isCustomAnim) {
@ -2423,7 +2423,7 @@ class PokemonSprite extends Sprite {
dogarsCheck(pokemon: Pokemon) {
if (pokemon.side.n === 1) return;
if (pokemon.species === 'Koffing' && pokemon.name.match(/dogars/i)) {
if (pokemon.cosmeticFormeName === 'Koffing' && pokemon.name.match(/dogars/i)) {
this.scene.setBgm(-1);
} else if (this.scene.bgmNum === -1) {
this.scene.rollBgm();
@ -2436,7 +2436,7 @@ class PokemonSprite extends Sprite {
getStatbarHTML(pokemon: Pokemon) {
let buf = '<div class="statbar' + (this.siden ? ' lstatbar' : ' rstatbar') + '" style="display: none">';
const ignoreNick = this.siden && (this.scene.battle.ignoreOpponent || this.scene.battle.ignoreNicks);
buf += `<strong>${BattleLog.escapeHTML(ignoreNick ? pokemon.species : pokemon.name)}`;
buf += `<strong>${BattleLog.escapeHTML(ignoreNick ? pokemon.cosmeticFormeName : pokemon.name)}`;
const gender = pokemon.gender;
if (gender === 'M' || gender === 'F') {
buf += ` <img src="${Dex.resourcePrefix}fx/gender-${gender.toLowerCase()}.png" alt="${gender}" width="7" height="10" class="pixelated" />`;
@ -2444,9 +2444,9 @@ class PokemonSprite extends Sprite {
buf += (pokemon.level === 100 ? `` : ` <small>L${pokemon.level}</small>`);
let symbol = '';
if (pokemon.species.indexOf('-Mega') >= 0) symbol = 'mega';
else if (pokemon.species === 'Kyogre-Primal') symbol = 'alpha';
else if (pokemon.species === 'Groudon-Primal') symbol = 'omega';
if (pokemon.cosmeticFormeName.indexOf('-Mega') >= 0) symbol = 'mega';
else if (pokemon.cosmeticFormeName === 'Kyogre-Primal') symbol = 'alpha';
else if (pokemon.cosmeticFormeName === 'Groudon-Primal') symbol = 'omega';
if (symbol) {
buf += ` <img src="${Dex.resourcePrefix}sprites/misc/${symbol}.png" alt="${symbol}" style="vertical-align:text-bottom;" />`;
}

View File

@ -375,9 +375,9 @@ class BattleChoiceBuilder {
curMatchLevel = 9;
} else if (choiceid === toID(serverPokemon.name)) {
curMatchLevel = 8;
} else if (choiceid === toID(serverPokemon.species)) {
} else if (choiceid === toID(serverPokemon.cosmeticFormeName)) {
curMatchLevel = 7;
} else if (choiceid === toID(Dex.getTemplate(serverPokemon.species).baseSpecies)) {
} else if (choiceid === toID(Dex.getSpecies(serverPokemon.cosmeticFormeName).baseSpecies)) {
curMatchLevel = 6;
}
if (curMatchLevel > matchLevel) {

View File

@ -956,9 +956,9 @@ interface Effect {
readonly id: ID;
readonly name: string;
readonly gen: number;
readonly effectType: 'Item' | 'Move' | 'Ability' | 'Template' | 'PureEffect';
readonly effectType: 'Item' | 'Move' | 'Ability' | 'Species' | 'PureEffect';
/**
* Do we have data on this item/move/ability/template?
* Do we have data on this item/move/ability/species?
* WARNING: Always false if the relevant data files aren't loaded.
*/
readonly exists: boolean;
@ -1292,17 +1292,15 @@ class Ability implements Effect {
}
}
class Template implements Effect {
class Species implements Effect {
// effect
readonly effectType = 'Template';
readonly effectType = 'Species';
readonly id: ID;
readonly name: string;
readonly gen: number;
readonly exists: boolean;
// name
readonly species: string;
readonly speciesid: ID;
readonly baseSpecies: string;
readonly forme: string;
readonly formeid: string;
@ -1330,7 +1328,7 @@ class Template implements Effect {
// format data
readonly otherFormes: ReadonlyArray<ID> | null;
// TODO: rename to cosmeticForms
readonly otherForms: ReadonlyArray<ID> | null;
readonly cosmeticFormes: ReadonlyArray<ID> | null;
readonly evos: ReadonlyArray<ID> | null;
readonly prevo: ID;
readonly evoType: 'trade' | 'useItem' | 'levelMove' | 'levelExtra' | 'levelFriendship' | 'levelHold' | 'other' | '';
@ -1351,13 +1349,11 @@ class Template implements Effect {
constructor(id: ID, name: string, data: any) {
if (!data || typeof data !== 'object') data = {};
if (data.name || data.species) name = data.name || data.species;
if (data.name) name = data.name;
this.name = Dex.sanitizeName(name);
this.id = id;
this.gen = data.gen || 0;
this.exists = ('exists' in data ? !!data.exists : true);
this.species = this.name;
this.speciesid = this.id;
if (!data.abilities &&
!['hooh', 'hakamoo', 'jangmoo', 'kommoo', 'porygonz'].includes(this.id)) {
const dashIndex = name.indexOf('-');
@ -1410,7 +1406,7 @@ class Template implements Effect {
this.eggGroups = data.eggGroups || [];
this.otherFormes = data.otherFormes || null;
this.otherForms = data.otherForms || null;
this.cosmeticFormes = data.cosmeticFormes || null;
this.evos = data.evos || null;
this.prevo = data.prevo || '';
this.evoType = data.evoType || '';
@ -1468,7 +1464,7 @@ if (typeof require === 'function') {
(global as any).BattleStats = BattleStats;
(global as any).BattleNatures = BattleNatures;
(global as any).PureEffect = PureEffect;
(global as any).Template = Template;
(global as any).Species = Species;
(global as any).Ability = Ability;
(global as any).Item = Item;
(global as any).Move = Move;

View File

@ -452,13 +452,13 @@ const Dex = new class implements ModdedDex {
return ability;
}
getTemplate(nameOrTemplate: string | Template | null | undefined): Template {
if (nameOrTemplate && typeof nameOrTemplate !== 'string') {
// TODO: don't accept Templates here
return nameOrTemplate;
getSpecies(nameOrSpecies: string | Species | null | undefined): Species {
if (nameOrSpecies && typeof nameOrSpecies !== 'string') {
// TODO: don't accept Species' here
return nameOrSpecies;
}
let name = nameOrTemplate || '';
let id = toID(nameOrTemplate);
let name = nameOrSpecies || '';
let id = toID(nameOrSpecies);
let formid = id;
if (!window.BattlePokedexAltForms) window.BattlePokedexAltForms = {};
if (formid in window.BattlePokedexAltForms) return window.BattlePokedexAltForms[formid];
@ -469,42 +469,42 @@ const Dex = new class implements ModdedDex {
if (!window.BattlePokedex) window.BattlePokedex = {};
let data = window.BattlePokedex[id];
let template: Template;
let species: Species;
if (data && typeof data.exists === 'boolean') {
template = data;
species = data;
} else {
if (!data) data = {exists: false};
if (!data.tier && id.slice(-5) === 'totem') {
data.tier = this.getTemplate(id.slice(0, -5)).tier;
data.tier = this.getSpecies(id.slice(0, -5)).tier;
}
if (!data.tier && data.baseSpecies && toID(data.baseSpecies) !== id) {
data.tier = this.getTemplate(data.baseSpecies).tier;
data.tier = this.getSpecies(data.baseSpecies).tier;
}
template = new Template(id, name, data);
window.BattlePokedex[id] = template;
species = new Species(id, name, data);
window.BattlePokedex[id] = species;
}
if (formid === id || !template.otherForms || !template.otherForms.includes(formid)) {
return template;
if (formid === id || !species.cosmeticFormes || !species.cosmeticFormes.includes(formid)) {
return species;
}
let forme = formid.slice(id.length);
forme = forme[0].toUpperCase() + forme.slice(1);
name = template.baseSpecies + (forme ? '-' + forme : '');
name = species.baseSpecies + (forme ? '-' + forme : '');
template = window.BattlePokedexAltForms[formid] = new Template(formid, name, {
...template,
species = window.BattlePokedexAltForms[formid] = new Species(formid, name, {
...species,
name,
forme,
});
return template;
return species;
}
/** @deprecated */
getTier(pokemon: string, genNum = 8, mod?: string): string {
let template = this.getTemplate(pokemon);
if (genNum < 8) template = this.forGen(genNum).getTemplate(pokemon);
let species = this.getSpecies(pokemon);
if (genNum < 8) species = this.forGen(genNum).getSpecies(pokemon);
let table = window.BattleTeambuilderTable;
if (!table) return template.tier;
if (!table) return species.tier;
if (mod === 'doubles') {
table = table[`gen${genNum}doubles`];
} else if (genNum < 8) {
@ -513,14 +513,14 @@ const Dex = new class implements ModdedDex {
table = table[toID(mod)];
}
if (!table.overrideTier) return template.tier;
if (!table.overrideTier) return species.tier;
let id = template.id;
let id = species.id;
if (id in table.overrideTier) {
return table.overrideTier[id];
}
return template.tier;
return species.tier;
}
getType(type: any): Effect {
@ -538,10 +538,10 @@ const Dex = new class implements ModdedDex {
return type;
}
hasAbility(template: Template, ability: string) {
for (const i in template.abilities) {
hasAbility(species: Species, ability: string) {
for (const i in species.abilities) {
// @ts-ignore
if (ability === template.abilities[i]) return true;
if (ability === species.abilities[i]) return true;
}
return false;
}
@ -558,7 +558,7 @@ const Dex = new class implements ModdedDex {
el.src = path + 'data/pokedex-mini-bw.js' + qs;
document.getElementsByTagName('body')[0].appendChild(el);
}
getSpriteData(pokemon: Pokemon | Template | string, siden: number, options: {
getSpriteData(pokemon: Pokemon | Species | string, siden: number, options: {
gen?: number, shiny?: boolean, gender?: GenderName, afd?: boolean, noScale?: boolean, mod?: string,
} = {gen: 6}) {
const mechanicsGen = options.gen || 6;
@ -572,9 +572,9 @@ const Dex = new class implements ModdedDex {
options.gender = pokemon.gender;
}
if (pokemon.volatiles.dynamax) isDynamax = true;
pokemon = pokemon.getSpecies();
pokemon = pokemon.getCosmeticFormeName();
}
const template = Dex.getTemplate(pokemon);
const species = Dex.getSpecies(pokemon);
let spriteData = {
gen: mechanicsGen,
w: 96,
@ -586,7 +586,7 @@ const Dex = new class implements ModdedDex {
cryurl: '',
shiny: options.shiny,
};
let name = template.spriteid;
let name = species.spriteid;
let dir;
let facing;
if (siden) {
@ -612,13 +612,13 @@ const Dex = new class implements ModdedDex {
let graphicsGen = mechanicsGen;
if (Dex.prefs('nopastgens')) graphicsGen = 6;
if (Dex.prefs('bwgfx') && graphicsGen >= 6) graphicsGen = 5;
spriteData.gen = Math.max(graphicsGen, Math.min(template.gen, 5));
spriteData.gen = Math.max(graphicsGen, Math.min(species.gen, 5));
const baseDir = ['', 'gen1', 'gen2', 'gen3', 'gen4', 'gen5', '', '', ''][spriteData.gen];
let animationData = null;
let miscData = null;
let speciesid = template.speciesid;
if (template.isTotem) speciesid = toID(name);
let speciesid = species.id;
if (species.isTotem) speciesid = toID(name);
if (baseDir === '' && window.BattlePokemonSprites) {
animationData = BattlePokemonSprites[speciesid];
}
@ -631,10 +631,10 @@ const Dex = new class implements ModdedDex {
if (!miscData) miscData = {};
if (miscData.num > 0) {
let baseSpeciesid = toID(template.baseSpecies);
let baseSpeciesid = toID(species.baseSpecies);
spriteData.cryurl = 'audio/cries/' + baseSpeciesid;
let formeid = template.formeid;
if (template.isMega || formeid && (
let formeid = species.formeid;
if (species.isMega || formeid && (
formeid === '-sky' ||
formeid === '-therian' ||
formeid === '-primal' ||
@ -664,7 +664,7 @@ const Dex = new class implements ModdedDex {
// Mod Cries
if (options.mod) {
spriteData.cryurl = `sprites/${options.mod}/audio/${toID(template.baseSpecies)}`;
spriteData.cryurl = `sprites/${options.mod}/audio/${toID(species.baseSpecies)}`;
spriteData.cryurl += (window.nodewebkit ? '.ogg' : '.mp3');
}
@ -711,7 +711,7 @@ const Dex = new class implements ModdedDex {
spriteData.w *= 2;
spriteData.h *= 2;
spriteData.y += -22;
} else if ((template.isTotem || isDynamax) && !options.noScale) {
} else if ((species.isTotem || isDynamax) && !options.noScale) {
spriteData.w *= 1.5;
spriteData.h *= 1.5;
spriteData.y += -11;
@ -760,7 +760,7 @@ const Dex = new class implements ModdedDex {
let id = toID(pokemon);
if (!pokemon || typeof pokemon === 'string') pokemon = null;
if (pokemon?.species) id = toID(pokemon.species);
if (pokemon?.cosmeticFormeName) id = toID(pokemon.cosmeticFormeName);
// @ts-ignore
if (pokemon?.volatiles?.formechange && !pokemon.volatiles.transform) {
// @ts-ignore
@ -777,11 +777,11 @@ const Dex = new class implements ModdedDex {
getTeambuilderSpriteData(pokemon: any, gen: number = 0): TeambuilderSpriteData {
let id = toID(pokemon.species);
let spriteid = pokemon.spriteid;
let template = Dex.getTemplate(pokemon.species);
let species = Dex.getSpecies(pokemon.species);
if (pokemon.species && !spriteid) {
spriteid = template.spriteid || toID(pokemon.species);
spriteid = species.spriteid || toID(pokemon.species);
}
if (template.exists === false) return { spriteDir: 'sprites/gen5', spriteid: '0', x: 10, y: 5 };
if (species.exists === false) return { spriteDir: 'sprites/gen5', spriteid: '0', x: 10, y: 5 };
const spriteData: TeambuilderSpriteData = {
spriteid,
spriteDir: 'sprites/dex',
@ -790,12 +790,12 @@ const Dex = new class implements ModdedDex {
};
if (pokemon.shiny) spriteData.shiny = true;
if (Dex.prefs('nopastgens')) gen = 6;
let xydexExists = (!template.isNonstandard || template.isNonstandard === 'Past') || [
let xydexExists = (!species.isNonstandard || species.isNonstandard === 'Past') || [
"pikachustarter", "eeveestarter", "meltan", "melmetal", "fidgit", "stratagem", "tomohawk", "mollux", "crucibelle", "crucibellemega", "kerfluffle", "pajantom", "jumbao", "caribolt", "smokomodo", "snaelstrom", "equilibra", "scratchet", "pluffle", "smogecko", "pokestarufo", "pokestarufo2", "pokestarbrycenman", "pokestarmt", "pokestarmt2", "pokestargiant", "pokestarhumanoid", "pokestarmonster", "pokestarf00", "pokestarf002", "pokestarspirit",
].includes(template.id);
if (template.gen === 8) xydexExists = false;
].includes(species.id);
if (species.gen === 8) xydexExists = false;
if ((!gen || gen >= 6) && xydexExists) {
if (template.gen >= 7) {
if (species.gen >= 7) {
spriteData.x = -6;
spriteData.y = -7;
} else if (id.substr(0, 6) === 'arceus') {
@ -811,10 +811,10 @@ const Dex = new class implements ModdedDex {
return spriteData;
}
spriteData.spriteDir = 'sprites/gen5';
if (gen <= 1 && template.gen <= 1) spriteData.spriteDir = 'sprites/gen1';
else if (gen <= 2 && template.gen <= 2) spriteData.spriteDir = 'sprites/gen2';
else if (gen <= 3 && template.gen <= 3) spriteData.spriteDir = 'sprites/gen3';
else if (gen <= 4 && template.gen <= 4) spriteData.spriteDir = 'sprites/gen4';
if (gen <= 1 && species.gen <= 1) spriteData.spriteDir = 'sprites/gen1';
else if (gen <= 2 && species.gen <= 2) spriteData.spriteDir = 'sprites/gen2';
else if (gen <= 3 && species.gen <= 3) spriteData.spriteDir = 'sprites/gen3';
else if (gen <= 4 && species.gen <= 4) spriteData.spriteDir = 'sprites/gen4';
spriteData.x = 10;
spriteData.y = 5;
return spriteData;
@ -862,7 +862,7 @@ class ModdedDex {
Moves: {} as any as {[k: string]: Move},
Items: {} as any as {[k: string]: Item},
Abilities: {} as any as {[k: string]: Ability},
Templates: {} as any as {[k: string]: Template},
Species: {} as any as {[k: string]: Species},
Types: {} as any as {[k: string]: Effect},
};
pokeballs: string[] | null = null;
@ -943,15 +943,15 @@ class ModdedDex {
this.cache.Abilities[id] = ability;
return ability;
}
getTemplate(name: string): Template {
getSpecies(name: string): Species {
let id = toID(name);
if (window.BattleAliases && id in BattleAliases) {
name = BattleAliases[id];
id = toID(name);
}
if (this.cache.Templates.hasOwnProperty(id)) return this.cache.Templates[id];
if (this.cache.Species.hasOwnProperty(id)) return this.cache.Species[id];
let data = {...Dex.getTemplate(name)};
let data = {...Dex.getSpecies(name)};
const table = window.BattleTeambuilderTable[this.modid];
if (this.gen < 3) {
@ -979,16 +979,16 @@ class ModdedDex {
if (id in table.overrideTier) data.tier = table.overrideTier[id];
if (!data.tier && id.slice(-5) === 'totem') {
data.tier = this.getTemplate(id.slice(0, -5)).tier;
data.tier = this.getSpecies(id.slice(0, -5)).tier;
}
if (!data.tier && data.baseSpecies && toID(data.baseSpecies) !== id) {
data.tier = this.getTemplate(data.baseSpecies).tier;
data.tier = this.getSpecies(data.baseSpecies).tier;
}
if (data.gen > this.gen) data.tier = 'Illegal';
const template = new Template(id, name, data);
this.cache.Templates[id] = template;
return template;
const species = new Species(id, name, data);
this.cache.Species[id] = species;
return species;
}
getType(name: string): Effect {
let id = toID(name) as string;

View File

@ -362,7 +362,7 @@ class BattleSearch {
buf.push(['header', `${type}-type Pok&eacute;mon`]);
for (let id in BattlePokedex) {
if (!BattlePokedex[id].types) continue;
if (this.dex.getTemplate(id).types.includes(type)) {
if (this.dex.getSpecies(id).types.includes(type)) {
(legal && !(id in legal) ? illegalBuf : buf).push(['pokemon', id as ID]);
}
}
@ -372,7 +372,7 @@ class BattleSearch {
buf.push(['header', `${ability} Pok&eacute;mon`]);
for (let id in BattlePokedex) {
if (!BattlePokedex[id].abilities) continue;
if (Dex.hasAbility(this.dex.getTemplate(id), ability)) {
if (Dex.hasAbility(this.dex.getSpecies(id), ability)) {
(legal && !(id in legal) ? illegalBuf : buf).push(['pokemon', id as ID]);
}
}
@ -598,10 +598,10 @@ class BattleSearch {
this.results = results;
}
private teambuilderMoves(format: ID, set: PokemonSet) {
let template = Dex.getTemplate(set.species);
let species = Dex.getSpecies(set.species);
const isBH = (format === 'balancedhackmons' || format === 'bh');
let learnsetid = this.nextLearnsetid(template.id);
let learnsetid = this.nextLearnsetid(species.id);
let moves: string[] = [];
let sMoves: string[] = [];
let sketch = false;
@ -628,7 +628,7 @@ class BattleSearch {
}
}
}
learnsetid = this.nextLearnsetid(learnsetid, template.id);
learnsetid = this.nextLearnsetid(learnsetid, species.id);
}
if (sketch || isBH) {
if (isBH) moves = [];
@ -667,34 +667,34 @@ class BattleSearch {
if (format === 'stabmons') {
for (let i in BattleMovedex) {
let types = [];
let baseTemplate = Dex.getTemplate(template.baseSpecies);
for (const type of template.types) {
if (template.battleOnly) continue;
let baseSpecies = Dex.getSpecies(species.baseSpecies);
for (const type of species.types) {
if (species.battleOnly) continue;
types.push(type);
}
if (template.prevo) {
const prevoTemplate = Dex.getTemplate(template.prevo);
for (const type of prevoTemplate.types) {
if (species.prevo) {
const prevoSpecies = Dex.getSpecies(species.prevo);
for (const type of prevoSpecies.types) {
types.push(type);
}
if (prevoTemplate.prevo) {
for (const type of Dex.getTemplate(prevoTemplate.prevo).types) {
if (prevoSpecies.prevo) {
for (const type of Dex.getSpecies(prevoSpecies.prevo).types) {
types.push(type);
}
}
}
if (template.battleOnly) template = baseTemplate;
if (baseTemplate.otherFormes && baseTemplate.baseSpecies !== 'Wormadam') {
for (const type of baseTemplate.types) {
if (template.forme === 'Alola' || template.forme === 'Alola-Totem') {
if (species.battleOnly) species = baseSpecies;
if (baseSpecies.otherFormes && baseSpecies.baseSpecies !== 'Wormadam') {
for (const type of baseSpecies.types) {
if (['Alola', 'Alola-Totem', 'Galar', 'Galar-Zen'].includes(species.forme)) {
continue;
}
types.push(type);
}
for (const formeid of baseTemplate.otherFormes) {
const forme = Dex.getTemplate(formeid);
for (const formeid of baseSpecies.otherFormes) {
const forme = Dex.getSpecies(formeid);
for (const type of forme.types) {
if (forme.battleOnly || forme.forme === 'Alola' || forme.forme === 'Alola-Totem') {
if (forme.battleOnly || ['Alola', 'Alola-Totem', 'Galar', 'Galar-Zen'].includes(species.forme)) {
continue;
}
types.push(type);
@ -723,7 +723,10 @@ class BattleSearch {
}
}
if (BattleMovedex[i].gen > this.gen) continue;
if (BattleMovedex[i].isZ || BattleMovedex[i].isNonstandard || BattleMovedex[i].isUnreleased) continue;
if (
BattleMovedex[i].isZ || BattleMovedex[i].isMax ||
BattleMovedex[i].isNonstandard || BattleMovedex[i].isUnreleased
) continue;
moves.push(i);
}
}
@ -740,7 +743,7 @@ class BattleSearch {
if (id === 'ancientpower') {
isViable = (
toID(set.ability) === 'technician' || (toID(set.ability) === 'serenegrace') ||
(template.types.includes('Rock') && moves.includes('powergem'))
(species.types.includes('Rock') && moves.includes('powergem'))
);
}
if (id === 'bellydrum') isViable = ['azumarill', 'linoone', 'slurpuff'].includes(toID(set.species));
@ -752,23 +755,23 @@ class BattleSearch {
if (id === 'drainingkiss') isViable = (toID(set.ability) === 'triage');
if (id === 'dynamicpunch') isViable = (toID(set.ability) === 'noguard');
if (id === 'electroball') isViable = (toID(set.ability) === 'surgesurfer');
if (id === 'gyroball') isViable = (template.baseStats.spe <= 60);
if (id === 'headbutt') isViable = (toID(set.ability) === 'serenegrace' && template.types.includes('Normal'));
if (id === 'gyroball') isViable = (species.baseStats.spe <= 60);
if (id === 'headbutt') isViable = (toID(set.ability) === 'serenegrace' && species.types.includes('Normal'));
if (id === 'heartswap') isViable = (toID(set.species) === 'magearna');
if (id === 'hiddenpowerelectric') isViable = !moves.includes('thunderbolt');
if (id === 'hiddenpowerfighting') isViable = (!moves.includes('aurasphere') && !moves.includes('focusblast'));
if (id === 'hiddenpowerfire') isViable = !moves.includes('flamethrower');
if (id === 'hiddenpowergrass') isViable = (!moves.includes('energyball') && !moves.includes('gigadrain'));
if (id === 'hiddenpowerice') isViable = (!moves.includes('icebeam') && template.id !== 'xerneas');
if (id === 'hiddenpowerice') isViable = (!moves.includes('icebeam') && species.id !== 'xerneas');
if (id === 'hypnosis') {
isViable = ((this.gen < 4 && !moves.includes('sleeppowder')) || toID(set.species) === 'darkrai');
}
if (id === 'icywind') isViable = toID(set.species).startsWith('keldeo');
if (id === 'infestation') isViable = (toID(set.species) === 'shuckle');
if (id === 'irontail') {
isViable = (template.types.includes('Steel') && moves.indexOf('ironhead') < 0) ||
isViable = (species.types.includes('Steel') && moves.indexOf('ironhead') < 0) ||
(
(template.types.includes('Dark') || template.types.includes('Dragon')) &&
(species.types.includes('Dark') || species.types.includes('Dragon')) &&
!moves.includes('ironhead') && !moves.indexOf('gunkshot')
);
}
@ -779,8 +782,8 @@ class BattleSearch {
if (id === 'rocktomb') isViable = (toID(set.species) === 'groudon' || toID(set.ability) === 'technician');
if (id === 'selfdestruct') isViable = (this.gen < 5 && moves.indexOf('explosion') < 0);
if (id === 'skyattack') isViable = (toID(set.species) === 'hawlucha');
if (id === 'smackdown') isViable = (template.types.indexOf('Ground') > 0);
if (id === 'smartstrike') isViable = (template.types.indexOf('Steel') > 0 && moves.indexOf('ironhead') < 0);
if (id === 'smackdown') isViable = (species.types.indexOf('Ground') > 0);
if (id === 'smartstrike') isViable = (species.types.indexOf('Steel') > 0 && moves.indexOf('ironhead') < 0);
if (id === 'solarbeam') isViable = ['drought', 'chlorophyll'].includes(toID(set.ability));
if (id === 'stompingtantrum') {
isViable = (
@ -793,7 +796,7 @@ class BattleSearch {
if (id === 'thunder') {
isViable = (['drizzle', 'primordialsea'].includes(toID(set.ability)) || (toID(set.species) === 'xerneas'));
}
if (id === 'trickroom') isViable = (template.baseStats.spe <= 100);
if (id === 'trickroom') isViable = (species.baseStats.spe <= 100);
if (id === 'waterpulse') isViable = (toID(set.ability) === 'megalauncher' && moves.indexOf('originpulse') < 0);
if (format === 'mixandmega') {
if (id === 'blizzard') isViable = (toID(set.item) === 'abomasite' || toID(set.item) === 'pidgeotite');
@ -867,33 +870,33 @@ class BattleSearch {
}
private teambuilderAbilities(format: ID, set: PokemonSet) {
const isBH = (format === 'balancedhackmons' || format === 'bh');
let template = this.dex.getTemplate(set.species);
let species = this.dex.getSpecies(set.species);
let abilitySet: SearchRow[] = [['header', "Abilities"]];
if (template.isMega) {
abilitySet.unshift(['html', `Will be <strong>${template.abilities['0']}</strong> after Mega Evolving.`]);
template = this.dex.getTemplate(template.baseSpecies);
if (species.isMega) {
abilitySet.unshift(['html', `Will be <strong>${species.abilities['0']}</strong> after Mega Evolving.`]);
species = this.dex.getSpecies(species.baseSpecies);
}
abilitySet.push(['ability', toID(template.abilities['0'])]);
if (template.abilities['1']) {
abilitySet.push(['ability', toID(template.abilities['1'])]);
abilitySet.push(['ability', toID(species.abilities['0'])]);
if (species.abilities['1']) {
abilitySet.push(['ability', toID(species.abilities['1'])]);
}
if (template.abilities['H']) {
if (species.abilities['H']) {
abilitySet.push(['header', "Hidden Ability"]);
abilitySet.push(['ability', toID(template.abilities['H'])]);
abilitySet.push(['ability', toID(species.abilities['H'])]);
}
if (template.abilities['S']) {
if (species.abilities['S']) {
abilitySet.push(['header', "Special Event Ability"]);
abilitySet.push(['ability', toID(template.abilities['S'])]);
abilitySet.push(['ability', toID(species.abilities['S'])]);
}
if (format === 'almostanyability' || isBH) {
template = Dex.getTemplate(set.species);
species = Dex.getSpecies(set.species);
let abilities: ID[] = [];
if (template.isMega) {
if (species.isMega) {
if (format === 'almostanyability') {
abilitySet.unshift(['html', `Will be <strong>${template.abilities['0']}</strong> after Mega Evolving.`]);
abilitySet.unshift(['html', `Will be <strong>${species.abilities['0']}</strong> after Mega Evolving.`]);
}
// template is unused after this, so no need to replace
// species is unused after this, so no need to replace
}
for (let i in BattleAbilities) {
if (BattleAbilities[i].isNonstandard) continue;
@ -928,8 +931,8 @@ class BattleSearch {
results.push(['category', 'status' as ID]);
this.results = results;
}
getTier(pokemon: Template) {
if (!this.isDoubles) return pokemon.tier;
getTier(pokemon: Species) {
if (this.isLetsGo) return pokemon.tier;
let table = window.BattleTeambuilderTable;
if (table && table[`gen${this.gen}doubles`]) {
table = table[`gen${this.gen}doubles`];
@ -969,22 +972,22 @@ class BattleSearch {
const genChar = '' + this.gen;
let i;
for (let id in BattlePokedex) {
let template = this.dex.getTemplate(id);
if (template.exists === false) continue;
let species = this.dex.getSpecies(id);
if (species.exists === false) continue;
for (i = 0; i < filters.length; i++) {
if (filters[i][0] === 'type') {
let type = filters[i][1];
if (template.types[0] !== type && template.types[1] !== type) break;
if (species.types[0] !== type && species.types[1] !== type) break;
} else if (filters[i][0] === 'egggroup') {
let egggroup = filters[i][1];
if (!template.eggGroups) continue;
if (template.eggGroups[0] !== egggroup && template.eggGroups[1] !== egggroup) break;
if (!species.eggGroups) continue;
if (species.eggGroups[0] !== egggroup && species.eggGroups[1] !== egggroup) break;
} else if (filters[i][0] === 'tier') {
let tier = filters[i][1];
if (this.getTier(template) !== tier) break;
if (this.getTier(species) !== tier) break;
} else if (filters[i][0] === 'ability') {
let ability = filters[i][1];
if (!Dex.hasAbility(template, ability)) break;
if (!Dex.hasAbility(species, ability)) break;
} else if (filters[i][0] === 'move') {
let learned = false;
let learnsetid = this.nextLearnsetid(id as ID);
@ -1043,12 +1046,12 @@ class BattleSearch {
if (learnsetid === 'lycanrocdusk' || (speciesid === 'rockruff' && learnsetid === 'rockruff')) {
return 'rockruffdusk' as ID;
}
let template = BattlePokedex[learnsetid];
if (!template) return '' as ID;
if (template.prevo) return template.prevo as ID;
let baseSpecies = template.baseSpecies;
if (baseSpecies !== template.species && (baseSpecies === 'Rotom' || baseSpecies === 'Pumpkaboo')) {
return toID(template.baseSpecies);
let species = BattlePokedex[learnsetid];
if (!species) return '' as ID;
if (species.prevo) return species.prevo as ID;
let baseSpecies = species.baseSpecies;
if (baseSpecies !== species.name && (baseSpecies === 'Rotom' || baseSpecies === 'Pumpkaboo')) {
return toID(species.baseSpecies);
}
return '' as ID;
}

View File

@ -40,7 +40,7 @@ class PSSearchResults extends preact.Component<{search: BattleSearch}> {
renderPokemonRow(id: ID, matchStart: number, matchEnd: number, errorMessage?: preact.ComponentChildren) {
const search = this.props.search;
const pokemon = search.dex.getTemplate(id);
const pokemon = search.dex.getSpecies(id);
if (!pokemon) return <li class="result">Unrecognized pokemon</li>;
let tagStart = (pokemon.forme ? pokemon.name.length - pokemon.forme.length - 1 : 0);

View File

@ -288,10 +288,10 @@ class BattleTooltips {
let pokemon = side.pokemon[parseInt(args[2], 10)];
if (args[3] === 'illusion') {
buf = '';
const species = pokemon.getBaseTemplate().baseSpecies;
const species = pokemon.getBaseSpecies().baseSpecies;
let index = 1;
for (const otherPokemon of side.pokemon) {
if (otherPokemon.getBaseTemplate().baseSpecies === species) {
if (otherPokemon.getBaseSpecies().baseSpecies === species) {
buf += this.showPokemonTooltip(otherPokemon, null, false, index);
index++;
}
@ -674,8 +674,8 @@ class BattleTooltips {
}
let name = BattleLog.escapeHTML(pokemon.name);
if (pokemon.species !== pokemon.name) {
name += ' <small>(' + BattleLog.escapeHTML(pokemon.species) + ')</small>';
if (pokemon.cosmeticFormeName !== pokemon.name) {
name += ' <small>(' + BattleLog.escapeHTML(pokemon.cosmeticFormeName) + ')</small>';
}
let levelBuf = (pokemon.level !== 100 ? ` <small>L${pokemon.level}</small>` : ``);
@ -883,7 +883,7 @@ class BattleTooltips {
let item = toID(serverPokemon.item);
if (ability === 'klutz' && item !== 'machobrace') item = '' as ID;
let species = Dex.getTemplate(clientPokemon ? clientPokemon.getSpecies() : serverPokemon.species).baseSpecies;
let species = Dex.getSpecies(clientPokemon ? clientPokemon.getCosmeticFormeName() : serverPokemon.cosmeticFormeName).baseSpecies;
// check for light ball, thick club, metal/quick powder
// the only stat modifying items in gen 2 were light ball, thick club, metal powder
@ -960,7 +960,7 @@ class BattleTooltips {
for (const ally of allyActive) {
if (!ally || ally.fainted) continue;
let allyAbility = this.getAllyAbility(ally);
if (allyAbility === 'Flower Gift' && (ally.getTemplate().baseSpecies === 'Cherrim' || this.battle.gen <= 4)) {
if (allyAbility === 'Flower Gift' && (ally.getSpecies().baseSpecies === 'Cherrim' || this.battle.gen <= 4)) {
stats.atk = Math.floor(stats.atk * 1.5);
stats.spd = Math.floor(stats.spd * 1.5);
}
@ -991,7 +991,7 @@ class BattleTooltips {
if (ability === 'marvelscale' && pokemon.status) {
stats.def = Math.floor(stats.def * 1.5);
}
if (item === 'eviolite' && Dex.getTemplate(pokemon.species).evos) {
if (item === 'eviolite' && Dex.getSpecies(pokemon.cosmeticFormeName).evos) {
stats.def = Math.floor(stats.def * 1.5);
stats.spd = Math.floor(stats.spd * 1.5);
}
@ -1126,7 +1126,7 @@ class BattleTooltips {
*/
getSpeedRange(pokemon: Pokemon): [number, number] {
let level = pokemon.level;
let baseSpe = pokemon.getTemplate().baseStats['spe'];
let baseSpe = pokemon.getSpecies().baseStats['spe'];
let tier = this.battle.tier;
let gen = this.battle.gen;
let isRandomBattle = tier.includes('Random Battle') ||
@ -1203,7 +1203,7 @@ class BattleTooltips {
}
// Aura Wheel as Morpeko-Hangry changes the type to Dark
if (move.id === 'aurawheel' && value.pokemon.getTemplate().species === 'Morpeko-Hangry') {
if (move.id === 'aurawheel' && value.pokemon.getSpecies().name === 'Morpeko-Hangry') {
moveType = 'Dark';
}
@ -1393,7 +1393,7 @@ class BattleTooltips {
if (move.id === 'weatherball') {
value.weatherModify(2);
}
if (move.id === 'watershuriken' && pokemon.getSpecies() === 'Greninja-Ash' && pokemon.ability === 'Battle Bond') {
if (move.id === 'watershuriken' && pokemon.getCosmeticFormeName() === 'Greninja-Ash' && pokemon.ability === 'Battle Bond') {
value.set(20, 'Battle Bond');
}
// Moves that check opponent speed
@ -1616,7 +1616,7 @@ class BattleTooltips {
'Spell Tag': 'Ghost',
'Twisted Spoon': 'Psychic',
};
static orbUsers: {[speciesName: string]: string} = {
static orbUsers: {[cosmeticFormeName: string]: string} = {
'Latias': 'Soul Dew',
'Latios': 'Soul Dew',
'Dialga': 'Adamant Orb',
@ -1661,7 +1661,7 @@ class BattleTooltips {
// Pokemon-specific items
if (item.name === 'Soul Dew' && this.battle.gen < 7) return value;
if (BattleTooltips.orbUsers[Dex.getTemplate(value.serverPokemon.species).baseSpecies] === item.name &&
if (BattleTooltips.orbUsers[Dex.getSpecies(value.serverPokemon.cosmeticFormeName).baseSpecies] === item.name &&
[BattleTooltips.orbTypes[item.name], 'Dragon'].includes(moveType)) {
value.itemModify(1.2);
return value;
@ -1678,7 +1678,7 @@ class BattleTooltips {
}
getPokemonTypes(pokemon: Pokemon | ServerPokemon): ReadonlyArray<TypeName> {
if (!(pokemon as Pokemon).getTypes) {
return this.battle.dex.getTemplate(pokemon.species).types;
return this.battle.dex.getSpecies(pokemon.cosmeticFormeName).types;
}
return (pokemon as Pokemon).getTypeList();
@ -1710,13 +1710,13 @@ class BattleTooltips {
abilityData.baseAbility = clientPokemon.baseAbility;
}
} else {
const species = clientPokemon.getSpecies() || serverPokemon?.species || '';
const template = this.battle.dex.getTemplate(species);
if (template.exists && template.abilities) {
abilityData.possibilities = [template.abilities['0']];
if (template.abilities['1']) abilityData.possibilities.push(template.abilities['1']);
if (template.abilities['H']) abilityData.possibilities.push(template.abilities['H']);
if (template.abilities['S']) abilityData.possibilities.push(template.abilities['S']);
const cosmeticFormeName = clientPokemon.getCosmeticFormeName() || serverPokemon?.cosmeticFormeName || '';
const species = this.battle.dex.getSpecies(cosmeticFormeName);
if (species.exists && species.abilities) {
abilityData.possibilities = [species.abilities['0']];
if (species.abilities['1']) abilityData.possibilities.push(species.abilities['1']);
if (species.abilities['H']) abilityData.possibilities.push(species.abilities['H']);
if (species.abilities['S']) abilityData.possibilities.push(species.abilities['S']);
}
}
}
@ -1853,13 +1853,13 @@ class BattleStatGuesser {
let item = this.dex.getItem(itemid);
let abilityid = toID(set.ability);
let template = this.dex.getTemplate(set.species || set.name!);
if (item.megaEvolves === template.species) template = this.dex.getTemplate(item.megaStone);
if (!template.exists) return '?';
let stats = template.baseStats;
let species = this.dex.getSpecies(set.species || set.name!);
if (item.megaEvolves === species.name) species = this.dex.getSpecies(item.megaStone);
if (!species.exists) return '?';
let stats = species.baseStats;
if (set.moves.length < 1) return '?';
let needsFourMoves = !['unown', 'ditto'].includes(template.id);
let needsFourMoves = !['unown', 'ditto'].includes(species.id);
let moveids = set.moves.map(toID);
if (moveids.includes('lastresort' as ID)) needsFourMoves = false;
if (set.moves.length < 4 && needsFourMoves && this.formatid !== 'gen8metronomebattle') {
@ -1952,7 +1952,7 @@ class BattleStatGuesser {
specialBulk *= 1.3;
moveCount['SpecialStall']++;
}
if (abilityid === 'sandstream' && template.types.includes('Rock')) {
if (abilityid === 'sandstream' && species.types.includes('Rock')) {
specialBulk *= 1.5;
}
@ -2046,8 +2046,8 @@ class BattleStatGuesser {
this.moveCount = moveCount;
this.hasMove = hasMove;
if (template.id === 'ditto') return abilityid === 'imposter' ? 'Physically Defensive' : 'Fast Bulky Support';
if (template.id === 'shedinja') return 'Fast Physical Sweeper';
if (species.id === 'ditto') return abilityid === 'imposter' ? 'Physically Defensive' : 'Fast Bulky Support';
if (species.id === 'shedinja') return 'Fast Physical Sweeper';
if (itemid === 'choiceband' && moveCount['PhysicalAttack'] >= 2) {
if (!isFast) return 'Bulky Band';
@ -2064,7 +2064,7 @@ class BattleStatGuesser {
return 'Physical Biased Mixed Scarf';
}
if (template.id === 'unown') return 'Fast Special Sweeper';
if (species.id === 'unown') return 'Fast Special Sweeper';
if (moveCount['PhysicalStall'] && moveCount['Restoration']) {
if (stats.spe > 110 && abilityid !== 'prankster') return 'Fast Bulky Support';
@ -2098,7 +2098,7 @@ class BattleStatGuesser {
}
if (moveCount['SpecialStall']) return 'Physically Defensive';
if (moveCount['PhysicalStall']) return 'Specially Defensive';
if (template.id === 'blissey' || template.id === 'chansey') return 'Physically Defensive';
if (species.id === 'blissey' || species.id === 'chansey') return 'Physically Defensive';
if (specialBulk >= physicalBulk) return 'Specially Defensive';
return 'Physically Defensive';
}
@ -2136,8 +2136,8 @@ class BattleStatGuesser {
guessEVs(set: PokemonSet, role: string): Partial<StatsTable> & {plusStat?: StatName | '', minusStat?: StatName | ''} {
if (!set) return {};
if (role === '?') return {};
let template = this.dex.getTemplate(set.species || set.name!);
let stats = template.baseStats;
let species = this.dex.getSpecies(set.species || set.name!);
let stats = species.baseStats;
let hasMove = this.hasMove;
let moveCount = this.moveCount;
@ -2222,14 +2222,14 @@ class BattleStatGuesser {
let SRresistances = ['Ground', 'Steel', 'Fighting'];
let SRweak = 0;
if (set.ability !== 'Magic Guard' && set.ability !== 'Mountaineer') {
if (SRweaknesses.indexOf(template.types[0]) >= 0) {
if (SRweaknesses.indexOf(species.types[0]) >= 0) {
SRweak++;
} else if (SRresistances.indexOf(template.types[0]) >= 0) {
} else if (SRresistances.indexOf(species.types[0]) >= 0) {
SRweak--;
}
if (SRweaknesses.indexOf(template.types[1]) >= 0) {
if (SRweaknesses.indexOf(species.types[1]) >= 0) {
SRweak++;
} else if (SRresistances.indexOf(template.types[1]) >= 0) {
} else if (SRresistances.indexOf(species.types[1]) >= 0) {
SRweak--;
}
}
@ -2273,19 +2273,19 @@ class BattleStatGuesser {
if (hp || evs['hp']) evs['hp'] = hp;
}
if (template.id === 'tentacruel') {
if (species.id === 'tentacruel') {
evTotal = this.ensureMinEVs(evs, 'spe', 16, evTotal);
} else if (template.id === 'skarmory') {
} else if (species.id === 'skarmory') {
evTotal = this.ensureMinEVs(evs, 'spe', 24, evTotal);
} else if (template.id === 'jirachi') {
} else if (species.id === 'jirachi') {
evTotal = this.ensureMinEVs(evs, 'spe', 32, evTotal);
} else if (template.id === 'celebi') {
} else if (species.id === 'celebi') {
evTotal = this.ensureMinEVs(evs, 'spe', 36, evTotal);
} else if (template.id === 'volcarona') {
} else if (species.id === 'volcarona') {
evTotal = this.ensureMinEVs(evs, 'spe', 52, evTotal);
} else if (template.id === 'gliscor') {
} else if (species.id === 'gliscor') {
evTotal = this.ensureMinEVs(evs, 'spe', 72, evTotal);
} else if (template.id === 'dragonite' && evs['hp']) {
} else if (species.id === 'dragonite' && evs['hp']) {
evTotal = this.ensureMaxEVs(evs, 'spe', 220, evTotal);
}
@ -2354,12 +2354,12 @@ class BattleStatGuesser {
}
getStat(stat: StatName, set: PokemonSet, evOverride?: number, natureOverride?: number) {
let template = this.dex.getTemplate(set.species);
if (!template.exists) return 0;
let species = this.dex.getSpecies(set.species);
if (!species.exists) return 0;
let level = set.level || 100;
let baseStat = template.baseStats[stat];
let baseStat = species.baseStats[stat];
let iv = (set.ivs && set.ivs[stat]);
if (typeof iv !== 'number') iv = 31;

View File

@ -36,7 +36,7 @@ type HPColor = 'r' | 'y' | 'g';
class Pokemon implements PokemonDetails, PokemonHealth {
name = '';
species = '';
cosmeticFormeName = '';
/**
* A string representing information extractable from textual
@ -104,7 +104,7 @@ class Pokemon implements PokemonDetails, PokemonHealth {
constructor(data: PokemonDetails, side: Side) {
this.side = side;
this.species = data.species;
this.cosmeticFormeName = data.cosmeticFormeName;
this.details = data.details;
this.name = data.name;
@ -399,7 +399,7 @@ class Pokemon implements PokemonDetails, PokemonHealth {
}
getWeightKg(serverPokemon?: ServerPokemon) {
let autotomizeFactor = this.volatiles.autotomize?.[1] * 100 || 0;
return Math.max(this.getTemplate(serverPokemon).weightkg - autotomizeFactor, 0.1);
return Math.max(this.getSpecies(serverPokemon).weightkg - autotomizeFactor, 0.1);
}
getBoostType(boostStat: BoostStatName) {
if (!this.boosts[boostStat]) return 'neutral';
@ -472,7 +472,7 @@ class Pokemon implements PokemonDetails, PokemonHealth {
if (this.volatiles.typechange) {
types = this.volatiles.typechange[1].split('/');
} else {
types = this.getTemplate(serverPokemon).types;
types = this.getSpecies(serverPokemon).types;
}
if (this.volatiles.roost && types.includes('Flying')) {
types = types.filter(typeName => typeName !== 'Flying');
@ -515,15 +515,15 @@ class Pokemon implements PokemonDetails, PokemonHealth {
const [types, addedType] = this.getTypes(serverPokemon);
return addedType ? types.concat(addedType) : types;
}
getSpecies(serverPokemon?: ServerPokemon): string {
getCosmeticFormeName(serverPokemon?: ServerPokemon): string {
return this.volatiles.formechange ? this.volatiles.formechange[1] :
(serverPokemon ? serverPokemon.species : this.species);
(serverPokemon ? serverPokemon.cosmeticFormeName : this.cosmeticFormeName);
}
getTemplate(serverPokemon?: ServerPokemon) {
return this.side.battle.dex.getTemplate(this.getSpecies(serverPokemon));
getSpecies(serverPokemon?: ServerPokemon) {
return this.side.battle.dex.getSpecies(this.getCosmeticFormeName(serverPokemon));
}
getBaseTemplate() {
return this.side.battle.dex.getTemplate(this.species);
getBaseSpecies() {
return this.side.battle.dex.getSpecies(this.cosmeticFormeName);
}
reset() {
this.clearVolatile();
@ -531,7 +531,7 @@ class Pokemon implements PokemonDetails, PokemonHealth {
this.fainted = false;
this.status = '';
this.moveTrack = [];
this.name = this.name || this.species;
this.name = this.name || this.cosmeticFormeName;
}
// This function is used for two things:
// 1) The percentage to display beside the HP bar.
@ -754,7 +754,7 @@ class Side {
if (curPoke === poke) continue;
if (curPoke.fainted) continue;
if (this.active.indexOf(curPoke) >= 0) continue;
if (curPoke.species === 'Zoroark' || curPoke.species === 'Zorua' || curPoke.ability === 'Illusion') {
if (curPoke.cosmeticFormeName === 'Zoroark' || curPoke.cosmeticFormeName === 'Zorua' || curPoke.ability === 'Illusion') {
illusionFound = curPoke;
break;
}
@ -957,7 +957,7 @@ enum Playback {
interface PokemonDetails {
details: string;
name: string;
species: string;
cosmeticFormeName: string;
level: number;
shiny: boolean;
gender: GenderName | '';
@ -2227,19 +2227,19 @@ class Battle {
poke.removeVolatile('typeadd' as ID);
poke.removeVolatile('typechange' as ID);
let newSpecies = args[2];
let commaIndex = newSpecies.indexOf(',');
let newCosmeticFormeName = args[2];
let commaIndex = newCosmeticFormeName.indexOf(',');
if (commaIndex !== -1) {
let level = newSpecies.substr(commaIndex + 1).trim();
let level = newCosmeticFormeName.substr(commaIndex + 1).trim();
if (level.charAt(0) === 'L') {
poke.level = parseInt(level.substr(1), 10);
}
newSpecies = args[2].substr(0, commaIndex);
newCosmeticFormeName = args[2].substr(0, commaIndex);
}
let template = this.dex.getTemplate(newSpecies);
let species = this.dex.getSpecies(newCosmeticFormeName);
poke.species = newSpecies;
poke.ability = poke.baseAbility = (template.abilities ? template.abilities['0'] : '');
poke.cosmeticFormeName = newCosmeticFormeName;
poke.ability = poke.baseAbility = (species.abilities ? species.abilities['0'] : '');
poke.details = args[2];
poke.searchid = args[1].substr(0, 2) + args[1].substr(3) + '|' + args[2];
@ -2261,23 +2261,23 @@ class Battle {
poke.boosts = {...tpoke.boosts};
poke.copyTypesFrom(tpoke);
poke.ability = tpoke.ability;
const species = (tpoke.volatiles.formechange ? tpoke.volatiles.formechange[1] : tpoke.species);
const cosmeticFormeName = (tpoke.volatiles.formechange ? tpoke.volatiles.formechange[1] : tpoke.cosmeticFormeName);
const pokemon = tpoke;
const shiny = tpoke.shiny;
const gender = tpoke.gender;
poke.addVolatile('transform' as ID, pokemon, shiny, gender);
poke.addVolatile('formechange' as ID, species);
poke.addVolatile('formechange' as ID, cosmeticFormeName);
for (const trackedMove of tpoke.moveTrack) {
poke.rememberMove(trackedMove[0], 0);
}
this.scene.animTransform(poke);
this.scene.resultAnim(poke, 'Transformed', 'good');
this.log(['-transform', args[1], args[2], tpoke.species], kwArgs);
this.log(['-transform', args[1], args[2], tpoke.cosmeticFormeName], kwArgs);
break;
}
case '-formechange': {
let poke = this.getPokemon(args[1])!;
let template = Dex.getTemplate(args[2]);
let species = Dex.getSpecies(args[2]);
let fromeffect = Dex.getEffect(kwArgs.from);
let isCustomAnim = false;
poke.removeVolatile('typeadd' as ID);
@ -2287,7 +2287,7 @@ class Battle {
if (!kwArgs.silent) {
this.activateAbility(poke, fromeffect);
}
poke.addVolatile('formechange' as ID, template.species); // the formechange volatile reminds us to revert the sprite change on switch-out
poke.addVolatile('formechange' as ID, species.name); // the formechange volatile reminds us to revert the sprite change on switch-out
this.scene.animTransform(poke, isCustomAnim);
this.log(args, kwArgs);
break;
@ -2869,7 +2869,7 @@ class Battle {
}
if (foe) siden = (siden ? 0 : 1);
let data = Dex.getTemplate(name);
let data = Dex.getSpecies(name);
return data.spriteData[siden];
}
*/
@ -2883,7 +2883,7 @@ class Battle {
const isTeamPreview = !name;
output.details = details;
output.name = name;
output.species = name;
output.cosmeticFormeName = name;
output.level = 100;
output.shiny = false;
output.gender = '';
@ -2902,7 +2902,7 @@ class Battle {
output.level = parseInt(splitDetails[1].substr(1), 10) || 100;
}
if (splitDetails[0]) {
output.species = splitDetails[0];
output.cosmeticFormeName = splitDetails[0];
}
return output;
}

View File

@ -25,8 +25,8 @@ class PSTeambuilder {
buf += '|' + toID(set.item);
// ability
let template = Dex.getTemplate(set.species || set.name);
let abilities = template.abilities;
let species = Dex.getSpecies(set.species || set.name);
let abilities = species.abilities;
id = toID(set.ability);
if (abilities) {
if (id === toID(abilities['0'])) {
@ -71,7 +71,7 @@ class PSTeambuilder {
}
// gender
if (set.gender && set.gender !== template.gender) {
if (set.gender && set.gender !== species.gender) {
buf += '|' + set.gender;
} else {
buf += '|';
@ -137,7 +137,7 @@ class PSTeambuilder {
// species
j = buf.indexOf('|', i);
set.species = Dex.getTemplate(buf.substring(i, j)).species || set.name;
set.species = Dex.getSpecies(buf.substring(i, j)).name || set.name;
i = j + 1;
// item
@ -148,10 +148,10 @@ class PSTeambuilder {
// ability
j = buf.indexOf('|', i);
let ability = Dex.getAbility(buf.substring(i, j)).name;
let template = Dex.getTemplate(set.species);
if (template.baseSpecies === 'Zygarde' && ability === 'H') ability = 'Power Construct';
let species = Dex.getSpecies(set.species);
if (species.baseSpecies === 'Zygarde' && ability === 'H') ability = 'Power Construct';
set.ability = ['', '0', '1', 'H', 'S'].includes(ability) ?
template.abilities[ability as '0' || '0'] || (ability === '' ? '' : '!!!ERROR!!!') :
species.abilities[ability as '0' || '0'] || (ability === '' ? '' : '!!!ERROR!!!') :
ability;
i = j + 1;