Converted wild pokemon pool to held item rewards

This commit is contained in:
Wlowscha 2025-06-03 23:19:44 +02:00
parent 9568488161
commit 9e1bbee58f
No known key found for this signature in database
GPG Key ID: 3C8F1AD330565D04
10 changed files with 334 additions and 25 deletions

View File

@ -53,7 +53,7 @@ import { allMoves } from "./data/data-lists";
import { MusicPreference } from "#app/system/settings/settings"; import { MusicPreference } from "#app/system/settings/settings";
import { import {
getDefaultModifierTypeForTier, getDefaultModifierTypeForTier,
getEnemyModifierTypesForWave, getEnemyHeldItemsForWave,
getLuckString, getLuckString,
getLuckTextTint, getLuckTextTint,
getModifierPoolForType, getModifierPoolForType,
@ -3223,13 +3223,13 @@ export default class BattleScene extends SceneBase {
if (isBoss) { if (isBoss) {
count = Math.max(count, Math.floor(chances / 2)); count = Math.max(count, Math.floor(chances / 2));
} }
getEnemyModifierTypesForWave( getEnemyHeldItemsForWave(
difficultyWaveIndex, difficultyWaveIndex,
count, count,
[enemyPokemon], [enemyPokemon],
this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD,
upgradeChance, upgradeChance,
).map(mt => mt.newModifier(enemyPokemon).add(this.enemyModifiers, false)); ).map(itemId => enemyPokemon.heldItemManager.add(itemId));
} }
return true; return true;
}); });

View File

@ -71,6 +71,17 @@ export const HeldItems = {
FLAME_ORB: 0x070C, FLAME_ORB: 0x070C,
SOUL_DEW: 0x070D, SOUL_DEW: 0x070D,
BATON: 0x070E, BATON: 0x070E,
// Mini Black Hole
MINI_BLACK_HOLE: 0x0801,
// Vitamins
HP_UP: 0x0901,
PROTEIN: 0x0902,
IRON: 0x0903,
CALCIUM: 0x0904,
ZINC: 0x0905,
CARBOS: 0x0906,
}; };
export type HeldItems = (typeof HeldItems)[keyof typeof HeldItems]; export type HeldItems = (typeof HeldItems)[keyof typeof HeldItems];

View File

