Add Guaranteed Secondary Mod
Some checks are pending
Node.js CI / build (18.x) (push) Waiting to run

This is currently for tests, but does have the side effect of plausibly
being fun as an actual mod to add to games.
This commit is contained in:
Guangcong Luo 2025-03-13 15:34:47 -07:00
parent 75533cca60
commit ae22234ed0
5 changed files with 23 additions and 30 deletions

View File

@ -2119,6 +2119,19 @@ export const Rulesets: import('../sim/dex-formats').FormatDataTable = {
pokemon.trapped = true;
},
},
guaranteedsecondarymod: {
effectType: 'Rule',
name: 'Guaranteed Secondary Mod',
desc: 'All moves\' secondary effect chances are set to 100% (Tri Attack and Dire Claw set a random status; Poison Touch is not a real secondary and remains at 30%).',
onModifyMove(move) {
if (move.secondaries) {
this.debug('Freeze test: Guaranteeing secondary');
for (const secondary of move.secondaries) {
secondary.chance = 100;
}
}
},
},
chimera1v1rule: {
effectType: 'Rule',
name: 'Chimera 1v1 Rule',

View File

@ -59,6 +59,7 @@ class TestTools {
options.endlessBattleClause ? '^Endless Battle Clause' : '^!Endless Battle Clause',
options.inverseMod && 'Inverse Mod',
options.overflowStatMod && 'Overflow Stat Mod',
options.customRules,
].filter(Boolean);
const customRulesID = customRules.length ? `@@@${customRules.join(',')}` : ``;

View File

@ -5,7 +5,7 @@ const common = require('./../common');
let battle;
describe('Battle#on', () => {
describe('Battle#onEvent', () => {
afterEach(() => {
battle.destroy();
});

View File

@ -182,37 +182,24 @@ describe('Freeze', () => {
});
it('should cause an afflicted Shaymin-Sky to revert to its base forme', () => {
battle = common.createBattle([
battle = common.createBattle({
customRules: 'guaranteedsecondarymod',
}, [
[{ species: 'Chansey', ability: 'serenegrace', moves: ['icebeam'] }],
[{ species: 'Shaymin-Sky', ability: 'sturdy', moves: ['sleeptalk'] }],
]);
// I didn't feel like manually testing seed after seed. Sue me.
battle.onEvent('ModifyMove', battle.format, function (move) {
if (move.secondaries) {
this.debug('Freeze test: Guaranteeing secondary');
for (const secondary of move.secondaries) {
secondary.chance = 100;
}
}
});
battle.makeChoices('move icebeam', 'move sleeptalk');
assert.equal(battle.p2.active[0].status, 'frz');
assert.equal(battle.p2.active[0].species.name, 'Shaymin');
});
it('should not cause an afflicted Pokemon transformed into Shaymin-Sky to change to Shaymin', () => {
battle = common.createBattle([
battle = common.createBattle({
customRules: 'guaranteedsecondarymod',
}, [
[{ species: 'Ditto', ability: 'imposter', moves: ['transform'] }],
[{ species: 'Shaymin-Sky', ability: 'sturdy', moves: ['icebeam', 'sleeptalk'] }],
]);
battle.onEvent('ModifyMove', battle.format, function (move) {
if (move.secondaries) {
this.debug('Freeze test: Guaranteeing secondary');
for (const secondary of move.secondaries) {
secondary.chance = 100;
}
}
});
battle.makeChoices('move sleeptalk', 'move icebeam');
assert.equal(battle.p1.active[0].status, 'frz');
assert.equal(battle.p1.active[0].species.name, 'Shaymin-Sky');
@ -220,21 +207,13 @@ describe('Freeze', () => {
it('should not linger after fainting from switch-out', () => {
battle = common.createBattle({
formatid: 'gen4customgame@@@freezeclausemod',
formatid: 'gen4customgame@@@freezeclausemod,guaranteedsecondarymod',
}, [[
{ species: 'weavile', moves: ['icebeam', 'pursuit'] },
], [
{ species: 'gastly', moves: ['splash'] },
{ species: 'seaking', moves: ['splash'] },
]]);
battle.onEvent('ModifyMove', battle.format, function (move) {
if (move.secondaries) {
this.debug('Freeze test: Guaranteeing secondary');
for (const secondary of move.secondaries) {
secondary.chance = 100;
}
}
});
battle.makeChoices('move icebeam', 'auto');
battle.makeChoices('move pursuit', 'switch seaking');
// battle.makeChoices('', 'switch seaking'); // in modern gens

View File

@ -78,7 +78,7 @@ describe('Substitute', () => {
battle.makeChoices('move highjumpkick', 'move agility');
// Modding accuracy so High Jump Kick will miss and cause recoil
battle.onEvent('Accuracy', battle.format, true);
battle.onEvent('Accuracy', battle.format, false);
battle.makeChoices('move highjumpkick', 'move agility');
// Only P1 has a substitute, so no one takes recoil damage.