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:
Alex "Mathy 2025-01-04 14:17:12 -06:00 committed by GitHub
parent eb935a4aca
commit 11679e3cef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 105 additions and 5 deletions

View File

@ -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: {
inherit: true,
basePower: 10,
@ -198,6 +225,22 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
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: {
inherit: true,
accuracy: 85,
@ -1007,6 +1050,23 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
metronome: {
inherit: true,
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: {
inherit: true,

View File

@ -12184,9 +12184,8 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
pp: 10,
priority: 0,
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 => (
(![2, 4].includes(this.gen) || !source.moves.includes(move.id)) &&
(!move.isNonstandard || move.isNonstandard === 'Unobtainable') &&
move.flags['metronome']
));
@ -12196,8 +12195,7 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
randomMove = this.sample(moves).id;
}
if (!randomMove) return false;
source.side.lastSelectedMove = this.toID(randomMove);
this.actions.useMove(randomMove, target);
this.actions.useMove(randomMove, pokemon);
},
callsMove: true,
secondary: null,

View File

@ -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 () {
});
}
});
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)

42
test/sim/moves/assist.js Normal file
View 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);
});
});