@ -1,11 +1,20 @@
import { getEnumValues } from "#app/utils/common";
import { BerryType } from "#enums/berry-type";
import { HeldItems } from "#enums/held-items"; import { HeldItems } from "#enums/held-items";
import type { PokemonType } from "#enums/pokemon-type"; import type { PokemonType } from "#enums/pokemon-type";
import type { PermanentStat } from "#enums/stat";
import { ITEM_EFFECT } from "./held-item"; import { ITEM_EFFECT } from "./held-item";
import { import {
type ATTACK_TYPE_BOOST_PARAMS, type ATTACK_TYPE_BOOST_PARAMS,
AttackTypeBoosterHeldItem, AttackTypeBoosterHeldItem,
attackTypeToHeldItem, attackTypeToHeldItem,
} from "./held-items/attack-type-booster"; } from "./held-items/attack-type-booster";
import {
type BASE_STAT_BOOSTER_PARAMS,
BaseStatBoosterHeldItem,
permanentStatToHeldItem,
} from "./held-items/base-stat-booster";
import { type BERRY_PARAMS, BerryHeldItem, berryTypeToHeldItem } from "./held-items/berry";
import { type EXP_BOOST_PARAMS, ExpBoosterHeldItem } from "./held-items/exp-booster"; import { type EXP_BOOST_PARAMS, ExpBoosterHeldItem } from "./held-items/exp-booster";
import { type HIT_HEAL_PARAMS, HitHealHeldItem } from "./held-items/hit-heal"; import { type HIT_HEAL_PARAMS, HitHealHeldItem } from "./held-items/hit-heal";
import type { RESET_NEGATIVE_STAT_STAGE_PARAMS } from "./held-items/reset-negative-stat-stage"; import type { RESET_NEGATIVE_STAT_STAGE_PARAMS } from "./held-items/reset-negative-stat-stage";
@ -20,12 +29,29 @@ export function initHeldItems() {
const pokemonType = Number(typeKey) as PokemonType; const pokemonType = Number(typeKey) as PokemonType;
allHeldItems[heldItemType] = new AttackTypeBoosterHeldItem(heldItemType, 99, pokemonType, 0.2); allHeldItems[heldItemType] = new AttackTypeBoosterHeldItem(heldItemType, 99, pokemonType, 0.2);
} }
// vitamins
for (const [statKey, heldItemType] of Object.entries(permanentStatToHeldItem)) {
const stat = Number(statKey) as PermanentStat;
allHeldItems[heldItemType] = new BaseStatBoosterHeldItem(heldItemType, 10, stat);
}
allHeldItems[HeldItems.LEFTOVERS] = new TurnEndHealHeldItem(HeldItems.LEFTOVERS, 4); allHeldItems[HeldItems.LEFTOVERS] = new TurnEndHealHeldItem(HeldItems.LEFTOVERS, 4);
allHeldItems[HeldItems.SHELL_BELL] = new HitHealHeldItem(HeldItems.SHELL_BELL, 4); allHeldItems[HeldItems.SHELL_BELL] = new HitHealHeldItem(HeldItems.SHELL_BELL, 4);
allHeldItems[HeldItems.LUCKY_EGG] = new ExpBoosterHeldItem(HeldItems.LUCKY_EGG, 99, 40); allHeldItems[HeldItems.LUCKY_EGG] = new ExpBoosterHeldItem(HeldItems.LUCKY_EGG, 99, 40);
allHeldItems[HeldItems.GOLDEN_EGG] = new ExpBoosterHeldItem(HeldItems.GOLDEN_EGG, 99, 100); allHeldItems[HeldItems.GOLDEN_EGG] = new ExpBoosterHeldItem(HeldItems.GOLDEN_EGG, 99, 100);
for (const berry of getEnumValues(BerryType)) {
let maxStackCount: number;
if ([BerryType.LUM, BerryType.LEPPA, BerryType.SITRUS, BerryType.ENIGMA].includes(berry)) {
maxStackCount = 2;
} else {
maxStackCount = 3;
}
const berryId = berryTypeToHeldItem[berry];
allHeldItems[berryId] = new BerryHeldItem(berry, maxStackCount);
}
console.log(allHeldItems); console.log(allHeldItems);
} }
@ -35,6 +61,8 @@ type APPLY_HELD_ITEMS_PARAMS = {
[ITEM_EFFECT.HIT_HEAL]: HIT_HEAL_PARAMS; [ITEM_EFFECT.HIT_HEAL]: HIT_HEAL_PARAMS;
[ITEM_EFFECT.RESET_NEGATIVE_STAT_STAGE]: RESET_NEGATIVE_STAT_STAGE_PARAMS; [ITEM_EFFECT.RESET_NEGATIVE_STAT_STAGE]: RESET_NEGATIVE_STAT_STAGE_PARAMS;
[ITEM_EFFECT.EXP_BOOSTER]: EXP_BOOST_PARAMS; [ITEM_EFFECT.EXP_BOOSTER]: EXP_BOOST_PARAMS;
[ITEM_EFFECT.BERRY]: BERRY_PARAMS;
[ITEM_EFFECT.BASE_STAT_BOOSTER]: BASE_STAT_BOOSTER_PARAMS;
}; };
export function applyHeldItems<T extends ITEM_EFFECT>(effect: T, params: APPLY_HELD_ITEMS_PARAMS[T]) { export function applyHeldItems<T extends ITEM_EFFECT>(effect: T, params: APPLY_HELD_ITEMS_PARAMS[T]) {

View File

@ -1,3 +1,4 @@
import { applyPostItemLostAbAttrs, PostItemLostAbAttr } from "#app/data/abilities/ability";
import type Pokemon from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import type { HeldItems } from "#enums/held-items"; import type { HeldItems } from "#enums/held-items";
@ -8,6 +9,9 @@ export const ITEM_EFFECT = {
HIT_HEAL: 3, HIT_HEAL: 3,
RESET_NEGATIVE_STAT_STAGE: 4, RESET_NEGATIVE_STAT_STAGE: 4,
EXP_BOOSTER: 5, EXP_BOOSTER: 5,
// Should we actually distinguish different berry effects?
BERRY: 6,
BASE_STAT_BOOSTER: 7,
} as const; } as const;
export type ITEM_EFFECT = (typeof ITEM_EFFECT)[keyof typeof ITEM_EFFECT]; export type ITEM_EFFECT = (typeof ITEM_EFFECT)[keyof typeof ITEM_EFFECT];
@ -41,6 +45,7 @@ export class HeldItem {
return ""; return "";
} }
// TODO: Aren't these fine as just properties to set in the subclass definition?
untransferable(): HeldItem { untransferable(): HeldItem {
this.isTransferable = false; this.isTransferable = false;
return this; return this;
@ -119,10 +124,15 @@ export class HeldItem {
} }
export class ConsumableHeldItem extends HeldItem { export class ConsumableHeldItem extends HeldItem {
consume(pokemon: Pokemon, isPlayer: boolean): boolean { // Sometimes berries are not eaten, some stuff may not proc unburden...
pokemon.heldItemManager.remove(this.type, 1); consume(pokemon: Pokemon, isPlayer: boolean, remove = true, unburden = true): void {
// TODO: Turn this into updateItemBar or something if (remove) {
globalScene.updateModifiers(isPlayer); pokemon.heldItemManager.remove(this.type, 1);
return true; // TODO: Turn this into updateItemBar or something
globalScene.updateModifiers(isPlayer);
}
if (unburden) {
applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false);
}
} }
} }

