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 01/17] 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 99d707c02b1b2..d8c6cb1cc80ed 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 742f18a29ddba..a1c07349707eb 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 02/17] 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 d8c6cb1cc80ed..b433c32509126 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 03/17] 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 b433c32509126..0d1cd64ba2773 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 04/17] Remove spaces --- data/items.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/data/items.ts b/data/items.ts index 0d1cd64ba2773..91297ae344839 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 05/17] 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 91297ae344839..738fc95c94a84 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 06/17] 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 46747db16e536..e99f0016e05ac 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 738fc95c94a84..b43ee6f810413 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 b0db83b3aa028..5f4682c238049 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; From 228d3dcd56328810f349b0cf1b30b97ebaa7c0f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Fri, 24 Jan 2025 13:44:26 +0000 Subject: [PATCH 07/17] Remove unnecessary transform checks --- data/abilities.ts | 8 ++------ data/items.ts | 3 +++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/data/abilities.ts b/data/abilities.ts index e99f0016e05ac..f8082e947c753 100644 --- a/data/abilities.ts +++ b/data/abilities.ts @@ -3428,8 +3428,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { // Protosynthesis is not affected by Utility Umbrella if (this.field.isWeather('sunnyday')) { pokemon.addVolatile('protosynthesis'); - } else if (!pokemon.transformed && !pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy') && - this.effectState.started) { + } else if (!pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy') && this.effectState.started) { pokemon.useItem(); } else if (!pokemon.volatiles['protosynthesis']?.fromBooster) { pokemon.removeVolatile('protosynthesis'); @@ -3437,7 +3436,6 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { }, 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') && @@ -3578,8 +3576,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { onTerrainChange(pokemon) { if (this.field.isTerrain('electricterrain')) { pokemon.addVolatile('quarkdrive'); - } else if (!pokemon.transformed && !pokemon.volatiles['quarkdrive'] && pokemon.hasItem('boosterenergy') && - this.effectState.started) { + } else if (!pokemon.volatiles['quarkdrive'] && pokemon.hasItem('boosterenergy') && this.effectState.started) { pokemon.useItem(); } else if (!pokemon.volatiles['quarkdrive']?.fromBooster) { pokemon.removeVolatile('quarkdrive'); @@ -3587,7 +3584,6 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { }, 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') && diff --git a/data/items.ts b/data/items.ts index b43ee6f810413..9ad6c5d78ae7d 100644 --- a/data/items.ts +++ b/data/items.ts @@ -617,6 +617,9 @@ export const Items: import('../sim/dex-items').ItemDataTable = { onStart() { this.effectState.started = true; }, + onUseItem(item, pokemon) { + return ['protosynthesis', 'quarkdrive'].includes(pokemon.ability); + }, onUse(pokemon) { pokemon.addVolatile(pokemon.ability); }, From 6b838dc15ad9c855a416f4502c92dace6fdf09ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Fri, 24 Jan 2025 13:46:31 +0000 Subject: [PATCH 08/17] Update dex-items.ts --- sim/dex-items.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sim/dex-items.ts b/sim/dex-items.ts index 5f4682c238049..16aa145e228b9 100644 --- a/sim/dex-items.ts +++ b/sim/dex-items.ts @@ -101,8 +101,8 @@ export class Item extends BasicEffect implements Readonly { declare readonly boosts?: SparseBoostsTable | false; 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 onPrimal?: (this: Battle, pokemon: Pokemon) => void; declare readonly onStart?: (this: Battle, target: Pokemon) => void; declare readonly onEnd?: (this: Battle, target: Pokemon) => void; From 4b69be89d6711c2ef3b526bfbce9943d7e858ef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Tue, 28 Jan 2025 23:42:12 +0000 Subject: [PATCH 09/17] Simplify with new switch logic --- data/abilities.ts | 22 ++++++++-------------- data/items.ts | 5 ----- sim/pokemon.ts | 3 --- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/data/abilities.ts b/data/abilities.ts index cb28d3d557071..20da9b06ddf64 100644 --- a/data/abilities.ts +++ b/data/abilities.ts @@ -3433,29 +3433,26 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { onSwitchInPriority: -2, 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'] && pokemon.hasItem('boosterenergy') && this.effectState.started) { + } else if (!pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy')) { pokemon.useItem(); } else if (!pokemon.volatiles['protosynthesis']?.fromBooster) { pokemon.removeVolatile('protosynthesis'); } }, onUpdate(pokemon) { - // don't trigger before hazards - if (this.queue.peek(true)?.choice === 'runSwitch') return; + // don't run between when a Pokemon switches in and the resulting onSwitchIn event + if (this.queue.peek()?.choice === 'runSwitch') return; - if (!pokemon.volatiles['protosynthesis'] && !this.field.isWeather('sunnyday') && pokemon.hasItem('boosterenergy') && - pokemon.itemState.started) { + if (!pokemon.volatiles['protosynthesis'] && !this.field.isWeather('sunnyday') && pokemon.hasItem('boosterenergy')) { pokemon.useItem(); } }, onEnd(pokemon) { - delete this.effectState.started; delete pokemon.volatiles['protosynthesis']; this.add('-end', pokemon, 'Protosynthesis', '[silent]'); }, @@ -3583,28 +3580,25 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { onSwitchInPriority: -2, 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.volatiles['quarkdrive'] && pokemon.hasItem('boosterenergy') && this.effectState.started) { + } else if (!pokemon.volatiles['quarkdrive'] && pokemon.hasItem('boosterenergy')) { pokemon.useItem(); } else if (!pokemon.volatiles['quarkdrive']?.fromBooster) { pokemon.removeVolatile('quarkdrive'); } }, onUpdate(pokemon) { - // don't trigger before hazards - if (this.queue.peek(true)?.choice === 'runSwitch') return; + // don't run between when a Pokemon switches in and the resulting onSwitchIn event + if (this.queue.peek()?.choice === 'runSwitch') return; - if (!pokemon.volatiles['quarkdrive'] && !this.field.isTerrain('electricterrain') && pokemon.hasItem('boosterenergy') && - pokemon.itemState.started) { + if (!pokemon.volatiles['quarkdrive'] && !this.field.isTerrain('electricterrain') && pokemon.hasItem('boosterenergy')) { 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 f89e58c671580..8f0ce3aeebb81 100644 --- a/data/items.ts +++ b/data/items.ts @@ -613,11 +613,6 @@ export const Items: import('../sim/dex-items').ItemDataTable = { fling: { basePower: 30, }, - onSwitchInPriority: -2, - onStart(pokemon) { - this.effectState.started = true; - ((this.effect as any).onUpdate as (p: Pokemon) => void).call(this, pokemon); - }, onUseItem(item, pokemon) { return ['protosynthesis', 'quarkdrive'].includes(pokemon.ability); }, diff --git a/sim/pokemon.ts b/sim/pokemon.ts index 0b5056ffccef2..a83b0fcad0af4 100644 --- a/sim/pokemon.ts +++ b/sim/pokemon.ts @@ -1492,9 +1492,6 @@ export class Pokemon { this.volatileStaleness = undefined; - delete this.abilityState.started; - delete this.itemState.started; - this.setSpecies(this.baseSpecies); } From 6b82f2e2a4ac064d9b0fd818e8aa1c2b9623325b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Tue, 28 Jan 2025 23:51:10 +0000 Subject: [PATCH 10/17] Fix Protosynthesis in gen9dlc1 --- data/mods/gen9dlc1/abilities.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/mods/gen9dlc1/abilities.ts b/data/mods/gen9dlc1/abilities.ts index ad0c66018f164..e493fa666ce51 100644 --- a/data/mods/gen9dlc1/abilities.ts +++ b/data/mods/gen9dlc1/abilities.ts @@ -13,6 +13,8 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa // Protosynthesis is not affected by Utility Umbrella if (this.field.isWeather('sunnyday')) { pokemon.addVolatile('protosynthesis'); + } else if (!pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy')) { + pokemon.useItem(); } else if (!pokemon.volatiles['protosynthesis']?.fromBooster && this.field.weather !== 'sunnyday') { // Protosynthesis will not deactivite if Sun is suppressed, hence the direct ID check (isWeather respects supression) pokemon.removeVolatile('protosynthesis'); From 77cf52e3c445f51d9efec6543c4ebd04eddcdd06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Wed, 29 Jan 2025 01:50:38 +0000 Subject: [PATCH 11/17] Update comment --- data/abilities.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/abilities.ts b/data/abilities.ts index 20da9b06ddf64..9fd65126dc3ed 100644 --- a/data/abilities.ts +++ b/data/abilities.ts @@ -605,7 +605,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { }, onUpdate(pokemon) { if (this.gameType !== 'doubles') return; - // don't run between when a Pokemon switches in and the resulting onSwitchIn event + // don't run between when a Pokemon switches in and the resulting SwitchIn event if (this.queue.peek()?.choice === 'runSwitch') return; const ally = pokemon.allies()[0]; @@ -3445,7 +3445,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { } }, onUpdate(pokemon) { - // don't run between when a Pokemon switches in and the resulting onSwitchIn event + // don't run between when a Pokemon switches in and the resulting SwitchIn event if (this.queue.peek()?.choice === 'runSwitch') return; if (!pokemon.volatiles['protosynthesis'] && !this.field.isWeather('sunnyday') && pokemon.hasItem('boosterenergy')) { @@ -3591,7 +3591,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { } }, onUpdate(pokemon) { - // don't run between when a Pokemon switches in and the resulting onSwitchIn event + // don't run between when a Pokemon switches in and the resulting SwitchIn event if (this.queue.peek()?.choice === 'runSwitch') return; if (!pokemon.volatiles['quarkdrive'] && !this.field.isTerrain('electricterrain') && pokemon.hasItem('boosterenergy')) { From 91e3c0964d32271b78ae382e43cab0dc14e56fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Wed, 29 Jan 2025 02:15:29 +0000 Subject: [PATCH 12/17] Update WeatherChange logic --- data/abilities.ts | 22 ++++++++++++++-------- data/items.ts | 2 +- data/mods/gen9dlc1/abilities.ts | 12 +++++++----- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/data/abilities.ts b/data/abilities.ts index 9fd65126dc3ed..76a7a932a89c0 100644 --- a/data/abilities.ts +++ b/data/abilities.ts @@ -3438,10 +3438,13 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { // Protosynthesis is not affected by Utility Umbrella if (this.field.isWeather('sunnyday')) { pokemon.addVolatile('protosynthesis'); - } else if (!pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(); - } else if (!pokemon.volatiles['protosynthesis']?.fromBooster) { - pokemon.removeVolatile('protosynthesis'); + } else { + if (!pokemon.volatiles['protosynthesis']?.fromBooster) { + pokemon.removeVolatile('protosynthesis'); + } + if (!pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy')) { + pokemon.useItem(); + } } }, onUpdate(pokemon) { @@ -3584,10 +3587,13 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { onTerrainChange(pokemon) { if (this.field.isTerrain('electricterrain')) { pokemon.addVolatile('quarkdrive'); - } else if (!pokemon.volatiles['quarkdrive'] && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(); - } else if (!pokemon.volatiles['quarkdrive']?.fromBooster) { - pokemon.removeVolatile('quarkdrive'); + } else { + if (!pokemon.volatiles['quarkdrive']?.fromBooster) { + pokemon.removeVolatile('quarkdrive'); + } + if (!pokemon.volatiles['quarkdrive'] && pokemon.hasItem('boosterenergy')) { + pokemon.useItem(); + } } }, onUpdate(pokemon) { diff --git a/data/items.ts b/data/items.ts index 8f0ce3aeebb81..2f01cf99b6368 100644 --- a/data/items.ts +++ b/data/items.ts @@ -614,7 +614,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = { basePower: 30, }, onUseItem(item, pokemon) { - return ['protosynthesis', 'quarkdrive'].includes(pokemon.ability); + return item.id === 'boosterenergy' && (pokemon.hasAbility('protosynthesis') || pokemon.hasAbility('quarkdrive')); }, onUse(pokemon) { pokemon.addVolatile(pokemon.ability); diff --git a/data/mods/gen9dlc1/abilities.ts b/data/mods/gen9dlc1/abilities.ts index e493fa666ce51..4521f1a1b5701 100644 --- a/data/mods/gen9dlc1/abilities.ts +++ b/data/mods/gen9dlc1/abilities.ts @@ -13,11 +13,13 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa // Protosynthesis is not affected by Utility Umbrella if (this.field.isWeather('sunnyday')) { pokemon.addVolatile('protosynthesis'); - } else if (!pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(); - } else if (!pokemon.volatiles['protosynthesis']?.fromBooster && this.field.weather !== 'sunnyday') { - // Protosynthesis will not deactivite if Sun is suppressed, hence the direct ID check (isWeather respects supression) - pokemon.removeVolatile('protosynthesis'); + } else { + if (!pokemon.volatiles['protosynthesis']?.fromBooster && this.field.weather !== 'sunnyday') { + pokemon.removeVolatile('protosynthesis'); + } + if (!pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy')) { + pokemon.useItem(); + } } }, condition: { From c25f406a0528893a07cdbe5571679ec052b2222f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Wed, 29 Jan 2025 02:25:11 +0000 Subject: [PATCH 13/17] Fix OMs --- data/abilities.ts | 8 ++++---- data/items.ts | 4 ++-- data/mods/gen9dlc1/abilities.ts | 2 +- sim/dex-conditions.ts | 2 +- sim/pokemon.ts | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/data/abilities.ts b/data/abilities.ts index 76a7a932a89c0..b6753ab29e3e8 100644 --- a/data/abilities.ts +++ b/data/abilities.ts @@ -3443,7 +3443,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { pokemon.removeVolatile('protosynthesis'); } if (!pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(); + pokemon.useItem(pokemon, pokemon.getAbility()); } } }, @@ -3452,7 +3452,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { if (this.queue.peek()?.choice === 'runSwitch') return; if (!pokemon.volatiles['protosynthesis'] && !this.field.isWeather('sunnyday') && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(); + pokemon.useItem(pokemon, pokemon.getAbility()); } }, onEnd(pokemon) { @@ -3592,7 +3592,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { pokemon.removeVolatile('quarkdrive'); } if (!pokemon.volatiles['quarkdrive'] && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(); + pokemon.useItem(pokemon, pokemon.getAbility()); } } }, @@ -3601,7 +3601,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { if (this.queue.peek()?.choice === 'runSwitch') return; if (!pokemon.volatiles['quarkdrive'] && !this.field.isTerrain('electricterrain') && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(); + pokemon.useItem(pokemon, pokemon.getAbility()); } }, onEnd(pokemon) { diff --git a/data/items.ts b/data/items.ts index 2f01cf99b6368..0da2e0208a4e5 100644 --- a/data/items.ts +++ b/data/items.ts @@ -613,8 +613,8 @@ export const Items: import('../sim/dex-items').ItemDataTable = { fling: { basePower: 30, }, - onUseItem(item, pokemon) { - return item.id === 'boosterenergy' && (pokemon.hasAbility('protosynthesis') || pokemon.hasAbility('quarkdrive')); + onUseItem(item, pokemon, source, sourceEffect) { + return item.id === 'boosterenergy' && pokemon === source && ['protosynthesis', 'quarkdrive'].includes(sourceEffect.id); }, onUse(pokemon) { pokemon.addVolatile(pokemon.ability); diff --git a/data/mods/gen9dlc1/abilities.ts b/data/mods/gen9dlc1/abilities.ts index 4521f1a1b5701..1a7528a729046 100644 --- a/data/mods/gen9dlc1/abilities.ts +++ b/data/mods/gen9dlc1/abilities.ts @@ -18,7 +18,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa pokemon.removeVolatile('protosynthesis'); } if (!pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(); + pokemon.useItem(pokemon, pokemon.getAbility()); } } }, diff --git a/sim/dex-conditions.ts b/sim/dex-conditions.ts index f8c160c98046f..8742385f145a4 100644 --- a/sim/dex-conditions.ts +++ b/sim/dex-conditions.ts @@ -115,7 +115,7 @@ export interface EventMethods { onTryMove?: MoveEventMethods['onTryMove']; onTryPrimaryHit?: (this: Battle, target: Pokemon, source: Pokemon, move: ActiveMove) => boolean | null | number | void; onType?: (this: Battle, types: string[], pokemon: Pokemon) => string[] | void; - onUseItem?: (this: Battle, item: Item, pokemon: Pokemon) => void; + onUseItem?: (this: Battle, item: Item, pokemon: Pokemon, source: Pokemon, sourceEffect: Effect) => void; onUpdate?: (this: Battle, pokemon: Pokemon) => void; onWeather?: (this: Battle, target: Pokemon, source: null, effect: Condition) => void; onWeatherModifyDamage?: CommonHandlers['ModifierSourceMove']; diff --git a/sim/pokemon.ts b/sim/pokemon.ts index a83b0fcad0af4..76ed7abadc202 100644 --- a/sim/pokemon.ts +++ b/sim/pokemon.ts @@ -1745,7 +1745,7 @@ export class Pokemon { if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect; if (!source && this.battle.event && this.battle.event.target) source = this.battle.event.target; const item = this.getItem(); - if (this.battle.runEvent('UseItem', this, null, null, item)) { + if (this.battle.runEvent('UseItem', this, source, sourceEffect, item)) { switch (item.id) { case 'redcard': this.battle.add('-enditem', this, item, '[of] ' + source); From 677febd340d626c04df228955813069014c2e497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Wed, 29 Jan 2025 02:35:41 +0000 Subject: [PATCH 14/17] Fix I got confused with a possible onAnyUseItem --- data/items.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/items.ts b/data/items.ts index 0da2e0208a4e5..c0d2bf223a676 100644 --- a/data/items.ts +++ b/data/items.ts @@ -614,7 +614,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = { basePower: 30, }, onUseItem(item, pokemon, source, sourceEffect) { - return item.id === 'boosterenergy' && pokemon === source && ['protosynthesis', 'quarkdrive'].includes(sourceEffect.id); + return pokemon === source && ['protosynthesis', 'quarkdrive'].includes(sourceEffect.id); }, onUse(pokemon) { pokemon.addVolatile(pokemon.ability); From 204912a46946d589a232cac4b7cc808506bccb7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Wed, 29 Jan 2025 02:42:10 +0000 Subject: [PATCH 15/17] Refactor onUse --- data/items.ts | 4 ++-- sim/dex-items.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/items.ts b/data/items.ts index c0d2bf223a676..c1ea6fbcc8eee 100644 --- a/data/items.ts +++ b/data/items.ts @@ -616,8 +616,8 @@ export const Items: import('../sim/dex-items').ItemDataTable = { onUseItem(item, pokemon, source, sourceEffect) { return pokemon === source && ['protosynthesis', 'quarkdrive'].includes(sourceEffect.id); }, - onUse(pokemon) { - pokemon.addVolatile(pokemon.ability); + onUse(pokemon, source, sourceEffect) { + pokemon.addVolatile(sourceEffect.id); }, onTakeItem(item, source) { if (source.baseSpecies.tags.includes("Paradox")) return false; diff --git a/sim/dex-items.ts b/sim/dex-items.ts index f0bbf26ae4667..dea026bf01774 100644 --- a/sim/dex-items.ts +++ b/sim/dex-items.ts @@ -103,7 +103,7 @@ export class Item extends BasicEffect implements Readonly { declare readonly boosts?: SparseBoostsTable | false; declare readonly onEat?: ((this: Battle, pokemon: Pokemon) => void) | false; - declare readonly onUse?: ((this: Battle, pokemon: Pokemon) => void) | false; + declare readonly onUse?: ((this: Battle, pokemon: Pokemon, source: Pokemon, sourceEffect: Effect) => void) | false; declare readonly onStart?: (this: Battle, target: Pokemon) => void; declare readonly onEnd?: (this: Battle, target: Pokemon) => void; From ca172207960e46ae9c15ea3e1dc6e17f456793a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Wed, 29 Jan 2025 02:59:27 +0000 Subject: [PATCH 16/17] Fix OMs --- data/abilities.ts | 8 ++++---- data/mods/gen9dlc1/abilities.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/data/abilities.ts b/data/abilities.ts index b6753ab29e3e8..5bb4a47fc5023 100644 --- a/data/abilities.ts +++ b/data/abilities.ts @@ -3443,7 +3443,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { pokemon.removeVolatile('protosynthesis'); } if (!pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(pokemon, pokemon.getAbility()); + pokemon.useItem(pokemon, this.dex.abilities.get('protosynthesis')); } } }, @@ -3452,7 +3452,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { if (this.queue.peek()?.choice === 'runSwitch') return; if (!pokemon.volatiles['protosynthesis'] && !this.field.isWeather('sunnyday') && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(pokemon, pokemon.getAbility()); + pokemon.useItem(pokemon, this.dex.abilities.get('protosynthesis')); } }, onEnd(pokemon) { @@ -3592,7 +3592,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { pokemon.removeVolatile('quarkdrive'); } if (!pokemon.volatiles['quarkdrive'] && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(pokemon, pokemon.getAbility()); + pokemon.useItem(pokemon, this.dex.abilities.get('quarkdrive')); } } }, @@ -3601,7 +3601,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { if (this.queue.peek()?.choice === 'runSwitch') return; if (!pokemon.volatiles['quarkdrive'] && !this.field.isTerrain('electricterrain') && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(pokemon, pokemon.getAbility()); + pokemon.useItem(pokemon, this.dex.abilities.get('quarkdrive')); } }, onEnd(pokemon) { diff --git a/data/mods/gen9dlc1/abilities.ts b/data/mods/gen9dlc1/abilities.ts index 1a7528a729046..2097febfe0d4e 100644 --- a/data/mods/gen9dlc1/abilities.ts +++ b/data/mods/gen9dlc1/abilities.ts @@ -18,7 +18,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa pokemon.removeVolatile('protosynthesis'); } if (!pokemon.volatiles['protosynthesis'] && pokemon.hasItem('boosterenergy')) { - pokemon.useItem(pokemon, pokemon.getAbility()); + pokemon.useItem(pokemon, this.dex.abilities.get('protosynthesis')); } } }, From fc060f02a459e57ff8557e746b260744b8b0e0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bastos=20Dias?= Date: Wed, 26 Feb 2025 22:02:24 +0000 Subject: [PATCH 17/17] Update to ESLint 9 --- test/sim/items/boosterenergy.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/sim/items/boosterenergy.js b/test/sim/items/boosterenergy.js index 24741a32da25c..2f0f651746575 100644 --- a/test/sim/items/boosterenergy.js +++ b/test/sim/items/boosterenergy.js @@ -25,13 +25,13 @@ describe('Booster Energy', () => { `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']}, + it(`should activate right after weather changes`, () => { + 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']}, + { species: 'Incineroar', ability: 'intimidate', moves: ['sleeptalk'] }, + { species: 'Torkoal', ability: 'drought', moves: ['sleeptalk'] }, ]]); const roaringMoon = battle.p1.active[1];