mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-05-15 17:00:23 -05:00
137 lines
5.2 KiB
TypeScript
137 lines
5.2 KiB
TypeScript
export const Scripts: ModdedBattleScriptsData = {
|
|
init() {
|
|
const moddedLearnset = (mon: string, addedMoves: string[] | null, removedMoves: string[] | null = null) => {
|
|
if (addedMoves) {
|
|
for (const move of addedMoves) {
|
|
const modData = this.modData('Learnsets', this.toID(mon));
|
|
if (!(this.toID(move) in modData.learnset)) modData.learnset[this.toID(move)] = [];
|
|
modData.learnset[this.toID(move)].push("8M");
|
|
}
|
|
}
|
|
if (removedMoves) {
|
|
for (const move of removedMoves) {
|
|
delete this.modData('Learnsets', this.toID(mon)).learnset[this.toID(move)];
|
|
}
|
|
}
|
|
};
|
|
moddedLearnset('porygon2', null, ['teleport']);
|
|
moddedLearnset('jellicent', ['haze'], ['toxic', 'recover']);
|
|
moddedLearnset('crabominable', ['hammerarm', 'icehammer'], ['payback']);
|
|
moddedLearnset('oricorio', ['reflecttype'], ['calmmind']);
|
|
moddedLearnset('wigglytuff', ['earthquake', 'jumpkick'], ['teleport']);
|
|
moddedLearnset('wormadamtrash', ['spikes', 'healorder'], ['quiverdance']);
|
|
moddedLearnset('heatmor', ['dragondance'], ['knockoff', 'suckerpunch', 'thunderpunch']);
|
|
moddedLearnset('beheeyem', ['signalbeam'], ['psyshock']);
|
|
moddedLearnset('golbat', ['hurricane', 'poisonjab']);
|
|
moddedLearnset('eelektross', ['flipturn', 'surf', 'liquidation'], ['flamethrower', 'uturn']);
|
|
moddedLearnset('togedemaru', ['healbell']);
|
|
moddedLearnset('garchomp', ['scorchingsands'], ['crunch', 'swordsdance']);
|
|
moddedLearnset('whimsicott', ['morningsun', 'synthesis']);
|
|
moddedLearnset('skuntank', ['calmmind', 'powertrip', 'slackoff'], ['nastyplot']);
|
|
moddedLearnset('lycanrocdusk', ['crosschop', 'tripleaxel']);
|
|
moddedLearnset('frosmoth', ['roost'], ['hurricane', 'airslash', 'dazzlinggleam']);
|
|
moddedLearnset('dragonair', ['flipturn', 'hydropump'], ['blizzard', 'flamethrower', 'fireblast', 'icebeam']);
|
|
moddedLearnset('reshiram', ['haze'], ['blueflare', 'earthpower', 'focusblast']);
|
|
moddedLearnset('aegislash', null, ['closecombat', 'shadowsneak', 'swordsdance']);
|
|
moddedLearnset('camerupt', ['gigadrain', 'scorchingsands'], ['eruption']);
|
|
moddedLearnset('empoleon', ['flipturn']);
|
|
moddedLearnset('delibird', null, ['destinybond']);
|
|
},
|
|
// Modded functions
|
|
modifyDamage(
|
|
baseDamage: number, pokemon: Pokemon, target: Pokemon, move: ActiveMove, suppressMessages = false
|
|
) {
|
|
const tr = this.trunc;
|
|
if (!move.type) move.type = '???';
|
|
const type = move.type;
|
|
|
|
baseDamage += 2;
|
|
|
|
// multi-target modifier (doubles only)
|
|
if (move.spreadHit) {
|
|
const spreadModifier = move.spreadModifier || (this.gameType === 'free-for-all' ? 0.5 : 0.75);
|
|
this.debug('Spread modifier: ' + spreadModifier);
|
|
baseDamage = this.modify(baseDamage, spreadModifier);
|
|
}
|
|
|
|
// weather modifier
|
|
baseDamage = this.runEvent('WeatherModifyDamage', pokemon, target, move, baseDamage);
|
|
|
|
// crit - not a modifier
|
|
const isCrit = target.getMoveHitData(move).crit;
|
|
if (isCrit) {
|
|
baseDamage = tr(baseDamage * (move.critModifier || (this.gen >= 6 ? 1.5 : 2)));
|
|
}
|
|
|
|
// random factor - also not a modifier
|
|
baseDamage = this.randomizer(baseDamage);
|
|
|
|
// STAB
|
|
if (move.forceSTAB || (type !== '???' && pokemon.hasType(type))) {
|
|
// The "???" type never gets STAB
|
|
// Not even if you Roost in Gen 4 and somehow manage to use
|
|
// Struggle in the same turn.
|
|
// (On second thought, it might be easier to get a MissingNo.)
|
|
baseDamage = this.modify(baseDamage, move.stab || 1.5);
|
|
}
|
|
// types
|
|
let typeMod = target.runEffectiveness(move);
|
|
typeMod = this.clampIntRange(typeMod, -6, 6);
|
|
target.getMoveHitData(move).typeMod = typeMod;
|
|
if (typeMod > 0) {
|
|
if (!suppressMessages) this.add('-supereffective', target);
|
|
|
|
for (let i = 0; i < typeMod; i++) {
|
|
baseDamage *= 2;
|
|
}
|
|
}
|
|
if (typeMod < 0) {
|
|
if (!suppressMessages) this.add('-resisted', target);
|
|
|
|
for (let i = 0; i > typeMod; i--) {
|
|
baseDamage = tr(baseDamage / 2);
|
|
}
|
|
}
|
|
|
|
if (isCrit && !suppressMessages) this.add('-crit', target);
|
|
// ONLY PART THAT IS CHANGED
|
|
if (pokemon.status === 'brn' && move.category === 'Physical' && !pokemon.hasAbility('unflagging')) {
|
|
//
|
|
if (this.gen < 6 || move.id !== 'facade') {
|
|
baseDamage = this.modify(baseDamage, 0.5);
|
|
}
|
|
}
|
|
|
|
// Generation 5, but nothing later, sets damage to 1 before the final damage modifiers
|
|
if (this.gen === 5 && !baseDamage) baseDamage = 1;
|
|
|
|
// Final modifier. Modifiers that modify damage after min damage check, such as Life Orb.
|
|
baseDamage = this.runEvent('ModifyDamage', pokemon, target, move, baseDamage);
|
|
|
|
if ((move.isZOrMaxPowered || move.isZOrMaxPowered) && target.getMoveHitData(move).zBrokeProtect) {
|
|
baseDamage = this.modify(baseDamage, 0.25);
|
|
this.add('-zbroken', target);
|
|
}
|
|
|
|
// Generation 6-7 moves the check for minimum 1 damage after the final modifier...
|
|
if (this.gen !== 5 && !baseDamage) return 1;
|
|
|
|
// ...but 16-bit truncation happens even later, and can truncate to 0
|
|
return tr(baseDamage, 16);
|
|
},
|
|
pokemon: {
|
|
ignoringItem() {
|
|
let embargoAct = false;
|
|
for (const target of this.side.foe.active) {
|
|
if (target.hasAbility('embargoact')) {
|
|
embargoAct = true;
|
|
break;
|
|
}
|
|
}
|
|
return !!((this.battle.gen >= 5 && !this.isActive) ||
|
|
(this.hasAbility('klutz') && !this.getItem().ignoreKlutz) ||
|
|
this.volatiles['embargo'] || this.battle.field.pseudoWeather['magicroom'] || embargoAct);
|
|
},
|
|
},
|
|
};
|