View File

@ -44,6 +44,7 @@ export class AttackTypeBoosterHeldItem extends HeldItem {
public moveType: PokemonType; public moveType: PokemonType;
public powerBoost: number; public powerBoost: number;
// This constructor may need a revision
constructor(type: HeldItems, maxStackCount = 1, moveType: PokemonType, powerBoost: number) { constructor(type: HeldItems, maxStackCount = 1, moveType: PokemonType, powerBoost: number) {
super(type, maxStackCount); super(type, maxStackCount);
this.moveType = moveType; this.moveType = moveType;

View File

@ -0,0 +1,81 @@
import type Pokemon from "#app/field/pokemon";
import { HeldItems } from "#enums/held-items";
import { getStatKey, type PermanentStat, Stat } from "#enums/stat";
import i18next from "i18next";
import { HeldItem, ITEM_EFFECT } from "../held-item";
export interface BASE_STAT_BOOSTER_PARAMS {
/** The pokemon with the item */
pokemon: Pokemon;
baseStats: number[];
}
interface PermanentStatToHeldItemMap {
[key: number]: HeldItems;
}
export const permanentStatToHeldItem: PermanentStatToHeldItemMap = {
[Stat.HP]: HeldItems.HP_UP,
[Stat.ATK]: HeldItems.PROTEIN,
[Stat.DEF]: HeldItems.IRON,
[Stat.SPATK]: HeldItems.CALCIUM,
[Stat.SPDEF]: HeldItems.ZINC,
[Stat.SPD]: HeldItems.CARBOS,
};
export const statBoostItems: Record<PermanentStat, string> = {
[Stat.HP]: "hp_up",
[Stat.ATK]: "protein",
[Stat.DEF]: "iron",
[Stat.SPATK]: "calcium",
[Stat.SPDEF]: "zinc",
[Stat.SPD]: "carbos",
};
export class BaseStatBoosterHeldItem extends HeldItem {
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.BASE_STAT_BOOSTER];
public stat: PermanentStat;
constructor(type: HeldItems, maxStackCount = 1, stat: PermanentStat) {
super(type, maxStackCount);
this.stat = stat;
}
get name(): string {
return i18next.t(`modifierType:BaseStatBoosterItem.${statBoostItems[this.stat]}`);
}
get description(): string {
return i18next.t("modifierType:ModifierType.BaseStatBoosterModifierType.description", {
stat: i18next.t(getStatKey(this.stat)),
});
}
get iconName(): string {
return statBoostItems[this.stat];
}
/**
* Checks if {@linkcode BaseStatModifier} should be applied to the specified {@linkcode Pokemon}.
* @param _pokemon the {@linkcode Pokemon} to be modified
* @param baseStats the base stats of the {@linkcode Pokemon}
* @returns `true` if the {@linkcode Pokemon} should be modified
*/
// override shouldApply(_pokemon?: Pokemon, baseStats?: number[]): boolean {
// return super.shouldApply(_pokemon, baseStats) && Array.isArray(baseStats);
// }
/**
* Applies the {@linkcode BaseStatModifier} to the specified {@linkcode Pokemon}.
* @param _pokemon the {@linkcode Pokemon} to be modified
* @param baseStats the base stats of the {@linkcode Pokemon}
* @returns always `true`
*/
apply(params: BASE_STAT_BOOSTER_PARAMS): boolean {
const pokemon = params.pokemon;
const stackCount = pokemon.heldItemManager.getStack(this.type);
const baseStats = params.baseStats;
baseStats[this.stat] = Math.floor(baseStats[this.stat] * (1 + stackCount * 0.1));
return true;
}
}

View File

@ -0,0 +1,99 @@
import { getBerryEffectDescription, getBerryEffectFunc, getBerryName } from "#app/data/berry";
import type Pokemon from "#app/field/pokemon";
import { globalScene } from "#app/global-scene";
import { ConsumableHeldItem, ITEM_EFFECT } from "#app/items/held-item";
import { PreserveBerryModifier } from "#app/modifier/modifier";
import { BooleanHolder } from "#app/utils/common";
import { BerryType } from "#enums/berry-type";
import { HeldItems } from "#enums/held-items";
interface BerryTypeToHeldItemMap {
[key: number]: HeldItems;
}
export const berryTypeToHeldItem: BerryTypeToHeldItemMap = {
[BerryType.SITRUS]: HeldItems.SITRUS_BERRY,
[BerryType.LUM]: HeldItems.LUM_BERRY,
[BerryType.ENIGMA]: HeldItems.ENIGMA_BERRY,
[BerryType.LIECHI]: HeldItems.LIECHI_BERRY,
[BerryType.GANLON]: HeldItems.GANLON_BERRY,
[BerryType.PETAYA]: HeldItems.PETAYA_BERRY,
[BerryType.APICOT]: HeldItems.APICOT_BERRY,
[BerryType.SALAC]: HeldItems.SALAC_BERRY,
[BerryType.LANSAT]: HeldItems.LANSAT_BERRY,
[BerryType.STARF]: HeldItems.STARF_BERRY,
[BerryType.LEPPA]: HeldItems.LEPPA_BERRY,
};
export interface BERRY_PARAMS {
/** The pokemon with the item */
pokemon: Pokemon;
/** Whether the move was used by a player pokemon */
isPlayer: boolean;
}
// TODO: Maybe split up into subclasses?
export class BerryHeldItem extends ConsumableHeldItem {
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.BERRY];
public berryType: BerryType;
constructor(berryType: BerryType, maxStackCount = 1) {
const type = berryTypeToHeldItem[berryType];
super(type, maxStackCount);
this.berryType = berryType;
}
get name(): string {
return getBerryName(this.berryType);
}
get description(): string {
return getBerryEffectDescription(this.berryType);
}
get iconName(): string {
return `${BerryType[this.berryType].toLowerCase()}_berry`;
}
/**
* Checks if {@linkcode BerryModifier} should be applied
* @param pokemon The {@linkcode Pokemon} that holds the berry
* @returns `true` if {@linkcode BerryModifier} should be applied
*/
// override shouldApply(pokemon: Pokemon): boolean {
// return !this.consumed && super.shouldApply(pokemon) && getBerryPredicate(this.berryType)(pokemon);
// }
/**
* Applies {@linkcode BerryHeldItem}
* @param pokemon The {@linkcode Pokemon} that holds the berry
* @returns always `true`
*/
apply(params: BERRY_PARAMS): boolean {
const pokemon = params.pokemon;
const isPlayer = params.isPlayer;
const preserve = new BooleanHolder(false);
globalScene.applyModifiers(PreserveBerryModifier, pokemon.isPlayer(), pokemon, preserve);
const consumed = !preserve.value;
// munch the berry and trigger unburden-like effects
getBerryEffectFunc(this.berryType)(pokemon);
this.consume(pokemon, isPlayer, consumed);
// TODO: Update this method to work with held items
// Update berry eaten trackers for Belch, Harvest, Cud Chew, etc.
// Don't recover it if we proc berry pouch (no item duplication)
pokemon.recordEatenBerry(this.berryType, consumed);
return true;
}
getMaxHeldItemCount(_pokemon: Pokemon): number {
if ([BerryType.LUM, BerryType.LEPPA, BerryType.SITRUS, BerryType.ENIGMA].includes(this.berryType)) {
return 2;
}
return 3;
}
}

View File

@ -22,7 +22,7 @@ export class HitHealHeldItem extends HeldItem {
return i18next.t("modifierType:ModifierType.SHELL_BELL.description"); return i18next.t("modifierType:ModifierType.SHELL_BELL.description");
} }
get icon(): string { get iconName(): string {
return "shell_bell"; return "shell_bell";
} }

