mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-06-02 22:08:36 -05:00
Add Fortemons (#9305)
* Add Fortemons * Fix validation * Apply suggestions from code review Co-authored-by: Alexander B. <4866817+MathyFurret@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Alexander B. <4866817+MathyFurret@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Alexander B. <4866817+MathyFurret@users.noreply.github.com> * Do some suggestion things * Apply suggestions from code review Co-authored-by: Alexander B. <4866817+MathyFurret@users.noreply.github.com> * ficks build Co-authored-by: Alexander B. <4866817+MathyFurret@users.noreply.github.com>
This commit is contained in:
parent
0921ba3112
commit
65c2c96009
|
|
@ -895,6 +895,135 @@ export const Formats: FormatList = [
|
|||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[Gen 9] Fortemons",
|
||||
desc: `Put an attacking move in the item slot to have all of a Pokémon's attacks inherit its properties.`,
|
||||
threads: [
|
||||
`• <a href="https://www.smogon.com/forums/threads/3713983/">Fortemons</a>`,
|
||||
],
|
||||
|
||||
mod: 'gen9',
|
||||
searchShow: false,
|
||||
ruleset: ['Standard OMs', 'Sleep Clause Mod', 'Min Source Gen = 9'],
|
||||
banlist: ['Koraidon', 'Miraidon', 'Palafin', 'Covert Cloak', 'Fake Out'],
|
||||
restricted: ['Dynamic Punch', 'Inferno', 'Mud Slap', 'Nuzzle', 'Power Trip', 'Rapid Spin', 'Stored Power', 'Zap Cannon'],
|
||||
validateSet(set, teamHas) {
|
||||
const item = set.item;
|
||||
const species = this.dex.species.get(set.species);
|
||||
const move = this.dex.moves.get(item);
|
||||
if (!move.exists || move.id === 'metronome' || move.category === 'Status') {
|
||||
return this.validateSet(set, teamHas);
|
||||
}
|
||||
set.item = '';
|
||||
const problems = this.validateSet(set, teamHas) || [];
|
||||
set.item = item;
|
||||
if (this.checkCanLearn(move, species, this.allSources(species), set)) {
|
||||
problems.push(`${species.name} can't learn ${move.name}.`);
|
||||
}
|
||||
if ((move.secondaries?.some(secondary => secondary.boosts?.accuracy && secondary.boosts.accuracy < 0) ||
|
||||
move.multihit || move.id === 'beatup' || move.flags['charge'] || move.priority > 0 || move.damageCallback) &&
|
||||
!this.ruleTable.has(`+move:${move.id}`)) {
|
||||
problems.push(`The move ${move.name} can't be used as an item.`);
|
||||
}
|
||||
return problems.length ? problems : null;
|
||||
},
|
||||
onBegin() {
|
||||
for (const pokemon of this.getAllPokemon()) {
|
||||
const move = this.dex.getActiveMove(pokemon.set.item);
|
||||
if (move.exists && move.category !== 'Status') {
|
||||
pokemon.m.forte = move;
|
||||
pokemon.item = 'mail' as ID;
|
||||
}
|
||||
}
|
||||
},
|
||||
onModifyMovePriority: 1,
|
||||
onModifyMove(move, pokemon, target) {
|
||||
const forte: ActiveMove = pokemon.m.forte;
|
||||
if (move.category !== 'Status' && forte) {
|
||||
move.flags = {...move.flags, ...forte.flags};
|
||||
if (forte.self) {
|
||||
if (forte.self.onHit && move.self?.onHit) {
|
||||
for (const i in forte.self) {
|
||||
if (i.startsWith('onHit')) continue;
|
||||
(move.self as any)[i] = (forte.self as any)[i];
|
||||
}
|
||||
} else {
|
||||
move.self = {...(move.self || {}), ...forte.self};
|
||||
}
|
||||
}
|
||||
if (forte.selfBoost?.boosts) {
|
||||
if (!move.selfBoost?.boosts) move.selfBoost = {boosts: {}};
|
||||
let boostid: BoostID;
|
||||
for (boostid in forte.selfBoost.boosts) {
|
||||
if (!move.selfBoost.boosts![boostid]) move.selfBoost.boosts![boostid] = 0;
|
||||
move.selfBoost.boosts![boostid]! += forte.selfBoost.boosts[boostid]!;
|
||||
}
|
||||
}
|
||||
if (forte.secondaries) {
|
||||
move.secondaries = [...(move.secondaries || []), ...forte.secondaries];
|
||||
}
|
||||
move.critRatio = (move.critRatio || 1) + (forte.critRatio || 1) - 1;
|
||||
const VALID_PROPERTIES = [
|
||||
'alwaysHit', 'basePowerCallback', 'breaksProtect', 'drain', 'forceSTAB', 'forceSwitch', 'hasCrashDamage', 'hasSheerForce',
|
||||
'ignoreAbility', 'ignoreAccuracy', 'ignoreDefensive', 'ignoreEvasion', 'ignoreImmunity', 'mindBlownRecoil', 'noDamageVariance',
|
||||
'ohko', 'overrideDefensivePokemon', 'overrideDefensiveStat', 'overrideOffensivePokemon', 'overrideOffensiveStat', 'pseudoWeather',
|
||||
'recoil', 'selfdestruct', 'selfSwitch', 'sleepUsable', 'smartTarget', 'stealsBoosts', 'thawsTarget', 'volatileStatus', 'willCrit',
|
||||
] as const;
|
||||
for (const property of VALID_PROPERTIES) {
|
||||
if (forte[property]) {
|
||||
move[property] = forte[property] as any;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onModifyPriority(priority, source, target, move) {
|
||||
if (move.category !== 'Status' && source?.m.forte) {
|
||||
if (source.hasAbility('Triage') && source.m.forte.flags['heal']) {
|
||||
return priority + (move.flags['heal'] ? 0 : 3);
|
||||
}
|
||||
return priority + source.m.forte.priority;
|
||||
}
|
||||
},
|
||||
onHitPriority: 1,
|
||||
onHit(target, source, move) {
|
||||
const forte = source.m.forte;
|
||||
if (move?.category !== 'Status' && forte) {
|
||||
if (forte.onHit) this.singleEvent('Hit', forte, {}, target, source, move);
|
||||
if (forte.self?.onHit) this.singleEvent('Hit', forte.self, {}, source, source, move);
|
||||
if (forte.onAfterHit) this.singleEvent('AfterHit', forte, {}, target, source, move);
|
||||
}
|
||||
},
|
||||
onAfterSubDamage(damage, target, source, move) {
|
||||
const forte = source.m.forte;
|
||||
if (move?.category !== 'Status' && forte?.onAfterSubDamage) {
|
||||
this.singleEvent('AfterSubDamage', forte, null, target, source, move);
|
||||
}
|
||||
},
|
||||
onModifySecondaries(secondaries, target, source, move) {
|
||||
if (secondaries.some(s => !!s.self)) move.selfDropped = false;
|
||||
},
|
||||
onAfterMoveSecondaryPriority: 1,
|
||||
onAfterMoveSecondarySelf(source, target, move) {
|
||||
const forte = source.m.forte;
|
||||
if (move?.category !== 'Status' && forte?.onAfterMoveSecondarySelf) {
|
||||
this.singleEvent('AfterMoveSecondarySelf', forte, null, source, target, move);
|
||||
}
|
||||
},
|
||||
onBasePowerPriority: 1,
|
||||
onBasePower(basePower, source, target, move) {
|
||||
const forte = source.m.forte;
|
||||
if (move.category !== 'Status' && forte?.onBasePower) {
|
||||
this.singleEvent('BasePower', forte, null, source, target, move, basePower);
|
||||
}
|
||||
},
|
||||
pokemon: {
|
||||
getItem() {
|
||||
const move = this.battle.dex.moves.get(this.m.forte);
|
||||
if (!move.exists) return Object.getPrototypeOf(this).getItem.call(this);
|
||||
return {...this.battle.dex.items.get('mail'), ignoreKlutz: true, onTakeItem: false};
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[Gen 9] Full Potential",
|
||||
desc: `Pokémon's moves hit off of their highest stat.`,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user