mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-09-23 15:03: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 { RewardId } from "#enums/reward-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 { generateRewardForTest } from "#test/test-utils/reward-test-utils";
|
||||
import Phaser from "phaser";
|
||||
|
@ -1,9 +1,9 @@
|
||||
import type { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
import type { SpeciesId } from "#enums/species-id";
|
||||
import type { EnemyPokemon } from "#field/pokemon";
|
||||
import type { TrainerItemConfiguration } from "#items/trainer-item-data-types";
|
||||
import type { TrainerConfig } from "#trainers/trainer-config";
|
||||
import type { TrainerPartyTemplate } from "#trainers/trainer-party-template";
|
||||
import type { TrainerItemConfiguration } from "./trainer-item-data-types";
|
||||
|
||||
export type PartyTemplateFunc = () => TrainerPartyTemplate;
|
||||
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 { applyHeldItems } from "#items/all-held-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 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 type { TrainerItemEffectParamMap } from "#items/trainer-item-parameter";
|
||||
import { getNewTrainerItemFromPool } from "#items/trainer-item-pool";
|
||||
import type { EnemyAttackStatusEffectChanceTrainerItem } from "#items/trainer-items/enemy-tokens";
|
||||
import { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterSaveData } from "#mystery-encounters/mystery-encounter-save-data";
|
||||
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 { vouchers } from "#system/voucher";
|
||||
import { trainerConfigs } from "#trainers/trainer-config";
|
||||
import type { HeldItemConfiguration } from "#types/held-item-data-types";
|
||||
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 { ArenaFlyout } from "#ui/arena-flyout";
|
||||
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 { Pokemon } 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 { PokemonMove } from "#moves/pokemon-move";
|
||||
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 { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option";
|
||||
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 { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
import i18next from "i18next";
|
||||
|
@ -2,6 +2,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { EncounterBattleAnim } from "#data/battle-anims";
|
||||
import { allAbilities } from "#data/data-lists";
|
||||
import { getHeldItemTier } from "#data/items/held-item-default-tiers";
|
||||
import { CustomPokemonData } from "#data/pokemon-data";
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { BattlerIndex } from "#enums/battler-index";
|
||||
@ -21,7 +22,6 @@ import { SpeciesId } from "#enums/species-id";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import type { PlayerPokemon } from "#field/pokemon";
|
||||
import { getHeldItemTier } from "#items/held-item-default-tiers";
|
||||
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
||||
import { PokemonMove } from "#moves/pokemon-move";
|
||||
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 { RewardId } from "#enums/reward-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 { initBattleWithEnemyConfig, leaveEncounterWithoutBattle } from "#mystery-encounters/encounter-phase-utils";
|
||||
import { getRandomPlayerPokemon, getRandomSpeciesByStarterCost } from "#mystery-encounters/encounter-pokemon-utils";
|
||||
import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option";
|
||||
import type { HeldItemConfiguration } from "#types/held-item-data-types";
|
||||
import { isNullOrUndefined, randSeedInt } from "#utils/common";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
|
||||
|
@ -8,9 +8,10 @@ import { RewardPoolType } from "#enums/reward-pool-type";
|
||||
import { RarityTier } from "#enums/reward-tier";
|
||||
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||
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 { isTmReward } from "#items/reward-utils";
|
||||
import type { TrainerItemReward } from "#items/rewards/trainer-item-reward";
|
||||
import { queueEncounterMessage } from "#mystery-encounters/encounter-dialogue-utils";
|
||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||
import {
|
||||
|
@ -3,6 +3,7 @@ import { timedEventManager } from "#app/global-event-manager";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { allHeldItems, allSpecies } from "#data/data-lists";
|
||||
import { Gender, getGenderSymbol } from "#data/gender";
|
||||
import { getHeldItemTier } from "#data/items/held-item-default-tiers";
|
||||
import { getNatureName } from "#data/nature";
|
||||
import { getPokeballAtlasKey, getPokeballTintColor } from "#data/pokeball";
|
||||
import type { PokemonSpecies } from "#data/pokemon-species";
|
||||
@ -21,7 +22,6 @@ import { TrainerType } from "#enums/trainer-type";
|
||||
import { doShinySparkleAnim } from "#field/anims";
|
||||
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||
import { EnemyPokemon } from "#field/pokemon";
|
||||
import { getHeldItemTier } from "#items/held-item-default-tiers";
|
||||
import type { RewardOption } from "#items/reward";
|
||||
import { generatePlayerRewardOptions, generateRewardPoolWeights, getRewardPoolForType } from "#items/reward-pool-utils";
|
||||
import { isTmReward } from "#items/reward-utils";
|
||||
|
@ -11,7 +11,6 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { PokeballType } from "#enums/pokeball";
|
||||
import { Stat } from "#enums/stat";
|
||||
import type { EnemyPokemon, Pokemon } from "#field/pokemon";
|
||||
import type { HeldItemSpecs } from "#items/held-item-data-types";
|
||||
import { getPartyBerries } from "#items/item-utility";
|
||||
import { PokemonMove } from "#moves/pokemon-move";
|
||||
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 { CHARMING_MOVES } from "#mystery-encounters/requirement-groups";
|
||||
import { PokemonData } from "#system/pokemon-data";
|
||||
import type { HeldItemSpecs } from "#types/held-item-data-types";
|
||||
import { isNullOrUndefined, pickWeightedIndex, randSeedInt } from "#utils/common";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
|
@ -19,7 +19,6 @@ import { StatusEffect } from "#enums/status-effect";
|
||||
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
||||
import { PokemonMove } from "#moves/pokemon-move";
|
||||
import { showEncounterText } from "#mystery-encounters/encounter-dialogue-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 { trainerConfigs } from "#trainers/trainer-config";
|
||||
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 { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
|
||||
|
@ -20,7 +20,6 @@ import { TrainerSlot } from "#enums/trainer-slot";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { TrainerVariant } from "#enums/trainer-variant";
|
||||
import type { EnemyPokemon } from "#field/pokemon";
|
||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
||||
import { PokemonMove } from "#moves/pokemon-move";
|
||||
import { getIsInitialized, initI18n } from "#plugins/i18n";
|
||||
import type { EvilTeam } from "#trainers/evil-admin-trainer-pools";
|
||||
@ -33,6 +32,7 @@ import {
|
||||
TrainerPartyTemplate,
|
||||
trainerPartyTemplates,
|
||||
} from "#trainers/trainer-party-template";
|
||||
import type { HeldItemConfiguration } from "#types/held-item-data-types";
|
||||
import type { SilentReward } from "#types/rewards";
|
||||
import type {
|
||||
GenAIFunc,
|
||||
|
@ -112,7 +112,6 @@ import { UiMode } from "#enums/ui-mode";
|
||||
import { WeatherType } from "#enums/weather-type";
|
||||
import { doShinySparkleAnim } from "#field/anims";
|
||||
import { applyHeldItems } from "#items/all-held-items";
|
||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
||||
import { HeldItemManager } from "#items/held-item-manager";
|
||||
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
||||
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 type { AbAttrMap, AbAttrString, TypeMultiplierAbAttrParams } from "#types/ability-types";
|
||||
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 { TurnMove } from "#types/turn-move";
|
||||
import { BattleInfo } from "#ui/battle-info";
|
||||
|
@ -12,11 +12,11 @@ import { TrainerSlot } from "#enums/trainer-slot";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { TrainerVariant } from "#enums/trainer-variant";
|
||||
import type { EnemyPokemon } from "#field/pokemon";
|
||||
import type { TrainerItemConfiguration } from "#items/trainer-item-data-types";
|
||||
import { getIsInitialized, initI18n } from "#plugins/i18n";
|
||||
import type { TrainerConfig } from "#trainers/trainer-config";
|
||||
import { trainerConfigs } from "#trainers/trainer-config";
|
||||
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 { getRandomLocaleEntry } from "#utils/i18n";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
|
@ -33,8 +33,8 @@ import { EvolutionStatBoostHeldItem, SpeciesStatBoostHeldItem } from "#items/sta
|
||||
import { SurviveChanceHeldItem } from "#items/survive-chance";
|
||||
import { TurnEndHealHeldItem } from "#items/turn-end-heal";
|
||||
import { TurnEndStatusHeldItem } from "#items/turn-end-status";
|
||||
import type { HeldItemEffectParamMap } from "#types/held-item-parameter";
|
||||
import { getEnumValues } from "#utils/enums";
|
||||
import type { HeldItemEffectParamMap } from "./held-item-parameter";
|
||||
|
||||
export function initHeldItems() {
|
||||
for (const berry of getEnumValues(BerryType)) {
|
||||
|
@ -3,40 +3,33 @@ import { RewardId } from "#enums/reward-id";
|
||||
import { RarityTier } from "#enums/reward-tier";
|
||||
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||
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 {
|
||||
AddMoneyReward,
|
||||
AddPokeballReward,
|
||||
AddVoucherReward,
|
||||
AllPokemonFullReviveReward,
|
||||
AllPokemonLevelIncrementReward,
|
||||
AttackTypeBoosterRewardGenerator,
|
||||
BaseStatBoosterRewardGenerator,
|
||||
BerryRewardGenerator,
|
||||
EvolutionItemRewardGenerator,
|
||||
FormChangeItemRewardGenerator,
|
||||
FusePokemonReward,
|
||||
LapsingTrainerItemReward,
|
||||
MintRewardGenerator,
|
||||
NoneReward,
|
||||
PokemonAllMovePpRestoreReward,
|
||||
PokemonHpRestoreReward,
|
||||
PokemonLevelIncrementReward,
|
||||
PokemonPpRestoreReward,
|
||||
PokemonPpUpReward,
|
||||
PokemonReviveReward,
|
||||
PokemonStatusHealReward,
|
||||
RememberMoveReward,
|
||||
type Reward,
|
||||
type RewardGenerator,
|
||||
SpeciesStatBoosterRewardGenerator,
|
||||
TempStatStageBoosterRewardGenerator,
|
||||
TeraTypeRewardGenerator,
|
||||
TmRewardGenerator,
|
||||
} from "./reward";
|
||||
} from "./rewards/held-item-reward";
|
||||
import { AllPokemonLevelIncrementReward, PokemonLevelIncrementReward } from "./rewards/level-increment";
|
||||
import { AddMoneyReward } from "./rewards/money";
|
||||
import { MintRewardGenerator } from "./rewards/nature-change";
|
||||
import { AddPokeballReward } from "./rewards/pokeball";
|
||||
import { PokemonAllMovePpRestoreReward, PokemonPpRestoreReward } from "./rewards/pp-restore";
|
||||
import { PokemonPpUpReward } from "./rewards/pp-up";
|
||||
import { RememberMoveReward } from "./rewards/remember-move";
|
||||
import { AllPokemonFullReviveReward, PokemonHpRestoreReward, PokemonReviveReward } from "./rewards/restore";
|
||||
import { SpeciesStatBoosterRewardGenerator } from "./rewards/species-stat-booster";
|
||||
import { PokemonStatusHealReward } from "./rewards/status-heal";
|
||||
import { TeraTypeRewardGenerator } from "./rewards/tera-type";
|
||||
import { TmRewardGenerator } from "./rewards/tm";
|
||||
import { LapsingTrainerItemReward, TempStatStageBoosterRewardGenerator } from "./rewards/trainer-item-reward";
|
||||
import { AddVoucherReward } from "./rewards/voucher";
|
||||
|
||||
// TODO: Move to `reward-utils.ts` and un-exportt
|
||||
export const allRewards = {
|
||||
[RewardId.NONE]: new NoneReward(),
|
||||
[RewardId.NONE]: new EmptyReward(),
|
||||
|
||||
// Pokeball rewards
|
||||
[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 {
|
||||
CriticalCatchChanceBoosterTrainerItem,
|
||||
DoubleBattleChanceBoosterTrainerItem,
|
||||
EnemyAttackStatusEffectChanceTrainerItem,
|
||||
EnemyDamageBoosterTrainerItem,
|
||||
EnemyDamageReducerTrainerItem,
|
||||
EnemyEndureChanceTrainerItem,
|
||||
EnemyFusionChanceTrainerItem,
|
||||
EnemyStatusEffectHealChanceTrainerItem,
|
||||
EnemyTurnHealTrainerItem,
|
||||
ExpBoosterTrainerItem,
|
||||
ExtraRewardTrainerItem,
|
||||
HealingBoosterTrainerItem,
|
||||
@ -22,14 +14,26 @@ import {
|
||||
MoneyMultiplierTrainerItem,
|
||||
PreserveBerryTrainerItem,
|
||||
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,
|
||||
TempCritBoosterTrainerItem,
|
||||
TempStatStageBoosterTrainerItem,
|
||||
TrainerItem,
|
||||
tempStatToTrainerItem,
|
||||
} from "#items/trainer-item";
|
||||
import type { TrainerItemManager } from "./trainer-item-manager";
|
||||
import type { TrainerItemEffectParamMap } from "./trainer-item-parameter";
|
||||
} from "./trainer-items/x-items";
|
||||
|
||||
export function initTrainerItems() {
|
||||
allTrainerItems[TrainerItemId.MAP] = new TrainerItem(TrainerItemId.MAP, 1);
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
type HeldItemSaveData,
|
||||
type HeldItemSpecs,
|
||||
isHeldItemSpecs,
|
||||
} from "#items/held-item-data-types";
|
||||
} from "#types/held-item-data-types";
|
||||
|
||||
export class HeldItemManager {
|
||||
// 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 type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||
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 {
|
||||
type HeldItemConfiguration,
|
||||
@ -19,7 +19,7 @@ import {
|
||||
isHeldItemCategoryEntry,
|
||||
isHeldItemPool,
|
||||
isHeldItemSpecs,
|
||||
} from "#items/held-item-data-types";
|
||||
} from "#types/held-item-data-types";
|
||||
import { coerceArray, isNullOrUndefined, pickWeightedIndex, randSeedInt } from "#utils/common";
|
||||
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 HeldItemId, HeldItemNames } from "#enums/held-item-id";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import type { HeldItemEffectParamMap } from "#types/held-item-parameter";
|
||||
import type { UniqueArray } from "#utils/common";
|
||||
import i18next from "i18next";
|
||||
import type { HeldItemEffectParamMap } from "./held-item-parameter";
|
||||
|
||||
export abstract class HeldItemBase {
|
||||
public type: HeldItemId;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import type { HeldItemId } from "#enums/held-item-id";
|
||||
import { HeldItem } from "#items/held-item";
|
||||
import type { AccuracyBoostParams } from "#items/held-item-parameter";
|
||||
import type { AccuracyBoostParams } from "#types/held-item-parameter";
|
||||
|
||||
/**
|
||||
* @sealed
|
||||
|
@ -2,7 +2,7 @@ import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import { HeldItemId, HeldItemNames } from "#enums/held-item-id";
|
||||
import { PokemonType } from "#enums/pokemon-type";
|
||||
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";
|
||||
|
||||
interface AttackTypeToHeldItemMap {
|
||||
|
@ -3,7 +3,7 @@ import type { HeldItemId } from "#enums/held-item-id";
|
||||
import { Stat } from "#enums/stat";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
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";
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@ import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import { HeldItemId } from "#enums/held-item-id";
|
||||
import { getStatKey, type PermanentStat, Stat } from "#enums/stat";
|
||||
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";
|
||||
|
||||
type PermanentStatToHeldItemMap = {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
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]> {
|
||||
public readonly effects = [HeldItemEffect.BATON] as const;
|
||||
@ -9,7 +9,7 @@ export class BatonHeldItem extends HeldItem<[typeof HeldItemEffect.BATON]> {
|
||||
* Applies {@linkcode SwitchEffectTransferModifier}
|
||||
* @returns always `true`
|
||||
*/
|
||||
apply(_effect: typeof HeldItemEffect.BATON, { pokemon }: BatonParams): true {
|
||||
apply(_effect: typeof HeldItemEffect.BATON, _params: BatonParams): true {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import { HeldItemId } from "#enums/held-item-id";
|
||||
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||
import { BerryUsedEvent } from "#events/battle-scene";
|
||||
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 { BooleanHolder } from "#utils/common";
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { Command } from "#enums/command";
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
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";
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@ import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import type { HeldItemId } from "#enums/held-item-id";
|
||||
import type { SpeciesId } from "#enums/species-id";
|
||||
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).
|
||||
|
@ -2,7 +2,7 @@ import { globalScene } from "#app/global-scene";
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||
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";
|
||||
|
||||
export class DamageMoneyRewardHeldItem extends HeldItem<[typeof HeldItemEffect.DAMAGE_MONEY_REWARD]> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import type { HeldItemId } from "#enums/held-item-id";
|
||||
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";
|
||||
|
||||
export class ExpBoosterHeldItem extends HeldItem<[typeof HeldItemEffect.EXP_BOOSTER]> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
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
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import type { HeldItemId } from "#enums/held-item-id";
|
||||
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
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
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";
|
||||
|
||||
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 { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import { HeldItem } from "#items/held-item";
|
||||
import type { HitHealParams } from "#items/held-item-parameter";
|
||||
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
||||
import type { HitHealParams } from "#types/held-item-parameter";
|
||||
import { toDmgValue } from "#utils/common";
|
||||
import i18next from "i18next";
|
||||
|
||||
|
@ -3,8 +3,8 @@ import { globalScene } from "#app/global-scene";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import { ConsumableHeldItem } from "#items/held-item";
|
||||
import type { InstantReviveParams } from "#items/held-item-parameter";
|
||||
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
||||
import type { InstantReviveParams } from "#types/held-item-parameter";
|
||||
import { toDmgValue } from "#utils/common";
|
||||
import i18next from "i18next";
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import type { HeldItemId } from "#enums/held-item-id";
|
||||
import { Pokemon } from "#field/pokemon";
|
||||
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 i18next from "i18next";
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import { Stat } from "#enums/stat";
|
||||
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";
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@ import { allMoves } from "#data/data-lists";
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
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 i18next from "i18next";
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
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]> {
|
||||
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 { BATTLE_STATS } from "#enums/stat";
|
||||
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";
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,7 @@ import type { SpeciesId } from "#enums/species-id";
|
||||
import type { Stat } from "#enums/stat";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
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)
|
||||
|
@ -2,7 +2,7 @@ import { globalScene } from "#app/global-scene";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
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";
|
||||
|
||||
/**
|
||||
|
@ -2,8 +2,8 @@ import { globalScene } from "#app/global-scene";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||
import { HeldItem } from "#items/held-item";
|
||||
import type { TurnEndHealParams } from "#items/held-item-parameter";
|
||||
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
||||
import type { TurnEndHealParams } from "#types/held-item-parameter";
|
||||
import { toDmgValue } from "#utils/common";
|
||||
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 { StatusEffect } from "#enums/status-effect";
|
||||
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
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import Overrides from "#app/overrides";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
||||
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:
|
||||
|
@ -3,7 +3,7 @@ import { allHeldItems, allTrainerItems } from "#data/data-lists";
|
||||
import { HeldItemCategoryId, type HeldItemId, isItemInCategory } from "#enums/held-item-id";
|
||||
import type { TrainerItemId } from "#enums/trainer-item-id";
|
||||
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 => {
|
||||
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 { getRewardCategory, RewardCategoryId, RewardId } from "#enums/reward-id";
|
||||
import type { RarityTier } from "#enums/reward-tier";
|
||||
import type { TrainerItemId } from "#enums/trainer-item-id";
|
||||
import { allRewards } from "#items/all-rewards";
|
||||
import type { RewardPoolId, RewardSpecs } from "#types/rewards";
|
||||
import { heldItemRarities } from "./held-item-default-tiers";
|
||||
import {
|
||||
HeldItemReward,
|
||||
NoneReward,
|
||||
type PokemonMoveReward,
|
||||
type RememberMoveReward,
|
||||
type Reward,
|
||||
RewardGenerator,
|
||||
RewardOption,
|
||||
type TmReward,
|
||||
TrainerItemReward,
|
||||
} from "./reward";
|
||||
import { rewardRarities } from "./reward-defaults-tiers";
|
||||
import { trainerItemRarities } from "./trainer-item-default-tiers";
|
||||
import { EmptyReward, type PokemonMoveReward, type Reward, RewardGenerator, RewardOption } from "./reward";
|
||||
import { HeldItemReward } from "./rewards/held-item-reward";
|
||||
import type { RememberMoveReward } from "./rewards/remember-move";
|
||||
import type { TmReward } from "./rewards/tm";
|
||||
import { TrainerItemReward } from "./rewards/trainer-item-reward";
|
||||
|
||||
export function isTmReward(reward: Reward): reward is TmReward {
|
||||
return getRewardCategory(reward.id) === RewardCategoryId.TM;
|
||||
@ -66,7 +60,7 @@ export function generateRewardOptionFromId<T extends RewardPoolId>(
|
||||
const tempReward = allRewards[id] as Reward | RewardGenerator;
|
||||
let reward = tempReward instanceof RewardGenerator ? tempReward.generateReward(pregenArgs) : tempReward;
|
||||
if (!reward) {
|
||||
reward = new NoneReward();
|
||||
reward = new EmptyReward();
|
||||
}
|
||||
const tier = tierOverride ?? rewardRarities[id];
|
||||
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 TrainerItemSaveData,
|
||||
type TrainerItemSpecs,
|
||||
} from "#items/trainer-item-data-types";
|
||||
} from "#types/trainer-item-data-types";
|
||||
import { getTypedEntries, getTypedKeys } from "#utils/common";
|
||||
|
||||
export class TrainerItemManager {
|
||||
|
@ -1,22 +1,12 @@
|
||||
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 { 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 { NumberHolderParams, PreserveBerryParams } from "#types/trainer-item-parameter";
|
||||
import { addTextObject } from "#ui/text";
|
||||
import { hslToHex, randSeedFloat, toDmgValue } from "#utils/common";
|
||||
import { hslToHex } from "#utils/common";
|
||||
import i18next from "i18next";
|
||||
import type {
|
||||
BooleanHolderParams,
|
||||
NumberHolderParams,
|
||||
PokemonParams,
|
||||
PreserveBerryParams,
|
||||
} from "./trainer-item-parameter";
|
||||
|
||||
export class TrainerItem {
|
||||
// public pokemonId: number;
|
||||
@ -25,9 +15,6 @@ export class TrainerItem {
|
||||
public isLapsing = false;
|
||||
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) {
|
||||
this.type = type;
|
||||
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
|
||||
export class LevelIncrementBoosterTrainerItem extends TrainerItem {
|
||||
public effects: TrainerItemEffect[] = [TrainerItemEffect.LEVEL_INCREMENT_BOOSTER];
|
||||
@ -211,326 +227,3 @@ export class HealShopCostTrainerItem extends TrainerItem {
|
||||
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 { VariantTier } from "#enums/variant-tier";
|
||||
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 { HeldItemConfiguration } from "#types/held-item-data-types";
|
||||
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
|
||||
|
@ -5,14 +5,15 @@ import { RewardPoolType } from "#enums/reward-pool-type";
|
||||
import type { RarityTier } from "#enums/reward-tier";
|
||||
import { TrainerItemEffect } from "#enums/trainer-item-effect";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import type {
|
||||
PokemonMoveRecallRewardParams,
|
||||
PokemonMoveRewardParams,
|
||||
PokemonRewardParams,
|
||||
Reward,
|
||||
RewardOption,
|
||||
import {
|
||||
type PokemonMoveRecallRewardParams,
|
||||
type PokemonMoveReward,
|
||||
type PokemonMoveRewardParams,
|
||||
PokemonReward,
|
||||
type PokemonRewardParams,
|
||||
type Reward,
|
||||
type RewardOption,
|
||||
} from "#items/reward";
|
||||
import { FusePokemonReward, type PokemonMoveReward, PokemonReward, RememberMoveReward, TmReward } from "#items/reward";
|
||||
import {
|
||||
type CustomRewardSettings,
|
||||
generatePlayerRewardOptions,
|
||||
@ -20,6 +21,9 @@ import {
|
||||
getRewardPoolForType,
|
||||
} from "#items/reward-pool-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 { PartyOption, PartyUiHandler, PartyUiMode, type PokemonMoveSelectFilter } from "#ui/party-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 { TagAddedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#events/arena";
|
||||
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 type { Variant } from "#sprites/variant";
|
||||
import { achvs } from "#system/achv";
|
||||
@ -59,6 +58,7 @@ import {
|
||||
import { VoucherType, vouchers } from "#system/voucher";
|
||||
import { trainerConfigs } from "#trainers/trainer-config";
|
||||
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 { applyChallenges } from "#utils/challenge-utils";
|
||||
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 { TrainerSlot } from "#enums/trainer-slot";
|
||||
import { EnemyPokemon, Pokemon } from "#field/pokemon";
|
||||
import type { HeldItemSaveData } from "#items/held-item-data-types";
|
||||
import { saveDataToConfig } from "#items/held-item-pool";
|
||||
import { PokemonMove } from "#moves/pokemon-move";
|
||||
import type { Variant } from "#sprites/variant";
|
||||
import type { HeldItemSaveData } from "#types/held-item-data-types";
|
||||
import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils";
|
||||
|
||||
export class PokemonData {
|
||||
|
Loading…
Reference in New Issue
Block a user