View File

@ -58,7 +58,7 @@ export class ResetNegativeStatStageHeldItem extends ConsumableHeldItem {
}), }),
); );
this.consume(pokemon, isPlayer); this.consume(pokemon, isPlayer, true, false);
} }
return statRestored; return statRestored;

View File

@ -133,6 +133,8 @@ import { HeldItems } from "#enums/held-items";
import { allHeldItems } from "#app/items/all-held-items"; import { allHeldItems } from "#app/items/all-held-items";
import { TYPE_BOOST_ITEM_BOOST_PERCENT } from "#app/constants"; import { TYPE_BOOST_ITEM_BOOST_PERCENT } from "#app/constants";
import { attackTypeToHeldItem } from "#app/items/held-items/attack-type-booster"; import { attackTypeToHeldItem } from "#app/items/held-items/attack-type-booster";
import { berryTypeToHeldItem } from "#app/items/held-items/berry";
import { permanentStatToHeldItem, statBoostItems } from "#app/items/held-items/base-stat-booster";
const outputModifierData = false; const outputModifierData = false;
const useMaxWeightForOutput = false; const useMaxWeightForOutput = false;
@ -859,6 +861,26 @@ export class BerryModifierType extends PokemonHeldItemModifierType implements Ge
} }
} }
export class BerryReward extends PokemonHeldItemReward implements GeneratedPersistentModifierType {
private berryType: BerryType;
constructor(berryType: BerryType) {
const itemId = berryTypeToHeldItem[berryType];
super(
itemId,
// Next argument is useless
(type, args) => new BerryModifier(type, (args[0] as Pokemon).id, berryType),
);
this.berryType = berryType;
this.id = "BERRY"; // needed to prevent harvest item deletion; remove after modifier rework
}
getPregenArgs(): any[] {
return [this.berryType];
}
}
export class AttackTypeBoosterReward extends PokemonHeldItemReward implements GeneratedPersistentModifierType { export class AttackTypeBoosterReward extends PokemonHeldItemReward implements GeneratedPersistentModifierType {
public moveType: PokemonType; public moveType: PokemonType;
public boostPercent: number; public boostPercent: number;
@ -1029,6 +1051,24 @@ export class BaseStatBoosterModifierType
} }
} }
export class BaseStatBoosterReward extends PokemonHeldItemReward implements GeneratedPersistentModifierType {
private stat: PermanentStat;
private key: string;
constructor(stat: PermanentStat) {
const key = statBoostItems[stat];
const itemId = permanentStatToHeldItem[stat];
super(itemId, (_type, args) => new BaseStatModifier(this, (args[0] as Pokemon).id, this.stat));
this.stat = stat;
this.key = key;
}
getPregenArgs(): any[] {
return [this.stat];
}
}
/** /**
* Shuckle Juice item * Shuckle Juice item
*/ */
@ -1524,6 +1564,18 @@ class BaseStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
} }
} }
class BaseStatBoosterRewardGenerator extends ModifierTypeGenerator {
constructor() {
super((_party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs) {
return new BaseStatBoosterReward(pregenArgs[0]);
}
const randStat: PermanentStat = randSeedInt(Stat.SPD + 1);
return new BaseStatBoosterReward(randStat);
});
}
}
class TempStatStageBoosterModifierTypeGenerator extends ModifierTypeGenerator { class TempStatStageBoosterModifierTypeGenerator extends ModifierTypeGenerator {
public static readonly items: Record<TempBattleStat, string> = { public static readonly items: Record<TempBattleStat, string> = {
[Stat.ATK]: "x_attack", [Stat.ATK]: "x_attack",
@ -2143,6 +2195,8 @@ export const modifierTypes = {
} }
})("modifierType:ModifierType.DIRE_HIT", "dire_hit", (type, _args) => new TempCritBoosterModifier(type, 5)), })("modifierType:ModifierType.DIRE_HIT", "dire_hit", (type, _args) => new TempCritBoosterModifier(type, 5)),
BASE_STAT_BOOSTER_REWARD: () => new BaseStatBoosterRewardGenerator(),
BASE_STAT_BOOSTER: () => new BaseStatBoosterModifierTypeGenerator(), BASE_STAT_BOOSTER: () => new BaseStatBoosterModifierTypeGenerator(),
ATTACK_TYPE_BOOSTER_REWARD: () => new AttackTypeBoosterRewardGenerator(), ATTACK_TYPE_BOOSTER_REWARD: () => new AttackTypeBoosterRewardGenerator(),
@ -2189,6 +2243,26 @@ export const modifierTypes = {
return new TerastallizeModifierType(shardType); return new TerastallizeModifierType(shardType);
}), }),
BERRY_REWARD: () =>
new ModifierTypeGenerator((_party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in BerryType) {
return new BerryModifierType(pregenArgs[0] as BerryType);
}
const berryTypes = getEnumValues(BerryType);
let randBerryType: BerryType;
const rand = randSeedInt(12);
if (rand < 2) {
randBerryType = BerryType.SITRUS;
} else if (rand < 4) {
randBerryType = BerryType.LUM;
} else if (rand < 6) {
randBerryType = BerryType.LEPPA;
} else {
randBerryType = berryTypes[randSeedInt(berryTypes.length - 3) + 2];
}
return new BerryReward(randBerryType);
}),
BERRY: () => BERRY: () =>
new ModifierTypeGenerator((_party: Pokemon[], pregenArgs?: any[]) => { new ModifierTypeGenerator((_party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in BerryType) { if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in BerryType) {
@ -3150,11 +3224,11 @@ const modifierPool: ModifierPool = {
}; };
const wildModifierPool: ModifierPool = { const wildModifierPool: ModifierPool = {
[ModifierTier.COMMON]: [new WeightedModifierType(modifierTypes.BERRY, 1)].map(m => { [ModifierTier.COMMON]: [new WeightedModifierType(modifierTypes.BERRY_REWARD, 1)].map(m => {
m.setTier(ModifierTier.COMMON); m.setTier(ModifierTier.COMMON);
return m; return m;
}), }),
[ModifierTier.GREAT]: [new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 1)].map(m => { [ModifierTier.GREAT]: [new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER_REWARD, 1)].map(m => {
m.setTier(ModifierTier.GREAT); m.setTier(ModifierTier.GREAT);
return m; return m;
}), }),
@ -3177,19 +3251,19 @@ const wildModifierPool: ModifierPool = {
const trainerModifierPool: ModifierPool = { const trainerModifierPool: ModifierPool = {
[ModifierTier.COMMON]: [ [ModifierTier.COMMON]: [
new WeightedModifierType(modifierTypes.BERRY, 8), new WeightedModifierType(modifierTypes.BERRY_REWARD, 8),
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3), new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER_REWARD, 3),
].map(m => { ].map(m => {
m.setTier(ModifierTier.COMMON); m.setTier(ModifierTier.COMMON);
return m; return m;
}), }),
[ModifierTier.GREAT]: [new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3)].map(m => { [ModifierTier.GREAT]: [new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER_REWARD, 3)].map(m => {
m.setTier(ModifierTier.GREAT); m.setTier(ModifierTier.GREAT);
return m; return m;
}), }),
[ModifierTier.ULTRA]: [ [ModifierTier.ULTRA]: [
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 10), new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER_REWARD, 10),
new WeightedModifierType(modifierTypes.WHITE_HERB, 0), new WeightedModifierType(modifierTypes.WHITE_HERB_REWARD, 0),
].map(m => { ].map(m => {
m.setTier(ModifierTier.ULTRA); m.setTier(ModifierTier.ULTRA);
return m; return m;
@ -3698,22 +3772,27 @@ export function getEnemyModifierTypesForWave(
return ret; return ret;
} }
// TODO: Add proper documentation to this function (once it fully works...)
// TODO: Convert trainer pool to HeldItems too
export function getEnemyHeldItemsForWave( export function getEnemyHeldItemsForWave(
waveIndex: number, waveIndex: number,
count: number, count: number,
party: EnemyPokemon[], party: EnemyPokemon[],
poolType: ModifierPoolType.WILD | ModifierPoolType.TRAINER, poolType: ModifierPoolType.WILD | ModifierPoolType.TRAINER,
upgradeChance = 0, upgradeChance = 0,
): PokemonHeldItemReward[] { ): HeldItems[] {
const ret = new Array(count).fill(0).map( const ret = new Array(count).fill(0).map(() => {
() => const reward = getNewModifierTypeOption(
// TODO: Change this to get held items (this function really could just return a list of ids honestly) party,
getNewModifierTypeOption(party, poolType, undefined, upgradeChance && !randSeedInt(upgradeChance) ? 1 : 0) poolType,
?.type as PokemonHeldItemReward, undefined,
); upgradeChance && !randSeedInt(upgradeChance) ? 1 : 0,
)?.type as PokemonHeldItemReward;
return reward.itemId;
});
if (!(waveIndex % 1000)) { if (!(waveIndex % 1000)) {
// TODO: Change this line with the actual held item when implemented // TODO: Change this line with the actual held item when implemented
ret.push(getModifierType(modifierTypes.MINI_BLACK_HOLE) as PokemonHeldItemReward); ret.push(HeldItems.MINI_BLACK_HOLE);
} }
return ret; return ret;
} }