From ba01c505d949a0b01d6c3a86c8470ffc40f8ec3a Mon Sep 17 00:00:00 2001 From: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Date: Thu, 29 May 2025 23:26:50 +0200 Subject: [PATCH] Moved some files around, added many held item ids --- src/enums/held-items.ts | 76 ++++++++++ src/field/pokemon-held-item-manager.ts | 44 ++++++ src/field/pokemon-item-manager.ts | 26 ---- src/field/pokemon.ts | 2 +- src/loading-scene.ts | 2 +- .../{held-items.ts => all-held-items.ts} | 54 +------ src/modifier/reward-generator.ts | 120 --------------- src/modifier/reward-pool-manager.ts | 94 ------------ src/modifier/reward-tier.ts | 8 - src/modifier/reward.ts | 143 ------------------ 10 files changed, 125 insertions(+), 444 deletions(-) create mode 100644 src/enums/held-items.ts create mode 100644 src/field/pokemon-held-item-manager.ts delete mode 100644 src/field/pokemon-item-manager.ts rename src/modifier/{held-items.ts => all-held-items.ts} (80%) delete mode 100644 src/modifier/reward-generator.ts delete mode 100644 src/modifier/reward-pool-manager.ts delete mode 100644 src/modifier/reward-tier.ts delete mode 100644 src/modifier/reward.ts diff --git a/src/enums/held-items.ts b/src/enums/held-items.ts new file mode 100644 index 00000000000..9a15559ac14 --- /dev/null +++ b/src/enums/held-items.ts @@ -0,0 +1,76 @@ +export const HeldItems = { + NONE: 0x0000, + + // Berries + SITRUS_BERRY: 0x0101, + LUM_BERRY: 0x0102, + ENIGMA_BERRY: 0x0103, + LIECHI_BERRY: 0x0104, + GANLON_BERRY: 0x0105, + PETAYA_BERRY: 0x0106, + APICOT_BERRY: 0x0107, + SALAC_BERRY: 0x0108, + LANSAT_BERRY: 0x0109, + STARF_BERRY: 0x010A, + LEPPA_BERRY: 0x010B, + + // Other items that are consumed + REVIVER_SEED: 0x0201, + WHITE_HERB: 0x0202, + + // Type Boosters + SILK_SCARF: 0x0301, + BLACK_BELT: 0x0302, + SHARP_BEAK: 0x0303, + POISON_BARB: 0x0304, + SOFT_SAND: 0x0305, + HARD_STONE: 0x0306, + SILVER_POWDER: 0x0307, + SPELL_TAG: 0x0308, + METAL_COAT: 0x0309, + CHARCOAL: 0x030A, + MYSTIC_WATER: 0x030B, + MIRACLE_SEED: 0x030C, + MAGNET: 0x030D, + TWISTED_SPOON: 0x030E, + NEVER_MELT_ICE: 0x030F, + DRAGON_FANG: 0x0310, + BLACK_GLASSES: 0x0311, + FAIRY_FEATHER: 0x0312, + + // Stat Boosters + EVIOLITE: 0x0401, + LIGHT_BALL: 0x0402, + THICK_CLUB: 0x0403, + METAL_POWDER: 0x0404, + QUICK_POWDER: 0x0405, + DEEP_SEA_SCALE: 0x0406, + DEEP_SEA_TOOTH: 0x0407, + + // Crit Boosters + SCOPE_LENS: 0x0501, + LEEK: 0x0502, + + // Items increasing gains + LUCKY_EGG: 0x0601, + GOLDEN_EGG: 0x0602, + SOOTHE_BELL: 0x0603, + + // Unique items + FOCUS_BAND: 0x0701, + QUICK_CLAW: 0x0702, + KINGS_ROCK: 0x0703, + LEFTOVERS: 0x0704, + SHELL_BELL: 0x0705, + MYSTICAL_ROCK: 0x0706, + WIDE_LENS: 0x0707, + MULTI_LENS: 0x0708, + GOLDEN_PUNCH: 0x0709, + GRIP_CLAW: 0x070A, + TOXIC_ORB: 0x070B, + FLAME_ORB: 0x070C, + SOUL_DEW: 0x070D, + BATON: 0x070E, +}; + +export type HeldItems = (typeof HeldItems)[keyof typeof HeldItems]; diff --git a/src/field/pokemon-held-item-manager.ts b/src/field/pokemon-held-item-manager.ts new file mode 100644 index 00000000000..08f8416861c --- /dev/null +++ b/src/field/pokemon-held-item-manager.ts @@ -0,0 +1,44 @@ +import { allHeldItems } from "#app/modifier/all-held-items"; +import type { HeldItems } from "#app/enums/held-items"; + +interface HeldItemProperties { + stack: number; + disabled: boolean; + cooldown?: number; +} + +type HeldItemPropertyMap = { + [key in HeldItems]: HeldItemProperties; +}; + +export class PokemonItemManager { + private heldItems: HeldItemPropertyMap; + + constructor() { + this.heldItems = {}; + } + + getHeldItems(): HeldItemPropertyMap { + return this.heldItems; + } + + hasItem(itemType: HeldItems): boolean { + return itemType in this.getHeldItems(); + } + + getItem(itemType: HeldItems): HeldItemProperties { + // TODO: Not very safe + return this.heldItems[itemType]; + } + + addHeldItem(itemType: HeldItems, addStack = 1) { + const maxStack = allHeldItems[itemType].getMaxStackCount(); + + if (this.hasItem(itemType)) { + // TODO: We may want an error message of some kind instead + this.heldItems[itemType].stack = Math.min(this.heldItems[itemType].stack + addStack, maxStack); + } else { + this.heldItems[itemType] = { stack: Math.min(addStack, maxStack), disabled: false }; + } + } +} diff --git a/src/field/pokemon-item-manager.ts b/src/field/pokemon-item-manager.ts deleted file mode 100644 index 58fb6ba4d40..00000000000 --- a/src/field/pokemon-item-manager.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { allHeldItems } from "#app/modifier/held-items"; -import type { HeldItems } from "#app/modifier/held-items"; - -export class PokemonItemManager { - private heldItems: [HeldItems, number][]; - - constructor() { - this.heldItems = []; - } - - getHeldItems(): [HeldItems, number][] { - return this.heldItems; - } - - addHeldItem(itemType: HeldItems, stack: number) { - const maxStack = allHeldItems[itemType].getMaxStackCount(); - - const existing = this.heldItems.find(([type]) => type === itemType); - - if (existing) { - existing[1] = Math.min(existing[1] + stack, maxStack); - } else { - this.heldItems.push([itemType, Math.min(stack, maxStack)]); - } - } -} diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index c7d7a4a456c..1c8d1e2cf0f 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -255,7 +255,7 @@ import { MoveFlags } from "#enums/MoveFlags"; import { timedEventManager } from "#app/global-event-manager"; import { loadMoveAnimations } from "#app/sprites/pokemon-asset-loader"; import { ResetStatusPhase } from "#app/phases/reset-status-phase"; -import { PokemonItemManager } from "./pokemon-item-manager"; +import { PokemonItemManager } from "./pokemon-held-item-manager"; export enum LearnMoveSituation { MISC, diff --git a/src/loading-scene.ts b/src/loading-scene.ts index f801061b665..38581e8ad0b 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -21,7 +21,7 @@ import { initVouchers } from "#app/system/voucher"; import { Biome } from "#enums/biome"; import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters"; import { timedEventManager } from "./global-event-manager"; -import { initHeldItems } from "./modifier/held-items"; +import { initHeldItems } from "./modifier/all-held-items"; export class LoadingScene extends SceneBase { public static readonly KEY = "loading"; diff --git a/src/modifier/held-items.ts b/src/modifier/all-held-items.ts similarity index 80% rename from src/modifier/held-items.ts rename to src/modifier/all-held-items.ts index 170004aa024..293a91d9207 100644 --- a/src/modifier/held-items.ts +++ b/src/modifier/all-held-items.ts @@ -2,58 +2,10 @@ import type Pokemon from "#app/field/pokemon"; import { globalScene } from "#app/global-scene"; import type { Localizable } from "#app/interfaces/locales"; import type { NumberHolder } from "#app/utils/common"; +import { HeldItems } from "#enums/held-items"; import { PokemonType } from "#enums/pokemon-type"; import i18next from "i18next"; -export const HeldItems = { - NONE: 0x0000, - - SITRUS_BERRY: 0x0101, - LEPPA_BERRY: 0x0102, - - SILK_SCARF: 0x0201, - BLACK_BELT: 0x0202, - SHARP_BEAK: 0x0203, - POISON_BARB: 0x0204, - SOFT_SAND: 0x0205, - HARD_STONE: 0x0206, - SILVER_POWDER: 0x0207, - SPELL_TAG: 0x0208, - METAL_COAT: 0x0209, - CHARCOAL: 0x020a, - MYSTIC_WATER: 0x020b, - MIRACLE_SEED: 0x020c, - MAGNET: 0x020d, - TWISTED_SPOON: 0x020e, - NEVER_MELT_ICE: 0x020f, - DRAGON_FANG: 0x0210, - BLACK_GLASSES: 0x0211, - FAIRY_FEATHER: 0x0212, - - REVIVER_SEED: 0x0301, - SOOTHE_BELL: 0x0302, - SOUL_DEW: 0x0303, - GOLDEN_PUNCH: 0x0304, - GRIP_CLAW: 0x0305, - BATON: 0x0306, - FOCUS_BAND: 0x0307, - QUICK_CLAW: 0x0308, - KINGS_ROCK: 0x0309, - LEFTOVERS: 0x030a, - SHELL_BELL: 0x030b, -}; - -export type HeldItems = (typeof HeldItems)[keyof typeof HeldItems]; - -export const HeldItemCategories = { - NONE: 0x0000, - BERRY: 0x0100, - ATTACK_TYPE_BOOSTER: 0x0200, - BASE_STAT_BOOSTER: 0x0400, -}; - -export type HeldItemCategories = (typeof HeldItemCategories)[keyof typeof HeldItemCategories]; - export class HeldItem implements Localizable { // public pokemonId: number; public type: HeldItems; @@ -207,9 +159,9 @@ export class AttackTypeBoosterHeldItem extends HeldItem { export function applyAttackTypeBoosterHeldItem(pokemon: Pokemon, moveType: PokemonType, movePower: NumberHolder) { if (pokemon) { - for (const [item, stackCount] of pokemon.heldItemManager.getHeldItems()) { + for (const [item, props] of Object.entries(pokemon.heldItemManager.getHeldItems())) { if (allHeldItems[item] instanceof AttackTypeBoosterHeldItem) { - allHeldItems[item].apply(stackCount, moveType, movePower); + allHeldItems[item].apply(props.stack, moveType, movePower); } } } diff --git a/src/modifier/reward-generator.ts b/src/modifier/reward-generator.ts deleted file mode 100644 index cedecd923bb..00000000000 --- a/src/modifier/reward-generator.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { AttackMove } from "#app/data/moves/move"; -import type Pokemon from "#app/field/pokemon"; -import { PokemonType } from "#enums/pokemon-type"; -import { attackTypeToHeldItem } from "./held-items"; -import { HeldItemReward, type Reward } from "./reward"; - -function getRandomWeightedSelection(weights: Map): T | null { - const totalWeight = Array.from(weights.values()).reduce((sum, weight) => sum + weight, 0); - - if (totalWeight === 0) { - return null; - } - - const randInt = Math.floor(Math.random() * totalWeight); - - let accumulatedWeight = 0; - for (const [item, weight] of weights.entries()) { - accumulatedWeight += weight; - if (randInt < accumulatedWeight) { - return item; - } - } - - return null; -} - -export class RewardGenerator { - options: T[]; - tempWeights: Map; - - constructor(options: T[]) { - this.options = options; - this.tempWeights = new Map(this.options.map(option => [option, 1])); - } - - generate(party: Pokemon[], overrideWeightFunction?: Function) { - const weights = overrideWeightFunction ? overrideWeightFunction(party) : this.weightFunction(party); - - for (const [option, tempWeight] of this.tempWeights.entries()) { - if (tempWeight === 0 && weights.has(option)) { - weights.set(option, 0); - } - } - - const value: T | null = getRandomWeightedSelection(weights); - - if (value) { - this.tempWeights.set(value, 0); - return this.generateReward(value); - } - - return null; - } - - weightFunction(_party: Pokemon[]): Map { - const defaultWeightMap = new Map(); - - this.options.forEach(option => { - defaultWeightMap.set(option, 1); - }); - - return defaultWeightMap; - } - - generateReward(_value: T): Reward | null { - return null; - } -} - -export class AttackTypeBoosterHeldItemRewardGenerator extends RewardGenerator { - constructor() { - //TODO: we can also construct this, but then have to handle options being null - const options = [ - PokemonType.NORMAL, - PokemonType.FIGHTING, - PokemonType.FLYING, - PokemonType.POISON, - PokemonType.GROUND, - PokemonType.ROCK, - PokemonType.BUG, - PokemonType.GHOST, - PokemonType.STEEL, - PokemonType.FIRE, - PokemonType.WATER, - PokemonType.GRASS, - PokemonType.ELECTRIC, - PokemonType.PSYCHIC, - PokemonType.ICE, - PokemonType.DRAGON, - PokemonType.DARK, - PokemonType.FAIRY, - ]; - super(options); - } - - weightFunction(party: Pokemon[]): Map { - const attackMoveTypes = party.flatMap(p => - p - .getMoveset() - .map(m => m.getMove()) - .filter(m => m instanceof AttackMove) - .map(m => m.type), - ); - - const attackMoveTypeWeights = new Map(); - - for (const type of attackMoveTypes) { - const currentWeight = attackMoveTypeWeights.get(type) ?? 0; - if (currentWeight < 3) { - attackMoveTypeWeights.set(type, currentWeight + 1); - } - } - - return attackMoveTypeWeights; - } - - generateReward(value: PokemonType) { - return new HeldItemReward(attackTypeToHeldItem[value]); - } -} diff --git a/src/modifier/reward-pool-manager.ts b/src/modifier/reward-pool-manager.ts deleted file mode 100644 index c49075505d6..00000000000 --- a/src/modifier/reward-pool-manager.ts +++ /dev/null @@ -1,94 +0,0 @@ -/** -import { globalScene } from "#app/global-scene"; -import { isNullOrUndefined, NumberHolder } from "#app/utils/common"; -import type { RewardGenerator } from "./reward-generator"; -import type { RewardTier } from "./reward-tier"; -import Overrides from "#app/overrides"; - -interface RewardPool { - [rewardTier: number]: RewardGenerator[]; -} - -export interface CustomRewardSettings { - guaranteedModifierTiers?: RewardTier[]; - guaranteedModifierTypeOptions?: ModifierTypeOption[]; - guaranteedModifierTypeFuncs?: ModifierTypeFunc[]; - fillRemaining?: boolean; - //Set to negative value to disable rerolls completely in shop - rerollMultiplier?: number; - allowLuckUpgrades?: boolean; -} - -export class RewardPoolManager { - public rerollCount: number; - private rewardPool: RewardPool; - private customRewardSettings?: CustomRewardSettings; //TODO: have a better scheme than just this - - constructor(rewardPool: RewardPool) { - this.rewardPool = rewardPool; - } - - getRerollCost(lockRarities: boolean): number { - let baseValue = 0; - if (Overrides.WAIVE_ROLL_FEE_OVERRIDE) { - return baseValue; - } - if (lockRarities) { - const tierValues = [50, 125, 300, 750, 2000]; - for (const opt of this.typeOptions) { - baseValue += tierValues[opt.type.tier ?? 0]; - } - } else { - baseValue = 250; - } - - let multiplier = 1; - if (!isNullOrUndefined(this.customRewardSettings?.rerollMultiplier)) { - if (this.customRewardSettings.rerollMultiplier < 0) { - // Completely overrides reroll cost to -1 and early exits - return -1; - } - - // Otherwise, continue with custom multiplier - multiplier = this.customRewardSettings.rerollMultiplier; - } - - const baseMultiplier = Math.min( - Math.ceil(globalScene.currentBattle.waveIndex / 10) * baseValue * 2 ** this.rerollCount * multiplier, - Number.MAX_SAFE_INTEGER, - ); - - // Apply Black Sludge to reroll cost - const modifiedRerollCost = new NumberHolder(baseMultiplier); - globalScene.applyModifier(HealShopCostModifier, true, modifiedRerollCost); - return modifiedRerollCost.value; - } - - getRewardCount(): NumberHolder { - const modifierCount = new NumberHolder(3); - - // TODO: This code is used by golden and silver pokéball to increase the number of item slots - // They will become a trainer item, so there will be no .applyModifiers - globalScene.applyModifiers(ExtraModifierModifier, true, modifierCount); - globalScene.applyModifiers(TempExtraModifierModifier, true, modifierCount); - - // If custom rewards are specified, overrides default item count - // TODO: Figure out exactly how and when that would happen - // Presumably in MEs, but possibly also after rerolls? And at specific waves... - if (this.customRewardSettings) { - const newItemCount = - (this.customRewardSettings.guaranteedModifierTiers?.length || 0) + - (this.customRewardSettings.guaranteedModifierTypeOptions?.length || 0) + - (this.customRewardSettings.guaranteedModifierTypeFuncs?.length || 0); - if (this.customRewardSettings.fillRemaining) { - const originalCount = modifierCount.value; - modifierCount.value = originalCount > newItemCount ? originalCount : newItemCount; - } else { - modifierCount.value = newItemCount; - } - } - - return modifierCount; - } -} -*/ diff --git a/src/modifier/reward-tier.ts b/src/modifier/reward-tier.ts deleted file mode 100644 index e7ccc1d9166..00000000000 --- a/src/modifier/reward-tier.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum RewardTier { - COMMON, - GREAT, - ULTRA, - ROGUE, - MASTER, - LUXURY, -} diff --git a/src/modifier/reward.ts b/src/modifier/reward.ts deleted file mode 100644 index 351ebc3a861..00000000000 --- a/src/modifier/reward.ts +++ /dev/null @@ -1,143 +0,0 @@ -/** -import { globalScene } from "#app/global-scene"; -import type { PokeballType } from "#enums/pokeball"; -import i18next from "i18next"; -import { allHeldItems, type HeldItems } from "./held-items"; -import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball"; -import type Pokemon from "#app/field/pokemon"; - -export class Reward { - - getName(): string { - return ""; - } - - getDescription(): string { - return ""; - } - - getIcon(): string { - return ""; - } - - createIcon(): Phaser.GameObjects.Container { - const container = globalScene.add.container(0, 0); - - const item = globalScene.add.sprite(0, 12, "items"); - item.setFrame(this.getIcon()); - item.setOrigin(0, 0.5); - container.add(item); - return container; - } -} - - -export class PokeballReward extends Reward { - private pokeballType: PokeballType; - private count: number; - - constructor(pokeballType: PokeballType, count: number) { - super(); - this.pokeballType = pokeballType; - this.count = count; - } - - getName(): string { - return i18next.t("modifierType:ModifierType.AddPokeballModifierType.name", { - modifierCount: this.count, - pokeballName: getPokeballName(this.pokeballType), - }); - } - - getDescription(): string { - return i18next.t("modifierType:ModifierType.AddPokeballModifierType.description", { - modifierCount: this.count, - pokeballName: getPokeballName(this.pokeballType), - catchRate: - getPokeballCatchMultiplier(this.pokeballType) > -1 - ? `${getPokeballCatchMultiplier(this.pokeballType)}x` - : "100%", - pokeballAmount: `${globalScene.pokeballCounts[this.pokeballType]}`, - }); - } - - apply(): boolean { - const pokeballCounts = globalScene.pokeballCounts; - pokeballCounts[this.pokeballType] = Math.min( - pokeballCounts[this.pokeballType] + this.count, - MAX_PER_TYPE_POKEBALLS, - ); - return true; - } -} - -export class PartySelectReward extends Reward { - apply(): { - } -} - -export class HeldItemReward extends PartySelectReward { - private itemId: HeldItems; - - constructor(itemId: HeldItems) { - super(); - this.itemId = itemId; - } - - getName(): string { - return allHeldItems[this.itemId].getName(); - } - - getDescription(): string { - return allHeldItems[this.itemId].getDescription(); - } - - getIcon(): string { - return allHeldItems[this.itemId].getIcon(); - } - - apply(): { - } -} - - - - - - - - - - - - - - - - - -export interface RewardInfo { - options: number[]; - rewardType: ; - condition?: (party: Pokemon[], option: number) => void; - optionWeight?: (party: Pokemon[], option: number) => void; -} - - - - -interface RewardPool { - [rewardTier: number]: RewardGenerator[]; -} - - -export class RewardManager { - - private rewardPool: RewardPool; - - constructor(rewardPool: RewardPool) { - this.rewardPool = rewardPool; - } - -} -*/