Moved allRewards to a const object; general cleanup

This commit is contained in:
Bertie690 2025-08-07 12:47:20 -04:00
parent 933450297c
commit 9dfbee9bb9
7 changed files with 177 additions and 357 deletions

View File

@ -1,121 +0,0 @@
import type { RewardId } from "#enums/reward-id";
import type {
AddMoneyReward,
AddPokeballReward,
AddVoucherReward,
AllPokemonFullReviveReward,
AllPokemonLevelIncrementReward,
AttackTypeBoosterRewardGenerator,
BaseStatBoosterRewardGenerator,
BerryRewardGenerator,
EvolutionItemRewardGenerator,
FormChangeItemRewardGenerator,
FusePokemonReward,
LapsingTrainerItemReward,
MintRewardGenerator,
PokemonAllMovePpRestoreReward,
PokemonHpRestoreReward,
PokemonLevelIncrementReward,
PokemonPpRestoreReward,
PokemonPpUpReward,
PokemonReviveReward,
PokemonStatusHealReward,
RememberMoveReward,
SpeciesStatBoosterRewardGenerator,
TempStatStageBoosterRewardGenerator,
TeraTypeRewardGenerator,
TmRewardGenerator,
} from "#items/reward";
/**
* The type of the `allRewards` const object.
* @todo Make `allRewards` a const object and replace all references to this with `typeof allRewards`
*/
export type allRewardsType = {
// Pokeball rewards
[RewardId.POKEBALL]: () => AddPokeballReward;
[RewardId.GREAT_BALL]: () => AddPokeballReward;
[RewardId.ULTRA_BALL]: () => AddPokeballReward;
[RewardId.ROGUE_BALL]: () => AddPokeballReward;
[RewardId.MASTER_BALL]: () => AddPokeballReward;
// Voucher rewards
[RewardId.VOUCHER]: () => AddVoucherReward;
[RewardId.VOUCHER_PLUS]: () => AddVoucherReward;
[RewardId.VOUCHER_PREMIUM]: () => AddVoucherReward;
// Money rewards
[RewardId.NUGGET]: () => AddMoneyReward;
[RewardId.BIG_NUGGET]: () => AddMoneyReward;
[RewardId.RELIC_GOLD]: () => AddMoneyReward;
// Party-wide consumables
[RewardId.RARER_CANDY]: () => AllPokemonLevelIncrementReward;
[RewardId.SACRED_ASH]: () => AllPokemonFullReviveReward;
// Pokemon consumables
[RewardId.RARE_CANDY]: () => PokemonLevelIncrementReward;
[RewardId.EVOLUTION_ITEM]: () => EvolutionItemRewardGenerator;
[RewardId.RARE_EVOLUTION_ITEM]: () => EvolutionItemRewardGenerator;
[RewardId.POTION]: () => PokemonHpRestoreReward;
[RewardId.SUPER_POTION]: () => PokemonHpRestoreReward;
[RewardId.HYPER_POTION]: () => PokemonHpRestoreReward;
[RewardId.MAX_POTION]: () => PokemonHpRestoreReward;
[RewardId.FULL_RESTORE]: () => PokemonHpRestoreReward;
[RewardId.REVIVE]: () => PokemonReviveReward;
[RewardId.MAX_REVIVE]: () => PokemonReviveReward;
[RewardId.FULL_HEAL]: () => PokemonStatusHealReward;
[RewardId.ETHER]: () => PokemonPpRestoreReward;
[RewardId.MAX_ETHER]: () => PokemonPpRestoreReward;
[RewardId.ELIXIR]: () => PokemonAllMovePpRestoreReward;
[RewardId.MAX_ELIXIR]: () => PokemonAllMovePpRestoreReward;
[RewardId.PP_UP]: () => PokemonPpUpReward;
[RewardId.PP_MAX]: () => PokemonPpUpReward;
[RewardId.MINT]: () => MintRewardGenerator;
[RewardId.TERA_SHARD]: () => TeraTypeRewardGenerator;
[RewardId.TM_COMMON]: () => TmRewardGenerator;
[RewardId.TM_GREAT]: () => TmRewardGenerator;
[RewardId.TM_ULTRA]: () => TmRewardGenerator;
[RewardId.MEMORY_MUSHROOM]: () => RememberMoveReward;
[RewardId.DNA_SPLICERS]: () => FusePokemonReward;
// Form change items
[RewardId.FORM_CHANGE_ITEM]: () => FormChangeItemRewardGenerator;
[RewardId.RARE_FORM_CHANGE_ITEM]: () => FormChangeItemRewardGenerator;
// Held items
[RewardId.SPECIES_STAT_BOOSTER]: () => SpeciesStatBoosterRewardGenerator;
[RewardId.RARE_SPECIES_STAT_BOOSTER]: () => SpeciesStatBoosterRewardGenerator;
[RewardId.BASE_STAT_BOOSTER]: () => BaseStatBoosterRewardGenerator;
[RewardId.ATTACK_TYPE_BOOSTER]: () => AttackTypeBoosterRewardGenerator;
[RewardId.BERRY]: () => BerryRewardGenerator;
// [RewardId.MINI_BLACK_HOLE]: () => HeldItemReward,
// Trainer items
[RewardId.LURE]: () => LapsingTrainerItemReward;
[RewardId.SUPER_LURE]: () => LapsingTrainerItemReward;
[RewardId.MAX_LURE]: () => LapsingTrainerItemReward;
[RewardId.TEMP_STAT_STAGE_BOOSTER]: () => TempStatStageBoosterRewardGenerator;
[RewardId.DIRE_HIT]: () => LapsingTrainerItemReward;
// [RewardId.GOLDEN_POKEBALL]: () => TrainerItemReward,
};

