Last active
January 6, 2017 13:28
-
-
Save Spandamn/f55e7a89aff5f76587ddfd7f0ec23592 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
name: "[Gen 7] Inheritance", | |
desc: [ | |
"Pokémon may use the ability and moves of another, as long as they forfeit their own learnset.", | |
"• <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