Pools can now take a HaldItemConfigurationId without weights; set up table of item tiers; used custom pools in Clowning Around ME

This commit is contained in:
Wlowscha 2025-06-19 19:55:17 +02:00
parent 46204067f5
commit f1c6cf4419
No known key found for this signature in database
GPG Key ID: 3C8F1AD330565D04
6 changed files with 147 additions and 145 deletions

View File

@ -1,6 +1,5 @@
import type { EnemyPartyConfig } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import type { EnemyPartyConfig } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { import {
generateModifierType,
initBattleWithEnemyConfig, initBattleWithEnemyConfig,
leaveEncounterWithoutBattle, leaveEncounterWithoutBattle,
loadCustomMovesForEncounter, loadCustomMovesForEncounter,
@ -12,8 +11,6 @@ import { trainerConfigs } from "#app/data/trainers/trainer-config";
import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate"; import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate";
import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate"; import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
import { RewardTier } from "#enums/reward-tier"; import { RewardTier } from "#enums/reward-tier";
import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
import { ModifierPoolType } from "#enums/modifier-pool-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { PartyMemberStrength } from "#enums/party-member-strength"; import { PartyMemberStrength } from "#enums/party-member-strength";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
@ -24,10 +21,7 @@ import { SpeciesId } from "#enums/species-id";
import { TrainerType } from "#enums/trainer-type"; import { TrainerType } from "#enums/trainer-type";
import { getPokemonSpecies } from "#app/utils/pokemon-utils"; import { getPokemonSpecies } from "#app/utils/pokemon-utils";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { import { applyAbilityOverrideToPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
applyAbilityOverrideToPokemon,
applyModifierTypeToPlayerPokemon,
} from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
import { PokemonType } from "#enums/pokemon-type"; import { PokemonType } from "#enums/pokemon-type";
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
@ -38,8 +32,6 @@ import i18next from "i18next";
import type { OptionSelectConfig } from "#app/ui/abstact-option-select-ui-handler"; import type { OptionSelectConfig } from "#app/ui/abstact-option-select-ui-handler";
import type { PlayerPokemon } from "#app/field/pokemon"; import type { PlayerPokemon } from "#app/field/pokemon";
import { PokemonMove } from "#app/data/moves/pokemon-move"; import { PokemonMove } from "#app/data/moves/pokemon-move";
import { BerryModifier } from "#app/modifier/modifier";
import { BerryType } from "#enums/berry-type";
import { BattlerIndex } from "#enums/battler-index"; import { BattlerIndex } from "#enums/battler-index";
import { MoveId } from "#enums/move-id"; import { MoveId } from "#enums/move-id";
import { EncounterBattleAnim } from "#app/data/battle-anims"; import { EncounterBattleAnim } from "#app/data/battle-anims";
@ -49,7 +41,10 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
import { EncounterAnim } from "#enums/encounter-anims"; import { EncounterAnim } from "#enums/encounter-anims";
import { Challenges } from "#enums/challenges"; import { Challenges } from "#enums/challenges";
import { MoveUseMode } from "#enums/move-use-mode"; import { MoveUseMode } from "#enums/move-use-mode";
import { allAbilities, modifierTypes } from "#app/data/data-lists"; import { allAbilities } from "#app/data/data-lists";
import { HeldItemCategoryId, HeldItemId, isItemInCategory } from "#enums/held-item-id";
import { getHeldItemTier } from "#app/items/held-item-tiers";
import { assignItemsFromConfiguration } from "#app/items/held-item-pool";
/** the i18n namespace for the encounter */ /** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/clowningAround"; const namespace = "mysteryEncounters/clowningAround";
@ -283,16 +278,16 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
const party = globalScene.getPlayerParty(); const party = globalScene.getPlayerParty();
let mostHeldItemsPokemon = party[0]; let mostHeldItemsPokemon = party[0];
let count = mostHeldItemsPokemon let count = mostHeldItemsPokemon.heldItemManager
.getHeldItems() .getTransferableHeldItems()
.filter(m => m.isTransferable && !(m instanceof BerryModifier)) .filter(m => !isItemInCategory(m, HeldItemCategoryId.BERRY))
.reduce((v, m) => v + m.stackCount, 0); .reduce((v, m) => v + mostHeldItemsPokemon.heldItemManager.getStack(m), 0);
for (const pokemon of party) { for (const pokemon of party) {
const nextCount = pokemon const nextCount = pokemon.heldItemManager
.getHeldItems() .getTransferableHeldItems()
.filter(m => m.isTransferable && !(m instanceof BerryModifier)) .filter(m => !isItemInCategory(m, HeldItemCategoryId.BERRY))
.reduce((v, m) => v + m.stackCount, 0); .reduce((v, m) => v + pokemon.heldItemManager.getStack(m), 0);
if (nextCount > count) { if (nextCount > count) {
mostHeldItemsPokemon = pokemon; mostHeldItemsPokemon = pokemon;
count = nextCount; count = nextCount;
@ -301,16 +296,31 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
encounter.setDialogueToken("switchPokemon", mostHeldItemsPokemon.getNameToRender()); encounter.setDialogueToken("switchPokemon", mostHeldItemsPokemon.getNameToRender());
const items = mostHeldItemsPokemon.getHeldItems(); const items = mostHeldItemsPokemon.heldItemManager
.getTransferableHeldItems()
.filter(m => !isItemInCategory(m, HeldItemCategoryId.BERRY));
// Shuffles Berries (if they have any) // Shuffles Berries (if they have any)
const oldBerries = mostHeldItemsPokemon.heldItemManager
.getHeldItems()
.filter(m => isItemInCategory(m, HeldItemCategoryId.BERRY));
let numBerries = 0; let numBerries = 0;
for (const m of items.filter(m => m instanceof BerryModifier)) { for (const berry of oldBerries) {
numBerries += m.stackCount; const stack = mostHeldItemsPokemon.heldItemManager.getStack(berry);
globalScene.removeModifier(m); numBerries += stack;
mostHeldItemsPokemon.heldItemManager.remove(berry, stack);
} }
generateItemsOfTier(mostHeldItemsPokemon, numBerries, "Berries"); assignItemsFromConfiguration(
[
{
entry: HeldItemCategoryId.BERRY,
count: numBerries,
},
],
mostHeldItemsPokemon,
);
// Shuffle Transferable held items in the same tier (only shuffles Ultra and Rogue atm) // Shuffle Transferable held items in the same tier (only shuffles Ultra and Rogue atm)
// For the purpose of this ME, Soothe Bells and Lucky Eggs are counted as Ultra tier // For the purpose of this ME, Soothe Bells and Lucky Eggs are counted as Ultra tier
@ -318,20 +328,36 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
let numUltra = 0; let numUltra = 0;
let numRogue = 0; let numRogue = 0;
for (const m of items.filter(m => m.isTransferable && !(m instanceof BerryModifier))) { for (const m of items) {
const type = m.type.withTierFromPool(ModifierPoolType.PLAYER, party); const tier = getHeldItemTier(m) ?? RewardTier.ULTRA;
const tier = type.tier ?? RewardTier.ULTRA; const stack = mostHeldItemsPokemon.heldItemManager.getStack(m);
if (type.id === "GOLDEN_EGG" || tier === RewardTier.ROGUE) { if (tier === RewardTier.ROGUE) {
numRogue += m.stackCount; numRogue += stack;
globalScene.removeModifier(m); } else if (tier === RewardTier.ULTRA) {
} else if (type.id === "LUCKY_EGG" || type.id === "SOOTHE_BELL" || tier === RewardTier.ULTRA) { numUltra += stack;
numUltra += m.stackCount;
globalScene.removeModifier(m);
} }
mostHeldItemsPokemon.heldItemManager.remove(m, stack);
} }
generateItemsOfTier(mostHeldItemsPokemon, numUltra, RewardTier.ULTRA); assignItemsFromConfiguration(
generateItemsOfTier(mostHeldItemsPokemon, numRogue, RewardTier.ROGUE); [
{
entry: ultraPool,
count: numUltra,
},
],
mostHeldItemsPokemon,
);
assignItemsFromConfiguration(
[
{
entry: roguePool,
count: numRogue,
},
],
mostHeldItemsPokemon,
);
}) })
.withOptionPhase(async () => { .withOptionPhase(async () => {
leaveEncounterWithoutBattle(true); leaveEncounterWithoutBattle(true);
@ -487,68 +513,21 @@ function onYesAbilitySwap(resolve) {
selectPokemonForOption(onPokemonSelected, onPokemonNotSelected); selectPokemonForOption(onPokemonSelected, onPokemonNotSelected);
} }
function generateItemsOfTier(pokemon: PlayerPokemon, numItems: number, tier: RewardTier | "Berries") {
// These pools have to be defined at runtime so that modifierTypes exist
// Pools have instances of the modifier type equal to the max stacks that modifier can be applied to any one pokemon
// This is to prevent "over-generating" a random item of a certain type during item swaps
const ultraPool = [ const ultraPool = [
[modifierTypes.REVIVER_SEED, 1], { entry: HeldItemCategoryId.TYPE_ATTACK_BOOSTER, weight: 1 },
[modifierTypes.GOLDEN_PUNCH, 5], { entry: HeldItemId.REVIVER_SEED, weight: 1 },
[modifierTypes.ATTACK_TYPE_BOOSTER, 99], { entry: HeldItemId.GOLDEN_PUNCH, weight: 1 },
[modifierTypes.QUICK_CLAW, 3], { entry: HeldItemId.QUICK_CLAW, weight: 1 },
[modifierTypes.WIDE_LENS, 3], { entry: HeldItemId.WIDE_LENS, weight: 1 },
]; ];
const roguePool = [ const roguePool = [
[modifierTypes.LEFTOVERS, 4], { entry: HeldItemId.LEFTOVERS, weight: 1 },
[modifierTypes.SHELL_BELL, 4], { entry: HeldItemId.SHELL_BELL, weight: 1 },
[modifierTypes.SOUL_DEW, 10], { entry: HeldItemId.SOUL_DEW, weight: 1 },
[modifierTypes.SCOPE_LENS, 1], { entry: HeldItemId.SCOPE_LENS, weight: 1 },
[modifierTypes.BATON, 1], { entry: HeldItemId.BATON, weight: 1 },
[modifierTypes.FOCUS_BAND, 5], { entry: HeldItemId.FOCUS_BAND, weight: 1 },
[modifierTypes.KINGS_ROCK, 3], { entry: HeldItemId.KINGS_ROCK, weight: 1 },
[modifierTypes.GRIP_CLAW, 5], { entry: HeldItemId.GRIP_CLAW, weight: 1 },
]; ];
const berryPool = [
[BerryType.APICOT, 3],
[BerryType.ENIGMA, 2],
[BerryType.GANLON, 3],
[BerryType.LANSAT, 3],
[BerryType.LEPPA, 2],
[BerryType.LIECHI, 3],
[BerryType.LUM, 2],
[BerryType.PETAYA, 3],
[BerryType.SALAC, 2],
[BerryType.SITRUS, 2],
[BerryType.STARF, 3],
];
let pool: any[];
if (tier === "Berries") {
pool = berryPool;
} else {
pool = tier === RewardTier.ULTRA ? ultraPool : roguePool;
}
for (let i = 0; i < numItems; i++) {
if (pool.length === 0) {
// Stop generating new items if somehow runs out of items to spawn
return;
}
const randIndex = randSeedInt(pool.length);
const newItemType = pool[randIndex];
let newMod: PokemonHeldItemModifierType;
if (tier === "Berries") {
newMod = generateModifierType(modifierTypes.BERRY, [newItemType[0]]) as PokemonHeldItemModifierType;
} else {
newMod = generateModifierType(newItemType[0]) as PokemonHeldItemModifierType;
}
applyModifierTypeToPlayerPokemon(pokemon, newMod);
// Decrement max stacks and remove from pool if at max
newItemType[1]--;
if (newItemType[1] <= 0) {
pool.splice(randIndex, 1);
}
}
}

View File

@ -46,9 +46,10 @@ import type { PokeballType } from "#enums/pokeball";
import { doShinySparkleAnim } from "#app/field/anims"; import { doShinySparkleAnim } from "#app/field/anims";
import { TrainerType } from "#enums/trainer-type"; import { TrainerType } from "#enums/trainer-type";
import { timedEventManager } from "#app/global-event-manager"; import { timedEventManager } from "#app/global-event-manager";
import { HeldItemCategoryId, HeldItemId, isItemInCategory } from "#enums/held-item-id"; import { HeldItemCategoryId, type HeldItemId, isItemInCategory } from "#enums/held-item-id";
import { allHeldItems } from "#app/items/all-held-items"; import { allHeldItems } from "#app/items/all-held-items";
import { RewardTier } from "#enums/reward-tier"; import { RewardTier } from "#enums/reward-tier";
import { getHeldItemTier } from "#app/items/held-item-tiers";
/** the i18n namespace for the encounter */ /** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/globalTradeSystem"; const namespace = "mysteryEncounters/globalTradeSystem";
@ -419,7 +420,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
const chosenPokemon: PlayerPokemon = encounter.misc.chosenPokemon; const chosenPokemon: PlayerPokemon = encounter.misc.chosenPokemon;
// Check tier of the traded item, the received item will be one tier up // Check tier of the traded item, the received item will be one tier up
let tier = globalTradeItemTiers[heldItemId] ?? RewardTier.GREAT; let tier = getHeldItemTier(heldItemId) ?? RewardTier.GREAT;
// Increment tier by 1 // Increment tier by 1
if (tier < RewardTier.MASTER) { if (tier < RewardTier.MASTER) {
@ -975,38 +976,3 @@ function generateRandomTraderName() {
const trainerNames = trainerNameString.split(" & "); const trainerNames = trainerNameString.split(" & ");
return trainerNames[randInt(trainerNames.length)]; return trainerNames[randInt(trainerNames.length)];
} }
const globalTradeItemTiers = {
[HeldItemCategoryId.BERRY]: RewardTier.COMMON,
[HeldItemCategoryId.BASE_STAT_BOOST]: RewardTier.GREAT,
[HeldItemId.WHITE_HERB]: RewardTier.GREAT,
[HeldItemId.METAL_POWDER]: RewardTier.GREAT,
[HeldItemId.QUICK_POWDER]: RewardTier.GREAT,
[HeldItemId.DEEP_SEA_SCALE]: RewardTier.GREAT,
[HeldItemId.DEEP_SEA_TOOTH]: RewardTier.GREAT,
[HeldItemCategoryId.TYPE_ATTACK_BOOSTER]: RewardTier.ULTRA,
[HeldItemId.REVIVER_SEED]: RewardTier.ULTRA,
[HeldItemId.LIGHT_BALL]: RewardTier.ULTRA,
[HeldItemId.EVIOLITE]: RewardTier.ULTRA,
[HeldItemId.QUICK_CLAW]: RewardTier.ULTRA,
[HeldItemId.MYSTICAL_ROCK]: RewardTier.ULTRA,
[HeldItemId.WIDE_LENS]: RewardTier.ULTRA,
[HeldItemId.GOLDEN_PUNCH]: RewardTier.ULTRA,
[HeldItemId.TOXIC_ORB]: RewardTier.ULTRA,
[HeldItemId.FLAME_ORB]: RewardTier.ULTRA,
[HeldItemId.LUCKY_EGG]: RewardTier.ULTRA,
[HeldItemId.FOCUS_BAND]: RewardTier.ROGUE,
[HeldItemId.KINGS_ROCK]: RewardTier.ROGUE,
[HeldItemId.LEFTOVERS]: RewardTier.ROGUE,
[HeldItemId.SHELL_BELL]: RewardTier.ROGUE,
[HeldItemId.GRIP_CLAW]: RewardTier.ROGUE,
[HeldItemId.SOUL_DEW]: RewardTier.ROGUE,
[HeldItemId.BATON]: RewardTier.ROGUE,
[HeldItemId.GOLDEN_EGG]: RewardTier.ULTRA,
[HeldItemId.MINI_BLACK_HOLE]: RewardTier.MASTER,
[HeldItemId.MULTI_LENS]: RewardTier.MASTER,
};

View File

@ -123,7 +123,7 @@ export type HeldItemCategoryId = (typeof HeldItemCategoryId)[keyof typeof HeldIt
const ITEM_CATEGORY_MASK = 0xFF00 const ITEM_CATEGORY_MASK = 0xFF00
function getHeldItemCategory(itemId: HeldItemId): HeldItemCategoryId { export function getHeldItemCategory(itemId: HeldItemId): HeldItemCategoryId {
return itemId & ITEM_CATEGORY_MASK; return itemId & ITEM_CATEGORY_MASK;
} }

View File

@ -50,7 +50,7 @@ export function isHeldItemCategoryEntry(entry: any): entry is HeldItemCategoryEn
} }
type HeldItemPoolEntry = { type HeldItemPoolEntry = {
entry: HeldItemId | HeldItemCategoryEntry | HeldItemSpecs; entry: HeldItemId | HeldItemCategoryId | HeldItemCategoryEntry | HeldItemSpecs;
weight: number | HeldItemWeightFunc; weight: number | HeldItemWeightFunc;
}; };
@ -65,7 +65,7 @@ export type HeldItemTieredPool = {
}; };
type HeldItemConfigurationEntry = { type HeldItemConfigurationEntry = {
entry: HeldItemId | HeldItemCategoryEntry | HeldItemSpecs | HeldItemPool; entry: HeldItemId | HeldItemCategoryId | HeldItemCategoryEntry | HeldItemSpecs | HeldItemPool;
count?: number | (() => number); count?: number | (() => number);
}; };

View File

@ -2,7 +2,7 @@ import type { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon";
import type Pokemon from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon";
import { coerceArray, getEnumValues, randSeedFloat, randSeedInt } from "#app/utils/common"; import { coerceArray, getEnumValues, randSeedFloat, randSeedInt } from "#app/utils/common";
import { BerryType } from "#enums/berry-type"; import { BerryType } from "#enums/berry-type";
import { HeldItemCategoryId, HeldItemId } from "#enums/held-item-id"; import { HeldItemCategoryId, HeldItemId, isCategoryId } from "#enums/held-item-id";
import { HeldItemPoolType } from "#enums/modifier-pool-type"; import { HeldItemPoolType } from "#enums/modifier-pool-type";
import type { PokemonType } from "#enums/pokemon-type"; import type { PokemonType } from "#enums/pokemon-type";
import { RewardTier } from "#enums/reward-tier"; import { RewardTier } from "#enums/reward-tier";
@ -263,6 +263,9 @@ function getNewHeldItemFromPool(pool: HeldItemPool, pokemon: Pokemon, party?: Po
const entry = pool[pickWeightedIndex(weights)].entry; const entry = pool[pickWeightedIndex(weights)].entry;
if (typeof entry === "number") { if (typeof entry === "number") {
if (isCategoryId(entry)) {
return getNewHeldItemFromCategory(entry, party ?? pokemon, {}, pokemon) as HeldItemId;
}
return entry as HeldItemId; return entry as HeldItemId;
} }
@ -273,12 +276,24 @@ function getNewHeldItemFromPool(pool: HeldItemPool, pokemon: Pokemon, party?: Po
return entry as HeldItemSpecs; return entry as HeldItemSpecs;
} }
function assignItemsFromCategory(id: HeldItemCategoryId, pokemon: Pokemon, count: number) {
for (let i = 1; i <= count; i++) {
const newItem = getNewHeldItemFromCategory(id, pokemon, {}, pokemon);
if (newItem) {
pokemon.heldItemManager.add(newItem);
}
}
}
export function assignItemsFromConfiguration(config: HeldItemConfiguration, pokemon: Pokemon) { export function assignItemsFromConfiguration(config: HeldItemConfiguration, pokemon: Pokemon) {
config.forEach(item => { config.forEach(item => {
const { entry, count } = item; const { entry, count } = item;
const actualCount = typeof count === "function" ? count() : (count ?? 1); const actualCount = typeof count === "function" ? count() : (count ?? 1);
if (typeof entry === "number") { if (typeof entry === "number") {
if (isCategoryId(entry)) {
assignItemsFromCategory(entry, pokemon, actualCount);
}
pokemon.heldItemManager.add(entry, actualCount); pokemon.heldItemManager.add(entry, actualCount);
} }
@ -287,12 +302,7 @@ export function assignItemsFromConfiguration(config: HeldItemConfiguration, poke
} }
if (isHeldItemCategoryEntry(entry)) { if (isHeldItemCategoryEntry(entry)) {
for (let i = 1; i <= actualCount; i++) { assignItemsFromCategory(entry.id, pokemon, actualCount);
const newItem = getNewHeldItemFromCategory(entry.id, pokemon, entry?.customWeights, pokemon);
if (newItem) {
pokemon.heldItemManager.add(newItem);
}
}
} }
if (isHeldItemPool(entry)) { if (isHeldItemPool(entry)) {

View File

@ -0,0 +1,47 @@
import { getHeldItemCategory, HeldItemCategoryId, HeldItemId } from "#enums/held-item-id";
import { RewardTier } from "#enums/reward-tier";
export const heldItemTiers = {
[HeldItemCategoryId.BERRY]: RewardTier.COMMON,
[HeldItemCategoryId.BASE_STAT_BOOST]: RewardTier.GREAT,
[HeldItemId.WHITE_HERB]: RewardTier.GREAT,
[HeldItemId.METAL_POWDER]: RewardTier.GREAT,
[HeldItemId.QUICK_POWDER]: RewardTier.GREAT,
[HeldItemId.DEEP_SEA_SCALE]: RewardTier.GREAT,
[HeldItemId.DEEP_SEA_TOOTH]: RewardTier.GREAT,
[HeldItemId.SOOTHE_BELL]: RewardTier.GREAT,
[HeldItemCategoryId.TYPE_ATTACK_BOOSTER]: RewardTier.ULTRA,
[HeldItemId.REVIVER_SEED]: RewardTier.ULTRA,
[HeldItemId.LIGHT_BALL]: RewardTier.ULTRA,
[HeldItemId.EVIOLITE]: RewardTier.ULTRA,
[HeldItemId.QUICK_CLAW]: RewardTier.ULTRA,
[HeldItemId.MYSTICAL_ROCK]: RewardTier.ULTRA,
[HeldItemId.WIDE_LENS]: RewardTier.ULTRA,
[HeldItemId.GOLDEN_PUNCH]: RewardTier.ULTRA,
[HeldItemId.TOXIC_ORB]: RewardTier.ULTRA,
[HeldItemId.FLAME_ORB]: RewardTier.ULTRA,
[HeldItemId.LUCKY_EGG]: RewardTier.ULTRA,
[HeldItemId.FOCUS_BAND]: RewardTier.ROGUE,
[HeldItemId.KINGS_ROCK]: RewardTier.ROGUE,
[HeldItemId.LEFTOVERS]: RewardTier.ROGUE,
[HeldItemId.SHELL_BELL]: RewardTier.ROGUE,
[HeldItemId.GRIP_CLAW]: RewardTier.ROGUE,
[HeldItemId.SOUL_DEW]: RewardTier.ROGUE,
[HeldItemId.BATON]: RewardTier.ROGUE,
[HeldItemId.GOLDEN_EGG]: RewardTier.ULTRA,
[HeldItemId.MINI_BLACK_HOLE]: RewardTier.MASTER,
[HeldItemId.MULTI_LENS]: RewardTier.MASTER,
};
export function getHeldItemTier(item: HeldItemId): RewardTier | undefined {
let tier = heldItemTiers[item];
if (!tier) {
const category = getHeldItemCategory(item);
tier = heldItemTiers[category];
}
return tier;
}