Skip to content

Instantly share code, notes, and snippets.

@Spandamn
Last active January 6, 2017 13:28
Show Gist options
  • Save Spandamn/f55e7a89aff5f76587ddfd7f0ec23592 to your computer and use it in GitHub Desktop.
Save Spandamn/f55e7a89aff5f76587ddfd7f0ec23592 to your computer and use it in GitHub Desktop.
{
name: "[Gen 7] Inheritance",
desc: [
"Pokémon may use the ability and moves of another, as long as they forfeit their own learnset.",
"&bullet; <a href=\"https://www.smogon.com/forums/threads/3529252/\">Inheritance</a>",
],
mod: 'inh',
ruleset: ['OU'],
customBans: {
receiver: {
regigigas: 1,
slaking: 1,
},
donor: {
araquanid: 1,
smeargle: 1
},
},
noChangeForme: true,
noChangeAbility: true,
getEvoFamily: function(species) {
let template = Tools.getTemplate(species);
while (template.prevo) {
template = Tools.getTemplate(template.prevo);
}
return template.speciesid;
},
onValidateTeam: function(team, format, teamHas) {
// Donor Clause
let evoFamilyLists = [];
for (let i = 0; i < team.length; i++) {
let set = team[i];
if (!set.abilitySources) continue;
evoFamilyLists.push(new Set(set.abilitySources.map(format.getEvoFamily)));
}
// Checking actual full incompatibility would require expensive algebra.
// Instead, we only check the trivial case of multiple Pokémon only legal for exactly one family. FIXME?
let requiredFamilies = Object.create(null);
for (let i = 0; i < evoFamilyLists.length; i++) {
let evoFamilies = evoFamilyLists[i];
if (evoFamilies.size !== 1) continue;
evoFamilies = Array.from(evoFamilies);
if (requiredFamilies[evoFamilies[0]]) return ["You are limited to one inheritance from each family by the Donor Clause.", "(You inherit more than once from " + this.getTemplate(evoFamilies[0]).species + "'s.)"];
requiredFamilies[evoFamilies[0]] = 1;
}
},
validateSet: function(set, teamHas) {
if (!this.format.abilityMap) {
let abilityMap = Object.create(null);
for (let speciesid in this.tools.data.Pokedex) {
let pokemon = this.tools.data.Pokedex[speciesid];
if (pokemon.num < 1 || pokemon.num > 802) continue;
for (let key in pokemon.abilities) {
let abilityId = toId(pokemon.abilities[key]);
if (abilityMap[abilityId]) {
abilityMap[abilityId][pokemon.evos ? 'push' : 'unshift'](speciesid);
} else {
abilityMap[abilityId] = [speciesid];
}
}
}
this.format.abilityMap = abilityMap;
}
this.format.noChangeForme = false;
let problems = this.tools.getFormat('Pokemon').onChangeSet.call(this.tools, set, this.format) || [];
this.format.noChangeForme = true;
if (problems.length) return problems;
let species = toId(set.species);
let template = this.tools.getTemplate(species);
if (!template.exists) return ["" + set.species + " is not a real Pok\u00E9mon."];
if (template.isUnreleased) return ["" + set.species + " is unreleased."];
if (template.speciesid in this.format.customBans.receiver) {
return ["" + set.species + " is banned."];
} else if (!this.tools.data.FormatsData[species] || !this.tools.data.FormatsData[species].tier) {
if (toId(template.baseSpecies) in this.format.customBans.receiver) {
return ["" + template.baseSpecies + " is banned."];
}
}
let name = set.name;
let abilityId = toId(set.ability);
if (!abilityId) return ["" + (set.name || set.species) + " must have an ability."];
let pokemonWithAbility = this.format.abilityMap[abilityId];
if (!pokemonWithAbility) return ["" + set.ability + " is an invalid ability."];
let isBaseAbility = Object.values(template.abilities).map(toId).indexOf(abilityId) >= 0;
// Items must be fully validated here since we may pass a different item to the base set validator.
let item = this.tools.getItem(set.item);
if (item.id) {
if (!item.exists) return ["" + set.item + " is an invalid item."];
if (item.isUnreleased) return ["" + (set.name || set.species) + "'s item " + item.name + " is unreleased."];
}
let validSources = set.abilitySources = []; // evolutionary families
for (let i = 0; i < pokemonWithAbility.length; i++) {
let donorTemplate = this.tools.getTemplate(pokemonWithAbility[i]);
let evoFamily = this.format.getEvoFamily(donorTemplate);
if (validSources.indexOf(evoFamily) >= 0) {
// The existence of a legal set has already been established.
// We only keep iterating to find all legal donor families (Donor Clause).
// Skip this redundant iteration.
continue;
}
if (set.name === set.species) delete set.name;
else if (toId(donorTemplate.species) !== toId(set.species) && donorTemplate.isMega) {
problems = [template.species+" is inheriting from a Mega Pokemon, which is banned."];
continue;
} else if (donorTemplate.tier === "Uber" || donorTemplate.tier === "Bank-Uber") {
problems = [template.species+" is inheriting from an Uber, which is banned."];
continue;
}
else if (toId(donorTemplate.species) !== (set.species) && toId(donorTemplate.speciesid ) in this.format.customBans.receiver) {
problems = [template.species+" is inheriting from an Uber, which is banned."];
continue;
}
set.species = donorTemplate.species;
if (donorTemplate.species !== template.species && donorTemplate.requiredItem) {
// Bypass forme validation. Relevant to inherit from Giratina-O, and Mega/Primal formes.
set.item = donorTemplate.requiredItem;
}
problems = this.validateSet(set, teamHas) || [];
if (!problems.length) {
validSources.push(evoFamily);
set.donorSpecies = donorTemplate.species;
}
if (validSources.length > 1) {
// This is an optimization only valid for the current basic implementation of Donor Clause.
// Remove if the FIXME? above actually gets fixed.
break;
}
}
// Restore the intended species, name and item.
set.species = template.species;
set.name = (name ? (name+" ("+set.donorSpecies+")") : (set.species+" ("+set.donorSpecies+")"));
set.item = item.name;
if (!validSources.length && pokemonWithAbility.length > 1) {
return ["" + (set.name || set.species) + " set is illegal."];
}
if (!validSources.length) {
problems.unshift("" + (set.name || set.species) + " has an illegal set with an ability from " + this.tools.getTemplate(pokemonWithAbility[0]).name+'.');
return problems;
}
},
onSwitchIn: function(pokemon) {
this.add('-start', pokemon, pokemon.donorSpecies || pokemon.species, '[silent]');
}
},
//mods/inh/scripts.js
'use strict';
exports.BattleScripts = {
init: function() {
this.getTeam = function (side, team) {
const format = this.getFormat();
const teamGenerator = typeof format.team === 'string' && format.team.startsWith('random') ? format.team + 'Team' : '';
if (!teamGenerator && team) return team;
// Reinitialize the RNG seed to create random teams.
this.seed = this.generateSeed();
this.startingSeed = this.startingSeed.concat(this.seed);
team = this[teamGenerator || 'randomTeam'](side);
// Restore the default seed
this.seed = this.startingSeed.slice(0, 4);
for(let i = 0 ;i < team.length ; i++) {
let arr = team[i].set.name.split(" ("), name = "";
team[i].donorSpecies = this.getTemplate(toId(arr[1])).species;
name = name+arr[0];
team[i].name = name;
team[i].set.name = name;
}
return team;
};
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment