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 { TrainerItemId } from "#enums/trainer-item-id";
import type { Pokemon } from "#field/pokemon";
import type { allRewardsType } from "#items/all-rewards";
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`
export type WeightedRewardWeightFunc = (party: Pokemon[], rerollCount?: number) => number;
export type RewardPoolId = RewardId | HeldItemId | TrainerItemId;
type allRewardsInstanceMap = {
[k in keyof allRewardsType as ReturnType<allRewardsType[k]> extends RewardGenerator ? k : never]: ReturnType<
allRewardsType[k]
>;
[k in keyof allRewardsType as allRewardsType[k] extends RewardGenerator ? k : never]: allRewardsType[k];
};
export type RewardGeneratorArgMap = {
type RewardGeneratorArgMap = {
[k in keyof allRewardsInstanceMap]: Exclude<Parameters<allRewardsInstanceMap[k]["generateReward"]>[0], undefined>;
};
/** Union type containing all `RewardId`s corresponding to valid {@linkcode RewardGenerator}s. */
export type RewardGeneratorId = keyof allRewardsInstanceMap;
/** Union type containing all {@linkcode RewardId}s corresponding to valid {@linkcode RewardGenerator}s. */
type RewardGeneratorId = keyof allRewardsInstanceMap;
// TODO: SOrt out which types can and cannot be exported
export type RewardGeneratorSpecs<T extends RewardGeneratorId = RewardGeneratorId> = {
type RewardGeneratorSpecs<T extends RewardGeneratorId = RewardGeneratorId> = {
id: T;
args: RewardGeneratorArgMap[T];
};
/** Union type used to specify fixed rewards used in generation. */
export type RewardSpecs<T extends RewardPoolId = RewardPoolId> = T extends RewardGeneratorId
? T | RewardGeneratorSpecs<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 { TrainerItem } from "#items/trainer-item";
import type { Move } from "#moves/move";
import type { allRewardsType } from "#types/all-reward-type";
export const allAbilities: Ability[] = [];
export const allMoves: Move[] = [];
@ -13,5 +12,3 @@ export const allSpecies: PokemonSpecies[] = [];
export const allHeldItems: Record<HeldItemId, HeldItem> = {};
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 { initPokemonForms } from "#data/pokemon-forms";
import { initHeldItems } from "#items/all-held-items";
import { initRewards } from "#items/all-rewards";
import { initTrainerItems } from "#items/all-trainer-items";
import { initHeldItemPools } from "#items/init-held-item-pools";
import { initRewardPools } from "#items/init-reward-pools";
@ -45,6 +44,5 @@ function initItems() {
initHeldItemPools();
initTrainerItems();
initTrainerItemPools();
initRewards();
initRewardPools();
}

View File

@ -1,9 +1,9 @@
import { allRewards } from "#data/data-lists";
import { PokeballType } from "#enums/pokeball";
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 type { RewardFunc } from "#types/rewards";
import {
AddMoneyReward,
AddPokeballReward,
@ -32,147 +32,159 @@ import {
TmRewardGenerator,
} from "./reward";
export function initRewards() {
// TODO: Move to `reward-utils.ts` and un-exportt
export const allRewards = {
// Pokeball rewards
allRewards[RewardId.POKEBALL] = () => new AddPokeballReward("pb", PokeballType.POKEBALL, 5, RewardId.POKEBALL);
allRewards[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);
allRewards[RewardId.ROGUE_BALL] = () => new AddPokeballReward("rb", PokeballType.ROGUE_BALL, 5, RewardId.ROGUE_BALL);
allRewards[RewardId.MASTER_BALL] = () =>
new AddPokeballReward("mb", PokeballType.MASTER_BALL, 1, RewardId.MASTER_BALL);
[RewardId.POKEBALL]: new AddPokeballReward("pb", PokeballType.POKEBALL, 5, RewardId.POKEBALL),
[RewardId.GREAT_BALL]: new AddPokeballReward("gb", PokeballType.GREAT_BALL, 5, RewardId.GREAT_BALL),
[RewardId.ULTRA_BALL]: new AddPokeballReward("ub", PokeballType.ULTRA_BALL, 5, RewardId.ULTRA_BALL),
[RewardId.ROGUE_BALL]: new AddPokeballReward("rb", PokeballType.ROGUE_BALL, 5, RewardId.ROGUE_BALL),
[RewardId.MASTER_BALL]: new AddPokeballReward("mb", PokeballType.MASTER_BALL, 1, RewardId.MASTER_BALL),
// Voucher rewards
allRewards[RewardId.VOUCHER] = () => new AddVoucherReward(VoucherType.REGULAR, 1, RewardId.VOUCHER);
allRewards[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]: new AddVoucherReward(VoucherType.REGULAR, 1, RewardId.VOUCHER),
[RewardId.VOUCHER_PLUS]: new AddVoucherReward(VoucherType.PLUS, 1, RewardId.VOUCHER_PLUS),
[RewardId.VOUCHER_PREMIUM]: new AddVoucherReward(VoucherType.PREMIUM, 1, RewardId.VOUCHER_PREMIUM),
// Money rewards
allRewards[RewardId.NUGGET] = () =>
new AddMoneyReward(
"modifierType:ModifierType.NUGGET",
"nugget",
1,
"modifierType:ModifierType.MoneyRewardModifierType.extra.small",
RewardId.NUGGET,
);
allRewards[RewardId.BIG_NUGGET] = () =>
new AddMoneyReward(
"modifierType:ModifierType.BIG_NUGGET",
"big_nugget",
2.5,
"modifierType:ModifierType.MoneyRewardModifierType.extra.moderate",
RewardId.BIG_NUGGET,
);
allRewards[RewardId.RELIC_GOLD] = () =>
new AddMoneyReward(
"modifierType:ModifierType.RELIC_GOLD",
"relic_gold",
10,
"modifierType:ModifierType.MoneyRewardModifierType.extra.large",
RewardId.RELIC_GOLD,
);
[RewardId.NUGGET]: new AddMoneyReward(
"modifierType:ModifierType.NUGGET",
"nugget",
1,
"modifierType:ModifierType.MoneyRewardModifierType.extra.small",
RewardId.NUGGET,
),
[RewardId.BIG_NUGGET]: new AddMoneyReward(
"modifierType:ModifierType.BIG_NUGGET",
"big_nugget",
2.5,
"modifierType:ModifierType.MoneyRewardModifierType.extra.moderate",
RewardId.BIG_NUGGET,
),
[RewardId.RELIC_GOLD]: new AddMoneyReward(
"modifierType:ModifierType.RELIC_GOLD",
"relic_gold",
10,
"modifierType:ModifierType.MoneyRewardModifierType.extra.large",
RewardId.RELIC_GOLD,
),
// Party-wide consumables
allRewards[RewardId.RARER_CANDY] = () =>
new AllPokemonLevelIncrementReward("modifierType:ModifierType.RARER_CANDY", "rarer_candy");
allRewards[RewardId.SACRED_ASH] = () =>
new AllPokemonFullReviveReward("modifierType:ModifierType.SACRED_ASH", "sacred_ash");
[RewardId.RARER_CANDY]: new AllPokemonLevelIncrementReward("modifierType:ModifierType.RARER_CANDY", "rarer_candy"),
[RewardId.SACRED_ASH]: new AllPokemonFullReviveReward("modifierType:ModifierType.SACRED_ASH", "sacred_ash"),
// Pokemon consumables
allRewards[RewardId.RARE_CANDY] = () =>
new PokemonLevelIncrementReward("modifierType:ModifierType.RARE_CANDY", "rare_candy");
[RewardId.RARE_CANDY]: new PokemonLevelIncrementReward("modifierType:ModifierType.RARE_CANDY", "rare_candy"),
allRewards[RewardId.EVOLUTION_ITEM] = () => new EvolutionItemRewardGenerator(false, RewardId.EVOLUTION_ITEM);
allRewards[RewardId.RARE_EVOLUTION_ITEM] = () => new EvolutionItemRewardGenerator(true, RewardId.RARE_EVOLUTION_ITEM);
[RewardId.EVOLUTION_ITEM]: new EvolutionItemRewardGenerator(false, RewardId.EVOLUTION_ITEM),
[RewardId.RARE_EVOLUTION_ITEM]: new EvolutionItemRewardGenerator(true, RewardId.RARE_EVOLUTION_ITEM),
allRewards[RewardId.POTION] = () =>
new PokemonHpRestoreReward("modifierType:ModifierType.POTION", "potion", RewardId.POTION, 20, 10);
allRewards[RewardId.SUPER_POTION] = () =>
new PokemonHpRestoreReward("modifierType:ModifierType.SUPER_POTION", "super_potion", RewardId.SUPER_POTION, 50, 25);
allRewards[RewardId.HYPER_POTION] = () =>
new PokemonHpRestoreReward(
"modifierType:ModifierType.HYPER_POTION",
"hyper_potion",
RewardId.HYPER_POTION,
200,
50,
);
allRewards[RewardId.MAX_POTION] = () =>
new PokemonHpRestoreReward("modifierType:ModifierType.MAX_POTION", "max_potion", RewardId.MAX_POTION, 0, 100);
allRewards[RewardId.FULL_RESTORE] = () =>
new PokemonHpRestoreReward(
"modifierType:ModifierType.FULL_RESTORE",
"full_restore",
RewardId.FULL_RESTORE,
0,
100,
true,
);
[RewardId.POTION]: new PokemonHpRestoreReward("modifierType:ModifierType.POTION", "potion", RewardId.POTION, 20, 10),
[RewardId.SUPER_POTION]: new PokemonHpRestoreReward(
"modifierType:ModifierType.SUPER_POTION",
"super_potion",
RewardId.SUPER_POTION,
50,
25,
),
[RewardId.HYPER_POTION]: new PokemonHpRestoreReward(
"modifierType:ModifierType.HYPER_POTION",
"hyper_potion",
RewardId.HYPER_POTION,
200,
50,
),
[RewardId.MAX_POTION]: new PokemonHpRestoreReward(
"modifierType:ModifierType.MAX_POTION",
"max_potion",
RewardId.MAX_POTION,
0,
100,
),
[RewardId.FULL_RESTORE]: new PokemonHpRestoreReward(
"modifierType:ModifierType.FULL_RESTORE",
"full_restore",
RewardId.FULL_RESTORE,
0,
100,
true,
),
allRewards[RewardId.REVIVE] = () =>
new PokemonReviveReward("modifierType:ModifierType.REVIVE", "revive", RewardId.REVIVE, 50);
allRewards[RewardId.MAX_REVIVE] = () =>
new PokemonReviveReward("modifierType:ModifierType.MAX_REVIVE", "max_revive", RewardId.MAX_REVIVE, 100);
[RewardId.REVIVE]: new PokemonReviveReward("modifierType:ModifierType.REVIVE", "revive", RewardId.REVIVE, 50),
[RewardId.MAX_REVIVE]: new PokemonReviveReward(
"modifierType:ModifierType.MAX_REVIVE",
"max_revive",
RewardId.MAX_REVIVE,
100,
),
allRewards[RewardId.FULL_HEAL] = () =>
new PokemonStatusHealReward("modifierType:ModifierType.FULL_HEAL", "full_heal");
[RewardId.FULL_HEAL]: new PokemonStatusHealReward("modifierType:ModifierType.FULL_HEAL", "full_heal"),
allRewards[RewardId.ETHER] = () =>
new PokemonPpRestoreReward("modifierType:ModifierType.ETHER", "ether", RewardId.ETHER, 10);
allRewards[RewardId.MAX_ETHER] = () =>
new PokemonPpRestoreReward("modifierType:ModifierType.MAX_ETHER", "max_ether", RewardId.MAX_ETHER, -1);
[RewardId.ETHER]: new PokemonPpRestoreReward("modifierType:ModifierType.ETHER", "ether", RewardId.ETHER, 10),
[RewardId.MAX_ETHER]: new PokemonPpRestoreReward(
"modifierType:ModifierType.MAX_ETHER",
"max_ether",
RewardId.MAX_ETHER,
-1,
),
allRewards[RewardId.ELIXIR] = () =>
new PokemonAllMovePpRestoreReward("modifierType:ModifierType.ELIXIR", "elixir", RewardId.ELIXIR, 10);
allRewards[RewardId.MAX_ELIXIR] = () =>
new PokemonAllMovePpRestoreReward("modifierType:ModifierType.MAX_ELIXIR", "max_elixir", RewardId.MAX_ELIXIR, -1);
[RewardId.ELIXIR]: new PokemonAllMovePpRestoreReward(
"modifierType:ModifierType.ELIXIR",
"elixir",
RewardId.ELIXIR,
10,
),
[RewardId.MAX_ELIXIR]: new PokemonAllMovePpRestoreReward(
"modifierType:ModifierType.MAX_ELIXIR",
"max_elixir",
RewardId.MAX_ELIXIR,
-1,
),
allRewards[RewardId.PP_UP] = () =>
new PokemonPpUpReward("modifierType:ModifierType.PP_UP", "pp_up", RewardId.PP_UP, 1);
allRewards[RewardId.PP_MAX] = () =>
new PokemonPpUpReward("modifierType:ModifierType.PP_MAX", "pp_max", RewardId.PP_MAX, 3);
[RewardId.PP_UP]: 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.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);
allRewards[RewardId.TM_GREAT] = () => new TmRewardGenerator(RarityTier.GREAT);
allRewards[RewardId.TM_ULTRA] = () => new TmRewardGenerator(RarityTier.ULTRA);
[RewardId.TM_COMMON]: new TmRewardGenerator(RarityTier.COMMON),
[RewardId.TM_GREAT]: new TmRewardGenerator(RarityTier.GREAT),
[RewardId.TM_ULTRA]: new TmRewardGenerator(RarityTier.ULTRA),
allRewards[RewardId.MEMORY_MUSHROOM] = () =>
new RememberMoveReward("modifierType:ModifierType.MEMORY_MUSHROOM", "big_mushroom");
[RewardId.MEMORY_MUSHROOM]: new RememberMoveReward("modifierType:ModifierType.MEMORY_MUSHROOM", "big_mushroom"),
allRewards[RewardId.DNA_SPLICERS] = () =>
new FusePokemonReward("modifierType:ModifierType.DNA_SPLICERS", "dna_splicers");
[RewardId.DNA_SPLICERS]: new FusePokemonReward("modifierType:ModifierType.DNA_SPLICERS", "dna_splicers"),
// Form change items
allRewards[RewardId.FORM_CHANGE_ITEM] = () => new FormChangeItemRewardGenerator(false, RewardId.FORM_CHANGE_ITEM);
allRewards[RewardId.RARE_FORM_CHANGE_ITEM] = () =>
new FormChangeItemRewardGenerator(true, RewardId.RARE_FORM_CHANGE_ITEM);
[RewardId.FORM_CHANGE_ITEM]: new FormChangeItemRewardGenerator(false, RewardId.FORM_CHANGE_ITEM),
[RewardId.RARE_FORM_CHANGE_ITEM]: new FormChangeItemRewardGenerator(true, RewardId.RARE_FORM_CHANGE_ITEM),
// Held items
allRewards[RewardId.SPECIES_STAT_BOOSTER] = () => new SpeciesStatBoosterRewardGenerator(false);
allRewards[RewardId.RARE_SPECIES_STAT_BOOSTER] = () => new SpeciesStatBoosterRewardGenerator(true);
[RewardId.SPECIES_STAT_BOOSTER]: new SpeciesStatBoosterRewardGenerator(false),
[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
allRewards[RewardId.LURE] = () => new LapsingTrainerItemReward(TrainerItemId.LURE, RewardId.LURE);
allRewards[RewardId.SUPER_LURE] = () => new LapsingTrainerItemReward(TrainerItemId.SUPER_LURE, RewardId.SUPER_LURE);
allRewards[RewardId.MAX_LURE] = () => new LapsingTrainerItemReward(TrainerItemId.MAX_LURE, RewardId.MAX_LURE);
[RewardId.LURE]: new LapsingTrainerItemReward(TrainerItemId.LURE, RewardId.LURE),
[RewardId.SUPER_LURE]: new LapsingTrainerItemReward(TrainerItemId.SUPER_LURE, RewardId.SUPER_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] = () =>
new LapsingTrainerItemReward(TrainerItemId.DIRE_HIT, RewardId.TEMP_STAT_STAGE_BOOSTER);
// GOLDEN_POKEBALL] = () => new TrainerItemReward(TrainerItemId.GOLDEN_POKEBALL),
}
[RewardId.DIRE_HIT]: new LapsingTrainerItemReward(TrainerItemId.DIRE_HIT, RewardId.TEMP_STAT_STAGE_BOOSTER),
// [RewardId.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 { getRewardCategory, RewardCategoryId, RewardId } from "#enums/reward-id";
import type { RarityTier } from "#enums/reward-tier";
import type { TrainerItemId } from "#enums/trainer-item-id";
import type {
RewardFunc,
RewardGeneratorArgMap,
RewardGeneratorId,
RewardGeneratorSpecs,
RewardPoolId,
} from "#types/rewards";
import { allRewards } from "#items/all-rewards";
import type { RewardFunc, RewardPoolId, RewardSpecs } from "#types/rewards";
import { heldItemRarities } from "./held-item-default-tiers";
import {
HeldItemReward,
@ -38,72 +32,23 @@ export function isRememberMoveReward(reward: Reward): reward is RememberMoveRewa
}
/**
* Generates a Reward from a given function.
* @param rewardFunc
*/
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
* Dynamically generate a {@linkcode RewardOption} from a given RewardSpecs.
* @param specs - The {@linkcode RewardSpecs} used to generate the reward
* @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`
* @returns The generated {@linkcode RewardOption}, or `null` if no reward could be generated
* @todo Remove `null` from signature eventually
*/
export function generateRewardOptionFromId<T extends RewardGeneratorId>(
specs: RewardGeneratorSpecs<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,
export function generateRewardOptionFromId<T extends RewardPoolId>(
specs: RewardSpecs<T>,
cost = 0,
tierOverride?: RarityTier,
upgradeCount = 0,
pregenArgs?: unknown,
): RewardOption | null {
// Destructure specs into objects
if (typeof id === "object") {
({ id, args: pregenArgs } = id);
}
// Destructure specs into individual parameters
const pregenArgs = typeof specs === "object" ? specs.args : undefined;
const id: RewardPoolId = typeof specs === "object" ? specs.id : specs;
if (isHeldItemId(id)) {
const reward = new HeldItemReward(id);
@ -117,9 +62,8 @@ export function generateRewardOptionFromId(
return new RewardOption(reward, upgradeCount, tier, cost);
}
// TODO: This narrows to `any`
const rewardFunc = allRewards[id];
const reward = generateReward(rewardFunc, pregenArgs);
const rewardFunc = allRewards[id] as RewardFunc;
const reward = rewardFunc instanceof RewardGenerator ? rewardFunc.generateReward(pregenArgs) : rewardFunc;
if (reward) {
const tier = tierOverride ?? rewardRarities[id];
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 { PokemonMoveSelectFilter, PokemonSelectFilter } 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 i18next from "i18next";
@ -97,7 +97,6 @@ type MatchExact<T> = T extends object ? Exact<T> : T;
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: Make abstract and readonly
public id: RewardId;
public localeKey: string;
public iconImage: string;
@ -466,35 +465,47 @@ export class ChangeTeraTypeReward extends PokemonReward {
pokemon.teraType = this.teraType;
return true;
}
}
// todo: denest
} // todo: denest
// TODO: Consider removing `revive` from the signature of PokemonHealPhase in the wake of this
// (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(
pokemon: Pokemon,
percentToRestore: number,
pointsToRestore = 0,
healStatus = false,
fainted = false,
{
pointsToRestore = 0,
healStatus = false,
fainted = false,
}: {
pointsToRestore?: number;
healStatus?: boolean;
fainted?: boolean;
} = {},
): boolean {
if (!pokemon.hp === fainted) {
if (fainted || healStatus) {
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;
if (pokemon.isFainted() !== fainted) {
return false;
}
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 {
@ -1517,23 +1528,3 @@ export class RewardOption {
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;