From 3080eb85eaf5d7d66a4ee4ec1fba00491f70990a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Sun, 19 Jan 2025 17:12:40 +0000 Subject: [PATCH 1/6] Booster Energy activates on weather changes --- data/items.ts | 15 +++++++++++++++ test/sim/items/boosterenergy.js | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/data/items.ts b/data/items.ts index 99d707c02b1b..d8c6cb1cc80e 100644 --- a/data/items.ts +++ b/data/items.ts @@ -615,8 +615,23 @@ export const Items: import('../sim/dex-items').ItemDataTable = { basePower: 30, }, onStart() { + // don't trigger before hazards this.effectState.started = true; }, + onWeatherChange(pokemon) { + if (pokemon.transformed) return; + + if (pokemon.hasAbility('protosynthesis') && (this.field.isWeather('sunnyday') || pokemon.useItem())) { + pokemon.addVolatile('protosynthesis'); + } + }, + onTerrainChange(pokemon) { + if (pokemon.transformed) return; + + if (pokemon.hasAbility('quarkdrive') && (this.field.isTerrain('electricterrain') || pokemon.useItem())) { + pokemon.addVolatile('quarkdrive'); + } + }, onUpdate(pokemon) { if (!this.effectState.started || pokemon.transformed) return; if (this.queue.peek(true)?.choice === 'runSwitch') return; diff --git a/test/sim/items/boosterenergy.js b/test/sim/items/boosterenergy.js index 742f18a29ddb..a1c07349707e 100644 --- a/test/sim/items/boosterenergy.js +++ b/test/sim/items/boosterenergy.js @@ -24,4 +24,19 @@ describe('Booster Energy', function () { assert.equal(bundle.volatiles['quarkdrive'].bestStat, 'spa', `Iron Bundle's Speed should have been lowered before Booster Energy activated, boosting its SpA instead.`); }); + + it(`should activate right after weather changes`, function () { + battle = common.createBattle({gameType: 'doubles'}, [[ + {species: 'Ninetales-Alola', ability: 'snowwarning', moves: ['sleeptalk']}, + {species: 'Roaring Moon', item: 'boosterenergy', ability: 'protosynthesis', moves: ['sleeptalk']}, + ], [ + {species: 'Incineroar', ability: 'intimidate', moves: ['sleeptalk']}, + {species: 'Torkoal', ability: 'drought', moves: ['sleeptalk']}, + ]]); + + const roaringMoon = battle.p1.active[1]; + assert(roaringMoon.volatiles['protosynthesis'].fromBooster); + assert.equal(roaringMoon.volatiles['protosynthesis'].bestStat, 'atk'); + assert.equal(battle.field.weather, 'sunnyday'); + }); }); From 197dfebe189165742f2cf6038e43e55368bef3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Sun, 19 Jan 2025 17:24:54 +0000 Subject: [PATCH 2/6] Change comment place --- data/items.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/items.ts b/data/items.ts index d8c6cb1cc80e..b433c3250912 100644 --- a/data/items.ts +++ b/data/items.ts @@ -615,7 +615,6 @@ export const Items: import('../sim/dex-items').ItemDataTable = { basePower: 30, }, onStart() { - // don't trigger before hazards this.effectState.started = true; }, onWeatherChange(pokemon) { @@ -633,6 +632,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = { } }, onUpdate(pokemon) { + // don't trigger before hazards if (!this.effectState.started || pokemon.transformed) return; if (this.queue.peek(true)?.choice === 'runSwitch') return; From a7b1889add4490e10e4288bf225c5763c50d1007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Sun, 19 Jan 2025 17:36:51 +0000 Subject: [PATCH 3/6] Fix Shouldn't be done like that because of the source and source effect. It's already covered by the ability WeatherChange anyway. --- data/items.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/items.ts b/data/items.ts index b433c3250912..0d1cd64ba277 100644 --- a/data/items.ts +++ b/data/items.ts @@ -620,14 +620,14 @@ export const Items: import('../sim/dex-items').ItemDataTable = { onWeatherChange(pokemon) { if (pokemon.transformed) return; - if (pokemon.hasAbility('protosynthesis') && (this.field.isWeather('sunnyday') || pokemon.useItem())) { + if (pokemon.hasAbility('protosynthesis') && !this.field.isWeather('sunnyday') && pokemon.useItem()) { pokemon.addVolatile('protosynthesis'); } }, onTerrainChange(pokemon) { if (pokemon.transformed) return; - if (pokemon.hasAbility('quarkdrive') && (this.field.isTerrain('electricterrain') || pokemon.useItem())) { + if (pokemon.hasAbility('quarkdrive') && !this.field.isTerrain('electricterrain') && pokemon.useItem()) { pokemon.addVolatile('quarkdrive'); } }, From 2a39dd5225bc64b6d28adb45c0bee7a5bf39cca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Mon, 20 Jan 2025 08:12:17 +0000 Subject: [PATCH 4/6] Remove spaces --- data/items.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/data/items.ts b/data/items.ts index 0d1cd64ba277..91297ae34483 100644 --- a/data/items.ts +++ b/data/items.ts @@ -619,14 +619,12 @@ export const Items: import('../sim/dex-items').ItemDataTable = { }, onWeatherChange(pokemon) { if (pokemon.transformed) return; - if (pokemon.hasAbility('protosynthesis') && !this.field.isWeather('sunnyday') && pokemon.useItem()) { pokemon.addVolatile('protosynthesis'); } }, onTerrainChange(pokemon) { if (pokemon.transformed) return; - if (pokemon.hasAbility('quarkdrive') && !this.field.isTerrain('electricterrain') && pokemon.useItem()) { pokemon.addVolatile('quarkdrive'); } From 448f4a6a6ced94aadf05d9fe23b323e2b731fc8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Mon, 20 Jan 2025 20:54:15 +0000 Subject: [PATCH 5/6] Possible trick shenanigans --- data/items.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/data/items.ts b/data/items.ts index 91297ae34483..738fc95c94a8 100644 --- a/data/items.ts +++ b/data/items.ts @@ -619,13 +619,15 @@ export const Items: import('../sim/dex-items').ItemDataTable = { }, onWeatherChange(pokemon) { if (pokemon.transformed) return; - if (pokemon.hasAbility('protosynthesis') && !this.field.isWeather('sunnyday') && pokemon.useItem()) { + if (!pokemon.volatiles['protosynthesis'] && pokemon.hasAbility('protosynthesis') && + !this.field.isWeather('sunnyday') && pokemon.useItem()) { pokemon.addVolatile('protosynthesis'); } }, onTerrainChange(pokemon) { if (pokemon.transformed) return; - if (pokemon.hasAbility('quarkdrive') && !this.field.isTerrain('electricterrain') && pokemon.useItem()) { + if (!pokemon.volatiles['quarkdrive'] && pokemon.hasAbility('quarkdrive') && + !this.field.isTerrain('electricterrain') && pokemon.useItem()) { pokemon.addVolatile('quarkdrive'); } }, @@ -634,10 +636,12 @@ export const Items: import('../sim/dex-items').ItemDataTable = { if (!this.effectState.started || pokemon.transformed) return; if (this.queue.peek(true)?.choice === 'runSwitch') return; - if (pokemon.hasAbility('protosynthesis') && !this.field.isWeather('sunnyday') && pokemon.useItem()) { + if (!pokemon.volatiles['protosynthesis'] && pokemon.hasAbility('protosynthesis') && + !this.field.isWeather('sunnyday') && pokemon.useItem()) { pokemon.addVolatile('protosynthesis'); } - if (pokemon.hasAbility('quarkdrive') && !this.field.isTerrain('electricterrain') && pokemon.useItem()) { + if (!pokemon.volatiles['quarkdrive'] && pokemon.hasAbility('quarkdrive') && + !this.field.isTerrain('electricterrain') && pokemon.useItem()) { pokemon.addVolatile('quarkdrive'); } }, From 71e2fa45c9a30b894dcc3a9c720dce744ce0dc1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Wed, 22 Jan 2025 04:59:59 +0000 Subject: [PATCH 6/6] Move Booster Energy logic to corresponding abilities --- data/abilities.ts | 32 +++++++++++++++++++++++++++++++- data/items.ts | 29 ++--------------------------- sim/dex-items.ts | 1 + 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/data/abilities.ts b/data/abilities.ts index 46747db16e53..e99f0016e05a 100644 --- a/data/abilities.ts +++ b/data/abilities.ts @@ -3422,16 +3422,31 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { protosynthesis: { onStart(pokemon) { this.singleEvent('WeatherChange', this.effect, this.effectState, pokemon); + this.effectState.started = true; }, onWeatherChange(pokemon) { // Protosynthesis is not affected by Utility Umbrella if (this.field.isWeather('sunnyday')) { pokemon.addVolatile('protosynthesis'); - } else if (!pokemon.volatiles['protosynthesis']?.fromBooster && !this.field.isWeather('sunnyday')) { + } else if (!pokemon.transformed && !pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy') && + this.effectState.started) { + pokemon.useItem(); + } else if (!pokemon.volatiles['protosynthesis']?.fromBooster) { pokemon.removeVolatile('protosynthesis'); } }, + onUpdate(pokemon) { + // don't trigger before hazards + if (pokemon.transformed) return; + if (this.queue.peek(true)?.choice === 'runSwitch') return; + + if (!pokemon.volatiles['protosynthesis'] && !this.field.isWeather('sunnyday') && pokemon.hasItem('boosterenergy') && + pokemon.itemState.started) { + pokemon.useItem(); + } + }, onEnd(pokemon) { + delete this.effectState.started; delete pokemon.volatiles['protosynthesis']; this.add('-end', pokemon, 'Protosynthesis', '[silent]'); }, @@ -3558,15 +3573,30 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { quarkdrive: { onStart(pokemon) { this.singleEvent('TerrainChange', this.effect, this.effectState, pokemon); + this.effectState.started = true; }, onTerrainChange(pokemon) { if (this.field.isTerrain('electricterrain')) { pokemon.addVolatile('quarkdrive'); + } else if (!pokemon.transformed && !pokemon.volatiles['quarkdrive'] && pokemon.hasItem('boosterenergy') && + this.effectState.started) { + pokemon.useItem(); } else if (!pokemon.volatiles['quarkdrive']?.fromBooster) { pokemon.removeVolatile('quarkdrive'); } }, + onUpdate(pokemon) { + // don't trigger before hazards + if (pokemon.transformed) return; + if (this.queue.peek(true)?.choice === 'runSwitch') return; + + if (!pokemon.volatiles['quarkdrive'] && !this.field.isTerrain('electricterrain') && pokemon.hasItem('boosterenergy') && + pokemon.itemState.started) { + pokemon.useItem(); + } + }, onEnd(pokemon) { + delete this.effectState.started; delete pokemon.volatiles['quarkdrive']; this.add('-end', pokemon, 'Quark Drive', '[silent]'); }, diff --git a/data/items.ts b/data/items.ts index 738fc95c94a8..b43ee6f81041 100644 --- a/data/items.ts +++ b/data/items.ts @@ -617,33 +617,8 @@ export const Items: import('../sim/dex-items').ItemDataTable = { onStart() { this.effectState.started = true; }, - onWeatherChange(pokemon) { - if (pokemon.transformed) return; - if (!pokemon.volatiles['protosynthesis'] && pokemon.hasAbility('protosynthesis') && - !this.field.isWeather('sunnyday') && pokemon.useItem()) { - pokemon.addVolatile('protosynthesis'); - } - }, - onTerrainChange(pokemon) { - if (pokemon.transformed) return; - if (!pokemon.volatiles['quarkdrive'] && pokemon.hasAbility('quarkdrive') && - !this.field.isTerrain('electricterrain') && pokemon.useItem()) { - pokemon.addVolatile('quarkdrive'); - } - }, - onUpdate(pokemon) { - // don't trigger before hazards - if (!this.effectState.started || pokemon.transformed) return; - if (this.queue.peek(true)?.choice === 'runSwitch') return; - - if (!pokemon.volatiles['protosynthesis'] && pokemon.hasAbility('protosynthesis') && - !this.field.isWeather('sunnyday') && pokemon.useItem()) { - pokemon.addVolatile('protosynthesis'); - } - if (!pokemon.volatiles['quarkdrive'] && pokemon.hasAbility('quarkdrive') && - !this.field.isTerrain('electricterrain') && pokemon.useItem()) { - pokemon.addVolatile('quarkdrive'); - } + onUse(pokemon) { + pokemon.addVolatile(pokemon.ability); }, onTakeItem(item, source) { if (source.baseSpecies.tags.includes("Paradox")) return false; diff --git a/sim/dex-items.ts b/sim/dex-items.ts index b0db83b3aa02..5f4682c23804 100644 --- a/sim/dex-items.ts +++ b/sim/dex-items.ts @@ -102,6 +102,7 @@ export class Item extends BasicEffect implements Readonly { declare readonly onEat?: ((this: Battle, pokemon: Pokemon) => void) | false; declare readonly onPrimal?: (this: Battle, pokemon: Pokemon) => void; + declare readonly onUse?: ((this: Battle, pokemon: Pokemon) => void) | false; declare readonly onStart?: (this: Battle, target: Pokemon) => void; declare readonly onEnd?: (this: Battle, target: Pokemon) => void;