View File

@ -2,34 +2,33 @@ import type { HeldItemId } from "#enums/held-item-id";
import type { RewardId } from "#enums/reward-id"; import type { RewardId } from "#enums/reward-id";
import type { TrainerItemId } from "#enums/trainer-item-id"; import type { TrainerItemId } from "#enums/trainer-item-id";
import type { Pokemon } from "#field/pokemon"; import type { Pokemon } from "#field/pokemon";
import type { allRewardsType } from "#items/all-rewards";
import type { Reward, RewardGenerator } from "#items/reward"; import type { Reward, RewardGenerator } from "#items/reward";
import type { allRewardsType } from "#types/all-reward-type";
export type RewardFunc = () => Reward | RewardGenerator; export type RewardFunc = Reward | RewardGenerator;
// TODO: Remove party from arguments can be accessed from `globalScene` // TODO: Remove party from arguments can be accessed from `globalScene`
export type WeightedRewardWeightFunc = (party: Pokemon[], rerollCount?: number) => number; export type WeightedRewardWeightFunc = (party: Pokemon[], rerollCount?: number) => number;
export type RewardPoolId = RewardId | HeldItemId | TrainerItemId; export type RewardPoolId = RewardId | HeldItemId | TrainerItemId;
type allRewardsInstanceMap = { type allRewardsInstanceMap = {
[k in keyof allRewardsType as ReturnType<allRewardsType[k]> extends RewardGenerator ? k : never]: ReturnType< [k in keyof allRewardsType as allRewardsType[k] extends RewardGenerator ? k : never]: allRewardsType[k];
allRewardsType[k]
>;
}; };
export type RewardGeneratorArgMap = { type RewardGeneratorArgMap = {
[k in keyof allRewardsInstanceMap]: Exclude<Parameters<allRewardsInstanceMap[k]["generateReward"]>[0], undefined>; [k in keyof allRewardsInstanceMap]: Exclude<Parameters<allRewardsInstanceMap[k]["generateReward"]>[0], undefined>;
}; };
/** Union type containing all `RewardId`s corresponding to valid {@linkcode RewardGenerator}s. */ /** Union type containing all {@linkcode RewardId}s corresponding to valid {@linkcode RewardGenerator}s. */
export type RewardGeneratorId = keyof allRewardsInstanceMap; type RewardGeneratorId = keyof allRewardsInstanceMap;
// TODO: SOrt out which types can and cannot be exported type RewardGeneratorSpecs<T extends RewardGeneratorId = RewardGeneratorId> = {
export type RewardGeneratorSpecs<T extends RewardGeneratorId = RewardGeneratorId> = {
id: T; id: T;
args: RewardGeneratorArgMap[T]; args: RewardGeneratorArgMap[T];
}; };
/** Union type used to specify fixed rewards used in generation. */
export type RewardSpecs<T extends RewardPoolId = RewardPoolId> = T extends RewardGeneratorId export type RewardSpecs<T extends RewardPoolId = RewardPoolId> = T extends RewardGeneratorId
? T | RewardGeneratorSpecs<T> ? T | RewardGeneratorSpecs<T>
: T; : T;

View File

@ -5,7 +5,6 @@ import type { TrainerItemId } from "#enums/trainer-item-id";
import type { HeldItem } from "#items/held-item"; import type { HeldItem } from "#items/held-item";
import type { TrainerItem } from "#items/trainer-item"; import type { TrainerItem } from "#items/trainer-item";
import type { Move } from "#moves/move"; import type { Move } from "#moves/move";
import type { allRewardsType } from "#types/all-reward-type";
export const allAbilities: Ability[] = []; export const allAbilities: Ability[] = [];
export const allMoves: Move[] = []; export const allMoves: Move[] = [];
@ -13,5 +12,3 @@ export const allSpecies: PokemonSpecies[] = [];
export const allHeldItems: Record<HeldItemId, HeldItem> = {}; export const allHeldItems: Record<HeldItemId, HeldItem> = {};
export const allTrainerItems: Record<TrainerItemId, TrainerItem> = {}; export const allTrainerItems: Record<TrainerItemId, TrainerItem> = {};
// TODO: Consider moving into `all-rewards.ts` as a const object - files should not be importing this
export const allRewards: allRewardsType = {};

