Jofthomas's picture
Upload 4781 files
5c2ed06 verified
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
stealthrock: {
inherit: true,
condition: {
// this is a side condition
onSideStart(side, source) {
this.add('-sidestart', side, 'move: Stealth Rock');
},
onSwitchIn(pokemon) {
const calc = calculate(this, this.effectState.source, pokemon, 'stealthrock');
if (pokemon.hasItem('heavydutyboots') || !calc) return;
this.damage(calc * pokemon.maxhp / 8);
},
},
},
gmaxsteelsurge: {
inherit: true,
condition: {
// this is a side condition
onSideStart(side, source) {
this.add('-sidestart', side, 'move: G-Max Steelsurge');
},
onSwitchIn(pokemon) {
const calc = calculate(this, this.effectState.source, pokemon, 'stealthrock');
if (pokemon.hasItem('heavydutyboots') || !calc) return;
this.damage(calc * pokemon.maxhp / 8);
},
},
},
spikes: {
inherit: true,
condition: {
// this is a side condition
onSideStart(side, source) {
this.add('-sidestart', side, 'Spikes');
this.effectState.layers = 1;
},
onSideRestart(side, source) {
if (this.effectState.layers >= 3) return false;
this.add('-sidestart', side, 'Spikes');
this.effectState.layers++;
},
onSwitchIn(pokemon) {
const calc = calculate(this, this.effectState.source, pokemon, 'spikes');
if (!calc || !pokemon.isGrounded() || pokemon.hasItem('heavydutyboots')) return;
const damageAmounts = [0, 3, 4, 6]; // 1/8, 1/6, 1/4
this.damage(calc * damageAmounts[this.effectState.layers] * pokemon.maxhp / 24);
},
},
},
axekick: {
inherit: true,
onMoveFail(target, source, move) {
const calc = calculate(this, source, source, 'axekick');
if (calc) this.damage(calc * source.baseMaxhp / 2, source, source, this.dex.conditions.get('High Jump Kick'));
},
},
curse: {
inherit: true,
condition: {
onStart(pokemon, source) {
this.add('-start', pokemon, 'Curse', `[of] ${source}`);
},
onResidualOrder: 12,
onResidual(pokemon) {
const calc = calculate(this, this.effectState.source, pokemon, 'curse');
if (calc) this.damage(calc * pokemon.baseMaxhp / 4);
},
},
},
firepledge: {
inherit: true,
condition: {
duration: 4,
onSideStart(targetSide, source) {
this.add('-sidestart', targetSide, 'Fire Pledge');
},
onResidualOrder: 5,
onResidualSubOrder: 1,
onResidual(pokemon) {
const calc = calculate(this, this.effectState.source, pokemon, 'firepledge');
if (!pokemon.hasType('Fire') && calc) this.damage(calc * pokemon.baseMaxhp / 8, pokemon);
},
onSideResidualOrder: 26,
onSideResidualSubOrder: 8,
onSideEnd(targetSide) {
this.add('-sideend', targetSide, 'Fire Pledge');
},
},
},
flameburst: {
inherit: true,
onHit(target, source, move) {
for (const ally of target.adjacentAllies()) {
const calc = calculate(this, source, ally, 'flameburst');
if (calc) this.damage(calc * ally.baseMaxhp / 16, ally, source, this.dex.conditions.get('Flame Burst'));
}
},
onAfterSubDamage(damage, target, source, move) {
for (const ally of target.adjacentAllies()) {
const calc = calculate(this, source, ally, 'flameburst');
if (calc) this.damage(calc * ally.baseMaxhp / 16, ally, source, this.dex.conditions.get('Flame Burst'));
}
},
},
highjumpkick: {
inherit: true,
onMoveFail(target, source, move) {
const calc = calculate(this, source, source, 'highjumpkick');
if (calc) this.damage(calc * source.baseMaxhp / 2, source, source, this.dex.conditions.get('High Jump Kick'));
},
},
jumpkick: {
inherit: true,
onMoveFail(target, source, move) {
const calc = calculate(this, source, source, 'jumpkick');
if (calc) this.damage(calc * source.baseMaxhp / 2, source, source, this.dex.conditions.get('Jump Kick'));
},
},
leechseed: {
inherit: true,
condition: {
onStart(target, source) {
this.add('-start', target, 'move: Leech Seed');
},
onResidualOrder: 8,
onResidual(pokemon) {
const target = this.getAtSlot(pokemon.volatiles['leechseed'].sourceSlot);
if (!target || target.fainted || target.hp <= 0) {
this.debug('Nothing to leech into');
return;
}
const calc = calculate(this, this.effectState.source, pokemon, 'leechseed');
const damage = this.damage(calc * pokemon.baseMaxhp / 8, pokemon, target);
if (damage) {
this.heal(damage, target, pokemon);
}
},
},
},
mindblown: {
inherit: true,
onAfterMove(pokemon, target, move) {
if (move.mindBlownRecoil && !move.multihit) {
const hpBeforeRecoil = pokemon.hp;
const calc = calculate(this, pokemon, pokemon, 'mindblown');
this.damage(Math.round(calc * pokemon.maxhp / 2), pokemon, pokemon, this.dex.conditions.get('Mind Blown'), true);
if (pokemon.hp <= pokemon.maxhp / 2 && hpBeforeRecoil > pokemon.maxhp / 2) {
this.runEvent('EmergencyExit', pokemon, pokemon);
}
}
},
},
nightmare: {
inherit: true,
condition: {
noCopy: true,
onStart(pokemon, source) {
if (pokemon.status !== 'slp' && !pokemon.hasAbility('comatose')) {
return false;
}
this.add('-start', pokemon, 'Nightmare');
this.effectState.source = source;
},
onResidualOrder: 11,
onResidual(pokemon) {
const calc = calculate(this, this.effectState.source, pokemon, 'nightmare');
if (calc) this.damage(calc * pokemon.baseMaxhp / 4);
},
},
},
powder: {
inherit: true,
condition: {
duration: 1,
onStart(target, source) {
this.add('-singleturn', target, 'Powder');
},
onTryMovePriority: -1,
onTryMove(pokemon, target, move) {
if (move.type === 'Fire') {
this.add('-activate', pokemon, 'move: Powder');
const calc = calculate(this, this.effectState.source, pokemon, 'powder');
if (calc) this.damage(this.clampIntRange(Math.round(calc * pokemon.maxhp / 4), 1));
this.attrLastMove('[still]');
return false;
}
},
},
},
saltcure: {
inherit: true,
condition: {
noCopy: true,
onStart(pokemon, source) {
this.add('-start', pokemon, 'Salt Cure');
this.effectState.source = source;
},
onResidualOrder: 13,
onResidual(pokemon) {
const calc = calculate(this, this.effectState.source, pokemon, 'saltcure');
if (calc) this.damage(calc * pokemon.baseMaxhp / (pokemon.hasType(['Water', 'Steel']) ? 4 : 8));
},
onEnd(pokemon) {
this.add('-end', pokemon, 'Salt Cure');
},
},
},
spikyshield: {
inherit: true,
condition: {
duration: 1,
onStart(target) {
this.add('-singleturn', target, 'move: Protect');
},
onTryHitPriority: 3,
onTryHit(target, source, move) {
if (!move.flags['protect']) {
if (['gmaxoneblow', 'gmaxrapidflow'].includes(move.id)) return;
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
return;
}
if (move.smartTarget) {
move.smartTarget = false;
} else {
this.add('-activate', target, 'move: Protect');
}
const lockedmove = source.getVolatile('lockedmove');
if (lockedmove) {
// Outrage counter is reset
if (source.volatiles['lockedmove'].duration === 2) {
delete source.volatiles['lockedmove'];
}
}
const calc = calculate(this, target, source, 'spikyshield');
if (this.checkMoveMakesContact(move, source, target) && calc) {
this.damage(calc * source.baseMaxhp / 8, source, target);
}
return this.NOT_FAIL;
},
onHit(target, source, move) {
const calc = calculate(this, target, source, 'spikyshield');
if (calc && move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) {
this.damage(calc * source.baseMaxhp / 8, source, target);
}
},
},
},
steelbeam: {
inherit: true,
onAfterMove(pokemon, target, move) {
if (move.mindBlownRecoil && !move.multihit) {
const hpBeforeRecoil = pokemon.hp;
const calc = calculate(this, pokemon, pokemon, 'steelbeam');
this.damage(Math.round(calc * pokemon.maxhp / 2), pokemon, pokemon, this.dex.conditions.get('Steel Beam'), true);
if (pokemon.hp <= pokemon.maxhp / 2 && hpBeforeRecoil > pokemon.maxhp / 2) {
this.runEvent('EmergencyExit', pokemon, pokemon);
}
}
},
},
supercellslam: {
inherit: true,
onMoveFail(target, source, move) {
const calc = calculate(this, source, source, 'supercellslam');
if (calc) this.damage(calc * source.baseMaxhp / 2, source, source, this.dex.conditions.get('Supercell Slam'));
},
},
toxicspikes: {
inherit: true,
condition: {
// this is a side condition
onSideStart(side) {
this.add('-sidestart', side, 'move: Toxic Spikes');
this.effectState.layers = 1;
},
onSideRestart(side) {
if (this.effectState.layers >= 2) return false;
this.add('-sidestart', side, 'move: Toxic Spikes');
this.effectState.layers++;
},
onSwitchIn(pokemon) {
if (!pokemon.isGrounded()) return;
if (pokemon.hasType('Poison')) {
this.add('-sideend', pokemon.side, 'move: Toxic Spikes', `[of] ${pokemon}`);
pokemon.side.removeSideCondition('toxicspikes');
} else if (pokemon.hasType('Steel') || pokemon.hasItem('heavydutyboots')) {
// do nothing
} else if (this.effectState.layers >= 2) {
pokemon.trySetStatus('tox', this.effectState.source);
} else {
pokemon.trySetStatus('psn', this.effectState.source);
}
},
},
},
};
function calculate(battle: Battle, source: Pokemon, pokemon: Pokemon, moveid = 'tackle') {
const move = battle.dex.getActiveMove(moveid);
move.type = source.getTypes()[0];
const typeMod = 2 ** battle.clampIntRange(pokemon.runEffectiveness(move), -6, 6);
if (!pokemon.runImmunity(move.type)) return 0;
return typeMod;
}