mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-09-24 07:23:24 +02:00
Moved various files
This commit is contained in:
parent
6e52baebee
commit
c89b584b41
@ -3,7 +3,7 @@ import { getHeldItemCategory, HeldItemCategoryId } from "#enums/held-item-id";
|
|||||||
import { MoveId } from "#enums/move-id";
|
import { MoveId } from "#enums/move-id";
|
||||||
import { RewardId } from "#enums/reward-id";
|
import { RewardId } from "#enums/reward-id";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { HeldItemReward } from "#items/reward";
|
import { HeldItemReward } from "#items/rewards/held-item-reward";
|
||||||
import { GameManager } from "#test/test-utils/game-manager";
|
import { GameManager } from "#test/test-utils/game-manager";
|
||||||
import { generateRewardForTest } from "#test/test-utils/reward-test-utils";
|
import { generateRewardForTest } from "#test/test-utils/reward-test-utils";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import type { PartyMemberStrength } from "#enums/party-member-strength";
|
import type { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
import type { SpeciesId } from "#enums/species-id";
|
import type { SpeciesId } from "#enums/species-id";
|
||||||
import type { EnemyPokemon } from "#field/pokemon";
|
import type { EnemyPokemon } from "#field/pokemon";
|
||||||
import type { TrainerItemConfiguration } from "#items/trainer-item-data-types";
|
|
||||||
import type { TrainerConfig } from "#trainers/trainer-config";
|
import type { TrainerConfig } from "#trainers/trainer-config";
|
||||||
import type { TrainerPartyTemplate } from "#trainers/trainer-party-template";
|
import type { TrainerPartyTemplate } from "#trainers/trainer-party-template";
|
||||||
|
import type { TrainerItemConfiguration } from "./trainer-item-data-types";
|
||||||
|
|
||||||
export type PartyTemplateFunc = () => TrainerPartyTemplate;
|
export type PartyTemplateFunc = () => TrainerPartyTemplate;
|
||||||
export type PartyMemberFunc = (level: number, strength: PartyMemberStrength) => EnemyPokemon;
|
export type PartyMemberFunc = (level: number, strength: PartyMemberStrength) => EnemyPokemon;
|
||||||
|
@ -79,19 +79,11 @@ import { PokemonSpriteSparkleHandler } from "#field/pokemon-sprite-sparkle-handl
|
|||||||
import { Trainer } from "#field/trainer";
|
import { Trainer } from "#field/trainer";
|
||||||
import { applyHeldItems } from "#items/all-held-items";
|
import { applyHeldItems } from "#items/all-held-items";
|
||||||
import { applyTrainerItems } from "#items/all-trainer-items";
|
import { applyTrainerItems } from "#items/all-trainer-items";
|
||||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
|
||||||
import { assignEnemyHeldItemsForWave, assignItemsFromConfiguration } from "#items/held-item-pool";
|
import { assignEnemyHeldItemsForWave, assignItemsFromConfiguration } from "#items/held-item-pool";
|
||||||
import type { MatchExact, Reward } from "#items/reward";
|
import type { MatchExact, Reward } from "#items/reward";
|
||||||
import type { EnemyAttackStatusEffectChanceTrainerItem } from "#items/trainer-item";
|
|
||||||
import {
|
|
||||||
isTrainerItemPool,
|
|
||||||
isTrainerItemSpecs,
|
|
||||||
type TrainerItemConfiguration,
|
|
||||||
type TrainerItemSaveData,
|
|
||||||
} from "#items/trainer-item-data-types";
|
|
||||||
import { TrainerItemManager } from "#items/trainer-item-manager";
|
import { TrainerItemManager } from "#items/trainer-item-manager";
|
||||||
import type { TrainerItemEffectParamMap } from "#items/trainer-item-parameter";
|
|
||||||
import { getNewTrainerItemFromPool } from "#items/trainer-item-pool";
|
import { getNewTrainerItemFromPool } from "#items/trainer-item-pool";
|
||||||
|
import type { EnemyAttackStatusEffectChanceTrainerItem } from "#items/trainer-items/enemy-tokens";
|
||||||
import { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
import { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
||||||
import { MysteryEncounterSaveData } from "#mystery-encounters/mystery-encounter-save-data";
|
import { MysteryEncounterSaveData } from "#mystery-encounters/mystery-encounter-save-data";
|
||||||
import { allMysteryEncounters, mysteryEncountersByBiome } from "#mystery-encounters/mystery-encounters";
|
import { allMysteryEncounters, mysteryEncountersByBiome } from "#mystery-encounters/mystery-encounters";
|
||||||
@ -110,7 +102,15 @@ import type { TrainerData } from "#system/trainer-data";
|
|||||||
import type { Voucher } from "#system/voucher";
|
import type { Voucher } from "#system/voucher";
|
||||||
import { vouchers } from "#system/voucher";
|
import { vouchers } from "#system/voucher";
|
||||||
import { trainerConfigs } from "#trainers/trainer-config";
|
import { trainerConfigs } from "#trainers/trainer-config";
|
||||||
|
import type { HeldItemConfiguration } from "#types/held-item-data-types";
|
||||||
import type { Localizable } from "#types/locales";
|
import type { Localizable } from "#types/locales";
|
||||||
|
import {
|
||||||
|
isTrainerItemPool,
|
||||||
|
isTrainerItemSpecs,
|
||||||
|
type TrainerItemConfiguration,
|
||||||
|
type TrainerItemSaveData,
|
||||||
|
} from "#types/trainer-item-data-types";
|
||||||
|
import type { TrainerItemEffectParamMap } from "#types/trainer-item-parameter";
|
||||||
import { AbilityBar } from "#ui/ability-bar";
|
import { AbilityBar } from "#ui/ability-bar";
|
||||||
import { ArenaFlyout } from "#ui/arena-flyout";
|
import { ArenaFlyout } from "#ui/arena-flyout";
|
||||||
import { CandyBar } from "#ui/candy-bar";
|
import { CandyBar } from "#ui/candy-bar";
|
||||||
|
@ -15,7 +15,6 @@ import { TrainerSlot } from "#enums/trainer-slot";
|
|||||||
import type { MysteryEncounterSpriteConfig } from "#field/mystery-encounter-intro";
|
import type { MysteryEncounterSpriteConfig } from "#field/mystery-encounter-intro";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { EnemyPokemon } from "#field/pokemon";
|
import { EnemyPokemon } from "#field/pokemon";
|
||||||
import type { HeldItemConfiguration, HeldItemSpecs, PokemonItemMap } from "#items/held-item-data-types";
|
|
||||||
import { getPartyBerries } from "#items/item-utility";
|
import { getPartyBerries } from "#items/item-utility";
|
||||||
import { PokemonMove } from "#moves/pokemon-move";
|
import { PokemonMove } from "#moves/pokemon-move";
|
||||||
import { queueEncounterMessage } from "#mystery-encounters/encounter-dialogue-utils";
|
import { queueEncounterMessage } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
@ -31,6 +30,7 @@ import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
|||||||
import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
|
import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
|
||||||
import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option";
|
import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option";
|
||||||
import { HeldItemRequirement } from "#mystery-encounters/mystery-encounter-requirements";
|
import { HeldItemRequirement } from "#mystery-encounters/mystery-encounter-requirements";
|
||||||
|
import type { HeldItemConfiguration, HeldItemSpecs, PokemonItemMap } from "#types/held-item-data-types";
|
||||||
import { pickWeightedIndex, randInt } from "#utils/common";
|
import { pickWeightedIndex, randInt } from "#utils/common";
|
||||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
@ -2,6 +2,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { EncounterBattleAnim } from "#data/battle-anims";
|
import { EncounterBattleAnim } from "#data/battle-anims";
|
||||||
import { allAbilities } from "#data/data-lists";
|
import { allAbilities } from "#data/data-lists";
|
||||||
|
import { getHeldItemTier } from "#data/items/held-item-default-tiers";
|
||||||
import { CustomPokemonData } from "#data/pokemon-data";
|
import { CustomPokemonData } from "#data/pokemon-data";
|
||||||
import { AbilityId } from "#enums/ability-id";
|
import { AbilityId } from "#enums/ability-id";
|
||||||
import { BattlerIndex } from "#enums/battler-index";
|
import { BattlerIndex } from "#enums/battler-index";
|
||||||
@ -21,7 +22,6 @@ import { SpeciesId } from "#enums/species-id";
|
|||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { UiMode } from "#enums/ui-mode";
|
import { UiMode } from "#enums/ui-mode";
|
||||||
import type { PlayerPokemon } from "#field/pokemon";
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
import { getHeldItemTier } from "#items/held-item-default-tiers";
|
|
||||||
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
||||||
import { PokemonMove } from "#moves/pokemon-move";
|
import { PokemonMove } from "#moves/pokemon-move";
|
||||||
import { showEncounterDialogue, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
import { showEncounterDialogue, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
|
@ -7,13 +7,13 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
|||||||
import type { PokemonType } from "#enums/pokemon-type";
|
import type { PokemonType } from "#enums/pokemon-type";
|
||||||
import { RewardId } from "#enums/reward-id";
|
import { RewardId } from "#enums/reward-id";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
|
||||||
import type { EnemyPartyConfig, EnemyPokemonConfig } from "#mystery-encounters/encounter-phase-utils";
|
import type { EnemyPartyConfig, EnemyPokemonConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||||
import { initBattleWithEnemyConfig, leaveEncounterWithoutBattle } from "#mystery-encounters/encounter-phase-utils";
|
import { initBattleWithEnemyConfig, leaveEncounterWithoutBattle } from "#mystery-encounters/encounter-phase-utils";
|
||||||
import { getRandomPlayerPokemon, getRandomSpeciesByStarterCost } from "#mystery-encounters/encounter-pokemon-utils";
|
import { getRandomPlayerPokemon, getRandomSpeciesByStarterCost } from "#mystery-encounters/encounter-pokemon-utils";
|
||||||
import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
||||||
import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
|
import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
|
||||||
import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option";
|
import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option";
|
||||||
|
import type { HeldItemConfiguration } from "#types/held-item-data-types";
|
||||||
import { isNullOrUndefined, randSeedInt } from "#utils/common";
|
import { isNullOrUndefined, randSeedInt } from "#utils/common";
|
||||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||||
|
|
||||||
|
@ -8,9 +8,10 @@ import { RewardPoolType } from "#enums/reward-pool-type";
|
|||||||
import { RarityTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { TrainerItemId } from "#enums/trainer-item-id";
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import type { RewardOption, TrainerItemReward } from "#items/reward";
|
import type { RewardOption } from "#items/reward";
|
||||||
import { generatePlayerRewardOptions, generateRewardPoolWeights, getRewardPoolForType } from "#items/reward-pool-utils";
|
import { generatePlayerRewardOptions, generateRewardPoolWeights, getRewardPoolForType } from "#items/reward-pool-utils";
|
||||||
import { isTmReward } from "#items/reward-utils";
|
import { isTmReward } from "#items/reward-utils";
|
||||||
|
import type { TrainerItemReward } from "#items/rewards/trainer-item-reward";
|
||||||
import { queueEncounterMessage } from "#mystery-encounters/encounter-dialogue-utils";
|
import { queueEncounterMessage } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||||
import {
|
import {
|
||||||
|
@ -3,6 +3,7 @@ import { timedEventManager } from "#app/global-event-manager";
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { allHeldItems, allSpecies } from "#data/data-lists";
|
import { allHeldItems, allSpecies } from "#data/data-lists";
|
||||||
import { Gender, getGenderSymbol } from "#data/gender";
|
import { Gender, getGenderSymbol } from "#data/gender";
|
||||||
|
import { getHeldItemTier } from "#data/items/held-item-default-tiers";
|
||||||
import { getNatureName } from "#data/nature";
|
import { getNatureName } from "#data/nature";
|
||||||
import { getPokeballAtlasKey, getPokeballTintColor } from "#data/pokeball";
|
import { getPokeballAtlasKey, getPokeballTintColor } from "#data/pokeball";
|
||||||
import type { PokemonSpecies } from "#data/pokemon-species";
|
import type { PokemonSpecies } from "#data/pokemon-species";
|
||||||
@ -21,7 +22,6 @@ import { TrainerType } from "#enums/trainer-type";
|
|||||||
import { doShinySparkleAnim } from "#field/anims";
|
import { doShinySparkleAnim } from "#field/anims";
|
||||||
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
import { EnemyPokemon } from "#field/pokemon";
|
import { EnemyPokemon } from "#field/pokemon";
|
||||||
import { getHeldItemTier } from "#items/held-item-default-tiers";
|
|
||||||
import type { RewardOption } from "#items/reward";
|
import type { RewardOption } from "#items/reward";
|
||||||
import { generatePlayerRewardOptions, generateRewardPoolWeights, getRewardPoolForType } from "#items/reward-pool-utils";
|
import { generatePlayerRewardOptions, generateRewardPoolWeights, getRewardPoolForType } from "#items/reward-pool-utils";
|
||||||
import { isTmReward } from "#items/reward-utils";
|
import { isTmReward } from "#items/reward-utils";
|
||||||
|
@ -11,7 +11,6 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
|||||||
import { PokeballType } from "#enums/pokeball";
|
import { PokeballType } from "#enums/pokeball";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import type { EnemyPokemon, Pokemon } from "#field/pokemon";
|
import type { EnemyPokemon, Pokemon } from "#field/pokemon";
|
||||||
import type { HeldItemSpecs } from "#items/held-item-data-types";
|
|
||||||
import { getPartyBerries } from "#items/item-utility";
|
import { getPartyBerries } from "#items/item-utility";
|
||||||
import { PokemonMove } from "#moves/pokemon-move";
|
import { PokemonMove } from "#moves/pokemon-move";
|
||||||
import { queueEncounterMessage } from "#mystery-encounters/encounter-dialogue-utils";
|
import { queueEncounterMessage } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
@ -34,6 +33,7 @@ import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encou
|
|||||||
import { HeldItemRequirement, MoveRequirement } from "#mystery-encounters/mystery-encounter-requirements";
|
import { HeldItemRequirement, MoveRequirement } from "#mystery-encounters/mystery-encounter-requirements";
|
||||||
import { CHARMING_MOVES } from "#mystery-encounters/requirement-groups";
|
import { CHARMING_MOVES } from "#mystery-encounters/requirement-groups";
|
||||||
import { PokemonData } from "#system/pokemon-data";
|
import { PokemonData } from "#system/pokemon-data";
|
||||||
|
import type { HeldItemSpecs } from "#types/held-item-data-types";
|
||||||
import { isNullOrUndefined, pickWeightedIndex, randSeedInt } from "#utils/common";
|
import { isNullOrUndefined, pickWeightedIndex, randSeedInt } from "#utils/common";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
|
@ -19,7 +19,6 @@ import { StatusEffect } from "#enums/status-effect";
|
|||||||
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
|
||||||
import { PokemonMove } from "#moves/pokemon-move";
|
import { PokemonMove } from "#moves/pokemon-move";
|
||||||
import { showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
import { showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
import type { EnemyPartyConfig, EnemyPokemonConfig } from "#mystery-encounters/encounter-phase-utils";
|
import type { EnemyPartyConfig, EnemyPokemonConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||||
@ -40,6 +39,7 @@ import { achvs } from "#system/achv";
|
|||||||
import { PokemonData } from "#system/pokemon-data";
|
import { PokemonData } from "#system/pokemon-data";
|
||||||
import { trainerConfigs } from "#trainers/trainer-config";
|
import { trainerConfigs } from "#trainers/trainer-config";
|
||||||
import { TrainerPartyTemplate } from "#trainers/trainer-party-template";
|
import { TrainerPartyTemplate } from "#trainers/trainer-party-template";
|
||||||
|
import type { HeldItemConfiguration } from "#types/held-item-data-types";
|
||||||
import { isNullOrUndefined, NumberHolder, randSeedInt, randSeedShuffle } from "#utils/common";
|
import { isNullOrUndefined, NumberHolder, randSeedInt, randSeedShuffle } from "#utils/common";
|
||||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ import { TrainerSlot } from "#enums/trainer-slot";
|
|||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { TrainerVariant } from "#enums/trainer-variant";
|
import { TrainerVariant } from "#enums/trainer-variant";
|
||||||
import type { EnemyPokemon } from "#field/pokemon";
|
import type { EnemyPokemon } from "#field/pokemon";
|
||||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
|
||||||
import { PokemonMove } from "#moves/pokemon-move";
|
import { PokemonMove } from "#moves/pokemon-move";
|
||||||
import { getIsInitialized, initI18n } from "#plugins/i18n";
|
import { getIsInitialized, initI18n } from "#plugins/i18n";
|
||||||
import type { EvilTeam } from "#trainers/evil-admin-trainer-pools";
|
import type { EvilTeam } from "#trainers/evil-admin-trainer-pools";
|
||||||
@ -33,6 +32,7 @@ import {
|
|||||||
TrainerPartyTemplate,
|
TrainerPartyTemplate,
|
||||||
trainerPartyTemplates,
|
trainerPartyTemplates,
|
||||||
} from "#trainers/trainer-party-template";
|
} from "#trainers/trainer-party-template";
|
||||||
|
import type { HeldItemConfiguration } from "#types/held-item-data-types";
|
||||||
import type { SilentReward } from "#types/rewards";
|
import type { SilentReward } from "#types/rewards";
|
||||||
import type {
|
import type {
|
||||||
GenAIFunc,
|
GenAIFunc,
|
||||||
|
@ -112,7 +112,6 @@ import { UiMode } from "#enums/ui-mode";
|
|||||||
import { WeatherType } from "#enums/weather-type";
|
import { WeatherType } from "#enums/weather-type";
|
||||||
import { doShinySparkleAnim } from "#field/anims";
|
import { doShinySparkleAnim } from "#field/anims";
|
||||||
import { applyHeldItems } from "#items/all-held-items";
|
import { applyHeldItems } from "#items/all-held-items";
|
||||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
|
||||||
import { HeldItemManager } from "#items/held-item-manager";
|
import { HeldItemManager } from "#items/held-item-manager";
|
||||||
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
||||||
import { applyMoveAttrs } from "#moves/apply-attrs";
|
import { applyMoveAttrs } from "#moves/apply-attrs";
|
||||||
@ -129,6 +128,7 @@ import { RibbonData } from "#system/ribbons/ribbon-data";
|
|||||||
import { awardRibbonsToSpeciesLine } from "#system/ribbons/ribbon-methods";
|
import { awardRibbonsToSpeciesLine } from "#system/ribbons/ribbon-methods";
|
||||||
import type { AbAttrMap, AbAttrString, TypeMultiplierAbAttrParams } from "#types/ability-types";
|
import type { AbAttrMap, AbAttrString, TypeMultiplierAbAttrParams } from "#types/ability-types";
|
||||||
import type { DamageCalculationResult, DamageResult } from "#types/damage-result";
|
import type { DamageCalculationResult, DamageResult } from "#types/damage-result";
|
||||||
|
import type { HeldItemConfiguration } from "#types/held-item-data-types";
|
||||||
import type { IllusionData } from "#types/illusion-data";
|
import type { IllusionData } from "#types/illusion-data";
|
||||||
import type { TurnMove } from "#types/turn-move";
|
import type { TurnMove } from "#types/turn-move";
|
||||||
import { BattleInfo } from "#ui/battle-info";
|
import { BattleInfo } from "#ui/battle-info";
|
||||||
|
@ -12,11 +12,11 @@ import { TrainerSlot } from "#enums/trainer-slot";
|
|||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { TrainerVariant } from "#enums/trainer-variant";
|
import { TrainerVariant } from "#enums/trainer-variant";
|
||||||
import type { EnemyPokemon } from "#field/pokemon";
|
import type { EnemyPokemon } from "#field/pokemon";
|
||||||
import type { TrainerItemConfiguration } from "#items/trainer-item-data-types";
|
|
||||||
import { getIsInitialized, initI18n } from "#plugins/i18n";
|
import { getIsInitialized, initI18n } from "#plugins/i18n";
|
||||||
import type { TrainerConfig } from "#trainers/trainer-config";
|
import type { TrainerConfig } from "#trainers/trainer-config";
|
||||||
import { trainerConfigs } from "#trainers/trainer-config";
|
import { trainerConfigs } from "#trainers/trainer-config";
|
||||||
import { TrainerPartyCompoundTemplate, type TrainerPartyTemplate } from "#trainers/trainer-party-template";
|
import { TrainerPartyCompoundTemplate, type TrainerPartyTemplate } from "#trainers/trainer-party-template";
|
||||||
|
import type { TrainerItemConfiguration } from "#types/trainer-item-data-types";
|
||||||
import { randSeedInt, randSeedItem } from "#utils/common";
|
import { randSeedInt, randSeedItem } from "#utils/common";
|
||||||
import { getRandomLocaleEntry } from "#utils/i18n";
|
import { getRandomLocaleEntry } from "#utils/i18n";
|
||||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||||
|
@ -33,8 +33,8 @@ import { EvolutionStatBoostHeldItem, SpeciesStatBoostHeldItem } from "#items/sta
|
|||||||
import { SurviveChanceHeldItem } from "#items/survive-chance";
|
import { SurviveChanceHeldItem } from "#items/survive-chance";
|
||||||
import { TurnEndHealHeldItem } from "#items/turn-end-heal";
|
import { TurnEndHealHeldItem } from "#items/turn-end-heal";
|
||||||
import { TurnEndStatusHeldItem } from "#items/turn-end-status";
|
import { TurnEndStatusHeldItem } from "#items/turn-end-status";
|
||||||
|
import type { HeldItemEffectParamMap } from "#types/held-item-parameter";
|
||||||
import { getEnumValues } from "#utils/enums";
|
import { getEnumValues } from "#utils/enums";
|
||||||
import type { HeldItemEffectParamMap } from "./held-item-parameter";
|
|
||||||
|
|
||||||
export function initHeldItems() {
|
export function initHeldItems() {
|
||||||
for (const berry of getEnumValues(BerryType)) {
|
for (const berry of getEnumValues(BerryType)) {
|
||||||
|
@ -3,40 +3,33 @@ import { RewardId } from "#enums/reward-id";
|
|||||||
import { RarityTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { TrainerItemId } from "#enums/trainer-item-id";
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import { VoucherType } from "#system/voucher";
|
import { VoucherType } from "#system/voucher";
|
||||||
|
import { EmptyReward, type Reward, type RewardGenerator } from "./reward";
|
||||||
|
import { EvolutionItemRewardGenerator } from "./rewards/evolution-item";
|
||||||
|
import { FormChangeItemRewardGenerator } from "./rewards/form-change";
|
||||||
|
import { FusePokemonReward } from "./rewards/fuse";
|
||||||
import {
|
import {
|
||||||
AddMoneyReward,
|
|
||||||
AddPokeballReward,
|
|
||||||
AddVoucherReward,
|
|
||||||
AllPokemonFullReviveReward,
|
|
||||||
AllPokemonLevelIncrementReward,
|
|
||||||
AttackTypeBoosterRewardGenerator,
|
AttackTypeBoosterRewardGenerator,
|
||||||
BaseStatBoosterRewardGenerator,
|
BaseStatBoosterRewardGenerator,
|
||||||
BerryRewardGenerator,
|
BerryRewardGenerator,
|
||||||
EvolutionItemRewardGenerator,
|
} from "./rewards/held-item-reward";
|
||||||
FormChangeItemRewardGenerator,
|
import { AllPokemonLevelIncrementReward, PokemonLevelIncrementReward } from "./rewards/level-increment";
|
||||||
FusePokemonReward,
|
import { AddMoneyReward } from "./rewards/money";
|
||||||
LapsingTrainerItemReward,
|
import { MintRewardGenerator } from "./rewards/nature-change";
|
||||||
MintRewardGenerator,
|
import { AddPokeballReward } from "./rewards/pokeball";
|
||||||
NoneReward,
|
import { PokemonAllMovePpRestoreReward, PokemonPpRestoreReward } from "./rewards/pp-restore";
|
||||||
PokemonAllMovePpRestoreReward,
|
import { PokemonPpUpReward } from "./rewards/pp-up";
|
||||||
PokemonHpRestoreReward,
|
import { RememberMoveReward } from "./rewards/remember-move";
|
||||||
PokemonLevelIncrementReward,
|
import { AllPokemonFullReviveReward, PokemonHpRestoreReward, PokemonReviveReward } from "./rewards/restore";
|
||||||
PokemonPpRestoreReward,
|
import { SpeciesStatBoosterRewardGenerator } from "./rewards/species-stat-booster";
|
||||||
PokemonPpUpReward,
|
import { PokemonStatusHealReward } from "./rewards/status-heal";
|
||||||
PokemonReviveReward,
|
import { TeraTypeRewardGenerator } from "./rewards/tera-type";
|
||||||
PokemonStatusHealReward,
|
import { TmRewardGenerator } from "./rewards/tm";
|
||||||
RememberMoveReward,
|
import { LapsingTrainerItemReward, TempStatStageBoosterRewardGenerator } from "./rewards/trainer-item-reward";
|
||||||
type Reward,
|
import { AddVoucherReward } from "./rewards/voucher";
|
||||||
type RewardGenerator,
|
|
||||||
SpeciesStatBoosterRewardGenerator,
|
|
||||||
TempStatStageBoosterRewardGenerator,
|
|
||||||
TeraTypeRewardGenerator,
|
|
||||||
TmRewardGenerator,
|
|
||||||
} from "./reward";
|
|
||||||
|
|
||||||
// TODO: Move to `reward-utils.ts` and un-exportt
|
// TODO: Move to `reward-utils.ts` and un-exportt
|
||||||
export const allRewards = {
|
export const allRewards = {
|
||||||
[RewardId.NONE]: new NoneReward(),
|
[RewardId.NONE]: new EmptyReward(),
|
||||||
|
|
||||||
// Pokeball rewards
|
// Pokeball rewards
|
||||||
[RewardId.POKEBALL]: new AddPokeballReward("pb", PokeballType.POKEBALL, 5, RewardId.POKEBALL),
|
[RewardId.POKEBALL]: new AddPokeballReward("pb", PokeballType.POKEBALL, 5, RewardId.POKEBALL),
|
||||||
|
@ -5,14 +5,6 @@ import type { TrainerItemEffect } from "#enums/trainer-item-effect";
|
|||||||
import { TrainerItemId } from "#enums/trainer-item-id";
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import {
|
import {
|
||||||
CriticalCatchChanceBoosterTrainerItem,
|
CriticalCatchChanceBoosterTrainerItem,
|
||||||
DoubleBattleChanceBoosterTrainerItem,
|
|
||||||
EnemyAttackStatusEffectChanceTrainerItem,
|
|
||||||
EnemyDamageBoosterTrainerItem,
|
|
||||||
EnemyDamageReducerTrainerItem,
|
|
||||||
EnemyEndureChanceTrainerItem,
|
|
||||||
EnemyFusionChanceTrainerItem,
|
|
||||||
EnemyStatusEffectHealChanceTrainerItem,
|
|
||||||
EnemyTurnHealTrainerItem,
|
|
||||||
ExpBoosterTrainerItem,
|
ExpBoosterTrainerItem,
|
||||||
ExtraRewardTrainerItem,
|
ExtraRewardTrainerItem,
|
||||||
HealingBoosterTrainerItem,
|
HealingBoosterTrainerItem,
|
||||||
@ -22,14 +14,26 @@ import {
|
|||||||
MoneyMultiplierTrainerItem,
|
MoneyMultiplierTrainerItem,
|
||||||
PreserveBerryTrainerItem,
|
PreserveBerryTrainerItem,
|
||||||
ShinyRateBoosterTrainerItem,
|
ShinyRateBoosterTrainerItem,
|
||||||
|
TrainerItem,
|
||||||
|
} from "#items/trainer-item";
|
||||||
|
import type { TrainerItemEffectParamMap } from "#types/trainer-item-parameter";
|
||||||
|
import type { TrainerItemManager } from "./trainer-item-manager";
|
||||||
|
import {
|
||||||
|
EnemyAttackStatusEffectChanceTrainerItem,
|
||||||
|
EnemyDamageBoosterTrainerItem,
|
||||||
|
EnemyDamageReducerTrainerItem,
|
||||||
|
EnemyEndureChanceTrainerItem,
|
||||||
|
EnemyFusionChanceTrainerItem,
|
||||||
|
EnemyStatusEffectHealChanceTrainerItem,
|
||||||
|
EnemyTurnHealTrainerItem,
|
||||||
|
} from "./trainer-items/enemy-tokens";
|
||||||
|
import { DoubleBattleChanceBoosterTrainerItem } from "./trainer-items/lure";
|
||||||
|
import {
|
||||||
TempAccuracyBoosterTrainerItem,
|
TempAccuracyBoosterTrainerItem,
|
||||||
TempCritBoosterTrainerItem,
|
TempCritBoosterTrainerItem,
|
||||||
TempStatStageBoosterTrainerItem,
|
TempStatStageBoosterTrainerItem,
|
||||||
TrainerItem,
|
|
||||||
tempStatToTrainerItem,
|
tempStatToTrainerItem,
|
||||||
} from "#items/trainer-item";
|
} from "./trainer-items/x-items";
|
||||||
import type { TrainerItemManager } from "./trainer-item-manager";
|
|
||||||
import type { TrainerItemEffectParamMap } from "./trainer-item-parameter";
|
|
||||||
|
|
||||||
export function initTrainerItems() {
|
export function initTrainerItems() {
|
||||||
allTrainerItems[TrainerItemId.MAP] = new TrainerItem(TrainerItemId.MAP, 1);
|
allTrainerItems[TrainerItemId.MAP] = new TrainerItem(TrainerItemId.MAP, 1);
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
type HeldItemSaveData,
|
type HeldItemSaveData,
|
||||||
type HeldItemSpecs,
|
type HeldItemSpecs,
|
||||||
isHeldItemSpecs,
|
isHeldItemSpecs,
|
||||||
} from "#items/held-item-data-types";
|
} from "#types/held-item-data-types";
|
||||||
|
|
||||||
export class HeldItemManager {
|
export class HeldItemManager {
|
||||||
// TODO: There should be a way of making these private...
|
// TODO: There should be a way of making these private...
|
||||||
|
@ -7,7 +7,7 @@ import { RarityTier } from "#enums/reward-tier";
|
|||||||
import { PERMANENT_STATS } from "#enums/stat";
|
import { PERMANENT_STATS } from "#enums/stat";
|
||||||
import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
import { attackTypeToHeldItem } from "#items/attack-type-booster";
|
import { attackTypeToHeldItem } from "#items/attack-type-booster";
|
||||||
import { permanentStatToHeldItem } from "#items/base-stat-booster";
|
import { permanentStatToHeldItem } from "#items/base-stat-multiply";
|
||||||
import { berryTypeToHeldItem } from "#items/berry";
|
import { berryTypeToHeldItem } from "#items/berry";
|
||||||
import {
|
import {
|
||||||
type HeldItemConfiguration,
|
type HeldItemConfiguration,
|
||||||
@ -19,7 +19,7 @@ import {
|
|||||||
isHeldItemCategoryEntry,
|
isHeldItemCategoryEntry,
|
||||||
isHeldItemPool,
|
isHeldItemPool,
|
||||||
isHeldItemSpecs,
|
isHeldItemSpecs,
|
||||||
} from "#items/held-item-data-types";
|
} from "#types/held-item-data-types";
|
||||||
import { coerceArray, isNullOrUndefined, pickWeightedIndex, randSeedInt } from "#utils/common";
|
import { coerceArray, isNullOrUndefined, pickWeightedIndex, randSeedInt } from "#utils/common";
|
||||||
import { getEnumValues } from "#utils/enums";
|
import { getEnumValues } from "#utils/enums";
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import type { HeldItemEffect } from "#enums/held-item-effect";
|
import type { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { type HeldItemId, HeldItemNames } from "#enums/held-item-id";
|
import { type HeldItemId, HeldItemNames } from "#enums/held-item-id";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
|
import type { HeldItemEffectParamMap } from "#types/held-item-parameter";
|
||||||
import type { UniqueArray } from "#utils/common";
|
import type { UniqueArray } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import type { HeldItemEffectParamMap } from "./held-item-parameter";
|
|
||||||
|
|
||||||
export abstract class HeldItemBase {
|
export abstract class HeldItemBase {
|
||||||
public type: HeldItemId;
|
public type: HeldItemId;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { AccuracyBoostParams } from "#items/held-item-parameter";
|
import type { AccuracyBoostParams } from "#types/held-item-parameter";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @sealed
|
* @sealed
|
||||||
|
@ -2,7 +2,7 @@ import { HeldItemEffect } from "#enums/held-item-effect";
|
|||||||
import { HeldItemId, HeldItemNames } from "#enums/held-item-id";
|
import { HeldItemId, HeldItemNames } from "#enums/held-item-id";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { AttackTypeBoostParams } from "#items/held-item-parameter";
|
import type { AttackTypeBoostParams } from "#types/held-item-parameter";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
interface AttackTypeToHeldItemMap {
|
interface AttackTypeToHeldItemMap {
|
||||||
|
@ -3,7 +3,7 @@ import type { HeldItemId } from "#enums/held-item-id";
|
|||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { BaseStatParams } from "#items/held-item-parameter";
|
import type { BaseStatParams } from "#types/held-item-parameter";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,7 +2,7 @@ import { HeldItemEffect } from "#enums/held-item-effect";
|
|||||||
import { HeldItemId } from "#enums/held-item-id";
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
import { getStatKey, type PermanentStat, Stat } from "#enums/stat";
|
import { getStatKey, type PermanentStat, Stat } from "#enums/stat";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { BaseStatParams } from "#items/held-item-parameter";
|
import type { BaseStatParams } from "#types/held-item-parameter";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
type PermanentStatToHeldItemMap = {
|
type PermanentStatToHeldItemMap = {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { BatonParams } from "#items/held-item-parameter";
|
import type { BatonParams } from "#types/held-item-parameter";
|
||||||
|
|
||||||
export class BatonHeldItem extends HeldItem<[typeof HeldItemEffect.BATON]> {
|
export class BatonHeldItem extends HeldItem<[typeof HeldItemEffect.BATON]> {
|
||||||
public readonly effects = [HeldItemEffect.BATON] as const;
|
public readonly effects = [HeldItemEffect.BATON] as const;
|
||||||
@ -9,7 +9,7 @@ export class BatonHeldItem extends HeldItem<[typeof HeldItemEffect.BATON]> {
|
|||||||
* Applies {@linkcode SwitchEffectTransferModifier}
|
* Applies {@linkcode SwitchEffectTransferModifier}
|
||||||
* @returns always `true`
|
* @returns always `true`
|
||||||
*/
|
*/
|
||||||
apply(_effect: typeof HeldItemEffect.BATON, { pokemon }: BatonParams): true {
|
apply(_effect: typeof HeldItemEffect.BATON, _params: BatonParams): true {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import { HeldItemId } from "#enums/held-item-id";
|
|||||||
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||||
import { BerryUsedEvent } from "#events/battle-scene";
|
import { BerryUsedEvent } from "#events/battle-scene";
|
||||||
import { ConsumableHeldItem } from "#items/held-item";
|
import { ConsumableHeldItem } from "#items/held-item";
|
||||||
import type { BerryParams } from "#items/held-item-parameter";
|
import type { BerryParams } from "#types/held-item-parameter";
|
||||||
import type { ObjectValues } from "#types/type-helpers";
|
import type { ObjectValues } from "#types/type-helpers";
|
||||||
import { BooleanHolder } from "#utils/common";
|
import { BooleanHolder } from "#utils/common";
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import { getPokemonNameWithAffix } from "#app/messages";
|
|||||||
import { Command } from "#enums/command";
|
import { Command } from "#enums/command";
|
||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { BypassSpeedChanceParams } from "#items/held-item-parameter";
|
import type { BypassSpeedChanceParams } from "#types/held-item-parameter";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,7 +2,7 @@ import { HeldItemEffect } from "#enums/held-item-effect";
|
|||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import type { SpeciesId } from "#enums/species-id";
|
import type { SpeciesId } from "#enums/species-id";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { CritBoostParams } from "#items/held-item-parameter";
|
import type { CritBoostParams } from "#types/held-item-parameter";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifier used for held items that apply critical-hit stage boost(s).
|
* Modifier used for held items that apply critical-hit stage boost(s).
|
||||||
|
@ -2,7 +2,7 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { DamageMoneyRewardParams } from "#items/held-item-parameter";
|
import type { DamageMoneyRewardParams } from "#types/held-item-parameter";
|
||||||
import { NumberHolder } from "#utils/common";
|
import { NumberHolder } from "#utils/common";
|
||||||
|
|
||||||
export class DamageMoneyRewardHeldItem extends HeldItem<[typeof HeldItemEffect.DAMAGE_MONEY_REWARD]> {
|
export class DamageMoneyRewardHeldItem extends HeldItem<[typeof HeldItemEffect.DAMAGE_MONEY_REWARD]> {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { ExpBoostParams } from "#items/held-item-parameter";
|
import type { ExpBoostParams } from "#types/held-item-parameter";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class ExpBoosterHeldItem extends HeldItem<[typeof HeldItemEffect.EXP_BOOSTER]> {
|
export class ExpBoosterHeldItem extends HeldItem<[typeof HeldItemEffect.EXP_BOOSTER]> {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { FieldEffectParams } from "#items/held-item-parameter";
|
import type { FieldEffectParams } from "#types/held-item-parameter";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifier used for held items, namely Mystical Rock, that extend the
|
* Modifier used for held items, namely Mystical Rock, that extend the
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { FlinchChanceParams } from "#items/held-item-parameter";
|
import type { FlinchChanceParams } from "#types/held-item-parameter";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifier used for held items, namely Toxic Orb and Flame Orb, that apply a
|
* Modifier used for held items, namely Toxic Orb and Flame Orb, that apply a
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { FriendshipBoostParams } from "#items/held-item-parameter";
|
import type { FriendshipBoostParams } from "#types/held-item-parameter";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class FriendshipBoosterHeldItem extends HeldItem<[typeof HeldItemEffect.FRIENDSHIP_BOOSTER]> {
|
export class FriendshipBoosterHeldItem extends HeldItem<[typeof HeldItemEffect.FRIENDSHIP_BOOSTER]> {
|
||||||
|
@ -2,8 +2,8 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { HitHealParams } from "#items/held-item-parameter";
|
|
||||||
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
||||||
|
import type { HitHealParams } from "#types/held-item-parameter";
|
||||||
import { toDmgValue } from "#utils/common";
|
import { toDmgValue } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { ConsumableHeldItem } from "#items/held-item";
|
import { ConsumableHeldItem } from "#items/held-item";
|
||||||
import type { InstantReviveParams } from "#items/held-item-parameter";
|
|
||||||
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
||||||
|
import type { InstantReviveParams } from "#types/held-item-parameter";
|
||||||
import { toDmgValue } from "#utils/common";
|
import { toDmgValue } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import { HeldItemEffect } from "#enums/held-item-effect";
|
|||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import { Pokemon } from "#field/pokemon";
|
import { Pokemon } from "#field/pokemon";
|
||||||
import { type EffectTuple, HeldItem } from "#items/held-item";
|
import { type EffectTuple, HeldItem } from "#items/held-item";
|
||||||
import type { ItemStealParams } from "#items/held-item-parameter";
|
import type { ItemStealParams } from "#types/held-item-parameter";
|
||||||
import { coerceArray, randSeedFloat } from "#utils/common";
|
import { coerceArray, randSeedFloat } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { StatBoostParams } from "#items/held-item-parameter";
|
import type { StatBoostParams } from "#types/held-item-parameter";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,7 +2,7 @@ import { allMoves } from "#data/data-lists";
|
|||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { HeldItemEffectParamMap, MultiHitCountParams, MultiHitDamageParams } from "#items/held-item-parameter";
|
import type { HeldItemEffectParamMap, MultiHitCountParams, MultiHitDamageParams } from "#types/held-item-parameter";
|
||||||
import type { NumberHolder } from "#utils/common";
|
import type { NumberHolder } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { NatureWeightBoostParams } from "#items/held-item-parameter";
|
import type { NatureWeightBoostParams } from "#types/held-item-parameter";
|
||||||
|
|
||||||
export class NatureWeightBoosterHeldItem extends HeldItem<[typeof HeldItemEffect.NATURE_WEIGHT_BOOSTER]> {
|
export class NatureWeightBoosterHeldItem extends HeldItem<[typeof HeldItemEffect.NATURE_WEIGHT_BOOSTER]> {
|
||||||
public readonly effects = [HeldItemEffect.NATURE_WEIGHT_BOOSTER] as const;
|
public readonly effects = [HeldItemEffect.NATURE_WEIGHT_BOOSTER] as const;
|
||||||
|
@ -3,7 +3,7 @@ import { getPokemonNameWithAffix } from "#app/messages";
|
|||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { BATTLE_STATS } from "#enums/stat";
|
import { BATTLE_STATS } from "#enums/stat";
|
||||||
import { ConsumableHeldItem } from "#items/held-item";
|
import { ConsumableHeldItem } from "#items/held-item";
|
||||||
import type { ResetNegativeStatStageParams } from "#items/held-item-parameter";
|
import type { ResetNegativeStatStageParams } from "#types/held-item-parameter";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +5,7 @@ import type { SpeciesId } from "#enums/species-id";
|
|||||||
import type { Stat } from "#enums/stat";
|
import type { Stat } from "#enums/stat";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { StatBoostParams } from "#items/held-item-parameter";
|
import type { StatBoostParams } from "#types/held-item-parameter";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifier used for held items that Applies {@linkcode Stat} boost(s)
|
* Modifier used for held items that Applies {@linkcode Stat} boost(s)
|
||||||
|
@ -2,7 +2,7 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { SurviveChanceParams } from "#items/held-item-parameter";
|
import type { SurviveChanceParams } from "#types/held-item-parameter";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,8 +2,8 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { TurnEndHealParams } from "#items/held-item-parameter";
|
|
||||||
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
||||||
|
import type { TurnEndHealParams } from "#types/held-item-parameter";
|
||||||
import { toDmgValue } from "#utils/common";
|
import { toDmgValue } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { HeldItemEffect } from "#enums/held-item-effect";
|
|||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import type { StatusEffect } from "#enums/status-effect";
|
import type { StatusEffect } from "#enums/status-effect";
|
||||||
import { HeldItem } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { TurnEndStatusParams } from "#items/held-item-parameter";
|
import type { TurnEndStatusParams } from "#types/held-item-parameter";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifier used for held items, namely Toxic Orb and Flame Orb, that apply a
|
* Modifier used for held items, namely Toxic Orb and Flame Orb, that apply a
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
|
||||||
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
||||||
import type { TrainerItemConfiguration } from "#items/trainer-item-data-types";
|
import type { HeldItemConfiguration } from "#types/held-item-data-types";
|
||||||
|
import type { TrainerItemConfiguration } from "#types/trainer-item-data-types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses either `MODIFIER_OVERRIDE` in overrides.ts to set {@linkcode PersistentModifier}s for either:
|
* Uses either `MODIFIER_OVERRIDE` in overrides.ts to set {@linkcode PersistentModifier}s for either:
|
||||||
|
@ -3,7 +3,7 @@ import { allHeldItems, allTrainerItems } from "#data/data-lists";
|
|||||||
import { HeldItemCategoryId, type HeldItemId, isItemInCategory } from "#enums/held-item-id";
|
import { HeldItemCategoryId, type HeldItemId, isItemInCategory } from "#enums/held-item-id";
|
||||||
import type { TrainerItemId } from "#enums/trainer-item-id";
|
import type { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import type { PokemonItemMap } from "./held-item-data-types";
|
import type { PokemonItemMap } from "#types/held-item-data-types";
|
||||||
|
|
||||||
export const trainerItemSortFunc = (a: TrainerItemId, b: TrainerItemId): number => {
|
export const trainerItemSortFunc = (a: TrainerItemId, b: TrainerItemId): number => {
|
||||||
const itemNameMatch = allTrainerItems[a].name.localeCompare(allTrainerItems[b].name);
|
const itemNameMatch = allTrainerItems[a].name.localeCompare(allTrainerItems[b].name);
|
||||||
|
@ -1,23 +1,17 @@
|
|||||||
|
import { heldItemRarities } from "#data/items/held-item-default-tiers";
|
||||||
|
import { rewardRarities } from "#data/items/reward-defaults-tiers";
|
||||||
|
import { trainerItemRarities } from "#data/items/trainer-item-default-tiers";
|
||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import { getRewardCategory, RewardCategoryId, RewardId } from "#enums/reward-id";
|
import { getRewardCategory, RewardCategoryId, RewardId } from "#enums/reward-id";
|
||||||
import type { RarityTier } from "#enums/reward-tier";
|
import type { RarityTier } from "#enums/reward-tier";
|
||||||
import type { TrainerItemId } from "#enums/trainer-item-id";
|
import type { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import { allRewards } from "#items/all-rewards";
|
import { allRewards } from "#items/all-rewards";
|
||||||
import type { RewardPoolId, RewardSpecs } from "#types/rewards";
|
import type { RewardPoolId, RewardSpecs } from "#types/rewards";
|
||||||
import { heldItemRarities } from "./held-item-default-tiers";
|
import { EmptyReward, type PokemonMoveReward, type Reward, RewardGenerator, RewardOption } from "./reward";
|
||||||
import {
|
import { HeldItemReward } from "./rewards/held-item-reward";
|
||||||
HeldItemReward,
|
import type { RememberMoveReward } from "./rewards/remember-move";
|
||||||
NoneReward,
|
import type { TmReward } from "./rewards/tm";
|
||||||
type PokemonMoveReward,
|
import { TrainerItemReward } from "./rewards/trainer-item-reward";
|
||||||
type RememberMoveReward,
|
|
||||||
type Reward,
|
|
||||||
RewardGenerator,
|
|
||||||
RewardOption,
|
|
||||||
type TmReward,
|
|
||||||
TrainerItemReward,
|
|
||||||
} from "./reward";
|
|
||||||
import { rewardRarities } from "./reward-defaults-tiers";
|
|
||||||
import { trainerItemRarities } from "./trainer-item-default-tiers";
|
|
||||||
|
|
||||||
export function isTmReward(reward: Reward): reward is TmReward {
|
export function isTmReward(reward: Reward): reward is TmReward {
|
||||||
return getRewardCategory(reward.id) === RewardCategoryId.TM;
|
return getRewardCategory(reward.id) === RewardCategoryId.TM;
|
||||||
@ -66,7 +60,7 @@ export function generateRewardOptionFromId<T extends RewardPoolId>(
|
|||||||
const tempReward = allRewards[id] as Reward | RewardGenerator;
|
const tempReward = allRewards[id] as Reward | RewardGenerator;
|
||||||
let reward = tempReward instanceof RewardGenerator ? tempReward.generateReward(pregenArgs) : tempReward;
|
let reward = tempReward instanceof RewardGenerator ? tempReward.generateReward(pregenArgs) : tempReward;
|
||||||
if (!reward) {
|
if (!reward) {
|
||||||
reward = new NoneReward();
|
reward = new EmptyReward();
|
||||||
}
|
}
|
||||||
const tier = tierOverride ?? rewardRarities[id];
|
const tier = tierOverride ?? rewardRarities[id];
|
||||||
return new RewardOption(reward, upgradeCount, tier, cost);
|
return new RewardOption(reward, upgradeCount, tier, cost);
|
||||||
|
1359
src/items/reward.ts
1359
src/items/reward.ts
File diff suppressed because it is too large
Load Diff
135
src/items/rewards/evolution-item.ts
Normal file
135
src/items/rewards/evolution-item.ts
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { EvolutionItem, FusionSpeciesFormEvolution, pokemonEvolutions } from "#balance/pokemon-evolutions";
|
||||||
|
import { SpeciesFormKey } from "#enums/species-form-key";
|
||||||
|
import { SpeciesId } from "#enums/species-id";
|
||||||
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import { PokemonReward, type PokemonRewardParams, RewardGenerator } from "#items/reward";
|
||||||
|
import { PartyUiHandler } from "#ui/party-ui-handler";
|
||||||
|
import { randSeedItem } from "#utils/common";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class EvolutionItemReward extends PokemonReward {
|
||||||
|
public evolutionItem: EvolutionItem;
|
||||||
|
|
||||||
|
constructor(evolutionItem: EvolutionItem) {
|
||||||
|
super("", EvolutionItem[evolutionItem].toLowerCase(), (pokemon: PlayerPokemon) => {
|
||||||
|
if (
|
||||||
|
pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) &&
|
||||||
|
pokemonEvolutions[pokemon.species.speciesId].filter(e => e.validate(pokemon, false, this.evolutionItem))
|
||||||
|
.length &&
|
||||||
|
pokemon.getFormKey() !== SpeciesFormKey.GIGANTAMAX
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
pokemon.isFusion() &&
|
||||||
|
pokemon.fusionSpecies &&
|
||||||
|
pokemonEvolutions.hasOwnProperty(pokemon.fusionSpecies.speciesId) &&
|
||||||
|
pokemonEvolutions[pokemon.fusionSpecies.speciesId].filter(e => e.validate(pokemon, true, this.evolutionItem))
|
||||||
|
.length &&
|
||||||
|
pokemon.getFusionFormKey() !== SpeciesFormKey.GIGANTAMAX
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.evolutionItem = evolutionItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return i18next.t(`modifierType:EvolutionItem.${EvolutionItem[this.evolutionItem]}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.EvolutionItemModifierType.description");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode EvolutionItemConsumable}
|
||||||
|
* @param playerPokemon The {@linkcode PlayerPokemon} that should evolve via item
|
||||||
|
* @returns `true` if the evolution was successful
|
||||||
|
*/
|
||||||
|
apply({ pokemon }: PokemonRewardParams): boolean {
|
||||||
|
let matchingEvolution = pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId)
|
||||||
|
? pokemonEvolutions[pokemon.species.speciesId].find(
|
||||||
|
e => e.evoItem === this.evolutionItem && e.validate(pokemon, false, e.item!),
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
if (!matchingEvolution && pokemon.isFusion()) {
|
||||||
|
matchingEvolution = pokemonEvolutions[pokemon.fusionSpecies!.speciesId].find(
|
||||||
|
e => e.evoItem === this.evolutionItem && e.validate(pokemon, true, e.item!),
|
||||||
|
);
|
||||||
|
if (matchingEvolution) {
|
||||||
|
matchingEvolution = new FusionSpeciesFormEvolution(pokemon.species.speciesId, matchingEvolution);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchingEvolution) {
|
||||||
|
globalScene.phaseManager.unshiftNew("EvolutionPhase", pokemon, matchingEvolution, pokemon.level - 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class EvolutionItemRewardGenerator extends RewardGenerator {
|
||||||
|
private rare: boolean;
|
||||||
|
constructor(rare: boolean) {
|
||||||
|
super();
|
||||||
|
this.rare = rare;
|
||||||
|
}
|
||||||
|
|
||||||
|
override generateReward(pregenArgs?: EvolutionItem) {
|
||||||
|
if (pregenArgs !== undefined) {
|
||||||
|
return new EvolutionItemReward(pregenArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
const party = globalScene.getPlayerParty();
|
||||||
|
|
||||||
|
const evolutionItemPool = [
|
||||||
|
party
|
||||||
|
.filter(
|
||||||
|
p =>
|
||||||
|
pokemonEvolutions.hasOwnProperty(p.species.speciesId) &&
|
||||||
|
(!p.pauseEvolutions ||
|
||||||
|
p.species.speciesId === SpeciesId.SLOWPOKE ||
|
||||||
|
p.species.speciesId === SpeciesId.EEVEE ||
|
||||||
|
p.species.speciesId === SpeciesId.KIRLIA ||
|
||||||
|
p.species.speciesId === SpeciesId.SNORUNT),
|
||||||
|
)
|
||||||
|
.flatMap(p => {
|
||||||
|
const evolutions = pokemonEvolutions[p.species.speciesId];
|
||||||
|
return evolutions.filter(e => e.isValidItemEvolution(p));
|
||||||
|
}),
|
||||||
|
party
|
||||||
|
.filter(
|
||||||
|
p =>
|
||||||
|
p.isFusion() &&
|
||||||
|
p.fusionSpecies &&
|
||||||
|
pokemonEvolutions.hasOwnProperty(p.fusionSpecies.speciesId) &&
|
||||||
|
(!p.pauseEvolutions ||
|
||||||
|
p.fusionSpecies.speciesId === SpeciesId.SLOWPOKE ||
|
||||||
|
p.fusionSpecies.speciesId === SpeciesId.EEVEE ||
|
||||||
|
p.fusionSpecies.speciesId === SpeciesId.KIRLIA ||
|
||||||
|
p.fusionSpecies.speciesId === SpeciesId.SNORUNT),
|
||||||
|
)
|
||||||
|
.flatMap(p => {
|
||||||
|
const evolutions = pokemonEvolutions[p.fusionSpecies!.speciesId];
|
||||||
|
return evolutions.filter(e => e.isValidItemEvolution(p, true));
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
.flat()
|
||||||
|
.flatMap(e => e.evoItem)
|
||||||
|
.filter(i => !!i && i > 50 === this.rare);
|
||||||
|
|
||||||
|
if (!evolutionItemPool.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EvolutionItemReward(randSeedItem(evolutionItemPool));
|
||||||
|
}
|
||||||
|
}
|
152
src/items/rewards/form-change.ts
Normal file
152
src/items/rewards/form-change.ts
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { allHeldItems } from "#data/data-lists";
|
||||||
|
import { SpeciesFormChangeItemTrigger } from "#data/form-change-triggers";
|
||||||
|
import { pokemonFormChanges, SpeciesFormChangeCondition } from "#data/pokemon-forms";
|
||||||
|
import { FormChangeItemId } from "#enums/form-change-item-id";
|
||||||
|
import { RewardId } from "#enums/reward-id";
|
||||||
|
import { SpeciesFormKey } from "#enums/species-form-key";
|
||||||
|
import { SpeciesId } from "#enums/species-id";
|
||||||
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import { PokemonReward, type PokemonRewardParams, RewardGenerator } from "#items/reward";
|
||||||
|
import { PartyUiHandler } from "#ui/party-ui-handler";
|
||||||
|
import { randSeedItem } from "#utils/common";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that represents form changing items
|
||||||
|
*/
|
||||||
|
export class FormChangeItemReward extends PokemonReward {
|
||||||
|
public formChangeItem: FormChangeItemId;
|
||||||
|
|
||||||
|
constructor(formChangeItem: FormChangeItemId) {
|
||||||
|
super("", allHeldItems[formChangeItem].iconName, (pokemon: PlayerPokemon) => {
|
||||||
|
// Make sure the Pokemon has alternate forms
|
||||||
|
if (
|
||||||
|
pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId) &&
|
||||||
|
// Get all form changes for this species with an item trigger, including any compound triggers
|
||||||
|
pokemonFormChanges[pokemon.species.speciesId]
|
||||||
|
.filter(
|
||||||
|
fc => fc.trigger.hasTriggerType(SpeciesFormChangeItemTrigger) && fc.preFormKey === pokemon.getFormKey(),
|
||||||
|
)
|
||||||
|
// Returns true if any form changes match this item
|
||||||
|
.flatMap(fc => fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger)
|
||||||
|
.flatMap(fc => fc.item)
|
||||||
|
.includes(this.formChangeItem)
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.formChangeItem = formChangeItem;
|
||||||
|
this.id = RewardId.FORM_CHANGE_ITEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return allHeldItems[this.formChangeItem].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return allHeldItems[this.formChangeItem].description;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply({ pokemon }: PokemonRewardParams): boolean {
|
||||||
|
if (pokemon.heldItemManager.hasItem(this.formChangeItem)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pokemon.heldItemManager.add(this.formChangeItem);
|
||||||
|
pokemon.heldItemManager.toggleActive(this.formChangeItem);
|
||||||
|
|
||||||
|
// TODO: revise logic of this trigger based on active/inactive item
|
||||||
|
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger);
|
||||||
|
|
||||||
|
globalScene.updateItems(true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FormChangeItemRewardGenerator extends RewardGenerator {
|
||||||
|
private isRareFormChangeItem: boolean;
|
||||||
|
|
||||||
|
constructor(isRareFormChangeItem: boolean) {
|
||||||
|
super();
|
||||||
|
this.isRareFormChangeItem = isRareFormChangeItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
override generateReward(pregenArgs?: FormChangeItemId) {
|
||||||
|
if (pregenArgs !== undefined) {
|
||||||
|
return new FormChangeItemReward(pregenArgs);
|
||||||
|
}
|
||||||
|
const party = globalScene.getPlayerParty();
|
||||||
|
|
||||||
|
// TODO: REFACTOR THIS FUCKERY PLEASE
|
||||||
|
const formChangeItemPool = [
|
||||||
|
...new Set(
|
||||||
|
party
|
||||||
|
.filter(p => pokemonFormChanges.hasOwnProperty(p.species.speciesId))
|
||||||
|
.flatMap(p => {
|
||||||
|
const formChanges = pokemonFormChanges[p.species.speciesId];
|
||||||
|
let formChangeItemTriggers = formChanges
|
||||||
|
.filter(
|
||||||
|
fc =>
|
||||||
|
((fc.formKey.indexOf(SpeciesFormKey.MEGA) === -1 &&
|
||||||
|
fc.formKey.indexOf(SpeciesFormKey.PRIMAL) === -1) ||
|
||||||
|
globalScene.trainerItems.hasItem(TrainerItemId.MEGA_BRACELET)) &&
|
||||||
|
((fc.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) === -1 &&
|
||||||
|
fc.formKey.indexOf(SpeciesFormKey.ETERNAMAX) === -1) ||
|
||||||
|
globalScene.trainerItems.hasItem(TrainerItemId.DYNAMAX_BAND)) &&
|
||||||
|
(!fc.conditions.length ||
|
||||||
|
fc.conditions.filter(cond => cond instanceof SpeciesFormChangeCondition && cond.predicate(p))
|
||||||
|
.length) &&
|
||||||
|
fc.preFormKey === p.getFormKey(),
|
||||||
|
)
|
||||||
|
.map(fc => fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger)
|
||||||
|
.filter(t => t?.active && !p.heldItemManager.hasItem(t.item));
|
||||||
|
|
||||||
|
if (p.species.speciesId === SpeciesId.NECROZMA) {
|
||||||
|
// technically we could use a simplified version and check for formChanges.length > 3, but in case any code changes later, this might break...
|
||||||
|
let foundULTRA_Z = false,
|
||||||
|
foundN_LUNA = false,
|
||||||
|
foundN_SOLAR = false;
|
||||||
|
formChangeItemTriggers.forEach((fc, _i) => {
|
||||||
|
console.log("Checking ", fc.item);
|
||||||
|
switch (fc.item) {
|
||||||
|
case FormChangeItemId.ULTRANECROZIUM_Z:
|
||||||
|
foundULTRA_Z = true;
|
||||||
|
break;
|
||||||
|
case FormChangeItemId.N_LUNARIZER:
|
||||||
|
foundN_LUNA = true;
|
||||||
|
break;
|
||||||
|
case FormChangeItemId.N_SOLARIZER:
|
||||||
|
foundN_SOLAR = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (foundULTRA_Z && foundN_LUNA && foundN_SOLAR) {
|
||||||
|
// all three items are present -> user hasn't acquired any of the N_*ARIZERs -> block ULTRANECROZIUM_Z acquisition.
|
||||||
|
formChangeItemTriggers = formChangeItemTriggers.filter(
|
||||||
|
fc => fc.item !== FormChangeItemId.ULTRANECROZIUM_Z,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.log("DID NOT FIND ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return formChangeItemTriggers;
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
.flat()
|
||||||
|
.flatMap(fc => fc.item)
|
||||||
|
.filter(i => (i && i < 100) === this.isRareFormChangeItem);
|
||||||
|
// convert it into a set to remove duplicate values, which can appear when the same species with a potential form change is in the party.
|
||||||
|
|
||||||
|
if (!formChangeItemPool.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new FormChangeItemReward(randSeedItem(formChangeItemPool));
|
||||||
|
}
|
||||||
|
}
|
32
src/items/rewards/fuse.ts
Normal file
32
src/items/rewards/fuse.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { RewardId } from "#enums/reward-id";
|
||||||
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import { type PokemonFusionRewardParams, PokemonReward } from "#items/reward";
|
||||||
|
import { PartyUiHandler } from "#ui/party-ui-handler";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class FusePokemonReward extends PokemonReward {
|
||||||
|
constructor(localeKey: string, iconImage: string) {
|
||||||
|
super(localeKey, iconImage, (pokemon: PlayerPokemon) => {
|
||||||
|
if (pokemon.isFusion()) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
this.id = RewardId.DNA_SPLICERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.FusePokemonModifierType.description");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode FusePokemonConsumable}
|
||||||
|
* @param playerPokemon {@linkcode PlayerPokemon} that should be fused
|
||||||
|
* @param playerPokemon2 {@linkcode PlayerPokemon} that should be fused with {@linkcode playerPokemon}
|
||||||
|
* @returns always Promise<true>
|
||||||
|
*/
|
||||||
|
apply({ pokemon, pokemon2 }: PokemonFusionRewardParams): boolean {
|
||||||
|
pokemon.fuse(pokemon2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
92
src/items/rewards/held-item-reward.ts
Normal file
92
src/items/rewards/held-item-reward.ts
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { allHeldItems } from "#data/data-lists";
|
||||||
|
import type { BerryType } from "#enums/berry-type";
|
||||||
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
|
import type { PokemonType } from "#enums/pokemon-type";
|
||||||
|
import type { PermanentStat } from "#enums/stat";
|
||||||
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import { attackTypeToHeldItem } from "#items/attack-type-booster";
|
||||||
|
import { permanentStatToHeldItem } from "#items/base-stat-multiply";
|
||||||
|
import { berryTypeToHeldItem } from "#items/berry";
|
||||||
|
import { getNewAttackTypeBoosterHeldItem, getNewBerryHeldItem, getNewVitaminHeldItem } from "#items/held-item-pool";
|
||||||
|
import { PokemonReward, type PokemonRewardParams, RewardGenerator } from "#items/reward";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class HeldItemReward extends PokemonReward {
|
||||||
|
public itemId: HeldItemId;
|
||||||
|
constructor(itemId: HeldItemId, group?: string, soundName?: string) {
|
||||||
|
super(
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
(pokemon: PlayerPokemon) => {
|
||||||
|
const hasItem = pokemon.heldItemManager.hasItem(this.itemId);
|
||||||
|
const maxStackCount = allHeldItems[this.itemId].getMaxStackCount();
|
||||||
|
if (!maxStackCount) {
|
||||||
|
return i18next.t("modifierType:ModifierType.PokemonHeldItemModifierType.extra.inoperable", {
|
||||||
|
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (hasItem && pokemon.heldItemManager.getStack(this.itemId) === maxStackCount) {
|
||||||
|
return i18next.t("modifierType:ModifierType.PokemonHeldItemModifierType.extra.tooMany", {
|
||||||
|
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
group,
|
||||||
|
soundName,
|
||||||
|
);
|
||||||
|
this.itemId = itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return allHeldItems[this.itemId].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return allHeldItems[this.itemId].description;
|
||||||
|
}
|
||||||
|
|
||||||
|
get iconName(): string {
|
||||||
|
return allHeldItems[this.itemId].iconName;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply({ pokemon }: PokemonRewardParams): boolean {
|
||||||
|
return pokemon.heldItemManager.add(this.itemId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BerryRewardGenerator extends RewardGenerator {
|
||||||
|
override generateReward(pregenArgs?: BerryType): HeldItemReward {
|
||||||
|
if (pregenArgs !== undefined) {
|
||||||
|
const item = berryTypeToHeldItem[pregenArgs];
|
||||||
|
return new HeldItemReward(item);
|
||||||
|
}
|
||||||
|
const item = getNewBerryHeldItem();
|
||||||
|
return new HeldItemReward(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AttackTypeBoosterRewardGenerator extends RewardGenerator {
|
||||||
|
override generateReward(pregenArgs?: PokemonType) {
|
||||||
|
if (pregenArgs !== undefined) {
|
||||||
|
const item = attackTypeToHeldItem[pregenArgs];
|
||||||
|
return new HeldItemReward(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
const item = getNewAttackTypeBoosterHeldItem(globalScene.getPlayerParty());
|
||||||
|
|
||||||
|
return item ? new HeldItemReward(item) : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BaseStatBoosterRewardGenerator extends RewardGenerator {
|
||||||
|
override generateReward(pregenArgs?: PermanentStat) {
|
||||||
|
if (pregenArgs !== undefined) {
|
||||||
|
const item = permanentStatToHeldItem[pregenArgs];
|
||||||
|
return new HeldItemReward(item);
|
||||||
|
}
|
||||||
|
return new HeldItemReward(getNewVitaminHeldItem());
|
||||||
|
}
|
||||||
|
}
|
76
src/items/rewards/level-increment.ts
Normal file
76
src/items/rewards/level-increment.ts
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { FRIENDSHIP_GAIN_FROM_RARE_CANDY } from "#balance/starters";
|
||||||
|
import { getLevelTotalExp } from "#data/exp";
|
||||||
|
import { RewardId } from "#enums/reward-id";
|
||||||
|
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||||
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
|
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
|
import { PokemonReward, type PokemonRewardParams, Reward } from "#items/reward";
|
||||||
|
import { NumberHolder } from "#utils/common";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
function incrementLevelWithCandy(pokemon: Pokemon): boolean {
|
||||||
|
const levelCount = new NumberHolder(1);
|
||||||
|
globalScene.applyPlayerItems(TrainerItemEffect.LEVEL_INCREMENT_BOOSTER, { numberHolder: levelCount });
|
||||||
|
|
||||||
|
pokemon.level += levelCount.value;
|
||||||
|
if (pokemon.level <= globalScene.getMaxExpLevel(true)) {
|
||||||
|
pokemon.exp = getLevelTotalExp(pokemon.level, pokemon.species.growthRate);
|
||||||
|
pokemon.levelExp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pokemon.isPlayer()) {
|
||||||
|
pokemon.addFriendship(FRIENDSHIP_GAIN_FROM_RARE_CANDY);
|
||||||
|
|
||||||
|
globalScene.phaseManager.unshiftNew(
|
||||||
|
"LevelUpPhase",
|
||||||
|
globalScene.getPlayerParty().indexOf(pokemon),
|
||||||
|
pokemon.level - levelCount.value,
|
||||||
|
pokemon.level,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PokemonLevelIncrementReward extends PokemonReward {
|
||||||
|
constructor(localeKey: string, iconImage: string) {
|
||||||
|
super(localeKey, iconImage, (_pokemon: PlayerPokemon) => null);
|
||||||
|
this.id = RewardId.RARE_CANDY;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
let levels = 1;
|
||||||
|
const candyJarStack = globalScene.trainerItems.getStack(TrainerItemId.CANDY_JAR);
|
||||||
|
levels += candyJarStack;
|
||||||
|
return i18next.t("modifierType:ModifierType.PokemonLevelIncrementModifierType.description", { levels });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode PokemonLevelIncrementConsumable}
|
||||||
|
* @param playerPokemon The {@linkcode PlayerPokemon} that should get levels incremented
|
||||||
|
* @param levelCount The amount of levels to increment
|
||||||
|
* @returns always `true`
|
||||||
|
*/
|
||||||
|
apply({ pokemon }: PokemonRewardParams): boolean {
|
||||||
|
return incrementLevelWithCandy(pokemon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AllPokemonLevelIncrementReward extends Reward {
|
||||||
|
id = RewardId.RARER_CANDY;
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
let levels = 1;
|
||||||
|
const candyJarStack = globalScene.trainerItems.getStack(TrainerItemId.CANDY_JAR);
|
||||||
|
levels += candyJarStack;
|
||||||
|
return i18next.t("modifierType:ModifierType.AllPokemonLevelIncrementModifierType.description", { levels });
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(): boolean {
|
||||||
|
for (const pokemon of globalScene.getPlayerParty()) {
|
||||||
|
incrementLevelWithCandy(pokemon);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
59
src/items/rewards/money.ts
Normal file
59
src/items/rewards/money.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
|
import type { RewardId } from "#enums/reward-id";
|
||||||
|
import { SpeciesId } from "#enums/species-id";
|
||||||
|
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||||
|
import { Reward } from "#items/reward";
|
||||||
|
import { formatMoney, NumberHolder } from "#utils/common";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class AddMoneyReward extends Reward {
|
||||||
|
private moneyMultiplier: number;
|
||||||
|
private moneyMultiplierDescriptorKey: string;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
localeKey: string,
|
||||||
|
iconImage: string,
|
||||||
|
moneyMultiplier: number,
|
||||||
|
moneyMultiplierDescriptorKey: string,
|
||||||
|
id: RewardId,
|
||||||
|
) {
|
||||||
|
super(localeKey, iconImage, "money", "se/buy");
|
||||||
|
|
||||||
|
this.moneyMultiplier = moneyMultiplier;
|
||||||
|
this.moneyMultiplierDescriptorKey = moneyMultiplierDescriptorKey;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
const moneyAmount = new NumberHolder(globalScene.getWaveMoneyAmount(this.moneyMultiplier));
|
||||||
|
globalScene.applyPlayerItems(TrainerItemEffect.MONEY_MULTIPLIER, { numberHolder: moneyAmount });
|
||||||
|
const formattedMoney = formatMoney(globalScene.moneyFormat, moneyAmount.value);
|
||||||
|
|
||||||
|
return i18next.t("modifierType:ModifierType.MoneyRewardModifierType.description", {
|
||||||
|
moneyMultiplier: i18next.t(this.moneyMultiplierDescriptorKey as any),
|
||||||
|
moneyAmount: formattedMoney,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode AddMoneyReward}
|
||||||
|
* @returns always `true`
|
||||||
|
*/
|
||||||
|
apply(): boolean {
|
||||||
|
const moneyAmount = new NumberHolder(globalScene.getWaveMoneyAmount(this.moneyMultiplier));
|
||||||
|
|
||||||
|
globalScene.applyPlayerItems(TrainerItemEffect.MONEY_MULTIPLIER, { numberHolder: moneyAmount });
|
||||||
|
|
||||||
|
globalScene.addMoney(moneyAmount.value);
|
||||||
|
|
||||||
|
for (const p of globalScene.getPlayerParty()) {
|
||||||
|
if (p.hasSpecies(SpeciesId.GIMMIGHOUL)) {
|
||||||
|
const factor = Math.min(Math.floor(this.moneyMultiplier), 3);
|
||||||
|
p.heldItemManager.add(HeldItemId.GIMMIGHOUL_EVO_TRACKER, factor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
69
src/items/rewards/nature-change.ts
Normal file
69
src/items/rewards/nature-change.ts
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { getNatureName, getNatureStatMultiplier } from "#data/nature";
|
||||||
|
import { Nature } from "#enums/nature";
|
||||||
|
import { RewardId } from "#enums/reward-id";
|
||||||
|
import { Stat } from "#enums/stat";
|
||||||
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import { PokemonReward, type PokemonRewardParams, RewardGenerator } from "#items/reward";
|
||||||
|
import { PartyUiHandler } from "#ui/party-ui-handler";
|
||||||
|
import { randSeedItem } from "#utils/common";
|
||||||
|
import { getEnumKeys, getEnumValues } from "#utils/enums";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class PokemonNatureChangeReward extends PokemonReward {
|
||||||
|
protected nature: Nature;
|
||||||
|
|
||||||
|
constructor(nature: Nature) {
|
||||||
|
super(
|
||||||
|
"",
|
||||||
|
`mint_${
|
||||||
|
getEnumKeys(Stat)
|
||||||
|
.find(s => getNatureStatMultiplier(nature, Stat[s]) > 1)
|
||||||
|
?.toLowerCase() || "neutral"
|
||||||
|
}`,
|
||||||
|
(pokemon: PlayerPokemon) => {
|
||||||
|
if (pokemon.getNature() === this.nature) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
"mint",
|
||||||
|
);
|
||||||
|
|
||||||
|
this.nature = nature;
|
||||||
|
this.id = RewardId.MINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.PokemonNatureChangeModifierType.name", {
|
||||||
|
natureName: getNatureName(this.nature),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.PokemonNatureChangeModifierType.description", {
|
||||||
|
natureName: getNatureName(this.nature, true, true, true),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode PokemonNatureChangeConsumable}
|
||||||
|
* @param playerPokemon {@linkcode PlayerPokemon} to apply the {@linkcode Nature} change to
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
apply({ pokemon }: PokemonRewardParams): boolean {
|
||||||
|
pokemon.setCustomNature(this.nature);
|
||||||
|
globalScene.gameData.unlockSpeciesNature(pokemon.species, this.nature);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MintRewardGenerator extends RewardGenerator {
|
||||||
|
override generateReward(pregenArgs?: Nature) {
|
||||||
|
if (pregenArgs !== undefined) {
|
||||||
|
return new PokemonNatureChangeReward(pregenArgs);
|
||||||
|
}
|
||||||
|
return new PokemonNatureChangeReward(randSeedItem(getEnumValues(Nature)));
|
||||||
|
}
|
||||||
|
}
|
51
src/items/rewards/pokeball.ts
Normal file
51
src/items/rewards/pokeball.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS } from "#data/pokeball";
|
||||||
|
import type { PokeballType } from "#enums/pokeball";
|
||||||
|
import type { RewardId } from "#enums/reward-id";
|
||||||
|
import { Reward } from "#items/reward";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class AddPokeballReward extends Reward {
|
||||||
|
private pokeballType: PokeballType;
|
||||||
|
private count: number;
|
||||||
|
|
||||||
|
constructor(iconImage: string, pokeballType: PokeballType, count: number, id: RewardId) {
|
||||||
|
super("", iconImage, "pb", "se/pb_bounce_1");
|
||||||
|
this.pokeballType = pokeballType;
|
||||||
|
this.count = count;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.AddPokeballModifierType.name", {
|
||||||
|
modifierCount: this.count,
|
||||||
|
pokeballName: getPokeballName(this.pokeballType),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.AddPokeballModifierType.description", {
|
||||||
|
modifierCount: this.count,
|
||||||
|
pokeballName: getPokeballName(this.pokeballType),
|
||||||
|
catchRate:
|
||||||
|
getPokeballCatchMultiplier(this.pokeballType) > -1
|
||||||
|
? `${getPokeballCatchMultiplier(this.pokeballType)}x`
|
||||||
|
: "100%",
|
||||||
|
pokeballAmount: `${globalScene.pokeballCounts[this.pokeballType]}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode AddPokeballReward}
|
||||||
|
* @returns always `true`
|
||||||
|
*/
|
||||||
|
apply(): boolean {
|
||||||
|
const pokeballCounts = globalScene.pokeballCounts;
|
||||||
|
pokeballCounts[this.pokeballType] = Math.min(
|
||||||
|
pokeballCounts[this.pokeballType] + this.count,
|
||||||
|
MAX_PER_TYPE_POKEBALLS,
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
102
src/items/rewards/pp-restore.ts
Normal file
102
src/items/rewards/pp-restore.ts
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import type { RewardId } from "#enums/reward-id";
|
||||||
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import {
|
||||||
|
PokemonMoveReward,
|
||||||
|
type PokemonMoveRewardParams,
|
||||||
|
PokemonReward,
|
||||||
|
type PokemonRewardParams,
|
||||||
|
} from "#items/reward";
|
||||||
|
import type { PokemonMove } from "#moves/pokemon-move";
|
||||||
|
import { PartyUiHandler } from "#ui/party-ui-handler";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class PokemonPpRestoreReward extends PokemonMoveReward {
|
||||||
|
protected restorePoints: number;
|
||||||
|
|
||||||
|
constructor(localeKey: string, iconImage: string, id: RewardId, restorePoints: number) {
|
||||||
|
super(
|
||||||
|
localeKey,
|
||||||
|
iconImage,
|
||||||
|
id,
|
||||||
|
(_pokemon: PlayerPokemon) => {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
(pokemonMove: PokemonMove) => {
|
||||||
|
if (!pokemonMove.ppUsed) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
"ether",
|
||||||
|
);
|
||||||
|
|
||||||
|
this.restorePoints = restorePoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return this.restorePoints > -1
|
||||||
|
? i18next.t("modifierType:ModifierType.PokemonPpRestoreModifierType.description", {
|
||||||
|
restorePoints: this.restorePoints,
|
||||||
|
})
|
||||||
|
: i18next.t("modifierType:ModifierType.PokemonPpRestoreModifierType.extra.fully");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode PokemonPpRestoreConsumable}
|
||||||
|
* @param playerPokemon The {@linkcode PlayerPokemon} that should get move pp restored
|
||||||
|
* @returns always `true`
|
||||||
|
*/
|
||||||
|
apply({ pokemon, moveIndex }: PokemonMoveRewardParams): boolean {
|
||||||
|
const move = pokemon.getMoveset()[moveIndex];
|
||||||
|
|
||||||
|
if (move) {
|
||||||
|
move.ppUsed = this.restorePoints > -1 ? Math.max(move.ppUsed - this.restorePoints, 0) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PokemonAllMovePpRestoreReward extends PokemonReward {
|
||||||
|
protected restorePoints: number;
|
||||||
|
|
||||||
|
constructor(localeKey: string, iconImage: string, id: RewardId, restorePoints: number) {
|
||||||
|
super(
|
||||||
|
localeKey,
|
||||||
|
iconImage,
|
||||||
|
(pokemon: PlayerPokemon) => {
|
||||||
|
if (!pokemon.getMoveset().filter(m => m.ppUsed).length) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
"elixir",
|
||||||
|
);
|
||||||
|
|
||||||
|
this.restorePoints = restorePoints;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return this.restorePoints > -1
|
||||||
|
? i18next.t("modifierType:ModifierType.PokemonAllMovePpRestoreModifierType.description", {
|
||||||
|
restorePoints: this.restorePoints,
|
||||||
|
})
|
||||||
|
: i18next.t("modifierType:ModifierType.PokemonAllMovePpRestoreModifierType.extra.fully");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode PokemonAllMovePpRestoreConsumable}
|
||||||
|
* @param playerPokemon The {@linkcode PlayerPokemon} that should get all move pp restored
|
||||||
|
* @returns always `true`
|
||||||
|
*/
|
||||||
|
apply({ pokemon }: PokemonRewardParams): boolean {
|
||||||
|
for (const move of pokemon.getMoveset()) {
|
||||||
|
if (move) {
|
||||||
|
move.ppUsed = this.restorePoints > -1 ? Math.max(move.ppUsed - this.restorePoints, 0) : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
49
src/items/rewards/pp-up.ts
Normal file
49
src/items/rewards/pp-up.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import type { RewardId } from "#enums/reward-id";
|
||||||
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import { PokemonMoveReward, type PokemonMoveRewardParams } from "#items/reward";
|
||||||
|
import type { PokemonMove } from "#moves/pokemon-move";
|
||||||
|
import { PartyUiHandler } from "#ui/party-ui-handler";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class PokemonPpUpReward extends PokemonMoveReward {
|
||||||
|
protected upPoints: number;
|
||||||
|
|
||||||
|
constructor(localeKey: string, iconImage: string, id: RewardId, upPoints: number) {
|
||||||
|
super(
|
||||||
|
localeKey,
|
||||||
|
iconImage,
|
||||||
|
id,
|
||||||
|
(_pokemon: PlayerPokemon) => {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
(pokemonMove: PokemonMove) => {
|
||||||
|
if (pokemonMove.getMove().pp < 5 || pokemonMove.ppUp >= 3 || pokemonMove.maxPpOverride) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
"ppUp",
|
||||||
|
);
|
||||||
|
|
||||||
|
this.upPoints = upPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.PokemonPpUpModifierType.description", { upPoints: this.upPoints });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode PokemonPpUpConsumable}
|
||||||
|
* @param playerPokemon The {@linkcode PlayerPokemon} that gets a pp up on move-slot {@linkcode moveIndex}
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
apply({ pokemon, moveIndex }: PokemonMoveRewardParams): boolean {
|
||||||
|
const move = pokemon.getMoveset()[moveIndex];
|
||||||
|
|
||||||
|
if (move && !move.maxPpOverride) {
|
||||||
|
move.ppUp = Math.min(move.ppUp + this.upPoints, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
40
src/items/rewards/remember-move.ts
Normal file
40
src/items/rewards/remember-move.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { LearnMoveType } from "#enums/learn-move-type";
|
||||||
|
import { RewardId } from "#enums/reward-id";
|
||||||
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import { type PokemonMoveRecallRewardParams, PokemonReward } from "#items/reward";
|
||||||
|
import { PartyUiHandler } from "#ui/party-ui-handler";
|
||||||
|
|
||||||
|
export class RememberMoveReward extends PokemonReward {
|
||||||
|
constructor(localeKey: string, iconImage: string, group?: string) {
|
||||||
|
super(
|
||||||
|
localeKey,
|
||||||
|
iconImage,
|
||||||
|
(pokemon: PlayerPokemon) => {
|
||||||
|
if (!pokemon.getLearnableLevelMoves().length) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
group,
|
||||||
|
);
|
||||||
|
this.id = RewardId.MEMORY_MUSHROOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode RememberMoveConsumable}
|
||||||
|
* @param playerPokemon The {@linkcode PlayerPokemon} that should remember the move
|
||||||
|
* @returns always `true`
|
||||||
|
*/
|
||||||
|
apply({ pokemon, moveIndex, cost }: PokemonMoveRecallRewardParams): boolean {
|
||||||
|
globalScene.phaseManager.unshiftNew(
|
||||||
|
"LearnMovePhase",
|
||||||
|
globalScene.getPlayerParty().indexOf(pokemon as PlayerPokemon),
|
||||||
|
pokemon.getLearnableLevelMoves()[moveIndex],
|
||||||
|
LearnMoveType.MEMORY,
|
||||||
|
cost,
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
160
src/items/rewards/restore.ts
Normal file
160
src/items/rewards/restore.ts
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
// TODO: Consider removing `revive` from the signature of PokemonHealPhase in the wake of this
|
||||||
|
// (was only used for revives)
|
||||||
|
|
||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
|
import { RewardId } from "#enums/reward-id";
|
||||||
|
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||||
|
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
|
import { PokemonReward, type PokemonRewardParams, Reward } from "#items/reward";
|
||||||
|
import { PartyUiHandler, type PokemonSelectFilter } from "#ui/party-ui-handler";
|
||||||
|
import { NumberHolder, toDmgValue } from "#utils/common";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to instantly restore a Pokemon's hp.
|
||||||
|
* @param pokemon - The {@linkcode Pokemon} being healed
|
||||||
|
* @param percentToRestore - The percentage of the Pokemon's {@linkcode Stat.HP | maximum HP} to heal
|
||||||
|
* @param pointsToRestore - A minimum amount of HP points to restore; default `0`
|
||||||
|
* @param healStatus - Whether to also heal status ailments; default `false`
|
||||||
|
* @param fainted - Whether to allow reviving fainted Pokemon; default `false`.
|
||||||
|
* If `true`, will also disable the effect of {@linkcode TrainerItemEffect.HEALING_BOOSTER | Healing Charms}.
|
||||||
|
* @returns Whether the healing succeeded
|
||||||
|
*/
|
||||||
|
function restorePokemonHp(
|
||||||
|
pokemon: Pokemon,
|
||||||
|
percentToRestore: number,
|
||||||
|
{
|
||||||
|
pointsToRestore = 0,
|
||||||
|
healStatus = false,
|
||||||
|
fainted = false,
|
||||||
|
}: {
|
||||||
|
pointsToRestore?: number;
|
||||||
|
healStatus?: boolean;
|
||||||
|
fainted?: boolean;
|
||||||
|
} = {},
|
||||||
|
): boolean {
|
||||||
|
if (pokemon.isFainted() !== fainted) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (fainted || healStatus) {
|
||||||
|
pokemon.resetStatus(true, true, false, false);
|
||||||
|
}
|
||||||
|
// Apply HealingCharm
|
||||||
|
const hpRestoreMultiplier = new NumberHolder(1);
|
||||||
|
if (!fainted) {
|
||||||
|
this.applyPlayerItems(TrainerItemEffect.HEALING_BOOSTER, { numberHolder: hpRestoreMultiplier });
|
||||||
|
}
|
||||||
|
const restorePoints = toDmgValue(pointsToRestore * hpRestoreMultiplier.value);
|
||||||
|
const restorePercent = toDmgValue((percentToRestore / 100) * hpRestoreMultiplier.value * pokemon.getMaxHp());
|
||||||
|
pokemon.heal(Math.max(restorePercent, restorePoints));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PokemonHpRestoreReward extends PokemonReward {
|
||||||
|
protected restorePoints: number;
|
||||||
|
protected restorePercent: number;
|
||||||
|
protected healStatus: boolean;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
localeKey: string,
|
||||||
|
iconImage: string,
|
||||||
|
id: RewardId,
|
||||||
|
restorePoints: number,
|
||||||
|
restorePercent: number,
|
||||||
|
healStatus = false,
|
||||||
|
selectFilter?: PokemonSelectFilter,
|
||||||
|
group?: string,
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
localeKey,
|
||||||
|
iconImage,
|
||||||
|
selectFilter ||
|
||||||
|
((pokemon: PlayerPokemon) => {
|
||||||
|
if (
|
||||||
|
!pokemon.hp ||
|
||||||
|
(pokemon.isFullHp() && (!this.healStatus || (!pokemon.status && !pokemon.getTag(BattlerTagType.CONFUSED))))
|
||||||
|
) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
group || "potion",
|
||||||
|
);
|
||||||
|
|
||||||
|
this.restorePoints = restorePoints;
|
||||||
|
this.restorePercent = restorePercent;
|
||||||
|
this.healStatus = healStatus;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return this.restorePoints
|
||||||
|
? i18next.t("modifierType:ModifierType.PokemonHpRestoreModifierType.description", {
|
||||||
|
restorePoints: this.restorePoints,
|
||||||
|
restorePercent: this.restorePercent,
|
||||||
|
})
|
||||||
|
: this.healStatus
|
||||||
|
? i18next.t("modifierType:ModifierType.PokemonHpRestoreModifierType.extra.fullyWithStatus")
|
||||||
|
: i18next.t("modifierType:ModifierType.PokemonHpRestoreModifierType.extra.fully");
|
||||||
|
}
|
||||||
|
|
||||||
|
apply({ pokemon }: PokemonRewardParams): boolean {
|
||||||
|
return restorePokemonHp(pokemon, this.restorePercent, {
|
||||||
|
pointsToRestore: this.restorePoints,
|
||||||
|
healStatus: this.healStatus,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PokemonReviveReward extends PokemonHpRestoreReward {
|
||||||
|
constructor(localeKey: string, iconImage: string, id: RewardId, restorePercent: number) {
|
||||||
|
super(
|
||||||
|
localeKey,
|
||||||
|
iconImage,
|
||||||
|
id,
|
||||||
|
0,
|
||||||
|
restorePercent,
|
||||||
|
false,
|
||||||
|
(pokemon: PlayerPokemon) => {
|
||||||
|
if (!pokemon.isFainted()) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
"revive",
|
||||||
|
);
|
||||||
|
|
||||||
|
this.selectFilter = (pokemon: PlayerPokemon) => {
|
||||||
|
if (pokemon.hp) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.PokemonReviveModifierType.description", {
|
||||||
|
restorePercent: this.restorePercent,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
apply({ pokemon }: PokemonRewardParams): boolean {
|
||||||
|
return restorePokemonHp(pokemon, this.restorePercent, { fainted: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AllPokemonFullReviveReward extends Reward {
|
||||||
|
constructor(localeKey: string, iconImage: string) {
|
||||||
|
super(localeKey, iconImage, "modifierType:ModifierType.AllPokemonFullReviveModifierType");
|
||||||
|
this.id = RewardId.SACRED_ASH;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(): boolean {
|
||||||
|
for (const pokemon of globalScene.getPlayerParty()) {
|
||||||
|
restorePokemonHp(pokemon, 100, { fainted: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
83
src/items/rewards/species-stat-booster.ts
Normal file
83
src/items/rewards/species-stat-booster.ts
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { allHeldItems } from "#data/data-lists";
|
||||||
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
|
import { SpeciesId } from "#enums/species-id";
|
||||||
|
import { RewardGenerator } from "#items/reward";
|
||||||
|
import type { SpeciesStatBoosterItemId, SpeciesStatBoostHeldItem } from "#items/stat-boost";
|
||||||
|
import { randSeedInt } from "#utils/common";
|
||||||
|
import { HeldItemReward } from "./held-item-reward";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consumable type generator for {@linkcode SpeciesStatBoosterReward}, which
|
||||||
|
* encapsulates the logic for weighting the most useful held item from
|
||||||
|
* the current list of {@linkcode items}.
|
||||||
|
* @extends RewardGenerator
|
||||||
|
*/
|
||||||
|
export class SpeciesStatBoosterRewardGenerator extends RewardGenerator {
|
||||||
|
/** Object comprised of the currently available species-based stat boosting held items */
|
||||||
|
|
||||||
|
private rare: boolean;
|
||||||
|
constructor(rare: boolean) {
|
||||||
|
super();
|
||||||
|
this.rare = rare;
|
||||||
|
}
|
||||||
|
override generateReward(pregenArgs?: SpeciesStatBoosterItemId) {
|
||||||
|
if (pregenArgs !== undefined) {
|
||||||
|
return new HeldItemReward(pregenArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a pool of items based on the rarity.
|
||||||
|
const tierItems = this.rare
|
||||||
|
? [HeldItemId.LIGHT_BALL, HeldItemId.THICK_CLUB, HeldItemId.METAL_POWDER, HeldItemId.QUICK_POWDER]
|
||||||
|
: [HeldItemId.DEEP_SEA_SCALE, HeldItemId.DEEP_SEA_TOOTH];
|
||||||
|
|
||||||
|
const weights = new Array(tierItems.length).fill(0);
|
||||||
|
|
||||||
|
for (const p of globalScene.getPlayerParty()) {
|
||||||
|
const speciesId = p.getSpeciesForm(true).speciesId;
|
||||||
|
const fusionSpeciesId = p.isFusion() ? p.getFusionSpeciesForm(true).speciesId : null;
|
||||||
|
// TODO: Use commented boolean when Fling is implemented
|
||||||
|
const hasFling = false; /* p.getMoveset(true).some(m => m.moveId === MoveId.FLING) */
|
||||||
|
|
||||||
|
for (const i in tierItems) {
|
||||||
|
const checkedSpecies = (allHeldItems[tierItems[i]] as SpeciesStatBoostHeldItem).species;
|
||||||
|
|
||||||
|
// If party member already has the item being weighted currently, skip to the next item
|
||||||
|
const hasItem = p.heldItemManager.hasItem(tierItems[i]);
|
||||||
|
|
||||||
|
if (!hasItem) {
|
||||||
|
if (checkedSpecies.includes(speciesId) || (!!fusionSpeciesId && checkedSpecies.includes(fusionSpeciesId))) {
|
||||||
|
// Add weight if party member has a matching species or, if applicable, a matching fusion species
|
||||||
|
weights[i]++;
|
||||||
|
} else if (checkedSpecies.includes(SpeciesId.PIKACHU) && hasFling) {
|
||||||
|
// Add weight to Light Ball if party member has Fling
|
||||||
|
weights[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Replace this with a helper function
|
||||||
|
let totalWeight = 0;
|
||||||
|
for (const weight of weights) {
|
||||||
|
totalWeight += weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalWeight !== 0) {
|
||||||
|
const randInt = randSeedInt(totalWeight, 1);
|
||||||
|
let weight = 0;
|
||||||
|
|
||||||
|
for (const i in weights) {
|
||||||
|
if (weights[i] !== 0) {
|
||||||
|
const curWeight = weight + weights[i];
|
||||||
|
if (randInt <= weight + weights[i]) {
|
||||||
|
return new HeldItemReward(tierItems[i]);
|
||||||
|
}
|
||||||
|
weight = curWeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
27
src/items/rewards/status-heal.ts
Normal file
27
src/items/rewards/status-heal.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
|
import { RewardId } from "#enums/reward-id";
|
||||||
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import { PokemonReward, type PokemonRewardParams } from "#items/reward";
|
||||||
|
import { PartyUiHandler } from "#ui/party-ui-handler";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class PokemonStatusHealReward extends PokemonReward {
|
||||||
|
constructor(localeKey: string, iconImage: string) {
|
||||||
|
super(localeKey, iconImage, (pokemon: PlayerPokemon) => {
|
||||||
|
if (!pokemon.hp || (!pokemon.status && !pokemon.getTag(BattlerTagType.CONFUSED))) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
this.id = RewardId.FULL_HEAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.PokemonStatusHealModifierType.description");
|
||||||
|
}
|
||||||
|
|
||||||
|
apply({ pokemon }: PokemonRewardParams): boolean {
|
||||||
|
pokemon.resetStatus(true, true, false, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
102
src/items/rewards/tera-type.ts
Normal file
102
src/items/rewards/tera-type.ts
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
|
import { SpeciesId } from "#enums/species-id";
|
||||||
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import { PokemonReward, type PokemonRewardParams, RewardGenerator } from "#items/reward";
|
||||||
|
import { PartyUiHandler } from "#ui/party-ui-handler";
|
||||||
|
import { randSeedInt, randSeedItem } from "#utils/common";
|
||||||
|
import { getEnumValues } from "#utils/enums";
|
||||||
|
import { toCamelCase } from "#utils/strings";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class ChangeTeraTypeReward extends PokemonReward {
|
||||||
|
private teraType: PokemonType;
|
||||||
|
|
||||||
|
constructor(teraType: PokemonType) {
|
||||||
|
super(
|
||||||
|
"",
|
||||||
|
`${PokemonType[teraType].toLowerCase()}_tera_shard`,
|
||||||
|
(pokemon: PlayerPokemon) => {
|
||||||
|
if (
|
||||||
|
[pokemon.species.speciesId, pokemon.fusionSpecies?.speciesId].filter(
|
||||||
|
s => s === SpeciesId.TERAPAGOS || s === SpeciesId.OGERPON || s === SpeciesId.SHEDINJA,
|
||||||
|
).length > 0
|
||||||
|
) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
"tera_shard",
|
||||||
|
);
|
||||||
|
|
||||||
|
this.teraType = teraType;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.ChangeTeraTypeModifierType.name", {
|
||||||
|
teraType: i18next.t(`pokemonInfo:type.${toCamelCase(PokemonType[this.teraType])}`),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.ChangeTeraTypeModifierType.description", {
|
||||||
|
teraType: i18next.t(`pokemonInfo:type.${toCamelCase(PokemonType[this.teraType])}`),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if {@linkcode TerrastalizeConsumable} should be applied
|
||||||
|
* @param playerPokemon The {@linkcode PlayerPokemon} that consumes the item
|
||||||
|
* @returns `true` if the {@linkcode TerrastalizeConsumable} should be applied
|
||||||
|
*/
|
||||||
|
shouldApply({ pokemon }: PokemonRewardParams): boolean {
|
||||||
|
return (
|
||||||
|
pokemon.teraType !== this.teraType &&
|
||||||
|
![SpeciesId.SHEDINJA, SpeciesId.OGERPON, SpeciesId.TERAPAGOS].some(s => pokemon.hasSpecies(s))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode TerrastalizeConsumable}
|
||||||
|
* @param pokemon The {@linkcode PlayerPokemon} that consumes the item
|
||||||
|
* @returns `true` if hp was restored
|
||||||
|
*/
|
||||||
|
apply({ pokemon }: PokemonRewardParams): boolean {
|
||||||
|
pokemon.teraType = this.teraType;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // todo: denest
|
||||||
|
|
||||||
|
export class TeraTypeRewardGenerator extends RewardGenerator {
|
||||||
|
override generateReward(pregenArgs?: PokemonType) {
|
||||||
|
if (pregenArgs !== undefined) {
|
||||||
|
return new ChangeTeraTypeReward(pregenArgs[0]);
|
||||||
|
}
|
||||||
|
if (!globalScene.trainerItems.hasItem(TrainerItemId.TERA_ORB)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const shardType = this.getTeraType();
|
||||||
|
return new ChangeTeraTypeReward(shardType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getTeraType(): PokemonType {
|
||||||
|
// If all party members have a given Tera Type, omit it from the pool
|
||||||
|
const excludedType = globalScene.getPlayerParty().reduce((prevType, p) => {
|
||||||
|
if (
|
||||||
|
// Ignore Pokemon with fixed Tera Types
|
||||||
|
p.hasSpecies(SpeciesId.TERAPAGOS) ||
|
||||||
|
p.hasSpecies(SpeciesId.OGERPON) ||
|
||||||
|
p.hasSpecies(SpeciesId.SHEDINJA)
|
||||||
|
) {
|
||||||
|
return prevType;
|
||||||
|
}
|
||||||
|
return prevType === p.teraType ? prevType : PokemonType.UNKNOWN;
|
||||||
|
}, PokemonType.UNKNOWN);
|
||||||
|
|
||||||
|
const validTypes = getEnumValues(PokemonType).filter(t => t !== excludedType);
|
||||||
|
// 1/64 chance for tera stellar
|
||||||
|
return randSeedInt(64) ? randSeedItem(validTypes) : PokemonType.STELLAR;
|
||||||
|
}
|
||||||
|
}
|
100
src/items/rewards/tm.ts
Normal file
100
src/items/rewards/tm.ts
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { tmPoolTiers, tmSpecies } from "#balance/tms";
|
||||||
|
import { allMoves } from "#data/data-lists";
|
||||||
|
import { LearnMoveType } from "#enums/learn-move-type";
|
||||||
|
import type { MoveId } from "#enums/move-id";
|
||||||
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
|
import type { RarityTier } from "#enums/reward-tier";
|
||||||
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import { PokemonReward, type PokemonRewardParams, RewardGenerator } from "#items/reward";
|
||||||
|
import { PartyUiHandler } from "#ui/party-ui-handler";
|
||||||
|
import { padInt, randSeedItem } from "#utils/common";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class TmReward extends PokemonReward {
|
||||||
|
public moveId: MoveId;
|
||||||
|
|
||||||
|
constructor(moveId: MoveId) {
|
||||||
|
super(
|
||||||
|
"",
|
||||||
|
`tm_${PokemonType[allMoves[moveId].type].toLowerCase()}`,
|
||||||
|
(pokemon: PlayerPokemon) => {
|
||||||
|
if (
|
||||||
|
pokemon.compatibleTms.indexOf(moveId) === -1 ||
|
||||||
|
pokemon.getMoveset().filter(m => m.moveId === moveId).length
|
||||||
|
) {
|
||||||
|
return PartyUiHandler.NoEffectMessage;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
"tm",
|
||||||
|
);
|
||||||
|
|
||||||
|
this.moveId = moveId;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.TmModifierType.name", {
|
||||||
|
moveId: padInt(Object.keys(tmSpecies).indexOf(this.moveId.toString()) + 1, 3),
|
||||||
|
moveName: allMoves[this.moveId].name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t(
|
||||||
|
globalScene.enableMoveInfo
|
||||||
|
? "modifierType:ModifierType.TmModifierTypeWithInfo.description"
|
||||||
|
: "modifierType:ModifierType.TmModifierType.description",
|
||||||
|
{ moveName: allMoves[this.moveId].name },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode TmConsumable}
|
||||||
|
* @param playerPokemon The {@linkcode PlayerPokemon} that should learn the TM
|
||||||
|
* @returns always `true`
|
||||||
|
*/
|
||||||
|
apply({ pokemon }: PokemonRewardParams): boolean {
|
||||||
|
globalScene.phaseManager.unshiftNew(
|
||||||
|
"LearnMovePhase",
|
||||||
|
globalScene.getPlayerParty().indexOf(pokemon),
|
||||||
|
this.moveId,
|
||||||
|
LearnMoveType.TM,
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TmRewardGenerator extends RewardGenerator {
|
||||||
|
private tier: RarityTier;
|
||||||
|
constructor(tier: RarityTier) {
|
||||||
|
super();
|
||||||
|
this.tier = tier;
|
||||||
|
}
|
||||||
|
|
||||||
|
override generateReward(pregenArgs?: MoveId) {
|
||||||
|
if (pregenArgs !== undefined) {
|
||||||
|
return new TmReward(pregenArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
const party = globalScene.getPlayerParty();
|
||||||
|
const partyMemberCompatibleTms = party.map(p => {
|
||||||
|
const previousLevelMoves = p.getLearnableLevelMoves();
|
||||||
|
return (p as PlayerPokemon).compatibleTms.filter(
|
||||||
|
tm => !p.moveset.find(m => m.moveId === tm) && !previousLevelMoves.find(lm => lm === tm),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
const tierUniqueCompatibleTms = partyMemberCompatibleTms
|
||||||
|
.flat()
|
||||||
|
.filter(tm => tmPoolTiers[tm] === this.tier)
|
||||||
|
.filter(tm => !allMoves[tm].name.endsWith(" (N)"))
|
||||||
|
.filter((tm, i, array) => array.indexOf(tm) === i);
|
||||||
|
if (!tierUniqueCompatibleTms.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const randTmIndex = randSeedItem(tierUniqueCompatibleTms);
|
||||||
|
return new TmReward(randTmIndex);
|
||||||
|
}
|
||||||
|
}
|
53
src/items/rewards/trainer-item-reward.ts
Normal file
53
src/items/rewards/trainer-item-reward.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { allTrainerItems } from "#data/data-lists";
|
||||||
|
import { Stat, TEMP_BATTLE_STATS, type TempBattleStat } from "#enums/stat";
|
||||||
|
import type { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
|
import { Reward, RewardGenerator } from "#items/reward";
|
||||||
|
import { tempStatToTrainerItem } from "#items/trainer-items/x-items";
|
||||||
|
import { randSeedItem } from "#utils/common";
|
||||||
|
|
||||||
|
export class TrainerItemReward extends Reward {
|
||||||
|
// TODO: This should not be public
|
||||||
|
public itemId: TrainerItemId;
|
||||||
|
constructor(itemId: TrainerItemId, group?: string) {
|
||||||
|
super("", "", group, "se/restore");
|
||||||
|
this.itemId = itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return allTrainerItems[this.itemId].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return allTrainerItems[this.itemId].description;
|
||||||
|
}
|
||||||
|
|
||||||
|
get iconName(): string {
|
||||||
|
return allTrainerItems[this.itemId].iconName;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(): boolean {
|
||||||
|
return globalScene.trainerItems.add(this.itemId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LapsingTrainerItemReward extends TrainerItemReward {
|
||||||
|
apply(): boolean {
|
||||||
|
return globalScene.trainerItems.add(this.itemId, allTrainerItems[this.itemId].getMaxStackCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TempStatStageBoosterRewardGenerator extends RewardGenerator {
|
||||||
|
public static readonly items: Record<TempBattleStat, string> = {
|
||||||
|
[Stat.ATK]: "x_attack",
|
||||||
|
[Stat.DEF]: "x_defense",
|
||||||
|
[Stat.SPATK]: "x_sp_atk",
|
||||||
|
[Stat.SPDEF]: "x_sp_def",
|
||||||
|
[Stat.SPD]: "x_speed",
|
||||||
|
[Stat.ACC]: "x_accuracy",
|
||||||
|
};
|
||||||
|
|
||||||
|
override generateReward(pregenArgs?: TempBattleStat) {
|
||||||
|
return new LapsingTrainerItemReward(tempStatToTrainerItem[pregenArgs ?? randSeedItem(TEMP_BATTLE_STATS)]);
|
||||||
|
}
|
||||||
|
}
|
43
src/items/rewards/voucher.ts
Normal file
43
src/items/rewards/voucher.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import type { RewardId } from "#enums/reward-id";
|
||||||
|
import { Reward } from "#items/reward";
|
||||||
|
import { getVoucherTypeIcon, getVoucherTypeName, type VoucherType } from "#system/voucher";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class AddVoucherReward extends Reward {
|
||||||
|
private voucherType: VoucherType;
|
||||||
|
private count: number;
|
||||||
|
|
||||||
|
constructor(voucherType: VoucherType, count: number, id: RewardId) {
|
||||||
|
super("", getVoucherTypeIcon(voucherType), "voucher");
|
||||||
|
this.count = count;
|
||||||
|
this.voucherType = voucherType;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.AddVoucherConsumableType.name", {
|
||||||
|
modifierCount: this.count,
|
||||||
|
voucherTypeName: getVoucherTypeName(this.voucherType),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.AddVoucherConsumableType.description", {
|
||||||
|
modifierCount: this.count,
|
||||||
|
voucherTypeName: getVoucherTypeName(this.voucherType),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies {@linkcode AddVoucherReward}
|
||||||
|
* @param battleScene {@linkcode BattleScene}
|
||||||
|
* @returns always `true`
|
||||||
|
*/
|
||||||
|
apply(): boolean {
|
||||||
|
const voucherCounts = globalScene.gameData.voucherCounts;
|
||||||
|
voucherCounts[this.voucherType] += this.count;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@ import {
|
|||||||
type TrainerItemDataMap,
|
type TrainerItemDataMap,
|
||||||
type TrainerItemSaveData,
|
type TrainerItemSaveData,
|
||||||
type TrainerItemSpecs,
|
type TrainerItemSpecs,
|
||||||
} from "#items/trainer-item-data-types";
|
} from "#types/trainer-item-data-types";
|
||||||
import { getTypedEntries, getTypedKeys } from "#utils/common";
|
import { getTypedEntries, getTypedKeys } from "#utils/common";
|
||||||
|
|
||||||
export class TrainerItemManager {
|
export class TrainerItemManager {
|
||||||
|
@ -1,22 +1,12 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
|
||||||
import { getStatusEffectDescriptor, getStatusEffectHealText } from "#data/status-effect";
|
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
|
||||||
import { getStatKey, Stat, type TempBattleStat } from "#enums/stat";
|
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
|
||||||
import { TextStyle } from "#enums/text-style";
|
import { TextStyle } from "#enums/text-style";
|
||||||
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||||
import { TrainerItemId, TrainerItemNames } from "#enums/trainer-item-id";
|
import { type TrainerItemId, TrainerItemNames } from "#enums/trainer-item-id";
|
||||||
import type { TrainerItemManager } from "#items/trainer-item-manager";
|
import type { TrainerItemManager } from "#items/trainer-item-manager";
|
||||||
|
import type { NumberHolderParams, PreserveBerryParams } from "#types/trainer-item-parameter";
|
||||||
import { addTextObject } from "#ui/text";
|
import { addTextObject } from "#ui/text";
|
||||||
import { hslToHex, randSeedFloat, toDmgValue } from "#utils/common";
|
import { hslToHex } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import type {
|
|
||||||
BooleanHolderParams,
|
|
||||||
NumberHolderParams,
|
|
||||||
PokemonParams,
|
|
||||||
PreserveBerryParams,
|
|
||||||
} from "./trainer-item-parameter";
|
|
||||||
|
|
||||||
export class TrainerItem {
|
export class TrainerItem {
|
||||||
// public pokemonId: number;
|
// public pokemonId: number;
|
||||||
@ -25,9 +15,6 @@ export class TrainerItem {
|
|||||||
public isLapsing = false;
|
public isLapsing = false;
|
||||||
public effects: TrainerItemEffect[] = [];
|
public effects: TrainerItemEffect[] = [];
|
||||||
|
|
||||||
//TODO: If this is actually never changed by any subclass, perhaps it should not be here
|
|
||||||
public soundName = "se/restore";
|
|
||||||
|
|
||||||
constructor(type: TrainerItemId, maxStackCount = 1) {
|
constructor(type: TrainerItemId, maxStackCount = 1) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.maxStackCount = maxStackCount;
|
this.maxStackCount = maxStackCount;
|
||||||
@ -83,6 +70,35 @@ export class TrainerItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class LapsingTrainerItem extends TrainerItem {
|
||||||
|
isLapsing = true;
|
||||||
|
|
||||||
|
createIcon(battleCount: number): Phaser.GameObjects.Container {
|
||||||
|
const container = globalScene.add.container(0, 0);
|
||||||
|
|
||||||
|
const item = globalScene.add.sprite(0, 12, "items").setFrame(this.iconName).setOrigin(0, 0.5);
|
||||||
|
container.add(item);
|
||||||
|
|
||||||
|
// Linear interpolation on hue
|
||||||
|
const hue = Math.floor(120 * (battleCount / this.getMaxStackCount()) + 5);
|
||||||
|
|
||||||
|
// Generates the color hex code with a constant saturation and lightness but varying hue
|
||||||
|
const typeHex = hslToHex(hue, 0.5, 0.9);
|
||||||
|
const strokeHex = hslToHex(hue, 0.7, 0.3);
|
||||||
|
|
||||||
|
const battleCountText = addTextObject(27, 0, battleCount.toString(), TextStyle.PARTY, {
|
||||||
|
fontSize: "66px",
|
||||||
|
color: typeHex,
|
||||||
|
});
|
||||||
|
battleCountText.setShadow(0, 0);
|
||||||
|
battleCountText.setStroke(strokeHex, 16);
|
||||||
|
battleCountText.setOrigin(1, 0);
|
||||||
|
container.add(battleCountText);
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Candy Jar
|
// Candy Jar
|
||||||
export class LevelIncrementBoosterTrainerItem extends TrainerItem {
|
export class LevelIncrementBoosterTrainerItem extends TrainerItem {
|
||||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.LEVEL_INCREMENT_BOOSTER];
|
public effects: TrainerItemEffect[] = [TrainerItemEffect.LEVEL_INCREMENT_BOOSTER];
|
||||||
@ -211,326 +227,3 @@ export class HealShopCostTrainerItem extends TrainerItem {
|
|||||||
moneyCost.value = Math.floor(moneyCost.value * this.shopMultiplier);
|
moneyCost.value = Math.floor(moneyCost.value * this.shopMultiplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LapsingTrainerItem extends TrainerItem {
|
|
||||||
isLapsing = true;
|
|
||||||
|
|
||||||
createIcon(battleCount: number): Phaser.GameObjects.Container {
|
|
||||||
const container = globalScene.add.container(0, 0);
|
|
||||||
|
|
||||||
const item = globalScene.add.sprite(0, 12, "items").setFrame(this.iconName).setOrigin(0, 0.5);
|
|
||||||
container.add(item);
|
|
||||||
|
|
||||||
// Linear interpolation on hue
|
|
||||||
const hue = Math.floor(120 * (battleCount / this.getMaxStackCount()) + 5);
|
|
||||||
|
|
||||||
// Generates the color hex code with a constant saturation and lightness but varying hue
|
|
||||||
const typeHex = hslToHex(hue, 0.5, 0.9);
|
|
||||||
const strokeHex = hslToHex(hue, 0.7, 0.3);
|
|
||||||
|
|
||||||
const battleCountText = addTextObject(27, 0, battleCount.toString(), TextStyle.PARTY, {
|
|
||||||
fontSize: "66px",
|
|
||||||
color: typeHex,
|
|
||||||
});
|
|
||||||
battleCountText.setShadow(0, 0);
|
|
||||||
battleCountText.setStroke(strokeHex, 16);
|
|
||||||
battleCountText.setOrigin(1, 0);
|
|
||||||
container.add(battleCountText);
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DoubleBattleChanceBoosterTrainerItem extends LapsingTrainerItem {
|
|
||||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.DOUBLE_BATTLE_CHANCE_BOOSTER];
|
|
||||||
|
|
||||||
get description(): string {
|
|
||||||
return i18next.t("modifierType:ModifierType.DoubleBattleChanceBoosterModifierType.description", {
|
|
||||||
battleCount: this.getMaxStackCount(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(_manager: TrainerItemManager, params: NumberHolderParams) {
|
|
||||||
const doubleBattleChance = params.numberHolder;
|
|
||||||
// This is divided because the chance is generated as a number from 0 to doubleBattleChance.value using randSeedInt
|
|
||||||
// A double battle will initiate if the generated number is 0
|
|
||||||
doubleBattleChance.value /= 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type TempStatToTrainerItemMap = {
|
|
||||||
[key in TempBattleStat]: TrainerItemId;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const tempStatToTrainerItem: TempStatToTrainerItemMap = {
|
|
||||||
[Stat.ATK]: TrainerItemId.X_ATTACK,
|
|
||||||
[Stat.DEF]: TrainerItemId.X_DEFENSE,
|
|
||||||
[Stat.SPATK]: TrainerItemId.X_SP_ATK,
|
|
||||||
[Stat.SPDEF]: TrainerItemId.X_SP_DEF,
|
|
||||||
[Stat.SPD]: TrainerItemId.X_SPEED,
|
|
||||||
[Stat.ACC]: TrainerItemId.X_ACCURACY,
|
|
||||||
};
|
|
||||||
|
|
||||||
export class TempStatStageBoosterTrainerItem extends LapsingTrainerItem {
|
|
||||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.TEMP_STAT_STAGE_BOOSTER];
|
|
||||||
private stat: TempBattleStat;
|
|
||||||
|
|
||||||
constructor(type: TrainerItemId, stat: TempBattleStat, stackCount?: number) {
|
|
||||||
super(type, stackCount);
|
|
||||||
|
|
||||||
this.stat = stat;
|
|
||||||
}
|
|
||||||
|
|
||||||
get name(): string {
|
|
||||||
return i18next.t(`modifierType:TempStatStageBoosterItem.${TrainerItemNames[this.type]?.toLowerCase()}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
get description(): string {
|
|
||||||
console.log();
|
|
||||||
return i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.description", {
|
|
||||||
stat: i18next.t(getStatKey(this.stat)),
|
|
||||||
amount: i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.extra.percentage"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(_manager: TrainerItemManager, params: NumberHolderParams) {
|
|
||||||
const statLevel = params.numberHolder;
|
|
||||||
const boost = 0.3;
|
|
||||||
statLevel.value += boost;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class TempAccuracyBoosterTrainerItem extends LapsingTrainerItem {
|
|
||||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.TEMP_ACCURACY_BOOSTER];
|
|
||||||
|
|
||||||
get name(): string {
|
|
||||||
return i18next.t(`modifierType:TempStatStageBoosterItem.${TrainerItemNames[this.type]?.toLowerCase()}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
get description(): string {
|
|
||||||
console.log();
|
|
||||||
return i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.description", {
|
|
||||||
stat: i18next.t(getStatKey(Stat.ACC)),
|
|
||||||
amount: i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.extra.percentage"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(_manager: TrainerItemManager, params: NumberHolderParams) {
|
|
||||||
const statLevel = params.numberHolder;
|
|
||||||
const boost = 1;
|
|
||||||
statLevel.value += boost;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class TempCritBoosterTrainerItem extends LapsingTrainerItem {
|
|
||||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.TEMP_CRIT_BOOSTER];
|
|
||||||
|
|
||||||
get description(): string {
|
|
||||||
return i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.description", {
|
|
||||||
stat: i18next.t("modifierType:ModifierType.DIRE_HIT.extra.raises"),
|
|
||||||
amount: i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.extra.stage"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(_manager: TrainerItemManager, params: NumberHolderParams) {
|
|
||||||
const critLevel = params.numberHolder;
|
|
||||||
critLevel.value++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class EnemyDamageBoosterTrainerItem extends TrainerItem {
|
|
||||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_DAMAGE_BOOSTER];
|
|
||||||
public damageBoost = 1.05;
|
|
||||||
|
|
||||||
get iconName(): string {
|
|
||||||
return "wl_item_drop";
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(manager: TrainerItemManager, params: NumberHolderParams): boolean {
|
|
||||||
const stack = manager.getStack(this.type);
|
|
||||||
const multiplier = params.numberHolder;
|
|
||||||
|
|
||||||
multiplier.value = toDmgValue(multiplier.value * Math.pow(this.damageBoost, stack));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
getMaxStackCount(): number {
|
|
||||||
return 999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class EnemyDamageReducerTrainerItem extends TrainerItem {
|
|
||||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_DAMAGE_REDUCER];
|
|
||||||
public damageReduction = 0.975;
|
|
||||||
|
|
||||||
get iconName(): string {
|
|
||||||
return "wl_guard_spec";
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(manager: TrainerItemManager, params: NumberHolderParams): boolean {
|
|
||||||
const stack = manager.getStack(this.type);
|
|
||||||
const multiplier = params.numberHolder;
|
|
||||||
|
|
||||||
multiplier.value = toDmgValue(multiplier.value * Math.pow(this.damageReduction, stack));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
getMaxStackCount(): number {
|
|
||||||
return globalScene.currentBattle.waveIndex < 2000 ? 99 : 999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class EnemyTurnHealTrainerItem extends TrainerItem {
|
|
||||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_HEAL];
|
|
||||||
public healPercent = 2;
|
|
||||||
|
|
||||||
get iconName(): string {
|
|
||||||
return "wl_potion";
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(manager: TrainerItemManager, params: PokemonParams): boolean {
|
|
||||||
const stack = manager.getStack(this.type);
|
|
||||||
const enemyPokemon = params.pokemon;
|
|
||||||
|
|
||||||
if (!enemyPokemon.isFullHp()) {
|
|
||||||
globalScene.phaseManager.unshiftNew(
|
|
||||||
"PokemonHealPhase",
|
|
||||||
enemyPokemon.getBattlerIndex(),
|
|
||||||
Math.max(Math.floor(enemyPokemon.getMaxHp() / (100 / this.healPercent)) * stack, 1),
|
|
||||||
i18next.t("modifier:enemyTurnHealApply", {
|
|
||||||
pokemonNameWithAffix: getPokemonNameWithAffix(enemyPokemon),
|
|
||||||
}),
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class EnemyAttackStatusEffectChanceTrainerItem extends TrainerItem {
|
|
||||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_ATTACK_STATUS_CHANCE];
|
|
||||||
public effect: StatusEffect;
|
|
||||||
|
|
||||||
constructor(type: TrainerItemId, effect: StatusEffect, stackCount?: number) {
|
|
||||||
super(type, stackCount);
|
|
||||||
|
|
||||||
this.effect = effect;
|
|
||||||
}
|
|
||||||
|
|
||||||
get iconName(): string {
|
|
||||||
if (this.effect === StatusEffect.POISON) {
|
|
||||||
return "wl_antidote";
|
|
||||||
}
|
|
||||||
if (this.effect === StatusEffect.PARALYSIS) {
|
|
||||||
return "wl_paralyze_heal";
|
|
||||||
}
|
|
||||||
if (this.effect === StatusEffect.BURN) {
|
|
||||||
return "wl_burn_heal";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
get description(): string {
|
|
||||||
return i18next.t("modifierType:ModifierType.EnemyAttackStatusEffectChanceModifierType.description", {
|
|
||||||
chancePercent: this.getChance() * 100,
|
|
||||||
statusEffect: getStatusEffectDescriptor(this.effect),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(manager: TrainerItemManager, params: PokemonParams): boolean {
|
|
||||||
const stack = manager.getStack(this.type);
|
|
||||||
const enemyPokemon = params.pokemon;
|
|
||||||
const chance = this.getChance();
|
|
||||||
|
|
||||||
if (randSeedFloat() <= chance * stack) {
|
|
||||||
return enemyPokemon.trySetStatus(this.effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
getChance(): number {
|
|
||||||
return 0.025 * (this.effect === StatusEffect.BURN || this.effect === StatusEffect.POISON ? 2 : 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class EnemyStatusEffectHealChanceTrainerItem extends TrainerItem {
|
|
||||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_STATUS_HEAL_CHANCE];
|
|
||||||
public chance = 0.025;
|
|
||||||
|
|
||||||
get iconName(): string {
|
|
||||||
return "wl_full_heal";
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(manager: TrainerItemManager, params: PokemonParams): boolean {
|
|
||||||
const stack = manager.getStack(this.type);
|
|
||||||
const enemyPokemon = params.pokemon;
|
|
||||||
|
|
||||||
if (!enemyPokemon.status || randSeedFloat() > this.chance * stack) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
globalScene.phaseManager.queueMessage(
|
|
||||||
getStatusEffectHealText(enemyPokemon.status.effect, getPokemonNameWithAffix(enemyPokemon)),
|
|
||||||
);
|
|
||||||
enemyPokemon.resetStatus();
|
|
||||||
enemyPokemon.updateInfo();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class EnemyEndureChanceTrainerItem extends TrainerItem {
|
|
||||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_ENDURE_CHANCE];
|
|
||||||
public chance = 2;
|
|
||||||
|
|
||||||
get iconName(): string {
|
|
||||||
return "wl_reset_urge";
|
|
||||||
}
|
|
||||||
|
|
||||||
get description(): string {
|
|
||||||
return i18next.t("modifierType:ModifierType.EnemyEndureChanceModifierType.description", {
|
|
||||||
chancePercent: this.chance,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(manager: TrainerItemManager, params: PokemonParams): boolean {
|
|
||||||
const stack = manager.getStack(this.type);
|
|
||||||
const target = params.pokemon;
|
|
||||||
|
|
||||||
if (target.waveData.endured || target.randBattleSeedInt(100) >= this.chance * stack) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
target.addTag(BattlerTagType.ENDURE_TOKEN, 1);
|
|
||||||
|
|
||||||
target.waveData.endured = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class EnemyFusionChanceTrainerItem extends TrainerItem {
|
|
||||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_FUSED_CHANCE];
|
|
||||||
public chance = 0.01;
|
|
||||||
|
|
||||||
get iconName(): string {
|
|
||||||
return "wl_custom_spliced";
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(manager: TrainerItemManager, params: BooleanHolderParams) {
|
|
||||||
const stack = manager.getStack(this.type);
|
|
||||||
const isFusion = params.booleanHolder;
|
|
||||||
if (randSeedFloat() > this.chance * stack) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
isFusion.value = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
209
src/items/trainer-items/enemy-tokens.ts
Normal file
209
src/items/trainer-items/enemy-tokens.ts
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { getStatusEffectDescriptor, getStatusEffectHealText } from "#data/status-effect";
|
||||||
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
|
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||||
|
import type { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
|
import { TrainerItem } from "#items/trainer-item";
|
||||||
|
import type { TrainerItemManager } from "#items/trainer-item-manager";
|
||||||
|
import type { BooleanHolderParams, NumberHolderParams, PokemonParams } from "#types/trainer-item-parameter";
|
||||||
|
import { randSeedFloat, toDmgValue } from "#utils/common";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class EnemyDamageBoosterTrainerItem extends TrainerItem {
|
||||||
|
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_DAMAGE_BOOSTER];
|
||||||
|
public damageBoost = 1.05;
|
||||||
|
|
||||||
|
get iconName(): string {
|
||||||
|
return "wl_item_drop";
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(manager: TrainerItemManager, params: NumberHolderParams): boolean {
|
||||||
|
const stack = manager.getStack(this.type);
|
||||||
|
const multiplier = params.numberHolder;
|
||||||
|
|
||||||
|
multiplier.value = toDmgValue(multiplier.value * Math.pow(this.damageBoost, stack));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getMaxStackCount(): number {
|
||||||
|
return 999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class EnemyDamageReducerTrainerItem extends TrainerItem {
|
||||||
|
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_DAMAGE_REDUCER];
|
||||||
|
public damageReduction = 0.975;
|
||||||
|
|
||||||
|
get iconName(): string {
|
||||||
|
return "wl_guard_spec";
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(manager: TrainerItemManager, params: NumberHolderParams): boolean {
|
||||||
|
const stack = manager.getStack(this.type);
|
||||||
|
const multiplier = params.numberHolder;
|
||||||
|
|
||||||
|
multiplier.value = toDmgValue(multiplier.value * Math.pow(this.damageReduction, stack));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getMaxStackCount(): number {
|
||||||
|
return globalScene.currentBattle.waveIndex < 2000 ? 99 : 999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class EnemyTurnHealTrainerItem extends TrainerItem {
|
||||||
|
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_HEAL];
|
||||||
|
public healPercent = 2;
|
||||||
|
|
||||||
|
get iconName(): string {
|
||||||
|
return "wl_potion";
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(manager: TrainerItemManager, params: PokemonParams): boolean {
|
||||||
|
const stack = manager.getStack(this.type);
|
||||||
|
const enemyPokemon = params.pokemon;
|
||||||
|
|
||||||
|
if (!enemyPokemon.isFullHp()) {
|
||||||
|
globalScene.phaseManager.unshiftNew(
|
||||||
|
"PokemonHealPhase",
|
||||||
|
enemyPokemon.getBattlerIndex(),
|
||||||
|
Math.max(Math.floor(enemyPokemon.getMaxHp() / (100 / this.healPercent)) * stack, 1),
|
||||||
|
i18next.t("modifier:enemyTurnHealApply", {
|
||||||
|
pokemonNameWithAffix: getPokemonNameWithAffix(enemyPokemon),
|
||||||
|
}),
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class EnemyAttackStatusEffectChanceTrainerItem extends TrainerItem {
|
||||||
|
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_ATTACK_STATUS_CHANCE];
|
||||||
|
public effect: StatusEffect;
|
||||||
|
|
||||||
|
constructor(type: TrainerItemId, effect: StatusEffect, stackCount?: number) {
|
||||||
|
super(type, stackCount);
|
||||||
|
|
||||||
|
this.effect = effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
get iconName(): string {
|
||||||
|
if (this.effect === StatusEffect.POISON) {
|
||||||
|
return "wl_antidote";
|
||||||
|
}
|
||||||
|
if (this.effect === StatusEffect.PARALYSIS) {
|
||||||
|
return "wl_paralyze_heal";
|
||||||
|
}
|
||||||
|
if (this.effect === StatusEffect.BURN) {
|
||||||
|
return "wl_burn_heal";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.EnemyAttackStatusEffectChanceModifierType.description", {
|
||||||
|
chancePercent: this.getChance() * 100,
|
||||||
|
statusEffect: getStatusEffectDescriptor(this.effect),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(manager: TrainerItemManager, params: PokemonParams): boolean {
|
||||||
|
const stack = manager.getStack(this.type);
|
||||||
|
const enemyPokemon = params.pokemon;
|
||||||
|
const chance = this.getChance();
|
||||||
|
|
||||||
|
if (randSeedFloat() <= chance * stack) {
|
||||||
|
return enemyPokemon.trySetStatus(this.effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getChance(): number {
|
||||||
|
return 0.025 * (this.effect === StatusEffect.BURN || this.effect === StatusEffect.POISON ? 2 : 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class EnemyStatusEffectHealChanceTrainerItem extends TrainerItem {
|
||||||
|
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_STATUS_HEAL_CHANCE];
|
||||||
|
public chance = 0.025;
|
||||||
|
|
||||||
|
get iconName(): string {
|
||||||
|
return "wl_full_heal";
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(manager: TrainerItemManager, params: PokemonParams): boolean {
|
||||||
|
const stack = manager.getStack(this.type);
|
||||||
|
const enemyPokemon = params.pokemon;
|
||||||
|
|
||||||
|
if (!enemyPokemon.status || randSeedFloat() > this.chance * stack) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
globalScene.phaseManager.queueMessage(
|
||||||
|
getStatusEffectHealText(enemyPokemon.status.effect, getPokemonNameWithAffix(enemyPokemon)),
|
||||||
|
);
|
||||||
|
enemyPokemon.resetStatus();
|
||||||
|
enemyPokemon.updateInfo();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class EnemyEndureChanceTrainerItem extends TrainerItem {
|
||||||
|
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_ENDURE_CHANCE];
|
||||||
|
public chance = 2;
|
||||||
|
|
||||||
|
get iconName(): string {
|
||||||
|
return "wl_reset_urge";
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.EnemyEndureChanceModifierType.description", {
|
||||||
|
chancePercent: this.chance,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(manager: TrainerItemManager, params: PokemonParams): boolean {
|
||||||
|
const stack = manager.getStack(this.type);
|
||||||
|
const target = params.pokemon;
|
||||||
|
|
||||||
|
if (target.waveData.endured || target.randBattleSeedInt(100) >= this.chance * stack) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
target.addTag(BattlerTagType.ENDURE_TOKEN, 1);
|
||||||
|
|
||||||
|
target.waveData.endured = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class EnemyFusionChanceTrainerItem extends TrainerItem {
|
||||||
|
public effects: TrainerItemEffect[] = [TrainerItemEffect.ENEMY_FUSED_CHANCE];
|
||||||
|
public chance = 0.01;
|
||||||
|
|
||||||
|
get iconName(): string {
|
||||||
|
return "wl_custom_spliced";
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(manager: TrainerItemManager, params: BooleanHolderParams) {
|
||||||
|
const stack = manager.getStack(this.type);
|
||||||
|
const isFusion = params.booleanHolder;
|
||||||
|
if (randSeedFloat() > this.chance * stack) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
isFusion.value = true;
|
||||||
|
}
|
||||||
|
}
|
22
src/items/trainer-items/lure.ts
Normal file
22
src/items/trainer-items/lure.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||||
|
import { LapsingTrainerItem } from "#items/trainer-item";
|
||||||
|
import type { TrainerItemManager } from "#items/trainer-item-manager";
|
||||||
|
import type { NumberHolderParams } from "#types/trainer-item-parameter";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
export class DoubleBattleChanceBoosterTrainerItem extends LapsingTrainerItem {
|
||||||
|
public effects: TrainerItemEffect[] = [TrainerItemEffect.DOUBLE_BATTLE_CHANCE_BOOSTER];
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.DoubleBattleChanceBoosterModifierType.description", {
|
||||||
|
battleCount: this.getMaxStackCount(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(_manager: TrainerItemManager, params: NumberHolderParams) {
|
||||||
|
const doubleBattleChance = params.numberHolder;
|
||||||
|
// This is divided because the chance is generated as a number from 0 to doubleBattleChance.value using randSeedInt
|
||||||
|
// A double battle will initiate if the generated number is 0
|
||||||
|
doubleBattleChance.value /= 4;
|
||||||
|
}
|
||||||
|
}
|
87
src/items/trainer-items/x-items.ts
Normal file
87
src/items/trainer-items/x-items.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import { getStatKey, Stat, type TempBattleStat } from "#enums/stat";
|
||||||
|
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||||
|
import { TrainerItemId, TrainerItemNames } from "#enums/trainer-item-id";
|
||||||
|
import { LapsingTrainerItem } from "#items/trainer-item";
|
||||||
|
import type { TrainerItemManager } from "#items/trainer-item-manager";
|
||||||
|
import type { NumberHolderParams } from "#types/trainer-item-parameter";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
type TempStatToTrainerItemMap = {
|
||||||
|
[key in TempBattleStat]: TrainerItemId;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const tempStatToTrainerItem: TempStatToTrainerItemMap = {
|
||||||
|
[Stat.ATK]: TrainerItemId.X_ATTACK,
|
||||||
|
[Stat.DEF]: TrainerItemId.X_DEFENSE,
|
||||||
|
[Stat.SPATK]: TrainerItemId.X_SP_ATK,
|
||||||
|
[Stat.SPDEF]: TrainerItemId.X_SP_DEF,
|
||||||
|
[Stat.SPD]: TrainerItemId.X_SPEED,
|
||||||
|
[Stat.ACC]: TrainerItemId.X_ACCURACY,
|
||||||
|
};
|
||||||
|
|
||||||
|
export class TempStatStageBoosterTrainerItem extends LapsingTrainerItem {
|
||||||
|
public effects: TrainerItemEffect[] = [TrainerItemEffect.TEMP_STAT_STAGE_BOOSTER];
|
||||||
|
private stat: TempBattleStat;
|
||||||
|
|
||||||
|
constructor(type: TrainerItemId, stat: TempBattleStat, stackCount?: number) {
|
||||||
|
super(type, stackCount);
|
||||||
|
|
||||||
|
this.stat = stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return i18next.t(`modifierType:TempStatStageBoosterItem.${TrainerItemNames[this.type]?.toLowerCase()}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
console.log();
|
||||||
|
return i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.description", {
|
||||||
|
stat: i18next.t(getStatKey(this.stat)),
|
||||||
|
amount: i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.extra.percentage"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(_manager: TrainerItemManager, params: NumberHolderParams) {
|
||||||
|
const statLevel = params.numberHolder;
|
||||||
|
const boost = 0.3;
|
||||||
|
statLevel.value += boost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TempAccuracyBoosterTrainerItem extends LapsingTrainerItem {
|
||||||
|
public effects: TrainerItemEffect[] = [TrainerItemEffect.TEMP_ACCURACY_BOOSTER];
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return i18next.t(`modifierType:TempStatStageBoosterItem.${TrainerItemNames[this.type]?.toLowerCase()}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
console.log();
|
||||||
|
return i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.description", {
|
||||||
|
stat: i18next.t(getStatKey(Stat.ACC)),
|
||||||
|
amount: i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.extra.percentage"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(_manager: TrainerItemManager, params: NumberHolderParams) {
|
||||||
|
const statLevel = params.numberHolder;
|
||||||
|
const boost = 1;
|
||||||
|
statLevel.value += boost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TempCritBoosterTrainerItem extends LapsingTrainerItem {
|
||||||
|
public effects: TrainerItemEffect[] = [TrainerItemEffect.TEMP_CRIT_BOOSTER];
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.description", {
|
||||||
|
stat: i18next.t("modifierType:ModifierType.DIRE_HIT.extra.raises"),
|
||||||
|
amount: i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.extra.stage"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(_manager: TrainerItemManager, params: NumberHolderParams) {
|
||||||
|
const critLevel = params.numberHolder;
|
||||||
|
critLevel.value++;
|
||||||
|
}
|
||||||
|
}
|
@ -21,10 +21,10 @@ import { TrainerType } from "#enums/trainer-type";
|
|||||||
import { Unlockables } from "#enums/unlockables";
|
import { Unlockables } from "#enums/unlockables";
|
||||||
import { VariantTier } from "#enums/variant-tier";
|
import { VariantTier } from "#enums/variant-tier";
|
||||||
import { WeatherType } from "#enums/weather-type";
|
import { WeatherType } from "#enums/weather-type";
|
||||||
import { HeldItemConfiguration } from "#items/held-item-data-types";
|
|
||||||
import { TrainerItemConfiguration } from "#items/trainer-item-data-types";
|
|
||||||
import { Variant } from "#sprites/variant";
|
import { Variant } from "#sprites/variant";
|
||||||
|
import { HeldItemConfiguration } from "#types/held-item-data-types";
|
||||||
import { RewardSpecs } from "#types/rewards";
|
import { RewardSpecs } from "#types/rewards";
|
||||||
|
import { TrainerItemConfiguration } from "#types/trainer-item-data-types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This comment block exists to prevent IDEs from automatically removing unused imports
|
* This comment block exists to prevent IDEs from automatically removing unused imports
|
||||||
|
@ -5,14 +5,15 @@ import { RewardPoolType } from "#enums/reward-pool-type";
|
|||||||
import type { RarityTier } from "#enums/reward-tier";
|
import type { RarityTier } from "#enums/reward-tier";
|
||||||
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||||
import { UiMode } from "#enums/ui-mode";
|
import { UiMode } from "#enums/ui-mode";
|
||||||
import type {
|
import {
|
||||||
PokemonMoveRecallRewardParams,
|
type PokemonMoveRecallRewardParams,
|
||||||
PokemonMoveRewardParams,
|
type PokemonMoveReward,
|
||||||
PokemonRewardParams,
|
type PokemonMoveRewardParams,
|
||||||
Reward,
|
PokemonReward,
|
||||||
RewardOption,
|
type PokemonRewardParams,
|
||||||
|
type Reward,
|
||||||
|
type RewardOption,
|
||||||
} from "#items/reward";
|
} from "#items/reward";
|
||||||
import { FusePokemonReward, type PokemonMoveReward, PokemonReward, RememberMoveReward, TmReward } from "#items/reward";
|
|
||||||
import {
|
import {
|
||||||
type CustomRewardSettings,
|
type CustomRewardSettings,
|
||||||
generatePlayerRewardOptions,
|
generatePlayerRewardOptions,
|
||||||
@ -20,6 +21,9 @@ import {
|
|||||||
getRewardPoolForType,
|
getRewardPoolForType,
|
||||||
} from "#items/reward-pool-utils";
|
} from "#items/reward-pool-utils";
|
||||||
import { getPlayerShopRewardOptionsForWave, isMoveReward, isRememberMoveReward, isTmReward } from "#items/reward-utils";
|
import { getPlayerShopRewardOptionsForWave, isMoveReward, isRememberMoveReward, isTmReward } from "#items/reward-utils";
|
||||||
|
import { FusePokemonReward } from "#items/rewards/fuse";
|
||||||
|
import { RememberMoveReward } from "#items/rewards/remember-move";
|
||||||
|
import { TmReward } from "#items/rewards/tm";
|
||||||
import { BattlePhase } from "#phases/battle-phase";
|
import { BattlePhase } from "#phases/battle-phase";
|
||||||
import { PartyOption, PartyUiHandler, PartyUiMode, type PokemonMoveSelectFilter } from "#ui/party-ui-handler";
|
import { PartyOption, PartyUiHandler, PartyUiMode, type PokemonMoveSelectFilter } from "#ui/party-ui-handler";
|
||||||
import { type RewardSelectUiHandler, SHOP_OPTIONS_ROW_LIMIT } from "#ui/reward-select-ui-handler";
|
import { type RewardSelectUiHandler, SHOP_OPTIONS_ROW_LIMIT } from "#ui/reward-select-ui-handler";
|
||||||
|
@ -36,7 +36,6 @@ import { Unlockables } from "#enums/unlockables";
|
|||||||
import { WeatherType } from "#enums/weather-type";
|
import { WeatherType } from "#enums/weather-type";
|
||||||
import { TagAddedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#events/arena";
|
import { TagAddedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#events/arena";
|
||||||
import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
import type { TrainerItemConfiguration, TrainerItemSaveData } from "#items/trainer-item-data-types";
|
|
||||||
import { MysteryEncounterSaveData } from "#mystery-encounters/mystery-encounter-save-data";
|
import { MysteryEncounterSaveData } from "#mystery-encounters/mystery-encounter-save-data";
|
||||||
import type { Variant } from "#sprites/variant";
|
import type { Variant } from "#sprites/variant";
|
||||||
import { achvs } from "#system/achv";
|
import { achvs } from "#system/achv";
|
||||||
@ -59,6 +58,7 @@ import {
|
|||||||
import { VoucherType, vouchers } from "#system/voucher";
|
import { VoucherType, vouchers } from "#system/voucher";
|
||||||
import { trainerConfigs } from "#trainers/trainer-config";
|
import { trainerConfigs } from "#trainers/trainer-config";
|
||||||
import type { DexData, DexEntry } from "#types/dex-data";
|
import type { DexData, DexEntry } from "#types/dex-data";
|
||||||
|
import type { TrainerItemConfiguration, TrainerItemSaveData } from "#types/trainer-item-data-types";
|
||||||
import { RUN_HISTORY_LIMIT } from "#ui/run-history-ui-handler";
|
import { RUN_HISTORY_LIMIT } from "#ui/run-history-ui-handler";
|
||||||
import { applyChallenges } from "#utils/challenge-utils";
|
import { applyChallenges } from "#utils/challenge-utils";
|
||||||
import { executeIf, fixedInt, isLocal, NumberHolder, randInt, randSeedItem } from "#utils/common";
|
import { executeIf, fixedInt, isLocal, NumberHolder, randInt, randSeedItem } from "#utils/common";
|
||||||
|
@ -11,10 +11,10 @@ import type { PokemonType } from "#enums/pokemon-type";
|
|||||||
import type { SpeciesId } from "#enums/species-id";
|
import type { SpeciesId } from "#enums/species-id";
|
||||||
import { TrainerSlot } from "#enums/trainer-slot";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { EnemyPokemon, Pokemon } from "#field/pokemon";
|
import { EnemyPokemon, Pokemon } from "#field/pokemon";
|
||||||
import type { HeldItemSaveData } from "#items/held-item-data-types";
|
|
||||||
import { saveDataToConfig } from "#items/held-item-pool";
|
import { saveDataToConfig } from "#items/held-item-pool";
|
||||||
import { PokemonMove } from "#moves/pokemon-move";
|
import { PokemonMove } from "#moves/pokemon-move";
|
||||||
import type { Variant } from "#sprites/variant";
|
import type { Variant } from "#sprites/variant";
|
||||||
|
import type { HeldItemSaveData } from "#types/held-item-data-types";
|
||||||
import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils";
|
import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils";
|
||||||
|
|
||||||
export class PokemonData {
|
export class PokemonData {
|
||||||
|
Loading…
Reference in New Issue
Block a user