View File

@ -7,7 +7,6 @@ import { initChallenges } from "#data/challenge";
import { initTrainerTypeDialogue } from "#data/dialogue"; import { initTrainerTypeDialogue } from "#data/dialogue";
import { initPokemonForms } from "#data/pokemon-forms"; import { initPokemonForms } from "#data/pokemon-forms";
import { initHeldItems } from "#items/all-held-items"; import { initHeldItems } from "#items/all-held-items";
import { initRewards } from "#items/all-rewards";
import { initTrainerItems } from "#items/all-trainer-items"; import { initTrainerItems } from "#items/all-trainer-items";
import { initHeldItemPools } from "#items/init-held-item-pools"; import { initHeldItemPools } from "#items/init-held-item-pools";
import { initRewardPools } from "#items/init-reward-pools"; import { initRewardPools } from "#items/init-reward-pools";
@ -45,6 +44,5 @@ function initItems() {
initHeldItemPools(); initHeldItemPools();
initTrainerItems(); initTrainerItems();
initTrainerItemPools(); initTrainerItemPools();
initRewards();
initRewardPools(); initRewardPools();
} }

View File

@ -1,9 +1,9 @@
import { allRewards } from "#data/data-lists";
import { PokeballType } from "#enums/pokeball"; import { PokeballType } from "#enums/pokeball";
import { RewardId } from "#enums/reward-id"; import { RewardId } from "#enums/reward-id";
import { RarityTier } from "#enums/reward-tier"; import { RarityTier } from "#enums/reward-tier";
import { TrainerItemId } from "#enums/trainer-item-id"; import { TrainerItemId } from "#enums/trainer-item-id";
import { VoucherType } from "#system/voucher"; import { VoucherType } from "#system/voucher";
import type { RewardFunc } from "#types/rewards";
import { import {
AddMoneyReward, AddMoneyReward,
AddPokeballReward, AddPokeballReward,
@ -32,147 +32,159 @@ import {
TmRewardGenerator, TmRewardGenerator,
} from "./reward"; } from "./reward";
export function initRewards() { // TODO: Move to `reward-utils.ts` and un-exportt
export const allRewards = {
// Pokeball rewards // Pokeball rewards
allRewards[RewardId.POKEBALL] = () => new AddPokeballReward("pb", PokeballType.POKEBALL, 5, RewardId.POKEBALL); [RewardId.POKEBALL]: new AddPokeballReward("pb", PokeballType.POKEBALL, 5, RewardId.POKEBALL),
allRewards[RewardId.GREAT_BALL] = () => new AddPokeballReward("gb", PokeballType.GREAT_BALL, 5, RewardId.GREAT_BALL); [RewardId.GREAT_BALL]: new AddPokeballReward("gb", PokeballType.GREAT_BALL, 5, RewardId.GREAT_BALL),
allRewards[RewardId.ULTRA_BALL] = () => new AddPokeballReward("ub", PokeballType.ULTRA_BALL, 5, RewardId.ULTRA_BALL); [RewardId.ULTRA_BALL]: new AddPokeballReward("ub", PokeballType.ULTRA_BALL, 5, RewardId.ULTRA_BALL),
allRewards[RewardId.ROGUE_BALL] = () => new AddPokeballReward("rb", PokeballType.ROGUE_BALL, 5, RewardId.ROGUE_BALL); [RewardId.ROGUE_BALL]: new AddPokeballReward("rb", PokeballType.ROGUE_BALL, 5, RewardId.ROGUE_BALL),
allRewards[RewardId.MASTER_BALL] = () => [RewardId.MASTER_BALL]: new AddPokeballReward("mb", PokeballType.MASTER_BALL, 1, RewardId.MASTER_BALL),
new AddPokeballReward("mb", PokeballType.MASTER_BALL, 1, RewardId.MASTER_BALL);
// Voucher rewards // Voucher rewards
allRewards[RewardId.VOUCHER] = () => new AddVoucherReward(VoucherType.REGULAR, 1, RewardId.VOUCHER); [RewardId.VOUCHER]: new AddVoucherReward(VoucherType.REGULAR, 1, RewardId.VOUCHER),
allRewards[RewardId.VOUCHER_PLUS] = () => new AddVoucherReward(VoucherType.PLUS, 1, RewardId.VOUCHER_PLUS); [RewardId.VOUCHER_PLUS]: new AddVoucherReward(VoucherType.PLUS, 1, RewardId.VOUCHER_PLUS),
allRewards[RewardId.VOUCHER_PREMIUM] = () => new AddVoucherReward(VoucherType.PREMIUM, 1, RewardId.VOUCHER_PREMIUM); [RewardId.VOUCHER_PREMIUM]: new AddVoucherReward(VoucherType.PREMIUM, 1, RewardId.VOUCHER_PREMIUM),
// Money rewards // Money rewards
allRewards[RewardId.NUGGET] = () => [RewardId.NUGGET]: new AddMoneyReward(
new AddMoneyReward( "modifierType:ModifierType.NUGGET",
"modifierType:ModifierType.NUGGET", "nugget",
"nugget", 1,
1, "modifierType:ModifierType.MoneyRewardModifierType.extra.small",
"modifierType:ModifierType.MoneyRewardModifierType.extra.small", RewardId.NUGGET,
RewardId.NUGGET, ),
); [RewardId.BIG_NUGGET]: new AddMoneyReward(
allRewards[RewardId.BIG_NUGGET] = () => "modifierType:ModifierType.BIG_NUGGET",
new AddMoneyReward( "big_nugget",
"modifierType:ModifierType.BIG_NUGGET", 2.5,
"big_nugget", "modifierType:ModifierType.MoneyRewardModifierType.extra.moderate",
2.5, RewardId.BIG_NUGGET,
"modifierType:ModifierType.MoneyRewardModifierType.extra.moderate", ),
RewardId.BIG_NUGGET, [RewardId.RELIC_GOLD]: new AddMoneyReward(
); "modifierType:ModifierType.RELIC_GOLD",
allRewards[RewardId.RELIC_GOLD] = () => "relic_gold",
new AddMoneyReward( 10,
"modifierType:ModifierType.RELIC_GOLD", "modifierType:ModifierType.MoneyRewardModifierType.extra.large",
"relic_gold", RewardId.RELIC_GOLD,
10, ),
"modifierType:ModifierType.MoneyRewardModifierType.extra.large",
RewardId.RELIC_GOLD,
);
// Party-wide consumables // Party-wide consumables
allRewards[RewardId.RARER_CANDY] = () => [RewardId.RARER_CANDY]: new AllPokemonLevelIncrementReward("modifierType:ModifierType.RARER_CANDY", "rarer_candy"),
new AllPokemonLevelIncrementReward("modifierType:ModifierType.RARER_CANDY", "rarer_candy"); [RewardId.SACRED_ASH]: new AllPokemonFullReviveReward("modifierType:ModifierType.SACRED_ASH", "sacred_ash"),
allRewards[RewardId.SACRED_ASH] = () =>
new AllPokemonFullReviveReward("modifierType:ModifierType.SACRED_ASH", "sacred_ash");
// Pokemon consumables // Pokemon consumables
allRewards[RewardId.RARE_CANDY] = () => [RewardId.RARE_CANDY]: new PokemonLevelIncrementReward("modifierType:ModifierType.RARE_CANDY", "rare_candy"),
new PokemonLevelIncrementReward("modifierType:ModifierType.RARE_CANDY", "rare_candy");
allRewards[RewardId.EVOLUTION_ITEM] = () => new EvolutionItemRewardGenerator(false, RewardId.EVOLUTION_ITEM); [RewardId.EVOLUTION_ITEM]: new EvolutionItemRewardGenerator(false, RewardId.EVOLUTION_ITEM),
allRewards[RewardId.RARE_EVOLUTION_ITEM] = () => new EvolutionItemRewardGenerator(true, RewardId.RARE_EVOLUTION_ITEM); [RewardId.RARE_EVOLUTION_ITEM]: new EvolutionItemRewardGenerator(true, RewardId.RARE_EVOLUTION_ITEM),
allRewards[RewardId.POTION] = () => [RewardId.POTION]: new PokemonHpRestoreReward("modifierType:ModifierType.POTION", "potion", RewardId.POTION, 20, 10),
new PokemonHpRestoreReward("modifierType:ModifierType.POTION", "potion", RewardId.POTION, 20, 10); [RewardId.SUPER_POTION]: new PokemonHpRestoreReward(
allRewards[RewardId.SUPER_POTION] = () => "modifierType:ModifierType.SUPER_POTION",
new PokemonHpRestoreReward("modifierType:ModifierType.SUPER_POTION", "super_potion", RewardId.SUPER_POTION, 50, 25); "super_potion",
allRewards[RewardId.HYPER_POTION] = () => RewardId.SUPER_POTION,
new PokemonHpRestoreReward( 50,
"modifierType:ModifierType.HYPER_POTION", 25,
"hyper_potion", ),
RewardId.HYPER_POTION, [RewardId.HYPER_POTION]: new PokemonHpRestoreReward(
200, "modifierType:ModifierType.HYPER_POTION",
50, "hyper_potion",
); RewardId.HYPER_POTION,
allRewards[RewardId.MAX_POTION] = () => 200,
new PokemonHpRestoreReward("modifierType:ModifierType.MAX_POTION", "max_potion", RewardId.MAX_POTION, 0, 100); 50,
allRewards[RewardId.FULL_RESTORE] = () => ),
new PokemonHpRestoreReward( [RewardId.MAX_POTION]: new PokemonHpRestoreReward(
"modifierType:ModifierType.FULL_RESTORE", "modifierType:ModifierType.MAX_POTION",
"full_restore", "max_potion",
RewardId.FULL_RESTORE, RewardId.MAX_POTION,
0, 0,
100, 100,
true, ),
); [RewardId.FULL_RESTORE]: new PokemonHpRestoreReward(
"modifierType:ModifierType.FULL_RESTORE",
"full_restore",
RewardId.FULL_RESTORE,
0,
100,
true,
),
allRewards[RewardId.REVIVE] = () => [RewardId.REVIVE]: new PokemonReviveReward("modifierType:ModifierType.REVIVE", "revive", RewardId.REVIVE, 50),
new PokemonReviveReward("modifierType:ModifierType.REVIVE", "revive", RewardId.REVIVE, 50); [RewardId.MAX_REVIVE]: new PokemonReviveReward(
allRewards[RewardId.MAX_REVIVE] = () => "modifierType:ModifierType.MAX_REVIVE",
new PokemonReviveReward("modifierType:ModifierType.MAX_REVIVE", "max_revive", RewardId.MAX_REVIVE, 100); "max_revive",
RewardId.MAX_REVIVE,
100,
),
allRewards[RewardId.FULL_HEAL] = () => [RewardId.FULL_HEAL]: new PokemonStatusHealReward("modifierType:ModifierType.FULL_HEAL", "full_heal"),
new PokemonStatusHealReward("modifierType:ModifierType.FULL_HEAL", "full_heal");
allRewards[RewardId.ETHER] = () => [RewardId.ETHER]: new PokemonPpRestoreReward("modifierType:ModifierType.ETHER", "ether", RewardId.ETHER, 10),
new PokemonPpRestoreReward("modifierType:ModifierType.ETHER", "ether", RewardId.ETHER, 10); [RewardId.MAX_ETHER]: new PokemonPpRestoreReward(
allRewards[RewardId.MAX_ETHER] = () => "modifierType:ModifierType.MAX_ETHER",
new PokemonPpRestoreReward("modifierType:ModifierType.MAX_ETHER", "max_ether", RewardId.MAX_ETHER, -1); "max_ether",
RewardId.MAX_ETHER,
-1,
),
allRewards[RewardId.ELIXIR] = () => [RewardId.ELIXIR]: new PokemonAllMovePpRestoreReward(
new PokemonAllMovePpRestoreReward("modifierType:ModifierType.ELIXIR", "elixir", RewardId.ELIXIR, 10); "modifierType:ModifierType.ELIXIR",
allRewards[RewardId.MAX_ELIXIR] = () => "elixir",
new PokemonAllMovePpRestoreReward("modifierType:ModifierType.MAX_ELIXIR", "max_elixir", RewardId.MAX_ELIXIR, -1); RewardId.ELIXIR,
10,
),
[RewardId.MAX_ELIXIR]: new PokemonAllMovePpRestoreReward(
"modifierType:ModifierType.MAX_ELIXIR",
"max_elixir",
RewardId.MAX_ELIXIR,
-1,
),
allRewards[RewardId.PP_UP] = () => [RewardId.PP_UP]: new PokemonPpUpReward("modifierType:ModifierType.PP_UP", "pp_up", RewardId.PP_UP, 1),
new PokemonPpUpReward("modifierType:ModifierType.PP_UP", "pp_up", RewardId.PP_UP, 1); [RewardId.PP_MAX]: new PokemonPpUpReward("modifierType:ModifierType.PP_MAX", "pp_max", RewardId.PP_MAX, 3),
allRewards[RewardId.PP_MAX] = () =>
new PokemonPpUpReward("modifierType:ModifierType.PP_MAX", "pp_max", RewardId.PP_MAX, 3);
allRewards[RewardId.MINT] = () => new MintRewardGenerator(); [RewardId.MINT]: new MintRewardGenerator(),
allRewards[RewardId.TERA_SHARD] = () => new TeraTypeRewardGenerator(); [RewardId.TERA_SHARD]: new TeraTypeRewardGenerator(),
allRewards[RewardId.TM_COMMON] = () => new TmRewardGenerator(RarityTier.COMMON); [RewardId.TM_COMMON]: new TmRewardGenerator(RarityTier.COMMON),
allRewards[RewardId.TM_GREAT] = () => new TmRewardGenerator(RarityTier.GREAT); [RewardId.TM_GREAT]: new TmRewardGenerator(RarityTier.GREAT),
allRewards[RewardId.TM_ULTRA] = () => new TmRewardGenerator(RarityTier.ULTRA); [RewardId.TM_ULTRA]: new TmRewardGenerator(RarityTier.ULTRA),
allRewards[RewardId.MEMORY_MUSHROOM] = () => [RewardId.MEMORY_MUSHROOM]: new RememberMoveReward("modifierType:ModifierType.MEMORY_MUSHROOM", "big_mushroom"),
new RememberMoveReward("modifierType:ModifierType.MEMORY_MUSHROOM", "big_mushroom");
allRewards[RewardId.DNA_SPLICERS] = () => [RewardId.DNA_SPLICERS]: new FusePokemonReward("modifierType:ModifierType.DNA_SPLICERS", "dna_splicers"),
new FusePokemonReward("modifierType:ModifierType.DNA_SPLICERS", "dna_splicers");
// Form change items // Form change items
allRewards[RewardId.FORM_CHANGE_ITEM] = () => new FormChangeItemRewardGenerator(false, RewardId.FORM_CHANGE_ITEM); [RewardId.FORM_CHANGE_ITEM]: new FormChangeItemRewardGenerator(false, RewardId.FORM_CHANGE_ITEM),
allRewards[RewardId.RARE_FORM_CHANGE_ITEM] = () => [RewardId.RARE_FORM_CHANGE_ITEM]: new FormChangeItemRewardGenerator(true, RewardId.RARE_FORM_CHANGE_ITEM),
new FormChangeItemRewardGenerator(true, RewardId.RARE_FORM_CHANGE_ITEM);
// Held items // Held items
allRewards[RewardId.SPECIES_STAT_BOOSTER] = () => new SpeciesStatBoosterRewardGenerator(false); [RewardId.SPECIES_STAT_BOOSTER]: new SpeciesStatBoosterRewardGenerator(false),
allRewards[RewardId.RARE_SPECIES_STAT_BOOSTER] = () => new SpeciesStatBoosterRewardGenerator(true); [RewardId.RARE_SPECIES_STAT_BOOSTER]: new SpeciesStatBoosterRewardGenerator(true),
allRewards[RewardId.BASE_STAT_BOOSTER] = () => new BaseStatBoosterRewardGenerator(); [RewardId.BASE_STAT_BOOSTER]: new BaseStatBoosterRewardGenerator(),
allRewards[RewardId.ATTACK_TYPE_BOOSTER] = () => new AttackTypeBoosterRewardGenerator(); [RewardId.ATTACK_TYPE_BOOSTER]: new AttackTypeBoosterRewardGenerator(),
allRewards[RewardId.BERRY] = () => new BerryRewardGenerator(); [RewardId.BERRY]: new BerryRewardGenerator(),
// MINI_BLACK_HOLE] = () => new HeldItemReward(HeldItemId.MINI_BLACK_HOLE), // [RewardId.MINI_BLACK_HOLE] = new HeldItemReward(HeldItemId.MINI_BLACK_HOLE),
// Trainer items // Trainer items
allRewards[RewardId.LURE] = () => new LapsingTrainerItemReward(TrainerItemId.LURE, RewardId.LURE); [RewardId.LURE]: new LapsingTrainerItemReward(TrainerItemId.LURE, RewardId.LURE),
allRewards[RewardId.SUPER_LURE] = () => new LapsingTrainerItemReward(TrainerItemId.SUPER_LURE, RewardId.SUPER_LURE); [RewardId.SUPER_LURE]: new LapsingTrainerItemReward(TrainerItemId.SUPER_LURE, RewardId.SUPER_LURE),
allRewards[RewardId.MAX_LURE] = () => new LapsingTrainerItemReward(TrainerItemId.MAX_LURE, RewardId.MAX_LURE); [RewardId.MAX_LURE]: new LapsingTrainerItemReward(TrainerItemId.MAX_LURE, RewardId.MAX_LURE),
allRewards[RewardId.TEMP_STAT_STAGE_BOOSTER] = () => new TempStatStageBoosterRewardGenerator(); [RewardId.TEMP_STAT_STAGE_BOOSTER]: new TempStatStageBoosterRewardGenerator(),
allRewards[RewardId.DIRE_HIT] = () => [RewardId.DIRE_HIT]: new LapsingTrainerItemReward(TrainerItemId.DIRE_HIT, RewardId.TEMP_STAT_STAGE_BOOSTER),
new LapsingTrainerItemReward(TrainerItemId.DIRE_HIT, RewardId.TEMP_STAT_STAGE_BOOSTER); // [RewardId.GOLDEN_POKEBALL]: new TrainerItemReward(TrainerItemId.GOLDEN_POKEBALL),
// GOLDEN_POKEBALL] = () => new TrainerItemReward(TrainerItemId.GOLDEN_POKEBALL), } as const satisfies {
} [k in RewardId]: RewardFunc;
};
export type allRewardsType = typeof allRewards;

View File

@ -1,15 +1,9 @@
import { allRewards } from "#data/data-lists";
import type { HeldItemId } from "#enums/held-item-id"; import type { HeldItemId } from "#enums/held-item-id";
import { getRewardCategory, RewardCategoryId, RewardId } from "#enums/reward-id"; import { getRewardCategory, RewardCategoryId, RewardId } from "#enums/reward-id";
import type { RarityTier } from "#enums/reward-tier"; import type { RarityTier } from "#enums/reward-tier";
import type { TrainerItemId } from "#enums/trainer-item-id"; import type { TrainerItemId } from "#enums/trainer-item-id";
import type { import { allRewards } from "#items/all-rewards";
RewardFunc, import type { RewardFunc, RewardPoolId, RewardSpecs } from "#types/rewards";
RewardGeneratorArgMap,
RewardGeneratorId,
RewardGeneratorSpecs,
RewardPoolId,
} from "#types/rewards";
import { heldItemRarities } from "./held-item-default-tiers"; import { heldItemRarities } from "./held-item-default-tiers";
import { import {
HeldItemReward, HeldItemReward,
@ -38,72 +32,23 @@ export function isRememberMoveReward(reward: Reward): reward is RememberMoveRewa
} }
/** /**
* Generates a Reward from a given function. * Dynamically generate a {@linkcode RewardOption} from a given RewardSpecs.
* @param rewardFunc * @param specs - The {@linkcode RewardSpecs} used to generate the reward
*/
function generateReward(rewardFunc: () => Reward): Reward | null;
/**
* Generates a Reward from a given function
* @param generator
* @param pregenArgs Can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc.
*/
function generateReward<T extends RewardGenerator>(
generator: () => T,
pregenArgs?: Parameters<T["generateReward"]>[0],
): Reward | null;
function generateReward(rewardFunc: RewardFunc, pregenArgs?: any[]): Reward | null {
const reward = rewardFunc();
return reward instanceof RewardGenerator ? reward.generateReward(pregenArgs) : reward;
}
/**
* Dynamically generate a {@linkcode RewardOption} from a given ID.
* @param specs - The {@linkcode RewardGeneratorSpecs} used to generate the reward
* @param cost - The monetary cost of selecting the option; default `0` * @param cost - The monetary cost of selecting the option; default `0`
* @param tierOverride - An optional {@linkcode RarityTier} to override the option's rarity * @param tierOverride - An optional {@linkcode RarityTier} to override the option's rarity
* @param upgradeCount - The number of tier upgrades having occurred; default `0` * @param upgradeCount - The number of tier upgrades having occurred; default `0`
* @returns The generated {@linkcode RewardOption}, or `null` if no reward could be generated * @returns The generated {@linkcode RewardOption}, or `null` if no reward could be generated
* @todo Remove `null` from signature eventually * @todo Remove `null` from signature eventually
*/ */
export function generateRewardOptionFromId<T extends RewardGeneratorId>( export function generateRewardOptionFromId<T extends RewardPoolId>(
specs: RewardGeneratorSpecs<T>, specs: RewardSpecs<T>,
cost?: number,
tierOverride?: RarityTier,
upgradeCount?: number,
): RewardOption | null;
/**
* Dynamically generate a {@linkcode RewardOption} from a given ID.
* @param id - The {@linkcode GeneratorRewardId} to generate a reward for
* @param cost - The monetary cost of selecting the option; default `0`
* @param tierOverride - An optional {@linkcode RarityTier} to override the option's rarity
* @param upgradeCount - The number of tier upgrades having occurred; default `0`
* @param pregenArgs - Optional arguments used to seed the generator.
* @returns The generated {@linkcode RewardOption}, or `null` if no reward could be generated
*/
export function generateRewardOptionFromId<T extends RewardGeneratorId>(
id: T,
cost?: number,
tierOverride?: RarityTier,
upgradeCount?: number,
pregenArgs?: RewardGeneratorArgMap[T],
): RewardOption | null;
export function generateRewardOptionFromId(
id: Exclude<RewardPoolId, RewardGeneratorId>,
cost?: number,
tierOverride?: RarityTier,
upgradeCount?: number,
): RewardOption | null;
export function generateRewardOptionFromId(
id: RewardGeneratorSpecs | RewardPoolId,
cost = 0, cost = 0,
tierOverride?: RarityTier, tierOverride?: RarityTier,
upgradeCount = 0, upgradeCount = 0,
pregenArgs?: unknown,
): RewardOption | null { ): RewardOption | null {
// Destructure specs into objects // Destructure specs into individual parameters
if (typeof id === "object") { const pregenArgs = typeof specs === "object" ? specs.args : undefined;
({ id, args: pregenArgs } = id); const id: RewardPoolId = typeof specs === "object" ? specs.id : specs;
}
if (isHeldItemId(id)) { if (isHeldItemId(id)) {
const reward = new HeldItemReward(id); const reward = new HeldItemReward(id);
@ -117,9 +62,8 @@ export function generateRewardOptionFromId(
return new RewardOption(reward, upgradeCount, tier, cost); return new RewardOption(reward, upgradeCount, tier, cost);
} }
// TODO: This narrows to `any` const rewardFunc = allRewards[id] as RewardFunc;
const rewardFunc = allRewards[id]; const reward = rewardFunc instanceof RewardGenerator ? rewardFunc.generateReward(pregenArgs) : rewardFunc;
const reward = generateReward(rewardFunc, pregenArgs);
if (reward) { if (reward) {
const tier = tierOverride ?? rewardRarities[id]; const tier = tierOverride ?? rewardRarities[id];
return new RewardOption(reward, upgradeCount, tier, cost); return new RewardOption(reward, upgradeCount, tier, cost);

View File

@ -39,7 +39,7 @@ import { getVoucherTypeIcon, getVoucherTypeName, type VoucherType } from "#syste
import type { Exact } from "#types/type-helpers"; import type { Exact } from "#types/type-helpers";
import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#ui/party-ui-handler"; import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#ui/party-ui-handler";
import { PartyUiHandler } from "#ui/party-ui-handler"; import { PartyUiHandler } from "#ui/party-ui-handler";
import { formatMoney, NumberHolder, padInt, randSeedInt, randSeedItem } from "#utils/common"; import { formatMoney, NumberHolder, padInt, randSeedInt, randSeedItem, toDmgValue } from "#utils/common";
import { getEnumKeys, getEnumValues } from "#utils/enums"; import { getEnumKeys, getEnumValues } from "#utils/enums";
import i18next from "i18next"; import i18next from "i18next";
@ -97,7 +97,6 @@ type MatchExact<T> = T extends object ? Exact<T> : T;
export abstract class Reward { export abstract class Reward {
// TODO: If all we care about for categorization is the reward's ID's _category_, why not do it there? // TODO: If all we care about for categorization is the reward's ID's _category_, why not do it there?
// TODO: Make abstract and readonly
public id: RewardId; public id: RewardId;
public localeKey: string; public localeKey: string;
public iconImage: string; public iconImage: string;
@ -466,35 +465,47 @@ export class ChangeTeraTypeReward extends PokemonReward {
pokemon.teraType = this.teraType; pokemon.teraType = this.teraType;
return true; return true;
} }
} } // todo: denest
// todo: denest
// TODO: Consider removing `revive` from the signature of PokemonHealPhase in the wake of this // TODO: Consider removing `revive` from the signature of PokemonHealPhase in the wake of this
// (was only used for revives) // (was only used for revives)
/**
* 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( function restorePokemonHp(
pokemon: Pokemon, pokemon: Pokemon,
percentToRestore: number, percentToRestore: number,
pointsToRestore = 0, {
healStatus = false, pointsToRestore = 0,
fainted = false, healStatus = false,
fainted = false,
}: {
pointsToRestore?: number;
healStatus?: boolean;
fainted?: boolean;
} = {},
): boolean { ): boolean {
if (!pokemon.hp === fainted) { if (pokemon.isFainted() !== fainted) {
if (fainted || healStatus) { return false;
pokemon.resetStatus(true, true, false, false);
}
// Apply HealingCharm
let multiplier = 1;
if (!fainted) {
const hpRestoreMultiplier = new NumberHolder(1);
this.applyPlayerItems(TrainerItemEffect.HEALING_BOOSTER, { numberHolder: hpRestoreMultiplier });
multiplier = hpRestoreMultiplier.value;
}
const restorePoints = Math.floor(pointsToRestore * multiplier);
const restorePercent = Math.floor(percentToRestore * 0.01 * multiplier * pokemon.getMaxHp());
pokemon.heal(Math.max(restorePercent, restorePoints, 1));
return true;
} }
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 { export class PokemonHpRestoreReward extends PokemonReward {
@ -1517,23 +1528,3 @@ export class RewardOption {
this.cost = Math.min(Math.round(cost), Number.MAX_SAFE_INTEGER); this.cost = Math.min(Math.round(cost), Number.MAX_SAFE_INTEGER);
} }
} }
// TODO: If necessary, add the rest of the modifier types here.
// For now, doing the minimal work until the modifier rework lands.
const RewardConstructorMap = Object.freeze({
RewardGenerator,
});
/**
* Map of of modifier type strings to their constructor type
*/
export type RewardConstructorMap = typeof RewardConstructorMap;
/**
* Map of modifier type strings to their instance type
*/
export type RewardInstanceMap = {
[K in keyof RewardConstructorMap]: InstanceType<RewardConstructorMap[K]>;
};
export type RewardString = keyof RewardConstructorMap;