mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-01 14:02:18 +02:00
Converted wild pokemon pool to held item rewards
This commit is contained in:
parent
9568488161
commit
9e1bbee58f
@ -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;
|
||||||
});
|
});
|
||||||
|
@ -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];
|
||||||
|
@ -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]) {
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
81
src/items/held-items/base-stat-booster.ts
Normal file
81
src/items/held-items/base-stat-booster.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
99
src/items/held-items/berry.ts
Normal file
99
src/items/held-items/berry.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ export class ResetNegativeStatStageHeldItem extends ConsumableHeldItem {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.consume(pokemon, isPlayer);
|
this.consume(pokemon, isPlayer, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return statRestored;
|
return statRestored;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user