Jofthomas's picture
Jofthomas HF staff
Upload 4781 files
5c2ed06 verified
import { RandomGen7Teams, ZeroAttackHPIVs } from '../gen7/teams';
const POWERFUL_ABILITIES = [
'Adaptability', 'Aftermath', 'Analytic', 'Arena Trap', 'Beast Boost', 'Berserk', 'Comatose', 'Competitive',
'Compound Eyes', 'Contrary', 'Cursed Body', 'Defiant', 'Desolate Land', 'Download', 'Drizzle', 'Drought', 'Dry Skin',
'Effect Spore', 'Filter', 'Flame Body', 'Flash Fire', 'Fluffy', 'Fur Coat', 'Gooey', 'Grassy Surge', 'Heatproof',
'Huge Power', 'Hustle', 'Illusion', 'Imposter', 'Innards Out', 'Intimidate', 'Iron Barbs', 'Levitate', 'Lightning Rod',
'Magic Bounce', 'Magic Guard', 'Marvel Scale', 'Mold Breaker', 'Moody', 'Motor Drive', 'Moxie', 'Multiscale',
'Natural Cure', 'Neuroforce', 'Parental Bond', 'Poison Point', 'Poison Touch', 'Prankster', 'Primordial Sea', 'Prism Armor',
'Protean', 'Pure Power', 'Regenerator', 'Rough Skin', 'Sand Stream', 'Sap Sipper', 'Serene Grace',
'Shadow Shield', 'Shadow Tag', 'Shed Skin', 'Sheer Force', 'Shield Dust', 'Simple', 'Snow Warning', 'Solid Rock',
'Soul-Heart', 'Speed Boost', 'Stakeout', 'Stamina', 'Static', 'Storm Drain', 'Sturdy', 'Tangling Hair', 'Technician',
'Teravolt', 'Thick Fat', 'Tinted Lens', 'Tough Claws', 'Trace', 'Triage', 'Turboblaze', 'Unaware', 'Volt Absorb',
'Water Absorb', 'Water Bubble', 'Wonder Guard',
];
export class RandomGen7ApexTeams extends RandomGen7Teams {
randomSet(
species: string | Species,
teamDetails: RandomTeamsTypes.TeamDetails = {},
isLead = false
): RandomTeamsTypes.RandomSet {
species = this.dex.species.get(species);
const forme = this.getForme(species);
const sets = this.randomSets[species.id]["sets"];
const possibleSets = [];
// Check if the Pokemon has a Z-Move user set
let canZMove = false;
for (const set of sets) {
if (!teamDetails.zMove && set.role === 'Z-Move user') canZMove = true;
}
for (const set of sets) {
// Prevent multiple Z-Move users
if (teamDetails.zMove && set.role === 'Z-Move user') continue;
// Prevent Setup Sweeper and Bulky Setup if Z-Move user is available
if (canZMove && ['Setup Sweeper', 'Bulky Setup'].includes(set.role)) continue;
possibleSets.push(set);
}
const set = this.sampleIfArray(possibleSets);
const role = set.role;
const movePool: string[] = Array.from(set.movepool);
const preferredTypes = set.preferredTypes;
const preferredType = this.sampleIfArray(preferredTypes) || '';
let ability = '';
let item = undefined;
const evs = { hp: 85, atk: 85, def: 85, spa: 85, spd: 85, spe: 85 };
const ivs = { hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31 };
const types = species.types;
const baseAbilities = set.abilities!;
// Use the mega's ability for moveset generation
const abilities = (species.battleOnly && !species.requiredAbility) ? Object.values(species.abilities) : baseAbilities;
// Get moves
const moves = this.randomMoveset(types, abilities, teamDetails, species, isLead, movePool,
preferredType, role);
const counter = this.newQueryMoves(moves, species, preferredType, abilities);
// Get ability
ability = this.getAbility(new Set(types), moves, baseAbilities, counter, movePool, teamDetails, species,
preferredType, role);
// Get items
item = this.getPriorityItem(ability, types, moves, counter, teamDetails, species, isLead, preferredType, role);
if (item === undefined) {
item = this.getItem(ability, types, moves, counter, teamDetails, species, isLead, preferredType, role);
}
// For Trick / Switcheroo
if (item === 'Leftovers' && types.includes('Poison')) {
item = 'Black Sludge';
}
const level = this.getLevel(species);
// Minimize confusion damage, including if Foul Play is its only physical attack
if (
(!counter.get('Physical') || (counter.get('Physical') <= 1 && (moves.has('foulplay') || moves.has('rapidspin')))) &&
!moves.has('copycat') && !moves.has('transform')
) {
evs.atk = 0;
ivs.atk = 0;
}
// Override regular ability with a random "powerful" ability
ability = this.sample(POWERFUL_ABILITIES);
if (ability === 'Beast Boost' && !counter.get('Special')) {
evs.spa = 0;
ivs.spa = 0;
}
// We use a special variable to track Hidden Power
// so that we can check for all Hidden Powers at once
let hasHiddenPower = false;
for (const move of moves) {
if (move.startsWith('hiddenpower')) hasHiddenPower = true;
}
// Fix IVs for non-Bottle Cap-able sets
if (hasHiddenPower && level < 100) {
let hpType;
for (const move of moves) {
if (move.startsWith('hiddenpower')) hpType = move.substr(11);
}
if (!hpType) throw new Error(`hasHiddenPower is true, but no Hidden Power move was found.`);
const HPivs = ivs.atk === 0 ? ZeroAttackHPIVs[hpType] : this.dex.types.get(hpType).HPivs;
let iv: StatID;
for (iv in HPivs) {
ivs[iv] = HPivs[iv]!;
}
}
// Prepare optimal HP
const srImmunity = ability === 'Magic Guard';
const srWeakness = srImmunity ? 0 : this.dex.getEffectiveness('Rock', species);
while (evs.hp > 1) {
const hp = Math.floor(Math.floor(2 * species.baseStats.hp + ivs.hp + Math.floor(evs.hp / 4) + 100) * level / 100 + 10);
if (moves.has('substitute') && !['Black Sludge', 'Leftovers'].includes(item)) {
if (item === 'Sitrus Berry') {
// Two Substitutes should activate Sitrus Berry
if (hp % 4 === 0) break;
} else {
// Should be able to use Substitute four times from full HP without fainting
if (hp % 4 > 0) break;
}
} else if (moves.has('bellydrum') && (item === 'Sitrus Berry')) {
// Belly Drum should activate Sitrus Berry
if (hp % 2 === 0) break;
} else if (['highjumpkick', 'jumpkick'].some(m => moves.has(m))) {
// Crash damage move users want an odd HP to survive two misses
if (hp % 2 > 0) break;
} else {
// Maximize number of Stealth Rock switch-ins
if (srWeakness <= 0 || ability === 'Regenerator') break;
if (srWeakness === 1 && ['Black Sludge', 'Leftovers', 'Life Orb'].includes(item)) break;
if (item !== 'Sitrus Berry' && hp % (4 / srWeakness) > 0) break;
// Minimise number of Stealth Rock switch-ins to activate Sitrus Berry
if (item === 'Sitrus Berry' && hp % (4 / srWeakness) === 0) break;
}
evs.hp -= 4;
}
if (['gyroball', 'metalburst', 'trickroom'].some(m => moves.has(m))) {
evs.spe = 0;
ivs.spe = (hasHiddenPower && level < 100) ? ivs.spe - 30 : 0;
}
// shuffle moves to add more randomness to camomons
const shuffledMoves = Array.from(moves);
this.prng.shuffle(shuffledMoves);
// Z-Conversion Porygon-Z should have Shadow Ball first if no Recover, otherwise Thunderbolt
if (species.id === 'porygonz' && role === 'Z-Move user') {
const firstMove = (moves.has('shadowball') ? 'shadowball' : 'thunderbolt');
this.fastPop(shuffledMoves, shuffledMoves.indexOf(firstMove));
shuffledMoves.unshift(firstMove);
}
return {
name: species.baseSpecies,
species: forme,
gender: species.baseSpecies === 'Greninja' ? 'M' : species.gender,
shiny: this.randomChance(1, 1024),
level,
moves: shuffledMoves,
ability,
evs,
ivs,
item,
role,
};
}
}
export default RandomGen7ApexTeams;