diff --git a/data/abilities.ts b/data/abilities.ts index 72f6e3f090..bb24816f5b 100644 --- a/data/abilities.ts +++ b/data/abilities.ts @@ -1375,8 +1375,8 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { this.singleEvent('WeatherChange', this.effect, this.effectState, pokemon); }, onWeatherChange(pokemon) { - if (!pokemon.isActive || pokemon.baseSpecies.baseSpecies !== 'Cherrim' || pokemon.transformed) return; - if (!pokemon.hp) return; + if (!pokemon.isActive || !pokemon.hp || pokemon.baseSpecies.baseSpecies !== 'Cherrim' || + pokemon.transformed) return; if (['sunnyday', 'desolateland'].includes(pokemon.effectiveWeather())) { if (pokemon.species.id !== 'cherrimsunshine') { pokemon.formeChange('Cherrim-Sunshine', this.effect, false, '0', '[msg]'); @@ -1387,6 +1387,13 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { } } }, + onEnd(pokemon) { + if (!pokemon.isActive || !pokemon.hp || pokemon.baseSpecies.baseSpecies !== 'Cherrim' || + pokemon.transformed || pokemon.beingCalledBack) return; + if (pokemon.species.id !== 'cherrim') { + pokemon.formeChange('Cherrim', this.effect, false, '0', '[msg]'); + } + }, onAllyModifyAtkPriority: 3, onAllyModifyAtk(atk, pokemon) { if (this.effectState.target.baseSpecies.baseSpecies !== 'Cherrim') return; @@ -1463,7 +1470,8 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { this.singleEvent('WeatherChange', this.effect, this.effectState, pokemon); }, onWeatherChange(pokemon) { - if (pokemon.baseSpecies.baseSpecies !== 'Castform' || pokemon.transformed) return; + if (!pokemon.isActive || !pokemon.hp || pokemon.baseSpecies.baseSpecies !== 'Castform' || + pokemon.transformed) return; let forme = null; switch (pokemon.effectiveWeather()) { case 'sunnyday': @@ -1482,10 +1490,17 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { if (pokemon.species.id !== 'castform') forme = 'Castform'; break; } - if (pokemon.isActive && forme) { + if (forme) { pokemon.formeChange(forme, this.effect, false, '0', '[msg]'); } }, + onEnd(pokemon) { + if (!pokemon.isActive || !pokemon.hp || pokemon.baseSpecies.baseSpecies !== 'Castform' || + pokemon.transformed || pokemon.beingCalledBack) return; + if (pokemon.species.id !== 'castform') { + pokemon.formeChange('Castform', this.effect, false, '0', '[msg]'); + } + }, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 }, name: "Forecast", rating: 2, @@ -2898,7 +2913,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { onSwitchIn(pokemon) { this.add('-ability', pokemon, 'Neutralizing Gas'); pokemon.abilityState.ending = false; - const strongWeathers = ['desolateland', 'primordialsea', 'deltastream']; + const strongWeathers = ['desolateland', 'primordialsea', 'deltastream', 'flowergift', 'forecast']; for (const target of this.getAllActive()) { if (target.hasItem('Ability Shield')) { this.add('-block', target, 'item: Ability Shield'); diff --git a/data/mods/gen4/abilities.ts b/data/mods/gen4/abilities.ts index a9d7b79746..d19518b4fd 100644 --- a/data/mods/gen4/abilities.ts +++ b/data/mods/gen4/abilities.ts @@ -2,9 +2,6 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa airlock: { inherit: true, onSwitchIn: undefined, // no inherit - onStart(pokemon) { - pokemon.abilityState.ending = false; - }, }, angerpoint: { inherit: true, @@ -37,9 +34,6 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa cloudnine: { inherit: true, onSwitchIn: undefined, // no inherit - onStart(pokemon) { - pokemon.abilityState.ending = false; - }, }, colorchange: { inherit: true, @@ -135,12 +129,15 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa }, flowergift: { inherit: true, - onAllyModifyAtk(atk) { + onStart: undefined, // no inherit + onWeatherChange: undefined, // no inherit + onEnd: undefined, // no inherit + onAllyModifyAtk() { if (this.field.isWeather('sunnyday')) { return this.chainModify(1.5); } }, - onAllyModifySpD(spd) { + onAllyModifySpD() { if (this.field.isWeather('sunnyday')) { return this.chainModify(1.5); } @@ -149,6 +146,28 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa }, forecast: { inherit: true, + onWeatherChange(pokemon) { + if (!pokemon.isActive || !pokemon.hp || pokemon.species.baseSpecies !== 'Castform') return; + let forme = null; + switch (pokemon.effectiveWeather()) { + case 'sunnyday': + if (pokemon.species.id !== 'castformsunny') forme = 'Castform-Sunny'; + break; + case 'raindance': + if (pokemon.species.id !== 'castformrainy') forme = 'Castform-Rainy'; + break; + case 'hail': + if (pokemon.species.id !== 'castformsnowy') forme = 'Castform-Snowy'; + break; + default: + if (pokemon.species.id !== 'castform') forme = 'Castform'; + break; + } + if (forme) { + pokemon.formeChange(forme, this.effect, false, '0', '[msg]'); + } + }, + onEnd: undefined, // no inherit flags: { notrace: 1 }, }, forewarn: { diff --git a/data/mods/gen4/conditions.ts b/data/mods/gen4/conditions.ts index 1f1d1a2dae..96d09c2851 100644 --- a/data/mods/gen4/conditions.ts +++ b/data/mods/gen4/conditions.ts @@ -173,4 +173,23 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa } }, }, + cherrim: { + name: "Cherrim", + onSwitchIn(pokemon) { + this.singleEvent('WeatherChange', this.effect, this.effectState, pokemon); + }, + onWeatherChange(pokemon) { + if (!pokemon.isActive || !pokemon.hp) return; + this.debug('Cherrim form change check'); + if (pokemon.effectiveWeather() === 'sunnyday') { + if (pokemon.species.id !== 'cherrimsunshine') { + pokemon.formeChange('Cherrim-Sunshine', null, false, '0', '[msg]'); + } + } else { + if (pokemon.species.id === 'cherrimsunshine') { + pokemon.formeChange('Cherrim', null, false, '0', '[msg]'); + } + } + }, + }, }; diff --git a/sim/battle.ts b/sim/battle.ts index c616ee74e3..4ec3172c81 100644 --- a/sim/battle.ts +++ b/sim/battle.ts @@ -1128,7 +1128,7 @@ export class Battle { effect: item, callback, state: pokemon.itemState, end: pokemon.clearItem, effectHolder: pokemon, }, callbackName)); } - const species = pokemon.baseSpecies; + const species = this.gen >= 5 ? pokemon.baseSpecies : pokemon.species; callback = this.getCallback(pokemon, species, callbackName); if (callback !== undefined) { handlers.push(this.resolvePriority({ diff --git a/test/sim/abilities/flowergift.js b/test/sim/abilities/flowergift.js index af125bb07d..5c74b5cb0d 100644 --- a/test/sim/abilities/flowergift.js +++ b/test/sim/abilities/flowergift.js @@ -77,4 +77,38 @@ describe('Flower Gift', () => { assert.equal(battle.field.weather, 'sunnyday'); assert.species(battle.p1.active[0], 'Cherrim'); }); + + describe('[Gen 4]', () => { + it(`Cherrim should transform without Flower Gift`, () => { + battle = common.gen(4).createBattle([[ + { species: 'Cherrim', ability: 'pressure', moves: ['sleeptalk'] }, + ], [ + { species: 'Torkoal', ability: 'drought', moves: ['sleeptalk'] }, + { species: 'Bulbasaur', ability: 'drizzle', moves: ['sleeptalk'] }, + ]]); + assert.equal(battle.field.weather, 'sunnyday'); + assert.species(battle.p1.active[0], 'Cherrim-Sunshine'); + battle.makeChoices('auto', 'switch 2'); + assert.equal(battle.field.weather, 'raindance'); + assert.species(battle.p1.active[0], 'Cherrim'); + }); + + it(`transformed Cherrim should transform without Flower Gift`, () => { + battle = common.gen(4).createBattle([[ + { species: 'Ditto', moves: ['transform'] }, + ], [ + { species: 'Cherrim', moves: ['sleeptalk'] }, + { species: 'Torkoal', ability: 'drought', moves: ['sleeptalk'] }, + { species: 'Bulbasaur', ability: 'drizzle', moves: ['sleeptalk'] }, + ]]); + battle.makeChoices(); + battle.makeChoices('move sleeptalk', 'switch 2'); + + assert.equal(battle.field.weather, 'sunnyday'); + assert.species(battle.p1.active[0], 'Cherrim-Sunshine'); + battle.makeChoices('auto', 'switch 3'); + assert.equal(battle.field.weather, 'raindance'); + assert.species(battle.p1.active[0], 'Cherrim'); + }); + }); }); diff --git a/test/sim/abilities/forecast.js b/test/sim/abilities/forecast.js new file mode 100644 index 0000000000..579f86c05e --- /dev/null +++ b/test/sim/abilities/forecast.js @@ -0,0 +1,36 @@ +'use strict'; + +const assert = require('./../../assert'); +const common = require('./../../common'); + +let battle; + +describe('Forecast', () => { + afterEach(() => { + battle.destroy(); + }); + + it(`should revert form if it loses its ability`, () => { + battle = common.createBattle([[ + { species: "Castform", ability: 'forecast', moves: ['sleeptalk'] }, + ], [ + { species: "Groudon", ability: 'drought', moves: ['skillswap'] }, + ]]); + assert.species(battle.p1.active[0], 'Castform-Sunny'); + battle.makeChoices(); + assert.species(battle.p1.active[0], 'Castform'); + }); + + describe('[Gen 4]', () => { + it(`should not revert form if it loses its ability`, () => { + battle = common.gen(4).createBattle([[ + { species: "Castform", ability: 'forecast', moves: ['sleeptalk'] }, + ], [ + { species: "Groudon", ability: 'drought', moves: ['skillswap'] }, + ]]); + assert.species(battle.p1.active[0], 'Castform-Sunny'); + battle.makeChoices(); + assert.species(battle.p1.active[0], 'Castform-Sunny'); + }); + }); +}); diff --git a/test/sim/abilities/neutralizinggas.js b/test/sim/abilities/neutralizinggas.js index b48b7a4643..ef66f6e0ba 100644 --- a/test/sim/abilities/neutralizinggas.js +++ b/test/sim/abilities/neutralizinggas.js @@ -171,6 +171,17 @@ describe('Neutralizing Gas', () => { assert(battle.log.some(line => line.includes('|-end|p1a: Zoroark|Illusion'))); }); + it(`should cause Cherrim-Sunshine to instantly revert form`, () => { + battle = common.createBattle([[ + { species: "Cherrim", ability: 'flowergift', moves: ['sleeptalk'] }, + ], [ + { species: "Torkoal", ability: 'drought', moves: ['sleeptalk'] }, + { species: "Weezing", ability: 'neutralizinggas', moves: ['sleeptalk'] }, + ]]); + battle.makeChoices('auto', 'switch 2'); + assert.species(battle.p1.active[0], 'Cherrim'); + }); + it(`should cause Slow Start to instantly wear off/restart when Neutralizing Gas leaves/enters the field`, () => { battle = common.createBattle([[ { species: "Regigigas", ability: 'slowstart', moves: ['sleeptalk'] },