mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-04-26 10:48:53 -05:00
Gen 4: Fix Assist/Copycat/Metronome under Gravity/Heal Block (#10757)
* Gen 4: Fix Assist/Copycat/Metronome under Gravity/Heal Block * Update data/mods/gen4/moves.ts * Update data/mods/gen4/moves.ts * Remove unnecessary checks * prefer const --------- Co-authored-by: Kris Johnson <11083252+KrisXV@users.noreply.github.com>
This commit is contained in:
parent
eb935a4aca
commit
11679e3cef
|
|
@ -47,6 +47,33 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
assist: {
|
||||||
|
inherit: true,
|
||||||
|
onHit(target) {
|
||||||
|
const moves = [];
|
||||||
|
for (const pokemon of target.side.pokemon) {
|
||||||
|
if (pokemon === target) continue;
|
||||||
|
for (const moveSlot of pokemon.moveSlots) {
|
||||||
|
const moveid = moveSlot.id;
|
||||||
|
const move = this.dex.moves.get(moveid);
|
||||||
|
if (
|
||||||
|
move.flags['noassist'] ||
|
||||||
|
(this.field.pseudoWeather['gravity'] && move.flags['gravity']) ||
|
||||||
|
(target.volatiles['healblock'] && move.flags['heal'])
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
moves.push(moveid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let randomMove = '';
|
||||||
|
if (moves.length) randomMove = this.sample(moves);
|
||||||
|
if (!randomMove) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.actions.useMove(randomMove, target);
|
||||||
|
},
|
||||||
|
},
|
||||||
beatup: {
|
beatup: {
|
||||||
inherit: true,
|
inherit: true,
|
||||||
basePower: 10,
|
basePower: 10,
|
||||||
|
|
@ -198,6 +225,22 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||||
this.add('-start', target, 'typechange', type);
|
this.add('-start', target, 'typechange', type);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
copycat: {
|
||||||
|
inherit: true,
|
||||||
|
onHit(pokemon) {
|
||||||
|
const move: Move | ActiveMove | null = this.lastMove;
|
||||||
|
if (!move) return;
|
||||||
|
|
||||||
|
if (
|
||||||
|
move.flags['failcopycat'] ||
|
||||||
|
(this.field.pseudoWeather['gravity'] && move.flags['gravity']) ||
|
||||||
|
(pokemon.volatiles['healblock'] && move.flags['heal'])
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.actions.useMove(move.id, pokemon);
|
||||||
|
},
|
||||||
|
},
|
||||||
cottonspore: {
|
cottonspore: {
|
||||||
inherit: true,
|
inherit: true,
|
||||||
accuracy: 85,
|
accuracy: 85,
|
||||||
|
|
@ -1007,6 +1050,23 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||||
metronome: {
|
metronome: {
|
||||||
inherit: true,
|
inherit: true,
|
||||||
flags: {noassist: 1, failcopycat: 1, nosleeptalk: 1, failmimic: 1},
|
flags: {noassist: 1, failcopycat: 1, nosleeptalk: 1, failmimic: 1},
|
||||||
|
onHit(pokemon) {
|
||||||
|
const moves = this.dex.moves.all().filter(move => (
|
||||||
|
(![2, 4].includes(this.gen) || !pokemon.moves.includes(move.id)) &&
|
||||||
|
(!move.isNonstandard || move.isNonstandard === 'Unobtainable') &&
|
||||||
|
move.flags['metronome'] &&
|
||||||
|
!(this.field.pseudoWeather['gravity'] && move.flags['gravity']) &&
|
||||||
|
!(pokemon.volatiles['healblock'] && move.flags['heal'])
|
||||||
|
));
|
||||||
|
let randomMove = '';
|
||||||
|
if (moves.length) {
|
||||||
|
moves.sort((a, b) => a.num - b.num);
|
||||||
|
randomMove = this.sample(moves).id;
|
||||||
|
}
|
||||||
|
if (!randomMove) return false;
|
||||||
|
pokemon.side.lastSelectedMove = this.toID(randomMove);
|
||||||
|
this.actions.useMove(randomMove, pokemon);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mimic: {
|
mimic: {
|
||||||
inherit: true,
|
inherit: true,
|
||||||
|
|
|
||||||
|
|
@ -12184,9 +12184,8 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
||||||
pp: 10,
|
pp: 10,
|
||||||
priority: 0,
|
priority: 0,
|
||||||
flags: {failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failmimic: 1, failinstruct: 1},
|
flags: {failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failmimic: 1, failinstruct: 1},
|
||||||
onHit(target, source, effect) {
|
onHit(pokemon) {
|
||||||
const moves = this.dex.moves.all().filter(move => (
|
const moves = this.dex.moves.all().filter(move => (
|
||||||
(![2, 4].includes(this.gen) || !source.moves.includes(move.id)) &&
|
|
||||||
(!move.isNonstandard || move.isNonstandard === 'Unobtainable') &&
|
(!move.isNonstandard || move.isNonstandard === 'Unobtainable') &&
|
||||||
move.flags['metronome']
|
move.flags['metronome']
|
||||||
));
|
));
|
||||||
|
|
@ -12196,8 +12195,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
||||||
randomMove = this.sample(moves).id;
|
randomMove = this.sample(moves).id;
|
||||||
}
|
}
|
||||||
if (!randomMove) return false;
|
if (!randomMove) return false;
|
||||||
source.side.lastSelectedMove = this.toID(randomMove);
|
this.actions.useMove(randomMove, pokemon);
|
||||||
this.actions.useMove(randomMove, target);
|
|
||||||
},
|
},
|
||||||
callsMove: true,
|
callsMove: true,
|
||||||
secondary: null,
|
secondary: null,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ Check the test/ directory to see if a file already exists for the effect that yo
|
||||||
it(`test should start here`, function () {
|
it(`test should start here`, function () {
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
To create the battle, use common.createBattle and pass in two arrays of teams. You can add additional flags as well:
|
To create the battle, use common.createBattle and pass in two arrays of teams. You can add additional flags as well:
|
||||||
- gameType: 'doubles', 'triples', 'multi', 'freeforall', etc (tests default to singles)
|
- gameType: 'doubles', 'triples', 'multi', 'freeforall', etc (tests default to singles)
|
||||||
|
|
|
||||||
42
test/sim/moves/assist.js
Normal file
42
test/sim/moves/assist.js
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('./../../assert');
|
||||||
|
const common = require('./../../common');
|
||||||
|
|
||||||
|
let battle;
|
||||||
|
|
||||||
|
describe(`[Gen 4] Assist`, function () {
|
||||||
|
afterEach(function () {
|
||||||
|
battle.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should never call moves that would fail under Gravity`, function () {
|
||||||
|
battle = common.gen(4).createBattle([[
|
||||||
|
{species: 'furret', moves: ['assist']},
|
||||||
|
{species: 'smeargle', moves: ['bounce', 'fly', 'highjumpkick', 'splash']},
|
||||||
|
{species: 'smeargle', moves: ['bounce', 'fly', 'highjumpkick', 'splash']},
|
||||||
|
{species: 'smeargle', moves: ['bounce', 'fly', 'highjumpkick', 'splash']},
|
||||||
|
{species: 'smeargle', moves: ['doubleteam', 'fly', 'highjumpkick', 'splash']},
|
||||||
|
{species: 'smeargle', moves: ['bounce', 'fly', 'highjumpkick', 'splash']},
|
||||||
|
], [
|
||||||
|
{species: 'deoxys', moves: ['gravity']},
|
||||||
|
]]);
|
||||||
|
for (let i = 0; i < 5; i++) battle.makeChoices();
|
||||||
|
assert.statStage(battle.p1.active[0], 'evasion', 5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should never call moves that would fail under Heal Block`, function () {
|
||||||
|
battle = common.gen(4).createBattle([[
|
||||||
|
{species: 'furret', moves: ['assist']},
|
||||||
|
{species: 'smeargle', moves: ['recover', 'rest', 'roost', 'wish']},
|
||||||
|
{species: 'smeargle', moves: ['recover', 'rest', 'doubleteam', 'wish']},
|
||||||
|
{species: 'smeargle', moves: ['recover', 'rest', 'roost', 'wish']},
|
||||||
|
{species: 'smeargle', moves: ['recover', 'rest', 'roost', 'wish']},
|
||||||
|
{species: 'smeargle', moves: ['recover', 'rest', 'roost', 'wish']},
|
||||||
|
], [
|
||||||
|
{species: 'latios', moves: ['healblock']},
|
||||||
|
]]);
|
||||||
|
for (let i = 0; i < 5; i++) battle.makeChoices();
|
||||||
|
assert.statStage(battle.p1.active[0], 'evasion', 5);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user