diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 2a1d680e0ad..e055b60326d 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -58,12 +58,12 @@ import { getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, - getModifierType, getPartyLuckValue, - modifierTypes, PokemonHeldItemModifierType, } from "#app/modifier/modifier-type"; -import { getModifierPoolForType } from "./utils/modifier-pool-utils"; +import { getModifierType } from "./utils/modifier-utils"; +import { modifierTypes } from "./data/data-lists"; +import { getModifierPoolForType } from "./utils/modifier-utils"; import { ModifierPoolType } from "#enums/modifier-pool-type"; import AbilityBar from "#app/ui/ability-bar"; import { applyAbAttrs, applyPostBattleInitAbAttrs, applyPostItemLostAbAttrs } from "./data/abilities/apply-ab-attrs"; diff --git a/src/battle.ts b/src/battle.ts index 229e769c622..064b54016a9 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -13,7 +13,7 @@ import { import Trainer from "./field/trainer"; import { TrainerVariant } from "#enums/trainer-variant"; import type { GameMode } from "./game-mode"; -import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier"; +import type { PokemonHeldItemModifier } from "./modifier/modifier"; import type { PokeballType } from "#enums/pokeball"; import { trainerConfigs } from "#app/data/trainers/trainer-config"; import { SpeciesFormKey } from "#enums/species-form-key"; @@ -173,7 +173,7 @@ export default class Battle { this.postBattleLoot.push( ...globalScene .findModifiers( - m => m instanceof PokemonHeldItemModifier && m.pokemonId === enemyPokemon.id && m.isTransferable, + m => m.is("PokemonHeldItemModifier") && m.pokemonId === enemyPokemon.id && m.isTransferable, false, ) .map(i => { diff --git a/src/data/balance/pokemon-evolutions.ts b/src/data/balance/pokemon-evolutions.ts index 298cf2d0719..d307f5cfbf6 100644 --- a/src/data/balance/pokemon-evolutions.ts +++ b/src/data/balance/pokemon-evolutions.ts @@ -11,7 +11,6 @@ import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; import { SpeciesFormKey } from "#enums/species-form-key"; import { TimeOfDay } from "#enums/time-of-day"; -import { DamageMoneyRewardModifier, ExtraModifierModifier, MoneyMultiplierModifier, SpeciesStatBoosterModifier, TempExtraModifierModifier } from "#app/modifier/modifier"; import type { SpeciesStatBoosterModifierType } from "#app/modifier/modifier-type"; import { speciesStarterCosts } from "./starters"; import i18next from "i18next"; @@ -275,9 +274,9 @@ class MoveTypeEvolutionCondition extends SpeciesEvolutionCondition { class TreasureEvolutionCondition extends SpeciesEvolutionCondition { constructor() { super(p => p.evoCounter - + p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length - + globalScene.findModifiers(m => m instanceof MoneyMultiplierModifier - || m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length > 9); + + p.getHeldItems().filter(m => m.is("DamageMoneyRewardModifier")).length + + globalScene.findModifiers(m => m.is("MoneyMultiplierModifier") + || m.is("ExtraModifierModifier") || m.is("TempExtraModifierModifier")).length > 9); this.description = i18next.t("pokemonEvolutions:treasure"); } } @@ -1794,8 +1793,8 @@ export const pokemonEvolutions: PokemonEvolutions = { ], [SpeciesId.CLAMPERL]: [ // TODO: Change the SpeciesEvolutionConditions here to use a bespoke HeldItemEvolutionCondition after the modifier rework - new SpeciesEvolution(SpeciesId.HUNTAIL, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.getHeldItems().some(m => m instanceof SpeciesStatBoosterModifier && (m.type as SpeciesStatBoosterModifierType).key === "DEEP_SEA_TOOTH")), SpeciesWildEvolutionDelay.VERY_LONG), - new SpeciesEvolution(SpeciesId.GOREBYSS, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.getHeldItems().some(m => m instanceof SpeciesStatBoosterModifier && (m.type as SpeciesStatBoosterModifierType).key === "DEEP_SEA_SCALE")), SpeciesWildEvolutionDelay.VERY_LONG) + new SpeciesEvolution(SpeciesId.HUNTAIL, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.getHeldItems().some(m => m.is("SpeciesStatBoosterModifier") && (m.type as SpeciesStatBoosterModifierType).key === "DEEP_SEA_TOOTH")), SpeciesWildEvolutionDelay.VERY_LONG), + new SpeciesEvolution(SpeciesId.GOREBYSS, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.getHeldItems().some(m => m.is("SpeciesStatBoosterModifier") && (m.type as SpeciesStatBoosterModifierType).key === "DEEP_SEA_SCALE")), SpeciesWildEvolutionDelay.VERY_LONG) ], [SpeciesId.BOLDORE]: [ new SpeciesEvolution(SpeciesId.GIGALITH, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG) diff --git a/src/data/data-lists.ts b/src/data/data-lists.ts index eb95fdd3b16..4d482dc2d7d 100644 --- a/src/data/data-lists.ts +++ b/src/data/data-lists.ts @@ -1,5 +1,9 @@ +import type { ModifierTypes } from "#app/modifier/modifier-type"; import type { Ability } from "./abilities/ability"; import type Move from "./moves/move"; export const allAbilities: Ability[] = []; export const allMoves: Move[] = []; + +// TODO: Figure out what this is used for and provide an appropriate tsdoc comment +export const modifierTypes = {} as ModifierTypes; diff --git a/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts b/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts index 2f2b5686ae1..7a1c9821e89 100644 --- a/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts +++ b/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts @@ -20,7 +20,7 @@ import type { IEggOptions } from "#app/data/egg"; import { EggSourceType } from "#enums/egg-source-types"; import { EggTier } from "#enums/egg-type"; import { ModifierTier } from "#enums/modifier-tier"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants"; /** the i18n namespace for the encounter */ diff --git a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts index 2213dc4afaa..3eda96e4028 100644 --- a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts +++ b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts @@ -10,7 +10,7 @@ import type Pokemon from "#app/field/pokemon"; import { EnemyPokemon } from "#app/field/pokemon"; import { PokemonMove } from "#app/data/moves/pokemon-move"; import type { BerryModifierType, PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; import { globalScene } from "#app/global-scene"; diff --git a/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts b/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts index cdb98c56ed1..271346616d1 100644 --- a/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts +++ b/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts @@ -4,7 +4,7 @@ import { setEncounterExp, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; import { globalScene } from "#app/global-scene"; diff --git a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts index eff055a5767..d86a8439804 100644 --- a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts +++ b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts @@ -12,7 +12,8 @@ import { import type { PlayerPokemon } from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon"; import type { BerryModifierType, ModifierTypeOption } from "#app/modifier/modifier-type"; -import { modifierTypes, regenerateModifierPoolThresholds } from "#app/modifier/modifier-type"; +import { regenerateModifierPoolThresholds } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { ModifierPoolType } from "#enums/modifier-pool-type"; import { randSeedInt } from "#app/utils/common"; import { BattlerTagType } from "#enums/battler-tag-type"; diff --git a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts index 1ebd72d9f03..df06f40c159 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -38,7 +38,7 @@ import { } from "#app/data/mystery-encounters/mystery-encounter-requirements"; import { PokemonType } from "#enums/pokemon-type"; import type { AttackTypeBoosterModifierType, ModifierTypeOption } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import type { PokemonHeldItemModifier } from "#app/modifier/modifier"; import { AttackTypeBoosterModifier, diff --git a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts index 7ae18ad0dd4..542bd163713 100644 --- a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts +++ b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts @@ -13,7 +13,7 @@ import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTem import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate"; import { ModifierTier } from "#enums/modifier-tier"; import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { ModifierPoolType } from "#enums/modifier-pool-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { PartyMemberStrength } from "#enums/party-member-strength"; diff --git a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts index a74980919d6..4444a2e6b1b 100644 --- a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts +++ b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts @@ -26,7 +26,7 @@ import type Pokemon from "#app/field/pokemon"; import { EnemyPokemon } from "#app/field/pokemon"; import { PokemonMove } from "#app/data/moves/pokemon-move"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import PokemonData from "#app/system/pokemon-data"; import type { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler"; import { BattlerTagType } from "#enums/battler-tag-type"; diff --git a/src/data/mystery-encounters/encounters/dark-deal-encounter.ts b/src/data/mystery-encounters/encounters/dark-deal-encounter.ts index 6474df3570e..002b38f445d 100644 --- a/src/data/mystery-encounters/encounters/dark-deal-encounter.ts +++ b/src/data/mystery-encounters/encounters/dark-deal-encounter.ts @@ -3,7 +3,7 @@ import { isNullOrUndefined, randSeedInt } from "#app/utils/common"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; import { globalScene } from "#app/global-scene"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { getPokemonSpecies } from "#app/data/pokemon-species"; import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter"; import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter"; diff --git a/src/data/mystery-encounters/encounters/delibirdy-encounter.ts b/src/data/mystery-encounters/encounters/delibirdy-encounter.ts index 40893d93930..692ffe6e80e 100644 --- a/src/data/mystery-encounters/encounters/delibirdy-encounter.ts +++ b/src/data/mystery-encounters/encounters/delibirdy-encounter.ts @@ -28,7 +28,7 @@ import { PreserveBerryModifier, } from "#app/modifier/modifier"; import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import i18next from "#app/plugins/i18n"; import type { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler"; import { randSeedItem } from "#app/utils/common"; diff --git a/src/data/mystery-encounters/encounters/department-store-sale-encounter.ts b/src/data/mystery-encounters/encounters/department-store-sale-encounter.ts index fb874691aa0..46152a7dc41 100644 --- a/src/data/mystery-encounters/encounters/department-store-sale-encounter.ts +++ b/src/data/mystery-encounters/encounters/department-store-sale-encounter.ts @@ -3,7 +3,7 @@ import { setEncounterRewards, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import type { ModifierTypeFunc } from "#app/@types/modifier-types"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { randSeedInt } from "#app/utils/common"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; diff --git a/src/data/mystery-encounters/encounters/field-trip-encounter.ts b/src/data/mystery-encounters/encounters/field-trip-encounter.ts index 82fbfd51eec..6ab0f8a6a4b 100644 --- a/src/data/mystery-encounters/encounters/field-trip-encounter.ts +++ b/src/data/mystery-encounters/encounters/field-trip-encounter.ts @@ -9,7 +9,7 @@ import { } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import type { PlayerPokemon } from "#app/field/pokemon"; import type { PokemonMove } from "#app/data/moves/pokemon-move"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import type { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { globalScene } from "#app/global-scene"; diff --git a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts index 08cef4cc4d8..4b24bf9cada 100644 --- a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts +++ b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts @@ -10,7 +10,7 @@ import { generateModifierType, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import type { AttackTypeBoosterModifierType } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { globalScene } from "#app/global-scene"; import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter"; diff --git a/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts b/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts index 456562ca70e..48557541512 100644 --- a/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts +++ b/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts @@ -26,7 +26,7 @@ import { PlayerGender } from "#enums/player-gender"; import { getPokeballAtlasKey, getPokeballTintColor } from "#app/data/pokeball"; import { addPokeballOpenParticles } from "#app/field/anims"; import { SpeciesFormChangeActiveTrigger } from "#app/data/pokemon-forms/form-change-triggers"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { Nature } from "#enums/nature"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants"; import { isPokemonValidForEncounterOptionSelection } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; diff --git a/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts b/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts index d19998cc051..010358ea3b2 100644 --- a/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts +++ b/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts @@ -8,7 +8,7 @@ import { trainerPartyTemplates } from "#app/data/trainers/TrainerPartyTemplate"; import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate"; import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate"; import { ModifierTier } from "#enums/modifier-tier"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { PartyMemberStrength } from "#enums/party-member-strength"; import { globalScene } from "#app/global-scene"; diff --git a/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts b/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts index 1afc67e1d12..967c105c740 100644 --- a/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts +++ b/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts @@ -7,7 +7,7 @@ import { } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import type { PlayerPokemon } from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { randSeedInt } from "#app/utils/common"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; diff --git a/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts b/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts index 1ecd73143fc..483c577e851 100644 --- a/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts +++ b/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts @@ -1,6 +1,6 @@ import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups"; import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { SpeciesId } from "#enums/species-id"; import { globalScene } from "#app/global-scene"; diff --git a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts index edc9cf13834..9c9232612c6 100644 --- a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts +++ b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts @@ -23,7 +23,8 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode import { BiomeId } from "#enums/biome-id"; import { getBiomeKey } from "#app/field/arena"; import { PokemonType } from "#enums/pokemon-type"; -import { getPartyLuckValue, modifierTypes } from "#app/modifier/modifier-type"; +import { getPartyLuckValue } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { TrainerSlot } from "#enums/trainer-slot"; import { BattlerTagType } from "#enums/battler-tag-type"; import { getPokemonNameWithAffix } from "#app/messages"; diff --git a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts index fdfcc8f2f13..0676b40c548 100644 --- a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts @@ -26,7 +26,7 @@ import { EggSourceType } from "#enums/egg-source-types"; import { EggTier } from "#enums/egg-type"; import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { PokemonType } from "#enums/pokemon-type"; import { getPokeballTintColor } from "#app/data/pokeball"; diff --git a/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts b/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts index a3eb78f479e..61d9dcfccfd 100644 --- a/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts @@ -8,7 +8,7 @@ import { generateModifierType, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { globalScene } from "#app/global-scene"; import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter"; diff --git a/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts b/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts index 336e4941ef7..e2c87d8c0ae 100644 --- a/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts @@ -8,7 +8,7 @@ import { transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { globalScene } from "#app/global-scene"; import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter"; diff --git a/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts b/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts index 18a84bd6bd2..1416c63dd28 100644 --- a/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts +++ b/src/data/mystery-encounters/encounters/trash-to-treasure-encounter.ts @@ -8,7 +8,7 @@ import { transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { globalScene } from "#app/global-scene"; import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter"; diff --git a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts index 3f28a9f2f3f..83e876d1aa8 100644 --- a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts +++ b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts @@ -25,7 +25,7 @@ import { HiddenAbilityRateBoosterModifier, PokemonFormChangeItemModifier } from import { achvs } from "#app/system/achv"; import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import i18next from "#app/plugins/i18n"; import { doPokemonTransformationSequence, diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index 85d389254d5..5112eed7147 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -19,9 +19,9 @@ import { getPartyLuckValue, ModifierTypeGenerator, ModifierTypeOption, - modifierTypes, regenerateModifierPoolThresholds, } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { ModifierPoolType } from "#enums/modifier-pool-type"; import type PokemonData from "#app/system/pokemon-data"; import type { OptionSelectConfig, OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler"; diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index e8a3db46cff..4671869a2ba 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -29,7 +29,7 @@ import { } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { getPokemonNameWithAffix } from "#app/messages"; import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { Gender } from "#app/data/gender"; import type { PermanentStat } from "#enums/stat"; import { SummaryUiMode } from "#app/ui/summary-ui-handler"; diff --git a/src/data/trainers/trainer-config.ts b/src/data/trainers/trainer-config.ts index f551015240a..31c7631c6dd 100644 --- a/src/data/trainers/trainer-config.ts +++ b/src/data/trainers/trainer-config.ts @@ -1,5 +1,5 @@ import { globalScene } from "#app/global-scene"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "../data-lists"; import { PokemonMove } from "../moves/pokemon-move"; import { toReadableString, isNullOrUndefined, randSeedItem, randSeedInt, randSeedIntRange } from "#app/utils/common"; import { pokemonEvolutions, pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions"; diff --git a/src/modifier/init-modifier-pools.ts b/src/modifier/init-modifier-pools.ts index 11836f522d0..7cc77a69ea2 100644 --- a/src/modifier/init-modifier-pools.ts +++ b/src/modifier/init-modifier-pools.ts @@ -7,16 +7,11 @@ import { wildModifierPool, } from "#app/modifier/modifier-pools"; import { globalScene } from "#app/global-scene"; -import { - DoubleBattleChanceBoosterModifier, - ResetNegativeStatStageModifier, - SpeciesCritBoosterModifier, - TurnStatusEffectModifier, -} from "./modifier"; +import { DoubleBattleChanceBoosterModifier, SpeciesCritBoosterModifier, TurnStatusEffectModifier } from "./modifier"; import { WeightedModifierType } from "./modifier-type"; import { ModifierTier } from "../enums/modifier-tier"; import type { WeightedModifierTypeWeightFunc } from "#app/@types/modifier-types"; -import { modifierTypes } from "./modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { PokeballType } from "#enums/pokeball"; import { BerryModifier } from "./modifier"; import { BerryType } from "#enums/berry-type"; diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 5c21ae6f65e..b34c23efdec 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -2,7 +2,7 @@ import { globalScene } from "#app/global-scene"; import { EvolutionItem, pokemonEvolutions } from "#app/data/balance/pokemon-evolutions"; import { tmPoolTiers, tmSpecies } from "#app/data/balance/tms"; import { getBerryEffectDescription, getBerryName } from "#app/data/berry"; -import { allMoves } from "#app/data/data-lists"; +import { allMoves, modifierTypes } from "#app/data/data-lists"; import { getNatureName, getNatureStatMultiplier } from "#app/data/nature"; import { getPokeballCatchMultiplier, getPokeballName } from "#app/data/pokeball"; import { pokemonFormChanges, SpeciesFormChangeCondition } from "#app/data/pokemon-forms"; @@ -127,10 +127,12 @@ import { timedEventManager } from "#app/global-event-manager"; import { TYPE_BOOST_ITEM_BOOST_PERCENT } from "#app/constants"; import { ModifierPoolType } from "#enums/modifier-pool-type"; - -import { getModifierPoolForType } from "#app/utils/modifier-pool-utils"; +import { getModifierPoolForType, getModifierType } from "#app/utils/modifier-utils"; import type { ModifierTypeFunc, WeightedModifierTypeWeightFunc } from "#app/@types/modifier-types"; +// biome-ignore lint/correctness/noUnusedImports: This import is used in a +import type { initModifierPools } from "./init-modifier-pools"; + const outputModifierData = false; const useMaxWeightForOutput = false; @@ -145,6 +147,19 @@ export class ModifierType { public tier: ModifierTier; protected newModifierFunc: NewModifierFunc | null; + /** + * Checks if the modifier type is of a specific type + * @param modifierType - The type to check against + * @return Whether the modifier type is of the specified type + */ + public is(modifierType: K): this is ModifierTypeInstanceMap[K] { + const targetType = ModifierTypeConstructorMap[modifierType]; + if (!targetType) { + return false; + } + return this instanceof targetType; + } + constructor( localeKey: string | null, iconImage: string | null, @@ -213,7 +228,7 @@ export class ModifierType { * @param func */ withIdFromFunc(func: ModifierTypeFunc): ModifierType { - this.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === func)!; // TODO: is this bang correct? + this.id = Object.keys(modifierTypeInitObj).find(k => modifierTypeInitObj[k] === func)!; // TODO: is this bang correct? return this; } @@ -1626,7 +1641,7 @@ class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator { } } -class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator { +export class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator { constructor(isRareFormChangeItem: boolean) { super((party: Pokemon[], pregenArgs?: any[]) => { if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in FormChangeItem) { @@ -1789,7 +1804,6 @@ export class EnemyEndureChanceModifierType extends ModifierType { } } - export class WeightedModifierType { public modifierType: ModifierType; public weight: number | WeightedModifierTypeWeightFunc; @@ -1801,7 +1815,7 @@ export class WeightedModifierType { maxWeight?: number | WeightedModifierTypeWeightFunc, ) { this.modifierType = modifierTypeFunc(); - this.modifierType.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifierTypeFunc)!; // TODO: is this bang correct? + this.modifierType.id = Object.keys(modifierTypeInitObj).find(k => modifierTypeInitObj[k] === modifierTypeFunc)!; // TODO: is this bang correct? this.weight = weight; this.maxWeight = maxWeight || (!(weight instanceof Function) ? weight : 0); } @@ -1811,7 +1825,6 @@ export class WeightedModifierType { } } - type BaseModifierOverride = { name: Exclude; count?: number; @@ -1822,39 +1835,39 @@ export type GeneratorModifierOverride = { count?: number; } & ( | { - name: keyof Pick; + name: keyof Pick; type?: SpeciesStatBoosterItem; } | { - name: keyof Pick; + name: keyof Pick; type?: TempBattleStat; } | { - name: keyof Pick; + name: keyof Pick; type?: Stat; } | { - name: keyof Pick; + name: keyof Pick; type?: Nature; } | { - name: keyof Pick; + name: keyof Pick; type?: PokemonType; } | { - name: keyof Pick; + name: keyof Pick; type?: BerryType; } | { - name: keyof Pick; + name: keyof Pick; type?: EvolutionItem; } | { - name: keyof Pick; + name: keyof Pick; type?: FormChangeItem; } | { - name: keyof Pick; + name: keyof Pick; type?: MoveId; } ); @@ -1862,9 +1875,9 @@ export type GeneratorModifierOverride = { /** Type used to construct modifiers and held items for overriding purposes. */ export type ModifierOverride = GeneratorModifierOverride | BaseModifierOverride; -export type ModifierTypeKeys = keyof typeof modifierTypes; +export type ModifierTypeKeys = keyof typeof modifierTypeInitObj; -export const modifierTypes = { +const modifierTypeInitObj = Object.freeze({ POKEBALL: () => new AddPokeballModifierType("pb", PokeballType.POKEBALL, 5), GREAT_BALL: () => new AddPokeballModifierType("gb", PokeballType.GREAT_BALL, 5), ULTRA_BALL: () => new AddPokeballModifierType("ub", PokeballType.ULTRA_BALL, 5), @@ -2373,23 +2386,18 @@ export const modifierTypes = { "golden_net", (type, _args) => new BoostBugSpawnModifier(type), ), -}; +}); + +/** + * The initial set of modifier types, used to generate the modifier pool. + */ +export type ModifierTypes = typeof modifierTypeInitObj; export interface ModifierPool { [tier: string]: WeightedModifierType[]; } - -const modifierPool: ModifierPool = { -}; - -export function getModifierType(modifierTypeFunc: ModifierTypeFunc): ModifierType { - const modifierType = modifierTypeFunc(); - if (!modifierType.id) { - modifierType.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifierTypeFunc)!; // TODO: is this bang correct? - } - return modifierType; -} +const modifierPool: ModifierPool = {}; let modifierPoolThresholds = {}; let ignoredPoolIndexes = {}; @@ -2519,7 +2527,7 @@ export interface CustomModifierSettings { } export function getModifierTypeFuncById(id: string): ModifierTypeFunc { - return modifierTypes[id]; + return modifierTypeInitObj[id]; } /** @@ -2572,12 +2580,12 @@ export function getPlayerModifierTypeOptions( customModifierSettings.guaranteedModifierTypeFuncs.length > 0 ) { customModifierSettings.guaranteedModifierTypeFuncs!.forEach((mod, _i) => { - const modifierId = Object.keys(modifierTypes).find(k => modifierTypes[k] === mod) as string; - let guaranteedMod: ModifierType = modifierTypes[modifierId]?.(); + const modifierId = Object.keys(modifierTypeInitObj).find(k => modifierTypeInitObj[k] === mod) as string; + let guaranteedMod: ModifierType = modifierTypeInitObj[modifierId]?.(); // Populates item id and tier guaranteedMod = guaranteedMod - .withIdFromFunc(modifierTypes[modifierId]) + .withIdFromFunc(modifierTypeInitObj[modifierId]) .withTierFromPool(ModifierPoolType.PLAYER, party); const modType = @@ -2656,7 +2664,7 @@ export function overridePlayerModifierTypeOptions(options: ModifierTypeOption[], const minLength = Math.min(options.length, Overrides.ITEM_REWARD_OVERRIDE.length); for (let i = 0; i < minLength; i++) { const override: ModifierOverride = Overrides.ITEM_REWARD_OVERRIDE[i]; - const modifierFunc = modifierTypes[override.name]; + const modifierFunc = modifierTypeInitObj[override.name]; let modifierType: ModifierType | null = modifierFunc(); if (modifierType instanceof ModifierTypeGenerator) { @@ -2677,29 +2685,29 @@ export function getPlayerShopModifierTypeOptionsForWave(waveIndex: number, baseC const options = [ [ - new ModifierTypeOption(modifierTypes.POTION(), 0, baseCost * 0.2), - new ModifierTypeOption(modifierTypes.ETHER(), 0, baseCost * 0.4), - new ModifierTypeOption(modifierTypes.REVIVE(), 0, baseCost * 2), + new ModifierTypeOption(modifierTypeInitObj.POTION(), 0, baseCost * 0.2), + new ModifierTypeOption(modifierTypeInitObj.ETHER(), 0, baseCost * 0.4), + new ModifierTypeOption(modifierTypeInitObj.REVIVE(), 0, baseCost * 2), ], [ - new ModifierTypeOption(modifierTypes.SUPER_POTION(), 0, baseCost * 0.45), - new ModifierTypeOption(modifierTypes.FULL_HEAL(), 0, baseCost), + new ModifierTypeOption(modifierTypeInitObj.SUPER_POTION(), 0, baseCost * 0.45), + new ModifierTypeOption(modifierTypeInitObj.FULL_HEAL(), 0, baseCost), ], [ - new ModifierTypeOption(modifierTypes.ELIXIR(), 0, baseCost), - new ModifierTypeOption(modifierTypes.MAX_ETHER(), 0, baseCost), + new ModifierTypeOption(modifierTypeInitObj.ELIXIR(), 0, baseCost), + new ModifierTypeOption(modifierTypeInitObj.MAX_ETHER(), 0, baseCost), ], [ - new ModifierTypeOption(modifierTypes.HYPER_POTION(), 0, baseCost * 0.8), - new ModifierTypeOption(modifierTypes.MAX_REVIVE(), 0, baseCost * 2.75), - new ModifierTypeOption(modifierTypes.MEMORY_MUSHROOM(), 0, baseCost * 4), + new ModifierTypeOption(modifierTypeInitObj.HYPER_POTION(), 0, baseCost * 0.8), + new ModifierTypeOption(modifierTypeInitObj.MAX_REVIVE(), 0, baseCost * 2.75), + new ModifierTypeOption(modifierTypeInitObj.MEMORY_MUSHROOM(), 0, baseCost * 4), ], [ - new ModifierTypeOption(modifierTypes.MAX_POTION(), 0, baseCost * 1.5), - new ModifierTypeOption(modifierTypes.MAX_ELIXIR(), 0, baseCost * 2.5), + new ModifierTypeOption(modifierTypeInitObj.MAX_POTION(), 0, baseCost * 1.5), + new ModifierTypeOption(modifierTypeInitObj.MAX_ELIXIR(), 0, baseCost * 2.5), ], - [new ModifierTypeOption(modifierTypes.FULL_RESTORE(), 0, baseCost * 2.25)], - [new ModifierTypeOption(modifierTypes.SACRED_ASH(), 0, baseCost * 10)], + [new ModifierTypeOption(modifierTypeInitObj.FULL_RESTORE(), 0, baseCost * 2.25)], + [new ModifierTypeOption(modifierTypeInitObj.SACRED_ASH(), 0, baseCost * 10)], ]; return options.slice(0, Math.ceil(Math.max(waveIndex + 10, 0) / 30)).flat(); } @@ -2754,7 +2762,7 @@ export function getEnemyModifierTypesForWave( ?.type as PokemonHeldItemModifierType, ); if (!(waveIndex % 1000)) { - ret.push(getModifierType(modifierTypes.MINI_BLACK_HOLE) as PokemonHeldItemModifierType); + ret.push(getModifierType(modifierTypeInitObj.MINI_BLACK_HOLE) as PokemonHeldItemModifierType); } return ret; } @@ -2984,3 +2992,34 @@ export function getLuckTextTint(luckValue: number): number { } return getModifierTierTextTint(modifierTier); } + +/** + * Initialize the modifier types object with the initial set of modifier types. + * {@linkcode initModifierPools} MUST be called before this function. + */ +export function initModifierTypes() { + for (const [key, value] of Object.entries(modifierTypeInitObj)) { + modifierTypes[key] = value; + } +} + +// TODO: If necessary, add the rest of the modifier types here. +// For now, doing the minimal work until the modifier rework lands. +const ModifierTypeConstructorMap = Object.freeze({ + ModifierTypeGenerator, + PokemonHeldItemModifierType, +}); + +/** + * Map of of modifier type strings to their constructor type + */ +export type ModifierTypeConstructorMap = typeof ModifierTypeConstructorMap; + +/** + * Map of modifier type strings to their instance type + */ +export type ModifierTypeInstanceMap = { + [K in keyof ModifierTypeConstructorMap]: InstanceType; +}; + +export type ModifierTypeString = keyof ModifierTypeConstructorMap; diff --git a/src/modifier/modifier-types.ts b/src/modifier/modifier-types.ts deleted file mode 100644 index 3b0043c1442..00000000000 --- a/src/modifier/modifier-types.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * - */ - -import type { AddPokeballModifierType, AllPokemonLevelIncrementModifierType, EvolutionItemModifierTypeGenerator, ModifierType, ModifierTypeGenerator, PokemonLevelIncrementModifierType } from "./modifier-type"; - -interface ModifierTypes { - POKEBALL: () => AddPokeballModifierType; - GREAT_BALL: () => AddPokeballModifierType; - ULTRA_BALL: () => AddPokeballModifierType; - ROGUE_BALL: () => AddPokeballModifierType; - MASTER_BALL: () => AddPokeballModifierType; - - RARE_CANDY: () => PokemonLevelIncrementModifierType; - RARER_CANDY: () => AllPokemonLevelIncrementModifierType; - - EVOLUTION_ITEM: () => EvolutionItemModifierTypeGenerator; - RARE_EVOLUTION_ITEM: () => EvolutionItemModifierTypeGenerator; - - FORM_CHANGE_ITEM: () => - -} \ No newline at end of file diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 3460c536f12..1c82fc19d91 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -1,12 +1,13 @@ import { FusionSpeciesFormEvolution, pokemonEvolutions } from "#app/data/balance/pokemon-evolutions"; import { getBerryEffectFunc, getBerryPredicate } from "#app/data/berry"; import { getLevelTotalExp } from "#app/data/exp"; -import { allMoves } from "#app/data/data-lists"; +import { allMoves, modifierTypes } from "#app/data/data-lists"; import { MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball"; import { SpeciesFormChangeItemTrigger } from "#app/data/pokemon-forms/form-change-triggers"; import type { FormChangeItem } from "#enums/form-change-item"; import { getStatusEffectHealText } from "#app/data/status-effect"; -import Pokemon, { type PlayerPokemon } from "#app/field/pokemon"; +import type { PlayerPokemon } from "#app/field/pokemon"; +import type Pokemon from "#app/field/pokemon"; import { getPokemonNameWithAffix } from "#app/messages"; import Overrides from "#app/overrides"; import { LearnMoveType } from "#enums/learn-move-type"; @@ -24,29 +25,26 @@ import { type PermanentStat, type TempBattleStat, BATTLE_STATS, Stat, TEMP_BATTL import { StatusEffect } from "#enums/status-effect"; import type { PokemonType } from "#enums/pokemon-type"; import i18next from "i18next"; -import { - type DoubleBattleChanceBoosterModifierType, - type EvolutionItemModifierType, - type FormChangeItemModifierType, - type ModifierOverride, - type ModifierType, - type PokemonBaseStatTotalModifierType, - type PokemonExpBoosterModifierType, - type PokemonFriendshipBoosterModifierType, - type PokemonMoveAccuracyBoosterModifierType, - type PokemonMultiHitModifierType, - type TerastallizeModifierType, - type TmModifierType, - getModifierType, - ModifierTypeGenerator, - modifierTypes, - PokemonHeldItemModifierType, +import type { + DoubleBattleChanceBoosterModifierType, + EvolutionItemModifierType, + FormChangeItemModifierType, + ModifierOverride, + ModifierType, + PokemonBaseStatTotalModifierType, + PokemonExpBoosterModifierType, + PokemonFriendshipBoosterModifierType, + PokemonMoveAccuracyBoosterModifierType, + PokemonMultiHitModifierType, + TerastallizeModifierType, + TmModifierType, } from "./modifier-type"; +import { getModifierType } from "#app/utils/modifier-utils"; import { Color, ShadowColor } from "#enums/color"; import { FRIENDSHIP_GAIN_FROM_RARE_CANDY } from "#app/data/balance/starters"; import { applyAbAttrs, applyPostItemLostAbAttrs } from "#app/data/abilities/apply-ab-attrs"; import { globalScene } from "#app/global-scene"; -import type { ModifierString } from "#app/@types/modifier-types"; +import type { ModifierInstanceMap, ModifierString } from "#app/@types/modifier-types"; export type ModifierPredicate = (modifier: Modifier) => boolean; @@ -161,7 +159,7 @@ export abstract class Modifier { } /** */ - public is(modifier: ModifierString): this is ModifierConstructorMap[T] { + public is(modifier: T): this is ModifierInstanceMap[T] { const targetModifier = ModifierClassMap[modifier]; if (!targetModifier) { return false; @@ -193,6 +191,9 @@ export abstract class PersistentModifier extends Modifier { public stackCount: number; public virtualStackCount: number; + /** */ + private declare _: never; + constructor(type: ModifierType, stackCount = 1) { super(type); this.stackCount = stackCount; @@ -1598,7 +1599,7 @@ export class BypassSpeedChanceModifier extends PokemonHeldItemModifier { doBypassSpeed.value = true; const isCommandFight = globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()]?.command === Command.FIGHT; - const hasQuickClaw = this.type instanceof PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW"; + const hasQuickClaw = this.type.is("PokemonHeldItemModifierType") && this.type.id === "QUICK_CLAW"; if (isCommandFight && hasQuickClaw) { globalScene.phaseManager.queueMessage( @@ -3220,7 +3221,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier { * @returns the opponents of the source {@linkcode Pokemon} */ getTargets(pokemon?: Pokemon, ..._args: unknown[]): Pokemon[] { - return pokemon instanceof Pokemon ? pokemon.getOpponents() : []; + return pokemon?.getOpponents?.() ?? []; } /** @@ -3792,7 +3793,7 @@ export function overrideModifiers(isPlayer = true): void { const modifierFunc = modifierTypes[item.name]; let modifierType: ModifierType | null = modifierFunc(); - if (modifierType instanceof ModifierTypeGenerator) { + if (modifierType.is("ModifierTypeGenerator")) { const pregenArgs = "type" in item && item.type !== null ? [item.type] : undefined; modifierType = modifierType.generateType([], pregenArgs); } @@ -3834,7 +3835,7 @@ export function overrideHeldItems(pokemon: Pokemon, isPlayer = true): void { let modifierType: ModifierType | null = modifierFunc(); const qty = item.count || 1; - if (modifierType instanceof ModifierTypeGenerator) { + if (modifierType.is("ModifierTypeGenerator")) { const pregenArgs = "type" in item && item.type !== null ? [item.type] : undefined; modifierType = modifierType.generateType([], pregenArgs); } @@ -3853,10 +3854,9 @@ export function overrideHeldItems(pokemon: Pokemon, isPlayer = true): void { } } - /** * Private map from modifier strings to their constructors. - * + * * @remarks * Used for {@linkcode Modifier.is} to check if a modifier is of a certain type without * requiring modifier types to be imported in every file. @@ -3948,6 +3948,7 @@ const ModifierClassMap = Object.freeze({ EnemyStatusEffectHealChanceModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, + MoneyMultiplierModifier, }); -export type ModifierConstructorMap = typeof ModifierClassMap; \ No newline at end of file +export type ModifierConstructorMap = typeof ModifierClassMap; diff --git a/src/phases/game-over-phase.ts b/src/phases/game-over-phase.ts index 5fabc5cee81..82c454e95f3 100644 --- a/src/phases/game-over-phase.ts +++ b/src/phases/game-over-phase.ts @@ -7,7 +7,7 @@ import type PokemonSpecies from "#app/data/pokemon-species"; import { getPokemonSpecies } from "#app/data/pokemon-species"; import { trainerConfigs } from "#app/data/trainers/trainer-config"; import type Pokemon from "#app/field/pokemon"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { BattlePhase } from "#app/phases/battle-phase"; import type { EndCardPhase } from "#app/phases/end-card-phase"; import { achvs, ChallengeAchv } from "#app/system/achv"; diff --git a/src/phases/modifier-reward-phase.ts b/src/phases/modifier-reward-phase.ts index 4c427f2284e..29bbe215fc0 100644 --- a/src/phases/modifier-reward-phase.ts +++ b/src/phases/modifier-reward-phase.ts @@ -1,7 +1,7 @@ import { globalScene } from "#app/global-scene"; import type { ModifierType } from "#app/modifier/modifier-type"; import type { ModifierTypeFunc } from "#app/@types/modifier-types"; -import { getModifierType } from "#app/modifier/modifier-type"; +import { getModifierType } from "#app/utils/modifier-utils"; import i18next from "i18next"; import { BattlePhase } from "./battle-phase"; diff --git a/src/phases/title-phase.ts b/src/phases/title-phase.ts index 5665f7148bd..785e88dba27 100644 --- a/src/phases/title-phase.ts +++ b/src/phases/title-phase.ts @@ -6,11 +6,8 @@ import { getBiomeKey } from "#app/field/arena"; import { GameMode, getGameMode } from "#app/game-mode"; import { GameModes } from "#enums/game-modes"; import type { Modifier } from "#app/modifier/modifier"; -import { - getDailyRunStarterModifiers, - modifierTypes, - regenerateModifierPoolThresholds, -} from "#app/modifier/modifier-type"; +import { getDailyRunStarterModifiers, regenerateModifierPoolThresholds } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { ModifierPoolType } from "#enums/modifier-pool-type"; import { Phase } from "#app/phase"; import type { SessionSaveData } from "#app/system/game-data"; diff --git a/src/phases/trainer-victory-phase.ts b/src/phases/trainer-victory-phase.ts index 5d35dd5d375..554b8109f02 100644 --- a/src/phases/trainer-victory-phase.ts +++ b/src/phases/trainer-victory-phase.ts @@ -1,6 +1,6 @@ import { getCharVariantFromDialogue } from "#app/data/dialogue"; import { TrainerType } from "#app/enums/trainer-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { vouchers } from "#app/system/voucher"; import i18next from "i18next"; import { randSeedItem } from "#app/utils/common"; diff --git a/src/phases/victory-phase.ts b/src/phases/victory-phase.ts index bf6ea6d4a43..ae5b727c2a6 100644 --- a/src/phases/victory-phase.ts +++ b/src/phases/victory-phase.ts @@ -2,7 +2,7 @@ import type { BattlerIndex } from "#enums/battler-index"; import { ClassicFixedBossWaves } from "#enums/fixed-boss-waves"; import { BattleType } from "#enums/battle-type"; import type { CustomModifierSettings } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { PokemonPhase } from "./pokemon-phase"; import { handleMysteryEncounterVictory } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { globalScene } from "#app/global-scene"; diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index f60bfa808ca..a2dfe83e996 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -7,11 +7,7 @@ import { Command } from "#enums/command"; import MessageUiHandler from "#app/ui/message-ui-handler"; import { UiMode } from "#enums/ui-mode"; import { BooleanHolder, toReadableString, randInt, getLocalizedSpriteKey } from "#app/utils/common"; -import { - PokemonFormChangeItemModifier, - PokemonHeldItemModifier, - SwitchEffectTransferModifier, -} from "#app/modifier/modifier"; +import type { PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/modifier/modifier"; import { allMoves } from "#app/data/data-lists"; import { Gender, getGenderColor, getGenderSymbol } from "#app/data/gender"; import { StatusEffect } from "#enums/status-effect"; @@ -226,7 +222,7 @@ export default class PartyUiHandler extends MessageUiHandler { public static FilterItemMaxStacks = (pokemon: PlayerPokemon, modifier: PokemonHeldItemModifier) => { const matchingModifier = globalScene.findModifier( - m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(modifier), + m => m.is("PokemonHeldItemModifier") && m.pokemonId === pokemon.id && m.matchType(modifier), ) as PokemonHeldItemModifier; if (matchingModifier && matchingModifier.stackCount === matchingModifier.getMaxStackCount()) { return i18next.t("partyUiHandler:tooManyItems", { pokemonName: getPokemonNameWithAffix(pokemon, false) }); @@ -554,7 +550,7 @@ export default class PartyUiHandler extends MessageUiHandler { // this returns `undefined` if the new pokemon doesn't have the item at all, otherwise it returns the `pokemonHeldItemModifier` for that item const matchingModifier = globalScene.findModifier( m => - m instanceof PokemonHeldItemModifier && + m.is("PokemonHeldItemModifier") && m.pokemonId === newPokemon.id && m.matchType(this.getTransferrableItemsFromPokemon(pokemon)[this.transferOptionCursor]), ) as PokemonHeldItemModifier; @@ -687,7 +683,7 @@ export default class PartyUiHandler extends MessageUiHandler { private getTransferrableItemsFromPokemon(pokemon: PlayerPokemon) { return globalScene.findModifiers( - m => m instanceof PokemonHeldItemModifier && m.isTransferable && m.pokemonId === pokemon.id, + m => m.is("PokemonHeldItemModifier") && m.isTransferable && m.pokemonId === pokemon.id, ) as PokemonHeldItemModifier[]; } @@ -928,7 +924,7 @@ export default class PartyUiHandler extends MessageUiHandler { /** Initialize item quantities for the selected Pokemon */ const itemModifiers = globalScene.findModifiers( m => - m instanceof PokemonHeldItemModifier && + m.is("PokemonHeldItemModifier") && m.isTransferable && m.pokemonId === globalScene.getPlayerParty()[this.cursor].id, ) as PokemonHeldItemModifier[]; @@ -1165,8 +1161,7 @@ export default class PartyUiHandler extends MessageUiHandler { return !!( this.partyUiMode !== PartyUiMode.FAINT_SWITCH && globalScene.findModifier( - m => - m instanceof SwitchEffectTransferModifier && m.pokemonId === globalScene.getPlayerField()[this.fieldIndex].id, + m => m.is("SwitchEffectTransferModifier") && m.pokemonId === globalScene.getPlayerField()[this.fieldIndex].id, ) ); } @@ -1185,7 +1180,7 @@ export default class PartyUiHandler extends MessageUiHandler { private getItemModifiers(pokemon: Pokemon): PokemonHeldItemModifier[] { return ( (globalScene.findModifiers( - m => m instanceof PokemonHeldItemModifier && m.isTransferable && m.pokemonId === pokemon.id, + m => m.is("PokemonHeldItemModifier") && m.isTransferable && m.pokemonId === pokemon.id, ) as PokemonHeldItemModifier[]) ?? [] ); } @@ -1565,7 +1560,7 @@ export default class PartyUiHandler extends MessageUiHandler { getFormChangeItemsModifiers(pokemon: Pokemon) { let formChangeItemModifiers = globalScene.findModifiers( - m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === pokemon.id, + m => m.is("PokemonFormChangeItemModifier") && m.pokemonId === pokemon.id, ) as PokemonFormChangeItemModifier[]; const ultraNecrozmaModifiers = formChangeItemModifiers.filter( m => m.active && m.formChangeItem === FormChangeItem.ULTRANECROZIUM_Z, diff --git a/src/utils/modifier-pool-utils.ts b/src/utils/modifier-utils.ts similarity index 55% rename from src/utils/modifier-pool-utils.ts rename to src/utils/modifier-utils.ts index 46d13ce6f96..3be4af3730c 100644 --- a/src/utils/modifier-pool-utils.ts +++ b/src/utils/modifier-utils.ts @@ -6,7 +6,9 @@ import { trainerModifierPool, wildModifierPool, } from "#app/modifier/modifier-pools"; -import type { ModifierPool } from "#app/@types/modifier-types"; +import type { ModifierPool, ModifierTypeFunc } from "#app/@types/modifier-types"; +import { modifierTypes } from "#app/data/data-lists"; +import type { ModifierType } from "#app/modifier/modifier-type"; export function getModifierPoolForType(poolType: ModifierPoolType): ModifierPool { switch (poolType) { @@ -22,3 +24,12 @@ export function getModifierPoolForType(poolType: ModifierPoolType): ModifierPool return dailyStarterModifierPool; } } + +// TODO: document this +export function getModifierType(modifierTypeFunc: ModifierTypeFunc): ModifierType { + const modifierType = modifierTypeFunc(); + if (!modifierType.id) { + modifierType.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifierTypeFunc)!; // TODO: is this bang correct? + } + return modifierType; +} diff --git a/test/abilities/healer.test.ts b/test/abilities/healer.test.ts index de79e6a6391..9d252523cc8 100644 --- a/test/abilities/healer.test.ts +++ b/test/abilities/healer.test.ts @@ -8,6 +8,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi, type MockIn import { isNullOrUndefined } from "#app/utils/common"; import { allAbilities } from "#app/data/data-lists"; import type Pokemon from "#app/field/pokemon"; +import type { PostTurnResetStatusAbAttr } from "#app/@types/ability-types"; describe("Abilities - Healer", () => { let phaserGame: Phaser.Game; diff --git a/test/battle/damage_calculation.test.ts b/test/battle/damage_calculation.test.ts index a054ad0f468..555b3a9c554 100644 --- a/test/battle/damage_calculation.test.ts +++ b/test/battle/damage_calculation.test.ts @@ -1,6 +1,6 @@ import { allMoves } from "#app/data/data-lists"; import type { EnemyPersistentModifier } from "#app/modifier/modifier"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { AbilityId } from "#enums/ability-id"; import { ArenaTagType } from "#enums/arena-tag-type"; import { MoveId } from "#enums/move-id"; diff --git a/test/items/light_ball.test.ts b/test/items/light_ball.test.ts index 84a1689260f..a0269506909 100644 --- a/test/items/light_ball.test.ts +++ b/test/items/light_ball.test.ts @@ -1,6 +1,6 @@ import { Stat } from "#enums/stat"; import { SpeciesStatBoosterModifier } from "#app/modifier/modifier"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import i18next from "#app/plugins/i18n"; import { NumberHolder } from "#app/utils/common"; import { SpeciesId } from "#enums/species-id"; diff --git a/test/items/metal_powder.test.ts b/test/items/metal_powder.test.ts index 20b0b90a766..576b4923d6d 100644 --- a/test/items/metal_powder.test.ts +++ b/test/items/metal_powder.test.ts @@ -1,6 +1,6 @@ import { Stat } from "#enums/stat"; import { SpeciesStatBoosterModifier } from "#app/modifier/modifier"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import i18next from "#app/plugins/i18n"; import { NumberHolder } from "#app/utils/common"; import { SpeciesId } from "#enums/species-id"; diff --git a/test/items/quick_powder.test.ts b/test/items/quick_powder.test.ts index 0192dec4635..af99f51273d 100644 --- a/test/items/quick_powder.test.ts +++ b/test/items/quick_powder.test.ts @@ -1,6 +1,6 @@ import { Stat } from "#enums/stat"; import { SpeciesStatBoosterModifier } from "#app/modifier/modifier"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import i18next from "#app/plugins/i18n"; import { NumberHolder } from "#app/utils/common"; import { SpeciesId } from "#enums/species-id"; diff --git a/test/items/thick_club.test.ts b/test/items/thick_club.test.ts index cff080d0e42..bc019ee99f8 100644 --- a/test/items/thick_club.test.ts +++ b/test/items/thick_club.test.ts @@ -1,6 +1,6 @@ import { Stat } from "#enums/stat"; import { SpeciesStatBoosterModifier } from "#app/modifier/modifier"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import i18next from "#app/plugins/i18n"; import { NumberHolder, randInt } from "#app/utils/common"; import { SpeciesId } from "#enums/species-id"; diff --git a/test/mystery-encounter/encounters/clowning-around-encounter.test.ts b/test/mystery-encounter/encounters/clowning-around-encounter.test.ts index dceab2f20cb..526a3a0ab67 100644 --- a/test/mystery-encounter/encounters/clowning-around-encounter.test.ts +++ b/test/mystery-encounter/encounters/clowning-around-encounter.test.ts @@ -29,7 +29,7 @@ import { Button } from "#enums/buttons"; import type PartyUiHandler from "#app/ui/party-ui-handler"; import type OptionSelectUiHandler from "#app/ui/settings/option-select-ui-handler"; import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { BerryType } from "#enums/berry-type"; import type { PokemonHeldItemModifier } from "#app/modifier/modifier"; import { PokemonType } from "#enums/pokemon-type"; diff --git a/test/mystery-encounter/encounters/delibirdy-encounter.test.ts b/test/mystery-encounter/encounters/delibirdy-encounter.test.ts index 0d1094831bc..e569c1d7789 100644 --- a/test/mystery-encounter/encounters/delibirdy-encounter.test.ts +++ b/test/mystery-encounter/encounters/delibirdy-encounter.test.ts @@ -26,7 +26,7 @@ import { } from "#app/modifier/modifier"; import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; import { generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { BerryType } from "#enums/berry-type"; const namespace = "mysteryEncounters/delibirdy"; diff --git a/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts b/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts index 53c1ee811e3..0aa1886b8e1 100644 --- a/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts +++ b/test/mystery-encounter/encounters/global-trade-system-encounter.test.ts @@ -11,7 +11,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import * as MysteryEncounters from "#app/data/mystery-encounters/mystery-encounters"; import { PokemonNatureWeightModifier } from "#app/modifier/modifier"; import { generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { GlobalTradeSystemEncounter } from "#app/data/mystery-encounters/encounters/global-trade-system-encounter"; import { CIVILIZATION_ENCOUNTER_BIOMES } from "#app/data/mystery-encounters/mystery-encounters"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; diff --git a/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts b/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts index 3316bf76280..2014cb215a4 100644 --- a/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts +++ b/test/mystery-encounter/encounters/trash-to-treasure-encounter.test.ts @@ -15,7 +15,8 @@ import { SpeciesId } from "#enums/species-id"; import { PokemonMove } from "#app/data/moves/pokemon-move"; import { HealShopCostModifier, HitHealModifier, TurnHealModifier } from "#app/modifier/modifier"; import { ModifierTier } from "#enums/modifier-tier"; -import { modifierTypes, type PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; +import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { CommandPhase } from "#app/phases/command-phase"; import { MovePhase } from "#app/phases/move-phase"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; diff --git a/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts b/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts index 12545b8d70a..60ca87d3ae2 100644 --- a/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts +++ b/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts @@ -26,7 +26,7 @@ import { BerryType } from "#enums/berry-type"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { Stat } from "#enums/stat"; import type { BerryModifier } from "#app/modifier/modifier"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { AbilityId } from "#enums/ability-id"; const namespace = "mysteryEncounters/uncommonBreed"; diff --git a/test/phases/form-change-phase.test.ts b/test/phases/form-change-phase.test.ts index 8531375a48b..99c072bdafe 100644 --- a/test/phases/form-change-phase.test.ts +++ b/test/phases/form-change-phase.test.ts @@ -6,7 +6,7 @@ import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { PokemonType } from "#enums/pokemon-type"; import { generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { modifierTypes } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; describe("Form Change Phase", () => { let phaserGame: Phaser.Game; diff --git a/test/phases/select-modifier-phase.test.ts b/test/phases/select-modifier-phase.test.ts index 0605fdf7809..3639d34d25e 100644 --- a/test/phases/select-modifier-phase.test.ts +++ b/test/phases/select-modifier-phase.test.ts @@ -3,7 +3,8 @@ import { getPokemonSpecies } from "#app/data/pokemon-species"; import { PlayerPokemon } from "#app/field/pokemon"; import { ModifierTier } from "#enums/modifier-tier"; import type { CustomModifierSettings } from "#app/modifier/modifier-type"; -import { ModifierTypeOption, modifierTypes } from "#app/modifier/modifier-type"; +import { ModifierTypeOption } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; import { UiMode } from "#enums/ui-mode"; diff --git a/test/testUtils/gameManager.ts b/test/testUtils/gameManager.ts index 128217a6472..5d3ed3b6c8c 100644 --- a/test/testUtils/gameManager.ts +++ b/test/testUtils/gameManager.ts @@ -6,7 +6,8 @@ import Trainer from "#app/field/trainer"; import { getGameMode } from "#app/game-mode"; import { GameModes } from "#enums/game-modes"; import { globalScene } from "#app/global-scene"; -import { ModifierTypeOption, modifierTypes } from "#app/modifier/modifier-type"; +import { ModifierTypeOption } from "#app/modifier/modifier-type"; +import { modifierTypes } from "#app/data/data-lists"; import overrides from "#app/overrides"; import { CheckSwitchPhase } from "#app/phases/check-switch-phase"; import { CommandPhase } from "#app/phases/command-phase"; diff --git a/test/testUtils/testFileInitialization.ts b/test/testUtils/testFileInitialization.ts index ba90cba7d5b..da390870300 100644 --- a/test/testUtils/testFileInitialization.ts +++ b/test/testUtils/testFileInitialization.ts @@ -5,6 +5,7 @@ import { initBiomes } from "#app/data/balance/biomes"; import { initEggMoves } from "#app/data/balance/egg-moves"; import { initPokemonPrevolutions, initPokemonStarters } from "#app/data/balance/pokemon-evolutions"; import { initMoves } from "#app/data/moves/move"; +import { initModifierPools } from "#app/modifier/init-modifier-pools"; import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters"; import { initPokemonForms } from "#app/data/pokemon-forms"; import { initSpecies } from "#app/data/pokemon-species"; @@ -22,6 +23,7 @@ import InputText from "phaser3-rex-plugins/plugins/inputtext"; import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; import { manageListeners } from "./listenersManager"; import { initI18n } from "#app/plugins/i18n"; +import { initModifierTypes } from "#app/modifier/modifier-type"; let wasInitialized = false; /** @@ -88,6 +90,8 @@ export function initTestFile() { if (!wasInitialized) { wasInitialized = true; initI18n(); + initModifierTypes(); + initModifierPools(); initVouchers(); initAchievements(); initStatsKeys();