mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-08 16:39:26 +02:00
RewardPool now uses ids; function to generate appropriate reward from id (including held item or trainer item)
This commit is contained in:
parent
c41fdc746f
commit
b293b9063e
@ -12,6 +12,7 @@ export type RewardPoolId = RewardId | HeldItemId | TrainerItemId;
|
||||
export type RewardPoolEntry = {
|
||||
id: RewardPoolId;
|
||||
weight: number | WeightedRewardWeightFunc;
|
||||
maxWeight?: number;
|
||||
};
|
||||
|
||||
export type RewardPool = {
|
||||
|
@ -1,23 +1,23 @@
|
||||
/* biome-ignore-start lint/correctness/noUnusedImports: tsdoc imports */
|
||||
import type { initRewards, Reward } from "#items/reward";
|
||||
import { initRewards, Reward } from "#items/reward";
|
||||
/* biome-ignore-end lint/correctness/noUnusedImports: tsdoc imports */
|
||||
|
||||
import { timedEventManager } from "#app/global-event-manager";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { pokemonEvolutions } from "#balance/pokemon-evolutions";
|
||||
import { allHeldItems, allRewards, allTrainerItems } from "#data/data-lists";
|
||||
import { allHeldItems, allTrainerItems } from "#data/data-lists";
|
||||
import { MAX_PER_TYPE_POKEBALLS } from "#data/pokeball";
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { HeldItemId } from "#enums/held-item-id";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import { PokeballType } from "#enums/pokeball";
|
||||
import { RewardId } from "#enums/reward-id";
|
||||
import { RarityTier } from "#enums/reward-tier";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||
import { Unlockables } from "#enums/unlockables";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import { WeightedReward } from "#items/reward";
|
||||
import { rewardPool } from "#items/reward-pools";
|
||||
import type { TurnEndStatusHeldItem } from "#items/turn-end-status";
|
||||
import type { WeightedRewardWeightFunc } from "#types/rewards";
|
||||
@ -28,33 +28,33 @@ import { isNullOrUndefined } from "#utils/common";
|
||||
*/
|
||||
function initCommonRewardPool() {
|
||||
rewardPool[RarityTier.COMMON] = [
|
||||
new WeightedReward(allRewards.POKEBALL, () => (hasMaximumBalls(PokeballType.POKEBALL) ? 0 : 6), 6),
|
||||
new WeightedReward(allRewards.RARE_CANDY, 2),
|
||||
new WeightedReward(
|
||||
allRewards.POTION,
|
||||
(party: Pokemon[]) => {
|
||||
{ id: RewardId.POKEBALL, weight: () => (hasMaximumBalls(PokeballType.POKEBALL) ? 0 : 6), maxWeight: 6 },
|
||||
{ id: RewardId.RARE_CANDY, weight: 2 },
|
||||
{
|
||||
id: RewardId.POTION,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = Math.min(
|
||||
party.filter(p => p.getInverseHp() >= 10 && p.getHpRatio() <= 0.875 && !p.isFainted()).length,
|
||||
3,
|
||||
);
|
||||
return thresholdPartyMemberCount * 3;
|
||||
},
|
||||
9,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.SUPER_POTION,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 9,
|
||||
},
|
||||
{
|
||||
id: RewardId.SUPER_POTION,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = Math.min(
|
||||
party.filter(p => p.getInverseHp() >= 25 && p.getHpRatio() <= 0.75 && !p.isFainted()).length,
|
||||
3,
|
||||
);
|
||||
return thresholdPartyMemberCount;
|
||||
},
|
||||
3,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.ETHER,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 3,
|
||||
},
|
||||
{
|
||||
id: RewardId.ETHER,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = Math.min(
|
||||
party.filter(
|
||||
p =>
|
||||
@ -69,11 +69,11 @@ function initCommonRewardPool() {
|
||||
);
|
||||
return thresholdPartyMemberCount * 3;
|
||||
},
|
||||
9,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.MAX_ETHER,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 9,
|
||||
},
|
||||
{
|
||||
id: RewardId.MAX_ETHER,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = Math.min(
|
||||
party.filter(
|
||||
p =>
|
||||
@ -88,12 +88,12 @@ function initCommonRewardPool() {
|
||||
);
|
||||
return thresholdPartyMemberCount;
|
||||
},
|
||||
3,
|
||||
),
|
||||
new WeightedReward(allRewards.LURE, lureWeightFunc(TrainerItemId.LURE, 2)),
|
||||
new WeightedReward(allRewards.TEMP_STAT_STAGE_BOOSTER, 4),
|
||||
new WeightedReward(allRewards.BERRY, 2),
|
||||
new WeightedReward(allRewards.TM_COMMON, 2),
|
||||
maxWeight: 3,
|
||||
},
|
||||
{ id: RewardId.LURE, weight: lureWeightFunc(TrainerItemId.LURE, 2) },
|
||||
{ id: RewardId.TEMP_STAT_STAGE_BOOSTER, weight: 4 },
|
||||
{ id: RewardId.BERRY, weight: 2 },
|
||||
{ id: RewardId.TM_COMMON, weight: 2 },
|
||||
];
|
||||
}
|
||||
|
||||
@ -102,11 +102,11 @@ function initCommonRewardPool() {
|
||||
*/
|
||||
function initGreatRewardPool() {
|
||||
rewardPool[RarityTier.GREAT] = [
|
||||
new WeightedReward(allRewards.GREAT_BALL, () => (hasMaximumBalls(PokeballType.GREAT_BALL) ? 0 : 6), 6),
|
||||
new WeightedReward(allRewards.PP_UP, 2),
|
||||
new WeightedReward(
|
||||
allRewards.FULL_HEAL,
|
||||
(party: Pokemon[]) => {
|
||||
{ id: RewardId.GREAT_BALL, weight: () => (hasMaximumBalls(PokeballType.GREAT_BALL) ? 0 : 6), maxWeight: 6 },
|
||||
{ id: RewardId.PP_UP, weight: 2 },
|
||||
{
|
||||
id: RewardId.FULL_HEAL,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const statusEffectPartyMemberCount = Math.min(
|
||||
party.filter(
|
||||
p =>
|
||||
@ -121,56 +121,56 @@ function initGreatRewardPool() {
|
||||
);
|
||||
return statusEffectPartyMemberCount * 6;
|
||||
},
|
||||
18,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.REVIVE,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 18,
|
||||
},
|
||||
{
|
||||
id: RewardId.REVIVE,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const faintedPartyMemberCount = Math.min(party.filter(p => p.isFainted()).length, 3);
|
||||
return faintedPartyMemberCount * 9;
|
||||
},
|
||||
27,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.MAX_REVIVE,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 27,
|
||||
},
|
||||
{
|
||||
id: RewardId.MAX_REVIVE,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const faintedPartyMemberCount = Math.min(party.filter(p => p.isFainted()).length, 3);
|
||||
return faintedPartyMemberCount * 3;
|
||||
},
|
||||
9,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.SACRED_ASH,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 9,
|
||||
},
|
||||
{
|
||||
id: RewardId.SACRED_ASH,
|
||||
weight: (party: Pokemon[]) => {
|
||||
return party.filter(p => p.isFainted()).length >= Math.ceil(party.length / 2) ? 1 : 0;
|
||||
},
|
||||
1,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.HYPER_POTION,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 1,
|
||||
},
|
||||
{
|
||||
id: RewardId.HYPER_POTION,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = Math.min(
|
||||
party.filter(p => p.getInverseHp() >= 100 && p.getHpRatio() <= 0.625 && !p.isFainted()).length,
|
||||
3,
|
||||
);
|
||||
return thresholdPartyMemberCount * 3;
|
||||
},
|
||||
9,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.MAX_POTION,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 9,
|
||||
},
|
||||
{
|
||||
id: RewardId.MAX_POTION,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = Math.min(
|
||||
party.filter(p => p.getInverseHp() >= 100 && p.getHpRatio() <= 0.5 && !p.isFainted()).length,
|
||||
3,
|
||||
);
|
||||
return thresholdPartyMemberCount;
|
||||
},
|
||||
3,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.FULL_RESTORE,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 3,
|
||||
},
|
||||
{
|
||||
id: RewardId.FULL_RESTORE,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const statusEffectPartyMemberCount = Math.min(
|
||||
party.filter(
|
||||
p =>
|
||||
@ -190,11 +190,11 @@ function initGreatRewardPool() {
|
||||
);
|
||||
return thresholdPartyMemberCount;
|
||||
},
|
||||
3,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.ELIXIR,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 3,
|
||||
},
|
||||
{
|
||||
id: RewardId.ELIXIR,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = Math.min(
|
||||
party.filter(
|
||||
p =>
|
||||
@ -209,11 +209,11 @@ function initGreatRewardPool() {
|
||||
);
|
||||
return thresholdPartyMemberCount * 3;
|
||||
},
|
||||
9,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.MAX_ELIXIR,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 9,
|
||||
},
|
||||
{
|
||||
id: RewardId.MAX_ELIXIR,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = Math.min(
|
||||
party.filter(
|
||||
p =>
|
||||
@ -228,29 +228,29 @@ function initGreatRewardPool() {
|
||||
);
|
||||
return thresholdPartyMemberCount;
|
||||
},
|
||||
3,
|
||||
),
|
||||
new WeightedReward(allRewards.DIRE_HIT, 4),
|
||||
new WeightedReward(allRewards.SUPER_LURE, lureWeightFunc(TrainerItemId.SUPER_LURE, 4)),
|
||||
new WeightedReward(allRewards.NUGGET, skipInLastClassicWaveOrDefault(5)),
|
||||
new WeightedReward(allRewards.SPECIES_STAT_BOOSTER, 4),
|
||||
new WeightedReward(
|
||||
allRewards.EVOLUTION_ITEM,
|
||||
() => {
|
||||
maxWeight: 3,
|
||||
},
|
||||
{ id: RewardId.DIRE_HIT, weight: 4 },
|
||||
{ id: RewardId.SUPER_LURE, weight: lureWeightFunc(TrainerItemId.SUPER_LURE, 4) },
|
||||
{ id: RewardId.NUGGET, weight: skipInLastClassicWaveOrDefault(5) },
|
||||
{ id: RewardId.SPECIES_STAT_BOOSTER, weight: 4 },
|
||||
{
|
||||
id: RewardId.EVOLUTION_ITEM,
|
||||
weight: () => {
|
||||
return Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 15), 8);
|
||||
},
|
||||
8,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.MAP,
|
||||
() => (globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex < 180 ? 2 : 0),
|
||||
2,
|
||||
),
|
||||
new WeightedReward(allRewards.SOOTHE_BELL, 2),
|
||||
new WeightedReward(allRewards.TM_GREAT, 3),
|
||||
new WeightedReward(
|
||||
allRewards.MEMORY_MUSHROOM,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 8,
|
||||
},
|
||||
{
|
||||
id: TrainerItemId.MAP,
|
||||
weight: () => (globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex < 180 ? 2 : 0),
|
||||
maxWeight: 2,
|
||||
},
|
||||
{ id: HeldItemId.SOOTHE_BELL, weight: 2 },
|
||||
{ id: RewardId.TM_GREAT, weight: 3 },
|
||||
{
|
||||
id: RewardId.MEMORY_MUSHROOM,
|
||||
weight: (party: Pokemon[]) => {
|
||||
if (!party.find(p => p.getLearnableLevelMoves().length)) {
|
||||
return 0;
|
||||
}
|
||||
@ -259,20 +259,22 @@ function initGreatRewardPool() {
|
||||
.reduce((highestLevel: number, level: number) => Math.max(highestLevel, level), 1);
|
||||
return Math.min(Math.ceil(highestPartyLevel / 20), 4);
|
||||
},
|
||||
4,
|
||||
),
|
||||
new WeightedReward(allRewards.BASE_STAT_BOOSTER, 3),
|
||||
new WeightedReward(allRewards.TERA_SHARD, (party: Pokemon[]) =>
|
||||
party.filter(
|
||||
p =>
|
||||
!(p.hasSpecies(SpeciesId.TERAPAGOS) || p.hasSpecies(SpeciesId.OGERPON) || p.hasSpecies(SpeciesId.SHEDINJA)),
|
||||
).length > 0
|
||||
? 1
|
||||
: 0,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.DNA_SPLICERS,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 4,
|
||||
},
|
||||
{ id: RewardId.BASE_STAT_BOOSTER, weight: 3 },
|
||||
{
|
||||
id: RewardId.TERA_SHARD,
|
||||
weight: (party: Pokemon[]) =>
|
||||
party.filter(
|
||||
p =>
|
||||
!(p.hasSpecies(SpeciesId.TERAPAGOS) || p.hasSpecies(SpeciesId.OGERPON) || p.hasSpecies(SpeciesId.SHEDINJA)),
|
||||
).length > 0
|
||||
? 1
|
||||
: 0,
|
||||
},
|
||||
{
|
||||
id: RewardId.DNA_SPLICERS,
|
||||
weight: (party: Pokemon[]) => {
|
||||
if (party.filter(p => !p.fusionSpecies).length > 1) {
|
||||
if (globalScene.gameMode.isSplicedOnly) {
|
||||
return 4;
|
||||
@ -283,13 +285,14 @@ function initGreatRewardPool() {
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
4,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.VOUCHER,
|
||||
(_party: Pokemon[], rerollCount: number) => (!globalScene.gameMode.isDaily ? Math.max(1 - rerollCount, 0) : 0),
|
||||
1,
|
||||
),
|
||||
maxWeight: 4,
|
||||
},
|
||||
{
|
||||
id: RewardId.VOUCHER,
|
||||
weight: (_party: Pokemon[], rerollCount: number) =>
|
||||
!globalScene.gameMode.isDaily ? Math.max(1 - rerollCount, 0) : 0,
|
||||
maxWeight: 1,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@ -298,46 +301,49 @@ function initGreatRewardPool() {
|
||||
*/
|
||||
function initUltraRewardPool() {
|
||||
rewardPool[RarityTier.ULTRA] = [
|
||||
new WeightedReward(allRewards.ULTRA_BALL, () => (hasMaximumBalls(PokeballType.ULTRA_BALL) ? 0 : 15), 15),
|
||||
new WeightedReward(allRewards.MAX_LURE, lureWeightFunc(TrainerItemId.MAX_LURE, 4)),
|
||||
new WeightedReward(allRewards.BIG_NUGGET, skipInLastClassicWaveOrDefault(12)),
|
||||
new WeightedReward(allRewards.PP_MAX, 3),
|
||||
new WeightedReward(allRewards.MINT, 4),
|
||||
new WeightedReward(
|
||||
allRewards.RARE_EVOLUTION_ITEM,
|
||||
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 15) * 4, 32),
|
||||
32,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.FORM_CHANGE_ITEM,
|
||||
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 6,
|
||||
24,
|
||||
),
|
||||
new WeightedReward(allRewards.AMULET_COIN, skipInLastClassicWaveOrDefault(3)),
|
||||
new WeightedReward(allRewards.EVIOLITE, (party: Pokemon[]) => {
|
||||
const { gameMode, gameData } = globalScene;
|
||||
if (gameMode.isDaily || (!gameMode.isFreshStartChallenge() && gameData.isUnlocked(Unlockables.EVIOLITE))) {
|
||||
return party.some(p => {
|
||||
// Check if Pokemon's species (or fusion species, if applicable) can evolve or if they're G-Max'd
|
||||
if (
|
||||
!p.isMax() &&
|
||||
(p.getSpeciesForm(true).speciesId in pokemonEvolutions ||
|
||||
(p.isFusion() && p.getFusionSpeciesForm(true).speciesId in pokemonEvolutions))
|
||||
) {
|
||||
// Check if Pokemon is already holding an Eviolite
|
||||
return !p.heldItemManager.hasItem(HeldItemId.EVIOLITE);
|
||||
}
|
||||
return false;
|
||||
})
|
||||
? 10
|
||||
: 0;
|
||||
}
|
||||
return 0;
|
||||
}),
|
||||
new WeightedReward(allRewards.RARE_SPECIES_STAT_BOOSTER, 12),
|
||||
new WeightedReward(
|
||||
allRewards.LEEK,
|
||||
(party: Pokemon[]) => {
|
||||
{ id: RewardId.ULTRA_BALL, weight: () => (hasMaximumBalls(PokeballType.ULTRA_BALL) ? 0 : 15), maxWeight: 15 },
|
||||
{ id: RewardId.MAX_LURE, weight: lureWeightFunc(TrainerItemId.MAX_LURE, 4) },
|
||||
{ id: RewardId.BIG_NUGGET, weight: skipInLastClassicWaveOrDefault(12) },
|
||||
{ id: RewardId.PP_MAX, weight: 3 },
|
||||
{ id: RewardId.MINT, weight: 4 },
|
||||
{
|
||||
id: RewardId.RARE_EVOLUTION_ITEM,
|
||||
weight: () => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 15) * 4, 32),
|
||||
maxWeight: 32,
|
||||
},
|
||||
{
|
||||
id: RewardId.FORM_CHANGE_ITEM,
|
||||
weight: () => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 6,
|
||||
maxWeight: 24,
|
||||
},
|
||||
{ id: TrainerItemId.AMULET_COIN, weight: skipInLastClassicWaveOrDefault(3) },
|
||||
{
|
||||
id: HeldItemId.EVIOLITE,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const { gameMode, gameData } = globalScene;
|
||||
if (gameMode.isDaily || (!gameMode.isFreshStartChallenge() && gameData.isUnlocked(Unlockables.EVIOLITE))) {
|
||||
return party.some(p => {
|
||||
// Check if Pokemon's species (or fusion species, if applicable) can evolve or if they're G-Max'd
|
||||
if (
|
||||
!p.isMax() &&
|
||||
(p.getSpeciesForm(true).speciesId in pokemonEvolutions ||
|
||||
(p.isFusion() && p.getFusionSpeciesForm(true).speciesId in pokemonEvolutions))
|
||||
) {
|
||||
// Check if Pokemon is already holding an Eviolite
|
||||
return !p.heldItemManager.hasItem(HeldItemId.EVIOLITE);
|
||||
}
|
||||
return false;
|
||||
})
|
||||
? 10
|
||||
: 0;
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
},
|
||||
{ id: RewardId.RARE_SPECIES_STAT_BOOSTER, weight: 12 },
|
||||
{
|
||||
id: HeldItemId.LEEK,
|
||||
weight: (party: Pokemon[]) => {
|
||||
const checkedSpecies = [SpeciesId.FARFETCHD, SpeciesId.GALAR_FARFETCHD, SpeciesId.SIRFETCHD];
|
||||
// If a party member doesn't already have a Leek and is one of the relevant species, Leek can appear
|
||||
return party.some(
|
||||
@ -349,11 +355,11 @@ function initUltraRewardPool() {
|
||||
? 12
|
||||
: 0;
|
||||
},
|
||||
12,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.TOXIC_ORB,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 12,
|
||||
},
|
||||
{
|
||||
id: HeldItemId.TOXIC_ORB,
|
||||
weight: (party: Pokemon[]) => {
|
||||
return party.some(p => {
|
||||
const isHoldingOrb = p.getHeldItems().some(i => i in [HeldItemId.FLAME_ORB, HeldItemId.TOXIC_ORB]);
|
||||
|
||||
@ -395,11 +401,11 @@ function initUltraRewardPool() {
|
||||
? 10
|
||||
: 0;
|
||||
},
|
||||
10,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.FLAME_ORB,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 10,
|
||||
},
|
||||
{
|
||||
id: HeldItemId.FLAME_ORB,
|
||||
weight: (party: Pokemon[]) => {
|
||||
return party.some(p => {
|
||||
const isHoldingOrb = p.getHeldItems().some(i => i in [HeldItemId.FLAME_ORB, HeldItemId.TOXIC_ORB]);
|
||||
|
||||
@ -441,11 +447,11 @@ function initUltraRewardPool() {
|
||||
? 10
|
||||
: 0;
|
||||
},
|
||||
10,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.MYSTICAL_ROCK,
|
||||
(party: Pokemon[]) => {
|
||||
maxWeight: 10,
|
||||
},
|
||||
{
|
||||
id: HeldItemId.MYSTICAL_ROCK,
|
||||
weight: (party: Pokemon[]) => {
|
||||
return party.some(p => {
|
||||
const stack = p.heldItemManager.getStack(HeldItemId.MYSTICAL_ROCK);
|
||||
const isHoldingMax = stack === allHeldItems[HeldItemId.MYSTICAL_ROCK].maxStackCount;
|
||||
@ -488,68 +494,68 @@ function initUltraRewardPool() {
|
||||
? 10
|
||||
: 0;
|
||||
},
|
||||
10,
|
||||
),
|
||||
new WeightedReward(allRewards.REVIVER_SEED, 4),
|
||||
new WeightedReward(allRewards.CANDY_JAR, skipInLastClassicWaveOrDefault(5)),
|
||||
new WeightedReward(allRewards.ATTACK_TYPE_BOOSTER, 9),
|
||||
new WeightedReward(allRewards.TM_ULTRA, 11),
|
||||
new WeightedReward(allRewards.RARER_CANDY, 4),
|
||||
new WeightedReward(allRewards.GOLDEN_PUNCH, skipInLastClassicWaveOrDefault(2)),
|
||||
new WeightedReward(allRewards.IV_SCANNER, skipInLastClassicWaveOrDefault(4)),
|
||||
new WeightedReward(allRewards.EXP_CHARM, skipInLastClassicWaveOrDefault(8)),
|
||||
new WeightedReward(allRewards.EXP_SHARE, skipInLastClassicWaveOrDefault(10)),
|
||||
new WeightedReward(
|
||||
allRewards.TERA_ORB,
|
||||
() =>
|
||||
maxWeight: 10,
|
||||
},
|
||||
{ id: HeldItemId.REVIVER_SEED, weight: 4 },
|
||||
{ id: TrainerItemId.CANDY_JAR, weight: skipInLastClassicWaveOrDefault(5) },
|
||||
{ id: RewardId.ATTACK_TYPE_BOOSTER, weight: 9 },
|
||||
{ id: RewardId.TM_ULTRA, weight: 11 },
|
||||
{ id: RewardId.RARER_CANDY, weight: 4 },
|
||||
{ id: HeldItemId.GOLDEN_PUNCH, weight: skipInLastClassicWaveOrDefault(2) },
|
||||
{ id: TrainerItemId.IV_SCANNER, weight: skipInLastClassicWaveOrDefault(4) },
|
||||
{ id: TrainerItemId.EXP_CHARM, weight: skipInLastClassicWaveOrDefault(8) },
|
||||
{ id: TrainerItemId.EXP_SHARE, weight: skipInLastClassicWaveOrDefault(10) },
|
||||
{
|
||||
id: TrainerItemId.TERA_ORB,
|
||||
weight: () =>
|
||||
!globalScene.gameMode.isClassic
|
||||
? Math.min(Math.max(Math.floor(globalScene.currentBattle.waveIndex / 50) * 2, 1), 4)
|
||||
: 0,
|
||||
4,
|
||||
),
|
||||
new WeightedReward(allRewards.QUICK_CLAW, 3),
|
||||
new WeightedReward(allRewards.WIDE_LENS, 7),
|
||||
maxWeight: 4,
|
||||
},
|
||||
{ id: HeldItemId.QUICK_CLAW, weight: 3 },
|
||||
{ id: HeldItemId.WIDE_LENS, weight: 7 },
|
||||
];
|
||||
}
|
||||
|
||||
function initRogueRewardPool() {
|
||||
rewardPool[RarityTier.ROGUE] = [
|
||||
new WeightedReward(allRewards.ROGUE_BALL, () => (hasMaximumBalls(PokeballType.ROGUE_BALL) ? 0 : 16), 16),
|
||||
new WeightedReward(allRewards.RELIC_GOLD, skipInLastClassicWaveOrDefault(2)),
|
||||
new WeightedReward(allRewards.LEFTOVERS, 3),
|
||||
new WeightedReward(allRewards.SHELL_BELL, 3),
|
||||
new WeightedReward(allRewards.BERRY_POUCH, 4),
|
||||
new WeightedReward(allRewards.GRIP_CLAW, 5),
|
||||
new WeightedReward(allRewards.SCOPE_LENS, 4),
|
||||
new WeightedReward(allRewards.BATON, 2),
|
||||
new WeightedReward(allRewards.SOUL_DEW, 7),
|
||||
new WeightedReward(allRewards.CATCHING_CHARM, () => (!globalScene.gameMode.isClassic ? 4 : 0), 4),
|
||||
new WeightedReward(allRewards.ABILITY_CHARM, skipInClassicAfterWave(189, 6)),
|
||||
new WeightedReward(allRewards.FOCUS_BAND, 5),
|
||||
new WeightedReward(allRewards.KINGS_ROCK, 3),
|
||||
new WeightedReward(allRewards.LOCK_CAPSULE, () => (globalScene.gameMode.isClassic ? 0 : 3)),
|
||||
new WeightedReward(allRewards.SUPER_EXP_CHARM, skipInLastClassicWaveOrDefault(8)),
|
||||
new WeightedReward(
|
||||
allRewards.RARE_FORM_CHANGE_ITEM,
|
||||
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 6,
|
||||
24,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.MEGA_BRACELET,
|
||||
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 9,
|
||||
36,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.DYNAMAX_BAND,
|
||||
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 9,
|
||||
36,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.VOUCHER_PLUS,
|
||||
(_party: Pokemon[], rerollCount: number) =>
|
||||
{ id: RewardId.ROGUE_BALL, weight: () => (hasMaximumBalls(PokeballType.ROGUE_BALL) ? 0 : 16), maxWeight: 16 },
|
||||
{ id: RewardId.RELIC_GOLD, weight: skipInLastClassicWaveOrDefault(2) },
|
||||
{ id: HeldItemId.LEFTOVERS, weight: 3 },
|
||||
{ id: HeldItemId.SHELL_BELL, weight: 3 },
|
||||
{ id: TrainerItemId.BERRY_POUCH, weight: 4 },
|
||||
{ id: HeldItemId.GRIP_CLAW, weight: 5 },
|
||||
{ id: HeldItemId.SCOPE_LENS, weight: 4 },
|
||||
{ id: HeldItemId.BATON, weight: 2 },
|
||||
{ id: HeldItemId.SOUL_DEW, weight: 7 },
|
||||
{ id: TrainerItemId.CATCHING_CHARM, weight: () => (!globalScene.gameMode.isClassic ? 4 : 0), maxWeight: 4 },
|
||||
{ id: TrainerItemId.ABILITY_CHARM, weight: skipInClassicAfterWave(189, 6) },
|
||||
{ id: HeldItemId.FOCUS_BAND, weight: 5 },
|
||||
{ id: HeldItemId.KINGS_ROCK, weight: 3 },
|
||||
{ id: TrainerItemId.LOCK_CAPSULE, weight: () => (globalScene.gameMode.isClassic ? 0 : 3) },
|
||||
{ id: TrainerItemId.SUPER_EXP_CHARM, weight: skipInLastClassicWaveOrDefault(8) },
|
||||
{
|
||||
id: RewardId.RARE_FORM_CHANGE_ITEM,
|
||||
weight: () => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 6,
|
||||
maxWeight: 24,
|
||||
},
|
||||
{
|
||||
id: TrainerItemId.MEGA_BRACELET,
|
||||
weight: () => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 9,
|
||||
maxWeight: 36,
|
||||
},
|
||||
{
|
||||
id: TrainerItemId.DYNAMAX_BAND,
|
||||
weight: () => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 9,
|
||||
maxWeight: 36,
|
||||
},
|
||||
{
|
||||
id: RewardId.VOUCHER_PLUS,
|
||||
weight: (_party: Pokemon[], rerollCount: number) =>
|
||||
!globalScene.gameMode.isDaily ? Math.max(3 - rerollCount * 1, 0) : 0,
|
||||
3,
|
||||
),
|
||||
maxWeight: 3,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@ -558,37 +564,37 @@ function initRogueRewardPool() {
|
||||
*/
|
||||
function initMasterRewardPool() {
|
||||
rewardPool[RarityTier.MASTER] = [
|
||||
new WeightedReward(allRewards.MASTER_BALL, () => (hasMaximumBalls(PokeballType.MASTER_BALL) ? 0 : 24), 24),
|
||||
new WeightedReward(allRewards.SHINY_CHARM, 14),
|
||||
new WeightedReward(allRewards.HEALING_CHARM, 18),
|
||||
new WeightedReward(allRewards.MULTI_LENS, 18),
|
||||
new WeightedReward(
|
||||
allRewards.VOUCHER_PREMIUM,
|
||||
(_party: Pokemon[], rerollCount: number) =>
|
||||
{ id: RewardId.MASTER_BALL, weight: () => (hasMaximumBalls(PokeballType.MASTER_BALL) ? 0 : 24), maxWeight: 24 },
|
||||
{ id: TrainerItemId.SHINY_CHARM, weight: 14 },
|
||||
{ id: TrainerItemId.HEALING_CHARM, weight: 18 },
|
||||
{ id: HeldItemId.MULTI_LENS, weight: 18 },
|
||||
{
|
||||
id: RewardId.VOUCHER_PREMIUM,
|
||||
weight: (_party: Pokemon[], rerollCount: number) =>
|
||||
!globalScene.gameMode.isDaily && !globalScene.gameMode.isEndless && !globalScene.gameMode.isSplicedOnly
|
||||
? Math.max(5 - rerollCount * 2, 0)
|
||||
: 0,
|
||||
5,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.DNA_SPLICERS,
|
||||
(party: Pokemon[]) =>
|
||||
maxWeight: 5,
|
||||
},
|
||||
{
|
||||
id: RewardId.DNA_SPLICERS,
|
||||
weight: (party: Pokemon[]) =>
|
||||
!(globalScene.gameMode.isClassic && timedEventManager.areFusionsBoosted()) &&
|
||||
!globalScene.gameMode.isSplicedOnly &&
|
||||
party.filter(p => !p.fusionSpecies).length > 1
|
||||
? 24
|
||||
: 0,
|
||||
24,
|
||||
),
|
||||
new WeightedReward(
|
||||
allRewards.MINI_BLACK_HOLE,
|
||||
() =>
|
||||
maxWeight: 24,
|
||||
},
|
||||
{
|
||||
id: HeldItemId.MINI_BLACK_HOLE,
|
||||
weight: () =>
|
||||
globalScene.gameMode.isDaily ||
|
||||
(!globalScene.gameMode.isFreshStartChallenge() && globalScene.gameData.isUnlocked(Unlockables.MINI_BLACK_HOLE))
|
||||
? 1
|
||||
: 0,
|
||||
1,
|
||||
),
|
||||
maxWeight: 1,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -2,22 +2,21 @@ import { globalScene } from "#app/global-scene";
|
||||
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, RewardPoolId } from "#types/rewards";
|
||||
import { getHeldItemTier } from "./held-item-default-tiers";
|
||||
import { heldItemRarities } from "./held-item-default-tiers";
|
||||
import {
|
||||
type HeldItemReward,
|
||||
HeldItemReward,
|
||||
type PokemonMoveReward,
|
||||
type RememberMoveReward,
|
||||
type Reward,
|
||||
RewardGenerator,
|
||||
RewardOption,
|
||||
type TmReward,
|
||||
type TrainerItemReward,
|
||||
TrainerItemReward,
|
||||
} from "./reward";
|
||||
import { getRewardTier } from "./reward-defaults-tiers";
|
||||
import { getTrainerItemTier } from "./trainer-item-default-tiers";
|
||||
import { rewardRarities } from "./reward-defaults-tiers";
|
||||
import { trainerItemRarities } from "./trainer-item-default-tiers";
|
||||
|
||||
export function isTmReward(reward: Reward): reward is TmReward {
|
||||
return getRewardCategory(reward.id) === RewardCategoryId.TM;
|
||||
@ -56,19 +55,26 @@ export function generateRewardOption(rewardFunc: RewardFunc, pregenArgs?: any[])
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the default rarity tier for a given reward. For unique held item or trainer item rewards,
|
||||
* falls back to the default rarity tier for the item.
|
||||
* @param reward The {@linkcode Reward} to determine the tier for.
|
||||
*/
|
||||
export function getRewardDefaultTier(reward: Reward): RarityTier {
|
||||
if (reward.id === RewardId.HELD_ITEM) {
|
||||
return getHeldItemTier((reward as HeldItemReward).itemId);
|
||||
export function generateRewardOptionFromId(id: RewardPoolId, pregenArgs?: any[]): RewardOption | null {
|
||||
if (isHeldItemId(id)) {
|
||||
const reward = new HeldItemReward(id);
|
||||
const tier = heldItemRarities[id];
|
||||
return new RewardOption(reward, 0, tier);
|
||||
}
|
||||
if (reward.id === RewardId.TRAINER_ITEM) {
|
||||
return getTrainerItemTier((reward as TrainerItemReward).itemId);
|
||||
|
||||
if (isTrainerItemId(id)) {
|
||||
const reward = new TrainerItemReward(id);
|
||||
const tier = trainerItemRarities[id];
|
||||
return new RewardOption(reward, 0, tier);
|
||||
}
|
||||
return getRewardTier(reward.id);
|
||||
|
||||
const rewardFunc = allRewards[id];
|
||||
const reward = generateReward(rewardFunc, pregenArgs);
|
||||
if (reward) {
|
||||
const tier = rewardRarities[id];
|
||||
return new RewardOption(reward, 0, tier);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getPlayerShopRewardOptionsForWave(waveIndex: number, baseCost: number): RewardOption[] {
|
||||
|
Loading…
Reference in New Issue
Block a user