mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-07 07:59:26 +02:00
Replace remaining Modifiers with Rewards (#6091)
* Changing remaining Modifiers to Consumables, and renaming ModifierType to Reward * Renamed modifier files and moved them into items folder * Using rewards in most places * Removed consumables in favor of using rewards directly * Renamed RewardTier to RarityTier * Reward ids, function to match rewards * Getting reward tiers from player pool still * Messing around with parameters of Reward.apply() * Always requiring player pokemon in rewards * Fixing some functions in select-reward-phase and battle-scene * Fixed various post-merge issues * Fixed most localization strings (accidentally broken by replacing modifierType with reward) * Fixed tests for select reward phase * Using Pokemon.hasSpecies() * Zero weight for trainer items rewards which are already max stack * Cleaning up SelectRewardPhase, held item rewards behave the same as any PokemonReward * Cleaned up some functions * Introduced RewardCategoryId, distributed RewardIds * Utility `is` functions for rewards * Minor fixes * Moved `HeldItemEffect` to its own file * rmade some todo comments * Adding a big comment * Added tsdocs and removed `RewardClass` * undid breaking changes * added TODO * Moved matchingRewards function to reward-utils.ts * Added RewardGenerator classes for mints and tera shards * Introducing default rarity tiers for trainer items and rewards * RewardFunc now can return RewardGenerator * Moved pool reward functions to their own file, plus other utility files * Fixed WeightedModifier to work with the new RewardFunc * Fixed wrong type import * Shifting trainer item and reward ids to avoid overlaps * Added some types * Updated comment in reward.ts * Added strong typing ot item maps * added type safety to held item name map --------- Co-authored-by: Bertie690 <taylormw163@gmail.com> Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com>
This commit is contained in:
parent
d3f2659cdf
commit
466c4aede2
@ -183,7 +183,7 @@ input:-internal-autofill-selected {
|
|||||||
/* Show #apadStats only in battle and shop */
|
/* Show #apadStats only in battle and shop */
|
||||||
#touchControls:not([data-ui-mode="COMMAND"]):not([data-ui-mode="FIGHT"]):not(
|
#touchControls:not([data-ui-mode="COMMAND"]):not([data-ui-mode="FIGHT"]):not(
|
||||||
[data-ui-mode="BALL"]
|
[data-ui-mode="BALL"]
|
||||||
):not([data-ui-mode="TARGET_SELECT"]):not([data-ui-mode="MODIFIER_SELECT"])
|
):not([data-ui-mode="TARGET_SELECT"]):not([data-ui-mode="REWARD_SELECT"])
|
||||||
#apadStats {
|
#apadStats {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -24,15 +24,15 @@ export interface AbilityTranslationEntries {
|
|||||||
[key: string]: AbilityTranslationEntry;
|
[key: string]: AbilityTranslationEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ModifierTypeTranslationEntry {
|
export interface RewardTranslationEntry {
|
||||||
name?: string;
|
name?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
extra?: SimpleTranslationEntries;
|
extra?: SimpleTranslationEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ModifierTypeTranslationEntries {
|
export interface RewardTranslationEntries {
|
||||||
ModifierType: { [key: string]: ModifierTypeTranslationEntry };
|
Reward: { [key: string]: RewardTranslationEntry };
|
||||||
SpeciesBoosterItem: { [key: string]: ModifierTypeTranslationEntry };
|
SpeciesBoosterItem: { [key: string]: RewardTranslationEntry };
|
||||||
AttackTypeBoosterItem: SimpleTranslationEntries;
|
AttackTypeBoosterItem: SimpleTranslationEntries;
|
||||||
TempStatStageBoosterItem: SimpleTranslationEntries;
|
TempStatStageBoosterItem: SimpleTranslationEntries;
|
||||||
BaseStatBoosterItem: SimpleTranslationEntries;
|
BaseStatBoosterItem: SimpleTranslationEntries;
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
// Intentionally re-exports `ModifierConstructorMap` from `modifier.ts`
|
|
||||||
|
|
||||||
import type { Pokemon } from "#field/pokemon";
|
|
||||||
import type { ModifierConstructorMap } from "#modifiers/modifier";
|
|
||||||
import type { ModifierType, WeightedModifierType } from "#modifiers/modifier-type";
|
|
||||||
|
|
||||||
export type ModifierTypeFunc = () => ModifierType;
|
|
||||||
export type WeightedModifierTypeWeightFunc = (party: Pokemon[], rerollCount?: number) => number;
|
|
||||||
|
|
||||||
export type { ModifierConstructorMap } from "#modifiers/modifier";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map of modifier names to their respective instance types
|
|
||||||
*/
|
|
||||||
export type ModifierInstanceMap = {
|
|
||||||
[K in keyof ModifierConstructorMap]: InstanceType<ModifierConstructorMap[K]>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Union type of all modifier constructors.
|
|
||||||
*/
|
|
||||||
export type ModifierClass = ModifierConstructorMap[keyof ModifierConstructorMap];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Union type of all modifier names as strings.
|
|
||||||
*/
|
|
||||||
export type ModifierString = keyof ModifierConstructorMap;
|
|
||||||
|
|
||||||
export type ModifierPool = {
|
|
||||||
[tier: string]: WeightedModifierType[];
|
|
||||||
};
|
|
23
src/@types/rewards.ts
Normal file
23
src/@types/rewards.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
|
import type { RewardId } from "#enums/reward-id";
|
||||||
|
import type { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
|
import type { Pokemon } from "#field/pokemon";
|
||||||
|
import type { Reward, RewardGenerator } from "#items/reward";
|
||||||
|
|
||||||
|
export type RewardFunc = () => Reward | RewardGenerator;
|
||||||
|
export type WeightedRewardWeightFunc = (party: Pokemon[], rerollCount?: number) => number;
|
||||||
|
|
||||||
|
export type RewardPoolId = RewardId | HeldItemId | TrainerItemId;
|
||||||
|
|
||||||
|
export type RewardPoolEntry = {
|
||||||
|
id: RewardPoolId;
|
||||||
|
weight: number | WeightedRewardWeightFunc;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RewardPool = {
|
||||||
|
[tier: string]: RewardPoolEntry[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface RewardPoolWeights {
|
||||||
|
[tier: string]: number[];
|
||||||
|
}
|
@ -53,8 +53,8 @@ import { ExpGainsSpeed } from "#enums/exp-gains-speed";
|
|||||||
import { ExpNotification } from "#enums/exp-notification";
|
import { ExpNotification } from "#enums/exp-notification";
|
||||||
import { FormChangeItem } from "#enums/form-change-item";
|
import { FormChangeItem } from "#enums/form-change-item";
|
||||||
import { GameModes } from "#enums/game-modes";
|
import { GameModes } from "#enums/game-modes";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItemId } from "#enums/held-item-id";
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
import { HeldItemPoolType, ModifierPoolType } from "#enums/modifier-pool-type";
|
|
||||||
import { MoneyFormat } from "#enums/money-format";
|
import { MoneyFormat } from "#enums/money-format";
|
||||||
import { MoveId } from "#enums/move-id";
|
import { MoveId } from "#enums/move-id";
|
||||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||||
@ -65,6 +65,7 @@ import { PlayerGender } from "#enums/player-gender";
|
|||||||
import { PokeballType } from "#enums/pokeball";
|
import { PokeballType } from "#enums/pokeball";
|
||||||
import type { PokemonAnimType } from "#enums/pokemon-anim-type";
|
import type { PokemonAnimType } from "#enums/pokemon-anim-type";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
|
import { HeldItemPoolType, RewardPoolType } from "#enums/reward-pool-type";
|
||||||
import { ShopCursorTarget } from "#enums/shop-cursor-target";
|
import { ShopCursorTarget } from "#enums/shop-cursor-target";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
@ -82,9 +83,10 @@ import { PokemonSpriteSparkleHandler } from "#field/pokemon-sprite-sparkle-handl
|
|||||||
import { Trainer } from "#field/trainer";
|
import { Trainer } from "#field/trainer";
|
||||||
import { applyHeldItems } from "#items/all-held-items";
|
import { applyHeldItems } from "#items/all-held-items";
|
||||||
import { type ApplyTrainerItemsParams, applyTrainerItems } from "#items/apply-trainer-items";
|
import { type ApplyTrainerItemsParams, applyTrainerItems } from "#items/apply-trainer-items";
|
||||||
import { HeldItemEffect } from "#items/held-item";
|
|
||||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
||||||
import { assignEnemyHeldItemsForWave, assignItemsFromConfiguration } from "#items/held-item-pool";
|
import { assignEnemyHeldItemsForWave, assignItemsFromConfiguration } from "#items/held-item-pool";
|
||||||
|
import type { Reward } from "#items/reward";
|
||||||
|
import { getRewardPoolForType } from "#items/reward-pool-utils";
|
||||||
import { type EnemyAttackStatusEffectChanceTrainerItem, TrainerItemEffect } from "#items/trainer-item";
|
import { type EnemyAttackStatusEffectChanceTrainerItem, TrainerItemEffect } from "#items/trainer-item";
|
||||||
import {
|
import {
|
||||||
isTrainerItemPool,
|
isTrainerItemPool,
|
||||||
@ -94,15 +96,6 @@ import {
|
|||||||
} from "#items/trainer-item-data-types";
|
} from "#items/trainer-item-data-types";
|
||||||
import { TrainerItemManager } from "#items/trainer-item-manager";
|
import { TrainerItemManager } from "#items/trainer-item-manager";
|
||||||
import { getNewTrainerItemFromPool } from "#items/trainer-item-pool";
|
import { getNewTrainerItemFromPool } from "#items/trainer-item-pool";
|
||||||
import type { Modifier } from "#modifiers/modifier";
|
|
||||||
import {
|
|
||||||
ConsumableModifier,
|
|
||||||
ConsumablePokemonModifier,
|
|
||||||
FusePokemonModifier,
|
|
||||||
PokemonHpRestoreModifier,
|
|
||||||
RememberMoveModifier,
|
|
||||||
} from "#modifiers/modifier";
|
|
||||||
import { getLuckString, getLuckTextTint, getPartyLuckValue } from "#modifiers/modifier-type";
|
|
||||||
import { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
import { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
||||||
import { MysteryEncounterSaveData } from "#mystery-encounters/mystery-encounter-save-data";
|
import { MysteryEncounterSaveData } from "#mystery-encounters/mystery-encounter-save-data";
|
||||||
import { allMysteryEncounters, mysteryEncountersByBiome } from "#mystery-encounters/mystery-encounters";
|
import { allMysteryEncounters, mysteryEncountersByBiome } from "#mystery-encounters/mystery-encounters";
|
||||||
@ -112,7 +105,7 @@ import { hasExpSprite } from "#sprites/sprite-utils";
|
|||||||
import type { Variant } from "#sprites/variant";
|
import type { Variant } from "#sprites/variant";
|
||||||
import { clearVariantData, variantData } from "#sprites/variant";
|
import { clearVariantData, variantData } from "#sprites/variant";
|
||||||
import type { Achv } from "#system/achv";
|
import type { Achv } from "#system/achv";
|
||||||
import { achvs, HeldItemAchv, ModifierAchv, MoneyAchv } from "#system/achv";
|
import { achvs, HeldItemAchv, MoneyAchv } from "#system/achv";
|
||||||
import { GameData } from "#system/game-data";
|
import { GameData } from "#system/game-data";
|
||||||
import { initGameSpeed } from "#system/game-speed";
|
import { initGameSpeed } from "#system/game-speed";
|
||||||
import type { PokemonData } from "#system/pokemon-data";
|
import type { PokemonData } from "#system/pokemon-data";
|
||||||
@ -148,7 +141,7 @@ import {
|
|||||||
} from "#utils/common";
|
} from "#utils/common";
|
||||||
import { deepMergeSpriteData } from "#utils/data";
|
import { deepMergeSpriteData } from "#utils/data";
|
||||||
import { getEnumValues } from "#utils/enums";
|
import { getEnumValues } from "#utils/enums";
|
||||||
import { getModifierPoolForType } from "#utils/modifier-utils";
|
import { getLuckString, getLuckTextTint, getPartyLuckValue } from "#utils/party";
|
||||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
@ -267,7 +260,7 @@ export class BattleScene extends SceneBase {
|
|||||||
public arena: Arena;
|
public arena: Arena;
|
||||||
public gameMode: GameMode;
|
public gameMode: GameMode;
|
||||||
public score: number;
|
public score: number;
|
||||||
public lockModifierTiers: boolean;
|
public lockRarityTiers: boolean;
|
||||||
public trainer: Phaser.GameObjects.Sprite;
|
public trainer: Phaser.GameObjects.Sprite;
|
||||||
public lastEnemyTrainer: Trainer | null;
|
public lastEnemyTrainer: Trainer | null;
|
||||||
public currentBattle: Battle;
|
public currentBattle: Battle;
|
||||||
@ -480,12 +473,12 @@ export class BattleScene extends SceneBase {
|
|||||||
this.enemyTrainerItems = new TrainerItemManager();
|
this.enemyTrainerItems = new TrainerItemManager();
|
||||||
|
|
||||||
this.itemBar = new ItemBar();
|
this.itemBar = new ItemBar();
|
||||||
this.itemBar.setName("modifier-bar");
|
this.itemBar.setName("item-bar");
|
||||||
this.add.existing(this.itemBar);
|
this.add.existing(this.itemBar);
|
||||||
uiContainer.add(this.itemBar);
|
uiContainer.add(this.itemBar);
|
||||||
|
|
||||||
this.enemyItemBar = new ItemBar(true);
|
this.enemyItemBar = new ItemBar(true);
|
||||||
this.enemyItemBar.setName("enemy-modifier-bar");
|
this.enemyItemBar.setName("enemy-item-bar");
|
||||||
this.add.existing(this.enemyItemBar);
|
this.add.existing(this.enemyItemBar);
|
||||||
uiContainer.add(this.enemyItemBar);
|
uiContainer.add(this.enemyItemBar);
|
||||||
|
|
||||||
@ -854,9 +847,9 @@ export class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ModifierBar of this scene, which is declared private and therefore not accessible elsewhere
|
* Returns the ItemBar of this scene, which is declared private and therefore not accessible elsewhere
|
||||||
* @param isEnemy - Whether to return the enemy modifier bar instead of the player bar; default `false`
|
* @param isEnemy - Whether to return the enemy modifier bar instead of the player bar; default `false`
|
||||||
* @returns The {@linkcode ModifierBar} for the given side of the field
|
* @returns The {@linkcode ItemBar} for the given side of the field
|
||||||
*/
|
*/
|
||||||
getItemBar(isEnemy = false): ItemBar {
|
getItemBar(isEnemy = false): ItemBar {
|
||||||
return isEnemy ? this.enemyItemBar : this.itemBar;
|
return isEnemy ? this.enemyItemBar : this.itemBar;
|
||||||
@ -1167,7 +1160,7 @@ export class BattleScene extends SceneBase {
|
|||||||
this.score = 0;
|
this.score = 0;
|
||||||
this.money = 0;
|
this.money = 0;
|
||||||
|
|
||||||
this.lockModifierTiers = false;
|
this.lockRarityTiers = false;
|
||||||
|
|
||||||
this.pokeballCounts = Object.fromEntries(
|
this.pokeballCounts = Object.fromEntries(
|
||||||
getEnumValues(PokeballType)
|
getEnumValues(PokeballType)
|
||||||
@ -1243,12 +1236,12 @@ export class BattleScene extends SceneBase {
|
|||||||
...allSpecies,
|
...allSpecies,
|
||||||
...allMoves,
|
...allMoves,
|
||||||
...allAbilities,
|
...allAbilities,
|
||||||
...getEnumValues(ModifierPoolType)
|
...getEnumValues(RewardPoolType)
|
||||||
.map(mpt => getModifierPoolForType(mpt))
|
.map(mpt => getRewardPoolForType(mpt))
|
||||||
.flatMap(mp =>
|
.flatMap(mp =>
|
||||||
Object.values(mp)
|
Object.values(mp)
|
||||||
.flat()
|
.flat()
|
||||||
.map(mt => mt.modifierType)
|
.map(mt => mt.reward)
|
||||||
.filter(mt => "localize" in mt)
|
.filter(mt => "localize" in mt)
|
||||||
.map(lpb => lpb as unknown as Localizable),
|
.map(lpb => lpb as unknown as Localizable),
|
||||||
),
|
),
|
||||||
@ -1987,11 +1980,11 @@ export class BattleScene extends SceneBase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showEnemyModifierBar(): void {
|
showEnemyItemBar(): void {
|
||||||
this.enemyItemBar.setVisible(true);
|
this.enemyItemBar.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
hideEnemyModifierBar(): void {
|
hideEnemyItemBar(): void {
|
||||||
this.enemyItemBar.setVisible(false);
|
this.enemyItemBar.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2085,11 +2078,11 @@ export class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateUIPositions(): void {
|
updateUIPositions(): void {
|
||||||
const enemyModifierCount = this.enemyItemBar.totalVisibleLength;
|
const enemyItemCount = this.enemyItemBar.totalVisibleLength;
|
||||||
const biomeWaveTextHeight = this.biomeWaveText.getBottomLeft().y - this.biomeWaveText.getTopLeft().y;
|
const biomeWaveTextHeight = this.biomeWaveText.getBottomLeft().y - this.biomeWaveText.getTopLeft().y;
|
||||||
this.biomeWaveText.setY(
|
this.biomeWaveText.setY(
|
||||||
-(this.game.canvas.height / 6) +
|
-(this.game.canvas.height / 6) +
|
||||||
(enemyModifierCount ? (enemyModifierCount <= 12 ? 15 : 24) : 0) +
|
(enemyItemCount ? (enemyItemCount <= 12 ? 15 : 24) : 0) +
|
||||||
biomeWaveTextHeight / 2,
|
biomeWaveTextHeight / 2,
|
||||||
);
|
);
|
||||||
this.moneyText.setY(this.biomeWaveText.y + 10);
|
this.moneyText.setY(this.biomeWaveText.y + 10);
|
||||||
@ -2641,56 +2634,19 @@ export class BattleScene extends SceneBase {
|
|||||||
applyTrainerItems(effect, this.trainerItems, params);
|
applyTrainerItems(effect, this.trainerItems, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
addModifier(modifier: Modifier | null, playSound?: boolean, instant?: boolean, cost?: number): boolean {
|
applyReward<T extends Reward>(reward: T, params: Parameters<T["apply"]>[0], playSound?: boolean): boolean {
|
||||||
// We check against modifier.type to stop a bug related to loading in a pokemon that has a form change item, which prior to some patch
|
const soundName = reward.soundName;
|
||||||
// that changed form change modifiers worked, had previously set the `type` field to null.
|
|
||||||
// TODO: This is not the right place to check for this; it should ideally go in a session migrator.
|
if (playSound && !this.sound.get(soundName)) {
|
||||||
if (!modifier || !modifier.type) {
|
this.playSound(soundName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reward.shouldApply(params)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let success = false;
|
|
||||||
const soundName = modifier.type.soundName;
|
|
||||||
this.validateAchvs(ModifierAchv, modifier);
|
|
||||||
if (modifier instanceof ConsumableModifier) {
|
|
||||||
if (playSound && !this.sound.get(soundName)) {
|
|
||||||
this.playSound(soundName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modifier instanceof ConsumablePokemonModifier) {
|
reward.apply(params);
|
||||||
for (const p in this.party) {
|
return true;
|
||||||
const pokemon = this.party[p];
|
|
||||||
|
|
||||||
const args: unknown[] = [];
|
|
||||||
if (modifier instanceof PokemonHpRestoreModifier) {
|
|
||||||
if (!(modifier as PokemonHpRestoreModifier).fainted) {
|
|
||||||
const hpRestoreMultiplier = new NumberHolder(1);
|
|
||||||
this.applyPlayerItems(TrainerItemEffect.HEALING_BOOSTER, { numberHolder: hpRestoreMultiplier });
|
|
||||||
args.push(hpRestoreMultiplier.value);
|
|
||||||
} else {
|
|
||||||
args.push(1);
|
|
||||||
}
|
|
||||||
} else if (modifier instanceof FusePokemonModifier) {
|
|
||||||
args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon);
|
|
||||||
} else if (modifier instanceof RememberMoveModifier && !isNullOrUndefined(cost)) {
|
|
||||||
args.push(cost);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modifier.shouldApply(pokemon, ...args)) {
|
|
||||||
const result = modifier.apply(pokemon, ...args);
|
|
||||||
success ||= result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.party.map(p => p.updateInfo(instant));
|
|
||||||
} else {
|
|
||||||
const args = [this];
|
|
||||||
if (modifier.shouldApply(...args)) {
|
|
||||||
const result = modifier.apply(...args);
|
|
||||||
success ||= result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addHeldItem(heldItemId: HeldItemId, pokemon: Pokemon, amount = 1, playSound?: boolean, ignoreUpdate?: boolean) {
|
addHeldItem(heldItemId: HeldItemId, pokemon: Pokemon, amount = 1, playSound?: boolean, ignoreUpdate?: boolean) {
|
||||||
@ -2864,7 +2820,7 @@ export class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for (let c = 0; c < chances; c++) {
|
for (let c = 0; c < chances; c++) {
|
||||||
if (!randSeedInt(this.gameMode.getEnemyModifierChance(isBoss))) {
|
if (!randSeedInt(this.gameMode.getEnemyItemChance(isBoss))) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2887,7 +2843,7 @@ export class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all modifiers from enemy pokemon of {@linkcode PersistentModifier} type
|
* Removes all items from enemy pokemon and trainers
|
||||||
*/
|
*/
|
||||||
clearEnemyItems(): void {
|
clearEnemyItems(): void {
|
||||||
this.enemyTrainerItems.clearItems();
|
this.enemyTrainerItems.clearItems();
|
||||||
@ -2911,7 +2867,7 @@ export class BattleScene extends SceneBase {
|
|||||||
this.updateUIPositions();
|
this.updateUIPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
setModifiersVisible(visible: boolean) {
|
setItemsVisible(visible: boolean) {
|
||||||
[this.itemBar, this.enemyItemBar].map(m => m.setVisible(visible));
|
[this.itemBar, this.enemyItemBar].map(m => m.setVisible(visible));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,15 +10,14 @@ import type { MoveId } from "#enums/move-id";
|
|||||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||||
import type { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import type { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import type { PokeballType } from "#enums/pokeball";
|
import type { PokeballType } from "#enums/pokeball";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
|
||||||
import { SpeciesFormKey } from "#enums/species-form-key";
|
import { SpeciesFormKey } from "#enums/species-form-key";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { TrainerVariant } from "#enums/trainer-variant";
|
import { TrainerVariant } from "#enums/trainer-variant";
|
||||||
import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
import { Trainer } from "#field/trainer";
|
import { Trainer } from "#field/trainer";
|
||||||
|
import type { CustomRewardSettings } from "#items/reward-pool-utils";
|
||||||
import { TrainerItemEffect } from "#items/trainer-item";
|
import { TrainerItemEffect } from "#items/trainer-item";
|
||||||
import type { CustomModifierSettings } from "#modifiers/modifier-type";
|
|
||||||
import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
||||||
import i18next from "#plugins/i18n";
|
import i18next from "#plugins/i18n";
|
||||||
import { MusicPreference } from "#system/settings";
|
import { MusicPreference } from "#system/settings";
|
||||||
@ -481,7 +480,7 @@ export class FixedBattleConfig {
|
|||||||
public getTrainer: GetTrainerFunc;
|
public getTrainer: GetTrainerFunc;
|
||||||
public getEnemyParty: GetEnemyPartyFunc;
|
public getEnemyParty: GetEnemyPartyFunc;
|
||||||
public seedOffsetWaveIndex: number;
|
public seedOffsetWaveIndex: number;
|
||||||
public customModifierRewardSettings?: CustomModifierSettings;
|
public customRewardSettings?: CustomRewardSettings;
|
||||||
|
|
||||||
setBattleType(battleType: BattleType): FixedBattleConfig {
|
setBattleType(battleType: BattleType): FixedBattleConfig {
|
||||||
this.battleType = battleType;
|
this.battleType = battleType;
|
||||||
@ -508,8 +507,8 @@ export class FixedBattleConfig {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
setCustomModifierRewards(customModifierRewardSettings: CustomModifierSettings) {
|
setCustomRewards(customRewardSettings: CustomRewardSettings) {
|
||||||
this.customModifierRewardSettings = customModifierRewardSettings;
|
this.customRewardSettings = customRewardSettings;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { MoveId } from "#enums/move-id";
|
import { MoveId } from "#enums/move-id";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
|
|
||||||
@ -68591,324 +68591,324 @@ function transposeTmSpecies(): SpeciesTmMoves {
|
|||||||
export const speciesTmMoves: SpeciesTmMoves = transposeTmSpecies();
|
export const speciesTmMoves: SpeciesTmMoves = transposeTmSpecies();
|
||||||
|
|
||||||
interface TmPoolTiers {
|
interface TmPoolTiers {
|
||||||
[key: number]: RewardTier
|
[key: number]: RarityTier
|
||||||
}
|
}
|
||||||
|
|
||||||
export const tmPoolTiers: TmPoolTiers = {
|
export const tmPoolTiers: TmPoolTiers = {
|
||||||
[MoveId.MEGA_PUNCH]: RewardTier.GREAT,
|
[MoveId.MEGA_PUNCH]: RarityTier.GREAT,
|
||||||
[MoveId.PAY_DAY]: RewardTier.ULTRA,
|
[MoveId.PAY_DAY]: RarityTier.ULTRA,
|
||||||
[MoveId.FIRE_PUNCH]: RewardTier.GREAT,
|
[MoveId.FIRE_PUNCH]: RarityTier.GREAT,
|
||||||
[MoveId.ICE_PUNCH]: RewardTier.GREAT,
|
[MoveId.ICE_PUNCH]: RarityTier.GREAT,
|
||||||
[MoveId.THUNDER_PUNCH]: RewardTier.GREAT,
|
[MoveId.THUNDER_PUNCH]: RarityTier.GREAT,
|
||||||
[MoveId.SWORDS_DANCE]: RewardTier.COMMON,
|
[MoveId.SWORDS_DANCE]: RarityTier.COMMON,
|
||||||
[MoveId.CUT]: RewardTier.COMMON,
|
[MoveId.CUT]: RarityTier.COMMON,
|
||||||
[MoveId.FLY]: RewardTier.COMMON,
|
[MoveId.FLY]: RarityTier.COMMON,
|
||||||
[MoveId.MEGA_KICK]: RewardTier.GREAT,
|
[MoveId.MEGA_KICK]: RarityTier.GREAT,
|
||||||
[MoveId.BODY_SLAM]: RewardTier.GREAT,
|
[MoveId.BODY_SLAM]: RarityTier.GREAT,
|
||||||
[MoveId.TAKE_DOWN]: RewardTier.GREAT,
|
[MoveId.TAKE_DOWN]: RarityTier.GREAT,
|
||||||
[MoveId.DOUBLE_EDGE]: RewardTier.ULTRA,
|
[MoveId.DOUBLE_EDGE]: RarityTier.ULTRA,
|
||||||
[MoveId.PIN_MISSILE]: RewardTier.COMMON,
|
[MoveId.PIN_MISSILE]: RarityTier.COMMON,
|
||||||
[MoveId.ROAR]: RewardTier.COMMON,
|
[MoveId.ROAR]: RarityTier.COMMON,
|
||||||
[MoveId.FLAMETHROWER]: RewardTier.ULTRA,
|
[MoveId.FLAMETHROWER]: RarityTier.ULTRA,
|
||||||
[MoveId.HYDRO_PUMP]: RewardTier.ULTRA,
|
[MoveId.HYDRO_PUMP]: RarityTier.ULTRA,
|
||||||
[MoveId.SURF]: RewardTier.ULTRA,
|
[MoveId.SURF]: RarityTier.ULTRA,
|
||||||
[MoveId.ICE_BEAM]: RewardTier.ULTRA,
|
[MoveId.ICE_BEAM]: RarityTier.ULTRA,
|
||||||
[MoveId.BLIZZARD]: RewardTier.ULTRA,
|
[MoveId.BLIZZARD]: RarityTier.ULTRA,
|
||||||
[MoveId.PSYBEAM]: RewardTier.GREAT,
|
[MoveId.PSYBEAM]: RarityTier.GREAT,
|
||||||
[MoveId.HYPER_BEAM]: RewardTier.ULTRA,
|
[MoveId.HYPER_BEAM]: RarityTier.ULTRA,
|
||||||
[MoveId.LOW_KICK]: RewardTier.COMMON,
|
[MoveId.LOW_KICK]: RarityTier.COMMON,
|
||||||
[MoveId.COUNTER]: RewardTier.COMMON,
|
[MoveId.COUNTER]: RarityTier.COMMON,
|
||||||
[MoveId.STRENGTH]: RewardTier.GREAT,
|
[MoveId.STRENGTH]: RarityTier.GREAT,
|
||||||
[MoveId.SOLAR_BEAM]: RewardTier.ULTRA,
|
[MoveId.SOLAR_BEAM]: RarityTier.ULTRA,
|
||||||
[MoveId.FIRE_SPIN]: RewardTier.COMMON,
|
[MoveId.FIRE_SPIN]: RarityTier.COMMON,
|
||||||
[MoveId.THUNDERBOLT]: RewardTier.ULTRA,
|
[MoveId.THUNDERBOLT]: RarityTier.ULTRA,
|
||||||
[MoveId.THUNDER_WAVE]: RewardTier.COMMON,
|
[MoveId.THUNDER_WAVE]: RarityTier.COMMON,
|
||||||
[MoveId.THUNDER]: RewardTier.ULTRA,
|
[MoveId.THUNDER]: RarityTier.ULTRA,
|
||||||
[MoveId.EARTHQUAKE]: RewardTier.ULTRA,
|
[MoveId.EARTHQUAKE]: RarityTier.ULTRA,
|
||||||
[MoveId.DIG]: RewardTier.GREAT,
|
[MoveId.DIG]: RarityTier.GREAT,
|
||||||
[MoveId.TOXIC]: RewardTier.GREAT,
|
[MoveId.TOXIC]: RarityTier.GREAT,
|
||||||
[MoveId.PSYCHIC]: RewardTier.ULTRA,
|
[MoveId.PSYCHIC]: RarityTier.ULTRA,
|
||||||
[MoveId.AGILITY]: RewardTier.COMMON,
|
[MoveId.AGILITY]: RarityTier.COMMON,
|
||||||
[MoveId.NIGHT_SHADE]: RewardTier.COMMON,
|
[MoveId.NIGHT_SHADE]: RarityTier.COMMON,
|
||||||
[MoveId.SCREECH]: RewardTier.COMMON,
|
[MoveId.SCREECH]: RarityTier.COMMON,
|
||||||
[MoveId.DOUBLE_TEAM]: RewardTier.COMMON,
|
[MoveId.DOUBLE_TEAM]: RarityTier.COMMON,
|
||||||
[MoveId.CONFUSE_RAY]: RewardTier.COMMON,
|
[MoveId.CONFUSE_RAY]: RarityTier.COMMON,
|
||||||
[MoveId.LIGHT_SCREEN]: RewardTier.COMMON,
|
[MoveId.LIGHT_SCREEN]: RarityTier.COMMON,
|
||||||
[MoveId.HAZE]: RewardTier.COMMON,
|
[MoveId.HAZE]: RarityTier.COMMON,
|
||||||
[MoveId.REFLECT]: RewardTier.COMMON,
|
[MoveId.REFLECT]: RarityTier.COMMON,
|
||||||
[MoveId.FOCUS_ENERGY]: RewardTier.COMMON,
|
[MoveId.FOCUS_ENERGY]: RarityTier.COMMON,
|
||||||
[MoveId.METRONOME]: RewardTier.COMMON,
|
[MoveId.METRONOME]: RarityTier.COMMON,
|
||||||
[MoveId.SELF_DESTRUCT]: RewardTier.GREAT,
|
[MoveId.SELF_DESTRUCT]: RarityTier.GREAT,
|
||||||
[MoveId.FIRE_BLAST]: RewardTier.ULTRA,
|
[MoveId.FIRE_BLAST]: RarityTier.ULTRA,
|
||||||
[MoveId.WATERFALL]: RewardTier.GREAT,
|
[MoveId.WATERFALL]: RarityTier.GREAT,
|
||||||
[MoveId.SWIFT]: RewardTier.COMMON,
|
[MoveId.SWIFT]: RarityTier.COMMON,
|
||||||
[MoveId.AMNESIA]: RewardTier.COMMON,
|
[MoveId.AMNESIA]: RarityTier.COMMON,
|
||||||
[MoveId.DREAM_EATER]: RewardTier.GREAT,
|
[MoveId.DREAM_EATER]: RarityTier.GREAT,
|
||||||
[MoveId.LEECH_LIFE]: RewardTier.ULTRA,
|
[MoveId.LEECH_LIFE]: RarityTier.ULTRA,
|
||||||
[MoveId.FLASH]: RewardTier.COMMON,
|
[MoveId.FLASH]: RarityTier.COMMON,
|
||||||
[MoveId.EXPLOSION]: RewardTier.GREAT,
|
[MoveId.EXPLOSION]: RarityTier.GREAT,
|
||||||
[MoveId.REST]: RewardTier.COMMON,
|
[MoveId.REST]: RarityTier.COMMON,
|
||||||
[MoveId.ROCK_SLIDE]: RewardTier.GREAT,
|
[MoveId.ROCK_SLIDE]: RarityTier.GREAT,
|
||||||
[MoveId.TRI_ATTACK]: RewardTier.ULTRA,
|
[MoveId.TRI_ATTACK]: RarityTier.ULTRA,
|
||||||
[MoveId.SUPER_FANG]: RewardTier.COMMON,
|
[MoveId.SUPER_FANG]: RarityTier.COMMON,
|
||||||
[MoveId.SUBSTITUTE]: RewardTier.COMMON,
|
[MoveId.SUBSTITUTE]: RarityTier.COMMON,
|
||||||
[MoveId.THIEF]: RewardTier.GREAT,
|
[MoveId.THIEF]: RarityTier.GREAT,
|
||||||
[MoveId.SNORE]: RewardTier.COMMON,
|
[MoveId.SNORE]: RarityTier.COMMON,
|
||||||
[MoveId.CURSE]: RewardTier.COMMON,
|
[MoveId.CURSE]: RarityTier.COMMON,
|
||||||
[MoveId.REVERSAL]: RewardTier.COMMON,
|
[MoveId.REVERSAL]: RarityTier.COMMON,
|
||||||
[MoveId.SPITE]: RewardTier.COMMON,
|
[MoveId.SPITE]: RarityTier.COMMON,
|
||||||
[MoveId.PROTECT]: RewardTier.COMMON,
|
[MoveId.PROTECT]: RarityTier.COMMON,
|
||||||
[MoveId.SCARY_FACE]: RewardTier.COMMON,
|
[MoveId.SCARY_FACE]: RarityTier.COMMON,
|
||||||
[MoveId.SLUDGE_BOMB]: RewardTier.GREAT,
|
[MoveId.SLUDGE_BOMB]: RarityTier.GREAT,
|
||||||
[MoveId.MUD_SLAP]: RewardTier.COMMON,
|
[MoveId.MUD_SLAP]: RarityTier.COMMON,
|
||||||
[MoveId.SPIKES]: RewardTier.COMMON,
|
[MoveId.SPIKES]: RarityTier.COMMON,
|
||||||
[MoveId.ICY_WIND]: RewardTier.GREAT,
|
[MoveId.ICY_WIND]: RarityTier.GREAT,
|
||||||
[MoveId.OUTRAGE]: RewardTier.ULTRA,
|
[MoveId.OUTRAGE]: RarityTier.ULTRA,
|
||||||
[MoveId.SANDSTORM]: RewardTier.COMMON,
|
[MoveId.SANDSTORM]: RarityTier.COMMON,
|
||||||
[MoveId.GIGA_DRAIN]: RewardTier.ULTRA,
|
[MoveId.GIGA_DRAIN]: RarityTier.ULTRA,
|
||||||
[MoveId.ENDURE]: RewardTier.COMMON,
|
[MoveId.ENDURE]: RarityTier.COMMON,
|
||||||
[MoveId.CHARM]: RewardTier.COMMON,
|
[MoveId.CHARM]: RarityTier.COMMON,
|
||||||
[MoveId.FALSE_SWIPE]: RewardTier.COMMON,
|
[MoveId.FALSE_SWIPE]: RarityTier.COMMON,
|
||||||
[MoveId.SWAGGER]: RewardTier.COMMON,
|
[MoveId.SWAGGER]: RarityTier.COMMON,
|
||||||
[MoveId.STEEL_WING]: RewardTier.GREAT,
|
[MoveId.STEEL_WING]: RarityTier.GREAT,
|
||||||
[MoveId.ATTRACT]: RewardTier.COMMON,
|
[MoveId.ATTRACT]: RarityTier.COMMON,
|
||||||
[MoveId.SLEEP_TALK]: RewardTier.COMMON,
|
[MoveId.SLEEP_TALK]: RarityTier.COMMON,
|
||||||
[MoveId.HEAL_BELL]: RewardTier.COMMON,
|
[MoveId.HEAL_BELL]: RarityTier.COMMON,
|
||||||
[MoveId.RETURN]: RewardTier.ULTRA,
|
[MoveId.RETURN]: RarityTier.ULTRA,
|
||||||
[MoveId.FRUSTRATION]: RewardTier.COMMON,
|
[MoveId.FRUSTRATION]: RarityTier.COMMON,
|
||||||
[MoveId.SAFEGUARD]: RewardTier.COMMON,
|
[MoveId.SAFEGUARD]: RarityTier.COMMON,
|
||||||
[MoveId.PAIN_SPLIT]: RewardTier.COMMON,
|
[MoveId.PAIN_SPLIT]: RarityTier.COMMON,
|
||||||
[MoveId.MEGAHORN]: RewardTier.ULTRA,
|
[MoveId.MEGAHORN]: RarityTier.ULTRA,
|
||||||
[MoveId.BATON_PASS]: RewardTier.COMMON,
|
[MoveId.BATON_PASS]: RarityTier.COMMON,
|
||||||
[MoveId.ENCORE]: RewardTier.COMMON,
|
[MoveId.ENCORE]: RarityTier.COMMON,
|
||||||
[MoveId.IRON_TAIL]: RewardTier.GREAT,
|
[MoveId.IRON_TAIL]: RarityTier.GREAT,
|
||||||
[MoveId.METAL_CLAW]: RewardTier.COMMON,
|
[MoveId.METAL_CLAW]: RarityTier.COMMON,
|
||||||
[MoveId.SYNTHESIS]: RewardTier.GREAT,
|
[MoveId.SYNTHESIS]: RarityTier.GREAT,
|
||||||
[MoveId.HIDDEN_POWER]: RewardTier.GREAT,
|
[MoveId.HIDDEN_POWER]: RarityTier.GREAT,
|
||||||
[MoveId.RAIN_DANCE]: RewardTier.COMMON,
|
[MoveId.RAIN_DANCE]: RarityTier.COMMON,
|
||||||
[MoveId.SUNNY_DAY]: RewardTier.COMMON,
|
[MoveId.SUNNY_DAY]: RarityTier.COMMON,
|
||||||
[MoveId.CRUNCH]: RewardTier.GREAT,
|
[MoveId.CRUNCH]: RarityTier.GREAT,
|
||||||
[MoveId.PSYCH_UP]: RewardTier.COMMON,
|
[MoveId.PSYCH_UP]: RarityTier.COMMON,
|
||||||
[MoveId.SHADOW_BALL]: RewardTier.ULTRA,
|
[MoveId.SHADOW_BALL]: RarityTier.ULTRA,
|
||||||
[MoveId.FUTURE_SIGHT]: RewardTier.GREAT,
|
[MoveId.FUTURE_SIGHT]: RarityTier.GREAT,
|
||||||
[MoveId.ROCK_SMASH]: RewardTier.COMMON,
|
[MoveId.ROCK_SMASH]: RarityTier.COMMON,
|
||||||
[MoveId.WHIRLPOOL]: RewardTier.COMMON,
|
[MoveId.WHIRLPOOL]: RarityTier.COMMON,
|
||||||
[MoveId.BEAT_UP]: RewardTier.COMMON,
|
[MoveId.BEAT_UP]: RarityTier.COMMON,
|
||||||
[MoveId.UPROAR]: RewardTier.GREAT,
|
[MoveId.UPROAR]: RarityTier.GREAT,
|
||||||
[MoveId.HEAT_WAVE]: RewardTier.ULTRA,
|
[MoveId.HEAT_WAVE]: RarityTier.ULTRA,
|
||||||
[MoveId.HAIL]: RewardTier.COMMON,
|
[MoveId.HAIL]: RarityTier.COMMON,
|
||||||
[MoveId.TORMENT]: RewardTier.COMMON,
|
[MoveId.TORMENT]: RarityTier.COMMON,
|
||||||
[MoveId.WILL_O_WISP]: RewardTier.COMMON,
|
[MoveId.WILL_O_WISP]: RarityTier.COMMON,
|
||||||
[MoveId.FACADE]: RewardTier.GREAT,
|
[MoveId.FACADE]: RarityTier.GREAT,
|
||||||
[MoveId.FOCUS_PUNCH]: RewardTier.COMMON,
|
[MoveId.FOCUS_PUNCH]: RarityTier.COMMON,
|
||||||
[MoveId.NATURE_POWER]: RewardTier.COMMON,
|
[MoveId.NATURE_POWER]: RarityTier.COMMON,
|
||||||
[MoveId.CHARGE]: RewardTier.COMMON,
|
[MoveId.CHARGE]: RarityTier.COMMON,
|
||||||
[MoveId.TAUNT]: RewardTier.COMMON,
|
[MoveId.TAUNT]: RarityTier.COMMON,
|
||||||
[MoveId.HELPING_HAND]: RewardTier.COMMON,
|
[MoveId.HELPING_HAND]: RarityTier.COMMON,
|
||||||
[MoveId.TRICK]: RewardTier.COMMON,
|
[MoveId.TRICK]: RarityTier.COMMON,
|
||||||
[MoveId.SUPERPOWER]: RewardTier.ULTRA,
|
[MoveId.SUPERPOWER]: RarityTier.ULTRA,
|
||||||
[MoveId.RECYCLE]: RewardTier.COMMON,
|
[MoveId.RECYCLE]: RarityTier.COMMON,
|
||||||
[MoveId.REVENGE]: RewardTier.GREAT,
|
[MoveId.REVENGE]: RarityTier.GREAT,
|
||||||
[MoveId.BRICK_BREAK]: RewardTier.GREAT,
|
[MoveId.BRICK_BREAK]: RarityTier.GREAT,
|
||||||
[MoveId.KNOCK_OFF]: RewardTier.GREAT,
|
[MoveId.KNOCK_OFF]: RarityTier.GREAT,
|
||||||
[MoveId.ENDEAVOR]: RewardTier.COMMON,
|
[MoveId.ENDEAVOR]: RarityTier.COMMON,
|
||||||
[MoveId.SKILL_SWAP]: RewardTier.COMMON,
|
[MoveId.SKILL_SWAP]: RarityTier.COMMON,
|
||||||
[MoveId.IMPRISON]: RewardTier.COMMON,
|
[MoveId.IMPRISON]: RarityTier.COMMON,
|
||||||
[MoveId.SECRET_POWER]: RewardTier.COMMON,
|
[MoveId.SECRET_POWER]: RarityTier.COMMON,
|
||||||
[MoveId.DIVE]: RewardTier.GREAT,
|
[MoveId.DIVE]: RarityTier.GREAT,
|
||||||
[MoveId.FEATHER_DANCE]: RewardTier.COMMON,
|
[MoveId.FEATHER_DANCE]: RarityTier.COMMON,
|
||||||
[MoveId.BLAZE_KICK]: RewardTier.GREAT,
|
[MoveId.BLAZE_KICK]: RarityTier.GREAT,
|
||||||
[MoveId.HYPER_VOICE]: RewardTier.ULTRA,
|
[MoveId.HYPER_VOICE]: RarityTier.ULTRA,
|
||||||
[MoveId.BLAST_BURN]: RewardTier.ULTRA,
|
[MoveId.BLAST_BURN]: RarityTier.ULTRA,
|
||||||
[MoveId.HYDRO_CANNON]: RewardTier.ULTRA,
|
[MoveId.HYDRO_CANNON]: RarityTier.ULTRA,
|
||||||
[MoveId.WEATHER_BALL]: RewardTier.COMMON,
|
[MoveId.WEATHER_BALL]: RarityTier.COMMON,
|
||||||
[MoveId.FAKE_TEARS]: RewardTier.COMMON,
|
[MoveId.FAKE_TEARS]: RarityTier.COMMON,
|
||||||
[MoveId.AIR_CUTTER]: RewardTier.GREAT,
|
[MoveId.AIR_CUTTER]: RarityTier.GREAT,
|
||||||
[MoveId.OVERHEAT]: RewardTier.ULTRA,
|
[MoveId.OVERHEAT]: RarityTier.ULTRA,
|
||||||
[MoveId.ROCK_TOMB]: RewardTier.GREAT,
|
[MoveId.ROCK_TOMB]: RarityTier.GREAT,
|
||||||
[MoveId.METAL_SOUND]: RewardTier.COMMON,
|
[MoveId.METAL_SOUND]: RarityTier.COMMON,
|
||||||
[MoveId.COSMIC_POWER]: RewardTier.COMMON,
|
[MoveId.COSMIC_POWER]: RarityTier.COMMON,
|
||||||
[MoveId.SIGNAL_BEAM]: RewardTier.GREAT,
|
[MoveId.SIGNAL_BEAM]: RarityTier.GREAT,
|
||||||
[MoveId.SAND_TOMB]: RewardTier.COMMON,
|
[MoveId.SAND_TOMB]: RarityTier.COMMON,
|
||||||
[MoveId.MUDDY_WATER]: RewardTier.GREAT,
|
[MoveId.MUDDY_WATER]: RarityTier.GREAT,
|
||||||
[MoveId.BULLET_SEED]: RewardTier.GREAT,
|
[MoveId.BULLET_SEED]: RarityTier.GREAT,
|
||||||
[MoveId.AERIAL_ACE]: RewardTier.GREAT,
|
[MoveId.AERIAL_ACE]: RarityTier.GREAT,
|
||||||
[MoveId.ICICLE_SPEAR]: RewardTier.GREAT,
|
[MoveId.ICICLE_SPEAR]: RarityTier.GREAT,
|
||||||
[MoveId.IRON_DEFENSE]: RewardTier.GREAT,
|
[MoveId.IRON_DEFENSE]: RarityTier.GREAT,
|
||||||
[MoveId.DRAGON_CLAW]: RewardTier.ULTRA,
|
[MoveId.DRAGON_CLAW]: RarityTier.ULTRA,
|
||||||
[MoveId.FRENZY_PLANT]: RewardTier.ULTRA,
|
[MoveId.FRENZY_PLANT]: RarityTier.ULTRA,
|
||||||
[MoveId.BULK_UP]: RewardTier.COMMON,
|
[MoveId.BULK_UP]: RarityTier.COMMON,
|
||||||
[MoveId.BOUNCE]: RewardTier.GREAT,
|
[MoveId.BOUNCE]: RarityTier.GREAT,
|
||||||
[MoveId.MUD_SHOT]: RewardTier.GREAT,
|
[MoveId.MUD_SHOT]: RarityTier.GREAT,
|
||||||
[MoveId.POISON_TAIL]: RewardTier.GREAT,
|
[MoveId.POISON_TAIL]: RarityTier.GREAT,
|
||||||
[MoveId.COVET]: RewardTier.GREAT,
|
[MoveId.COVET]: RarityTier.GREAT,
|
||||||
[MoveId.MAGICAL_LEAF]: RewardTier.GREAT,
|
[MoveId.MAGICAL_LEAF]: RarityTier.GREAT,
|
||||||
[MoveId.CALM_MIND]: RewardTier.GREAT,
|
[MoveId.CALM_MIND]: RarityTier.GREAT,
|
||||||
[MoveId.LEAF_BLADE]: RewardTier.ULTRA,
|
[MoveId.LEAF_BLADE]: RarityTier.ULTRA,
|
||||||
[MoveId.DRAGON_DANCE]: RewardTier.GREAT,
|
[MoveId.DRAGON_DANCE]: RarityTier.GREAT,
|
||||||
[MoveId.ROCK_BLAST]: RewardTier.GREAT,
|
[MoveId.ROCK_BLAST]: RarityTier.GREAT,
|
||||||
[MoveId.WATER_PULSE]: RewardTier.GREAT,
|
[MoveId.WATER_PULSE]: RarityTier.GREAT,
|
||||||
[MoveId.ROOST]: RewardTier.GREAT,
|
[MoveId.ROOST]: RarityTier.GREAT,
|
||||||
[MoveId.GRAVITY]: RewardTier.COMMON,
|
[MoveId.GRAVITY]: RarityTier.COMMON,
|
||||||
[MoveId.GYRO_BALL]: RewardTier.COMMON,
|
[MoveId.GYRO_BALL]: RarityTier.COMMON,
|
||||||
[MoveId.BRINE]: RewardTier.GREAT,
|
[MoveId.BRINE]: RarityTier.GREAT,
|
||||||
[MoveId.PLUCK]: RewardTier.GREAT,
|
[MoveId.PLUCK]: RarityTier.GREAT,
|
||||||
[MoveId.TAILWIND]: RewardTier.GREAT,
|
[MoveId.TAILWIND]: RarityTier.GREAT,
|
||||||
[MoveId.U_TURN]: RewardTier.GREAT,
|
[MoveId.U_TURN]: RarityTier.GREAT,
|
||||||
[MoveId.CLOSE_COMBAT]: RewardTier.ULTRA,
|
[MoveId.CLOSE_COMBAT]: RarityTier.ULTRA,
|
||||||
[MoveId.PAYBACK]: RewardTier.COMMON,
|
[MoveId.PAYBACK]: RarityTier.COMMON,
|
||||||
[MoveId.ASSURANCE]: RewardTier.COMMON,
|
[MoveId.ASSURANCE]: RarityTier.COMMON,
|
||||||
[MoveId.EMBARGO]: RewardTier.COMMON,
|
[MoveId.EMBARGO]: RarityTier.COMMON,
|
||||||
[MoveId.FLING]: RewardTier.COMMON,
|
[MoveId.FLING]: RarityTier.COMMON,
|
||||||
[MoveId.GASTRO_ACID]: RewardTier.GREAT,
|
[MoveId.GASTRO_ACID]: RarityTier.GREAT,
|
||||||
[MoveId.POWER_SWAP]: RewardTier.COMMON,
|
[MoveId.POWER_SWAP]: RarityTier.COMMON,
|
||||||
[MoveId.GUARD_SWAP]: RewardTier.COMMON,
|
[MoveId.GUARD_SWAP]: RarityTier.COMMON,
|
||||||
[MoveId.WORRY_SEED]: RewardTier.GREAT,
|
[MoveId.WORRY_SEED]: RarityTier.GREAT,
|
||||||
[MoveId.TOXIC_SPIKES]: RewardTier.GREAT,
|
[MoveId.TOXIC_SPIKES]: RarityTier.GREAT,
|
||||||
[MoveId.FLARE_BLITZ]: RewardTier.ULTRA,
|
[MoveId.FLARE_BLITZ]: RarityTier.ULTRA,
|
||||||
[MoveId.AURA_SPHERE]: RewardTier.GREAT,
|
[MoveId.AURA_SPHERE]: RarityTier.GREAT,
|
||||||
[MoveId.ROCK_POLISH]: RewardTier.COMMON,
|
[MoveId.ROCK_POLISH]: RarityTier.COMMON,
|
||||||
[MoveId.POISON_JAB]: RewardTier.GREAT,
|
[MoveId.POISON_JAB]: RarityTier.GREAT,
|
||||||
[MoveId.DARK_PULSE]: RewardTier.GREAT,
|
[MoveId.DARK_PULSE]: RarityTier.GREAT,
|
||||||
[MoveId.AQUA_TAIL]: RewardTier.GREAT,
|
[MoveId.AQUA_TAIL]: RarityTier.GREAT,
|
||||||
[MoveId.SEED_BOMB]: RewardTier.GREAT,
|
[MoveId.SEED_BOMB]: RarityTier.GREAT,
|
||||||
[MoveId.AIR_SLASH]: RewardTier.GREAT,
|
[MoveId.AIR_SLASH]: RarityTier.GREAT,
|
||||||
[MoveId.X_SCISSOR]: RewardTier.GREAT,
|
[MoveId.X_SCISSOR]: RarityTier.GREAT,
|
||||||
[MoveId.BUG_BUZZ]: RewardTier.GREAT,
|
[MoveId.BUG_BUZZ]: RarityTier.GREAT,
|
||||||
[MoveId.DRAGON_PULSE]: RewardTier.GREAT,
|
[MoveId.DRAGON_PULSE]: RarityTier.GREAT,
|
||||||
[MoveId.POWER_GEM]: RewardTier.GREAT,
|
[MoveId.POWER_GEM]: RarityTier.GREAT,
|
||||||
[MoveId.DRAIN_PUNCH]: RewardTier.GREAT,
|
[MoveId.DRAIN_PUNCH]: RarityTier.GREAT,
|
||||||
[MoveId.VACUUM_WAVE]: RewardTier.COMMON,
|
[MoveId.VACUUM_WAVE]: RarityTier.COMMON,
|
||||||
[MoveId.FOCUS_BLAST]: RewardTier.GREAT,
|
[MoveId.FOCUS_BLAST]: RarityTier.GREAT,
|
||||||
[MoveId.ENERGY_BALL]: RewardTier.GREAT,
|
[MoveId.ENERGY_BALL]: RarityTier.GREAT,
|
||||||
[MoveId.BRAVE_BIRD]: RewardTier.ULTRA,
|
[MoveId.BRAVE_BIRD]: RarityTier.ULTRA,
|
||||||
[MoveId.EARTH_POWER]: RewardTier.ULTRA,
|
[MoveId.EARTH_POWER]: RarityTier.ULTRA,
|
||||||
[MoveId.GIGA_IMPACT]: RewardTier.GREAT,
|
[MoveId.GIGA_IMPACT]: RarityTier.GREAT,
|
||||||
[MoveId.NASTY_PLOT]: RewardTier.COMMON,
|
[MoveId.NASTY_PLOT]: RarityTier.COMMON,
|
||||||
[MoveId.AVALANCHE]: RewardTier.GREAT,
|
[MoveId.AVALANCHE]: RarityTier.GREAT,
|
||||||
[MoveId.SHADOW_CLAW]: RewardTier.GREAT,
|
[MoveId.SHADOW_CLAW]: RarityTier.GREAT,
|
||||||
[MoveId.THUNDER_FANG]: RewardTier.GREAT,
|
[MoveId.THUNDER_FANG]: RarityTier.GREAT,
|
||||||
[MoveId.ICE_FANG]: RewardTier.GREAT,
|
[MoveId.ICE_FANG]: RarityTier.GREAT,
|
||||||
[MoveId.FIRE_FANG]: RewardTier.GREAT,
|
[MoveId.FIRE_FANG]: RarityTier.GREAT,
|
||||||
[MoveId.PSYCHO_CUT]: RewardTier.GREAT,
|
[MoveId.PSYCHO_CUT]: RarityTier.GREAT,
|
||||||
[MoveId.ZEN_HEADBUTT]: RewardTier.GREAT,
|
[MoveId.ZEN_HEADBUTT]: RarityTier.GREAT,
|
||||||
[MoveId.FLASH_CANNON]: RewardTier.GREAT,
|
[MoveId.FLASH_CANNON]: RarityTier.GREAT,
|
||||||
[MoveId.ROCK_CLIMB]: RewardTier.GREAT,
|
[MoveId.ROCK_CLIMB]: RarityTier.GREAT,
|
||||||
[MoveId.DEFOG]: RewardTier.COMMON,
|
[MoveId.DEFOG]: RarityTier.COMMON,
|
||||||
[MoveId.TRICK_ROOM]: RewardTier.COMMON,
|
[MoveId.TRICK_ROOM]: RarityTier.COMMON,
|
||||||
[MoveId.DRACO_METEOR]: RewardTier.ULTRA,
|
[MoveId.DRACO_METEOR]: RarityTier.ULTRA,
|
||||||
[MoveId.LEAF_STORM]: RewardTier.ULTRA,
|
[MoveId.LEAF_STORM]: RarityTier.ULTRA,
|
||||||
[MoveId.POWER_WHIP]: RewardTier.ULTRA,
|
[MoveId.POWER_WHIP]: RarityTier.ULTRA,
|
||||||
[MoveId.CROSS_POISON]: RewardTier.GREAT,
|
[MoveId.CROSS_POISON]: RarityTier.GREAT,
|
||||||
[MoveId.GUNK_SHOT]: RewardTier.ULTRA,
|
[MoveId.GUNK_SHOT]: RarityTier.ULTRA,
|
||||||
[MoveId.IRON_HEAD]: RewardTier.GREAT,
|
[MoveId.IRON_HEAD]: RarityTier.GREAT,
|
||||||
[MoveId.STONE_EDGE]: RewardTier.ULTRA,
|
[MoveId.STONE_EDGE]: RarityTier.ULTRA,
|
||||||
[MoveId.STEALTH_ROCK]: RewardTier.COMMON,
|
[MoveId.STEALTH_ROCK]: RarityTier.COMMON,
|
||||||
[MoveId.GRASS_KNOT]: RewardTier.ULTRA,
|
[MoveId.GRASS_KNOT]: RarityTier.ULTRA,
|
||||||
[MoveId.BUG_BITE]: RewardTier.GREAT,
|
[MoveId.BUG_BITE]: RarityTier.GREAT,
|
||||||
[MoveId.CHARGE_BEAM]: RewardTier.GREAT,
|
[MoveId.CHARGE_BEAM]: RarityTier.GREAT,
|
||||||
[MoveId.HONE_CLAWS]: RewardTier.COMMON,
|
[MoveId.HONE_CLAWS]: RarityTier.COMMON,
|
||||||
[MoveId.WONDER_ROOM]: RewardTier.COMMON,
|
[MoveId.WONDER_ROOM]: RarityTier.COMMON,
|
||||||
[MoveId.PSYSHOCK]: RewardTier.GREAT,
|
[MoveId.PSYSHOCK]: RarityTier.GREAT,
|
||||||
[MoveId.VENOSHOCK]: RewardTier.GREAT,
|
[MoveId.VENOSHOCK]: RarityTier.GREAT,
|
||||||
[MoveId.MAGIC_ROOM]: RewardTier.COMMON,
|
[MoveId.MAGIC_ROOM]: RarityTier.COMMON,
|
||||||
[MoveId.SMACK_DOWN]: RewardTier.COMMON,
|
[MoveId.SMACK_DOWN]: RarityTier.COMMON,
|
||||||
[MoveId.SLUDGE_WAVE]: RewardTier.GREAT,
|
[MoveId.SLUDGE_WAVE]: RarityTier.GREAT,
|
||||||
[MoveId.HEAVY_SLAM]: RewardTier.GREAT,
|
[MoveId.HEAVY_SLAM]: RarityTier.GREAT,
|
||||||
[MoveId.ELECTRO_BALL]: RewardTier.GREAT,
|
[MoveId.ELECTRO_BALL]: RarityTier.GREAT,
|
||||||
[MoveId.FLAME_CHARGE]: RewardTier.GREAT,
|
[MoveId.FLAME_CHARGE]: RarityTier.GREAT,
|
||||||
[MoveId.LOW_SWEEP]: RewardTier.GREAT,
|
[MoveId.LOW_SWEEP]: RarityTier.GREAT,
|
||||||
[MoveId.ACID_SPRAY]: RewardTier.COMMON,
|
[MoveId.ACID_SPRAY]: RarityTier.COMMON,
|
||||||
[MoveId.FOUL_PLAY]: RewardTier.ULTRA,
|
[MoveId.FOUL_PLAY]: RarityTier.ULTRA,
|
||||||
[MoveId.ROUND]: RewardTier.COMMON,
|
[MoveId.ROUND]: RarityTier.COMMON,
|
||||||
[MoveId.ECHOED_VOICE]: RewardTier.COMMON,
|
[MoveId.ECHOED_VOICE]: RarityTier.COMMON,
|
||||||
[MoveId.STORED_POWER]: RewardTier.COMMON,
|
[MoveId.STORED_POWER]: RarityTier.COMMON,
|
||||||
[MoveId.ALLY_SWITCH]: RewardTier.COMMON,
|
[MoveId.ALLY_SWITCH]: RarityTier.COMMON,
|
||||||
[MoveId.SCALD]: RewardTier.GREAT,
|
[MoveId.SCALD]: RarityTier.GREAT,
|
||||||
[MoveId.HEX]: RewardTier.GREAT,
|
[MoveId.HEX]: RarityTier.GREAT,
|
||||||
[MoveId.SKY_DROP]: RewardTier.GREAT,
|
[MoveId.SKY_DROP]: RarityTier.GREAT,
|
||||||
[MoveId.INCINERATE]: RewardTier.GREAT,
|
[MoveId.INCINERATE]: RarityTier.GREAT,
|
||||||
[MoveId.QUASH]: RewardTier.COMMON,
|
[MoveId.QUASH]: RarityTier.COMMON,
|
||||||
[MoveId.ACROBATICS]: RewardTier.GREAT,
|
[MoveId.ACROBATICS]: RarityTier.GREAT,
|
||||||
[MoveId.RETALIATE]: RewardTier.GREAT,
|
[MoveId.RETALIATE]: RarityTier.GREAT,
|
||||||
[MoveId.WATER_PLEDGE]: RewardTier.GREAT,
|
[MoveId.WATER_PLEDGE]: RarityTier.GREAT,
|
||||||
[MoveId.FIRE_PLEDGE]: RewardTier.GREAT,
|
[MoveId.FIRE_PLEDGE]: RarityTier.GREAT,
|
||||||
[MoveId.GRASS_PLEDGE]: RewardTier.GREAT,
|
[MoveId.GRASS_PLEDGE]: RarityTier.GREAT,
|
||||||
[MoveId.VOLT_SWITCH]: RewardTier.GREAT,
|
[MoveId.VOLT_SWITCH]: RarityTier.GREAT,
|
||||||
[MoveId.STRUGGLE_BUG]: RewardTier.COMMON,
|
[MoveId.STRUGGLE_BUG]: RarityTier.COMMON,
|
||||||
[MoveId.BULLDOZE]: RewardTier.GREAT,
|
[MoveId.BULLDOZE]: RarityTier.GREAT,
|
||||||
[MoveId.FROST_BREATH]: RewardTier.GREAT,
|
[MoveId.FROST_BREATH]: RarityTier.GREAT,
|
||||||
[MoveId.DRAGON_TAIL]: RewardTier.GREAT,
|
[MoveId.DRAGON_TAIL]: RarityTier.GREAT,
|
||||||
[MoveId.WORK_UP]: RewardTier.COMMON,
|
[MoveId.WORK_UP]: RarityTier.COMMON,
|
||||||
[MoveId.ELECTROWEB]: RewardTier.GREAT,
|
[MoveId.ELECTROWEB]: RarityTier.GREAT,
|
||||||
[MoveId.WILD_CHARGE]: RewardTier.GREAT,
|
[MoveId.WILD_CHARGE]: RarityTier.GREAT,
|
||||||
[MoveId.DRILL_RUN]: RewardTier.GREAT,
|
[MoveId.DRILL_RUN]: RarityTier.GREAT,
|
||||||
[MoveId.RAZOR_SHELL]: RewardTier.GREAT,
|
[MoveId.RAZOR_SHELL]: RarityTier.GREAT,
|
||||||
[MoveId.HEAT_CRASH]: RewardTier.GREAT,
|
[MoveId.HEAT_CRASH]: RarityTier.GREAT,
|
||||||
[MoveId.TAIL_SLAP]: RewardTier.GREAT,
|
[MoveId.TAIL_SLAP]: RarityTier.GREAT,
|
||||||
[MoveId.HURRICANE]: RewardTier.ULTRA,
|
[MoveId.HURRICANE]: RarityTier.ULTRA,
|
||||||
[MoveId.SNARL]: RewardTier.COMMON,
|
[MoveId.SNARL]: RarityTier.COMMON,
|
||||||
[MoveId.PHANTOM_FORCE]: RewardTier.ULTRA,
|
[MoveId.PHANTOM_FORCE]: RarityTier.ULTRA,
|
||||||
[MoveId.PETAL_BLIZZARD]: RewardTier.GREAT,
|
[MoveId.PETAL_BLIZZARD]: RarityTier.GREAT,
|
||||||
[MoveId.DISARMING_VOICE]: RewardTier.GREAT,
|
[MoveId.DISARMING_VOICE]: RarityTier.GREAT,
|
||||||
[MoveId.DRAINING_KISS]: RewardTier.GREAT,
|
[MoveId.DRAINING_KISS]: RarityTier.GREAT,
|
||||||
[MoveId.GRASSY_TERRAIN]: RewardTier.COMMON,
|
[MoveId.GRASSY_TERRAIN]: RarityTier.COMMON,
|
||||||
[MoveId.MISTY_TERRAIN]: RewardTier.COMMON,
|
[MoveId.MISTY_TERRAIN]: RarityTier.COMMON,
|
||||||
[MoveId.PLAY_ROUGH]: RewardTier.GREAT,
|
[MoveId.PLAY_ROUGH]: RarityTier.GREAT,
|
||||||
[MoveId.CONFIDE]: RewardTier.COMMON,
|
[MoveId.CONFIDE]: RarityTier.COMMON,
|
||||||
[MoveId.MYSTICAL_FIRE]: RewardTier.GREAT,
|
[MoveId.MYSTICAL_FIRE]: RarityTier.GREAT,
|
||||||
[MoveId.EERIE_IMPULSE]: RewardTier.COMMON,
|
[MoveId.EERIE_IMPULSE]: RarityTier.COMMON,
|
||||||
[MoveId.VENOM_DRENCH]: RewardTier.COMMON,
|
[MoveId.VENOM_DRENCH]: RarityTier.COMMON,
|
||||||
[MoveId.ELECTRIC_TERRAIN]: RewardTier.COMMON,
|
[MoveId.ELECTRIC_TERRAIN]: RarityTier.COMMON,
|
||||||
[MoveId.DAZZLING_GLEAM]: RewardTier.ULTRA,
|
[MoveId.DAZZLING_GLEAM]: RarityTier.ULTRA,
|
||||||
[MoveId.INFESTATION]: RewardTier.COMMON,
|
[MoveId.INFESTATION]: RarityTier.COMMON,
|
||||||
[MoveId.POWER_UP_PUNCH]: RewardTier.GREAT,
|
[MoveId.POWER_UP_PUNCH]: RarityTier.GREAT,
|
||||||
[MoveId.DARKEST_LARIAT]: RewardTier.GREAT,
|
[MoveId.DARKEST_LARIAT]: RarityTier.GREAT,
|
||||||
[MoveId.HIGH_HORSEPOWER]: RewardTier.ULTRA,
|
[MoveId.HIGH_HORSEPOWER]: RarityTier.ULTRA,
|
||||||
[MoveId.SOLAR_BLADE]: RewardTier.GREAT,
|
[MoveId.SOLAR_BLADE]: RarityTier.GREAT,
|
||||||
[MoveId.THROAT_CHOP]: RewardTier.GREAT,
|
[MoveId.THROAT_CHOP]: RarityTier.GREAT,
|
||||||
[MoveId.POLLEN_PUFF]: RewardTier.GREAT,
|
[MoveId.POLLEN_PUFF]: RarityTier.GREAT,
|
||||||
[MoveId.PSYCHIC_TERRAIN]: RewardTier.COMMON,
|
[MoveId.PSYCHIC_TERRAIN]: RarityTier.COMMON,
|
||||||
[MoveId.LUNGE]: RewardTier.GREAT,
|
[MoveId.LUNGE]: RarityTier.GREAT,
|
||||||
[MoveId.SPEED_SWAP]: RewardTier.COMMON,
|
[MoveId.SPEED_SWAP]: RarityTier.COMMON,
|
||||||
[MoveId.SMART_STRIKE]: RewardTier.GREAT,
|
[MoveId.SMART_STRIKE]: RarityTier.GREAT,
|
||||||
[MoveId.BRUTAL_SWING]: RewardTier.GREAT,
|
[MoveId.BRUTAL_SWING]: RarityTier.GREAT,
|
||||||
[MoveId.AURORA_VEIL]: RewardTier.COMMON,
|
[MoveId.AURORA_VEIL]: RarityTier.COMMON,
|
||||||
[MoveId.PSYCHIC_FANGS]: RewardTier.GREAT,
|
[MoveId.PSYCHIC_FANGS]: RarityTier.GREAT,
|
||||||
[MoveId.STOMPING_TANTRUM]: RewardTier.GREAT,
|
[MoveId.STOMPING_TANTRUM]: RarityTier.GREAT,
|
||||||
[MoveId.LIQUIDATION]: RewardTier.ULTRA,
|
[MoveId.LIQUIDATION]: RarityTier.ULTRA,
|
||||||
[MoveId.BODY_PRESS]: RewardTier.ULTRA,
|
[MoveId.BODY_PRESS]: RarityTier.ULTRA,
|
||||||
[MoveId.BREAKING_SWIPE]: RewardTier.GREAT,
|
[MoveId.BREAKING_SWIPE]: RarityTier.GREAT,
|
||||||
[MoveId.STEEL_BEAM]: RewardTier.ULTRA,
|
[MoveId.STEEL_BEAM]: RarityTier.ULTRA,
|
||||||
[MoveId.EXPANDING_FORCE]: RewardTier.GREAT,
|
[MoveId.EXPANDING_FORCE]: RarityTier.GREAT,
|
||||||
[MoveId.STEEL_ROLLER]: RewardTier.COMMON,
|
[MoveId.STEEL_ROLLER]: RarityTier.COMMON,
|
||||||
[MoveId.SCALE_SHOT]: RewardTier.ULTRA,
|
[MoveId.SCALE_SHOT]: RarityTier.ULTRA,
|
||||||
[MoveId.METEOR_BEAM]: RewardTier.GREAT,
|
[MoveId.METEOR_BEAM]: RarityTier.GREAT,
|
||||||
[MoveId.MISTY_EXPLOSION]: RewardTier.COMMON,
|
[MoveId.MISTY_EXPLOSION]: RarityTier.COMMON,
|
||||||
[MoveId.GRASSY_GLIDE]: RewardTier.COMMON,
|
[MoveId.GRASSY_GLIDE]: RarityTier.COMMON,
|
||||||
[MoveId.RISING_VOLTAGE]: RewardTier.COMMON,
|
[MoveId.RISING_VOLTAGE]: RarityTier.COMMON,
|
||||||
[MoveId.TERRAIN_PULSE]: RewardTier.COMMON,
|
[MoveId.TERRAIN_PULSE]: RarityTier.COMMON,
|
||||||
[MoveId.SKITTER_SMACK]: RewardTier.GREAT,
|
[MoveId.SKITTER_SMACK]: RarityTier.GREAT,
|
||||||
[MoveId.BURNING_JEALOUSY]: RewardTier.GREAT,
|
[MoveId.BURNING_JEALOUSY]: RarityTier.GREAT,
|
||||||
[MoveId.LASH_OUT]: RewardTier.GREAT,
|
[MoveId.LASH_OUT]: RarityTier.GREAT,
|
||||||
[MoveId.POLTERGEIST]: RewardTier.ULTRA,
|
[MoveId.POLTERGEIST]: RarityTier.ULTRA,
|
||||||
[MoveId.CORROSIVE_GAS]: RewardTier.COMMON,
|
[MoveId.CORROSIVE_GAS]: RarityTier.COMMON,
|
||||||
[MoveId.COACHING]: RewardTier.COMMON,
|
[MoveId.COACHING]: RarityTier.COMMON,
|
||||||
[MoveId.FLIP_TURN]: RewardTier.COMMON,
|
[MoveId.FLIP_TURN]: RarityTier.COMMON,
|
||||||
[MoveId.TRIPLE_AXEL]: RewardTier.COMMON,
|
[MoveId.TRIPLE_AXEL]: RarityTier.COMMON,
|
||||||
[MoveId.DUAL_WINGBEAT]: RewardTier.COMMON,
|
[MoveId.DUAL_WINGBEAT]: RarityTier.COMMON,
|
||||||
[MoveId.SCORCHING_SANDS]: RewardTier.GREAT,
|
[MoveId.SCORCHING_SANDS]: RarityTier.GREAT,
|
||||||
[MoveId.TERA_BLAST]: RewardTier.GREAT,
|
[MoveId.TERA_BLAST]: RarityTier.GREAT,
|
||||||
[MoveId.ICE_SPINNER]: RewardTier.GREAT,
|
[MoveId.ICE_SPINNER]: RarityTier.GREAT,
|
||||||
[MoveId.SNOWSCAPE]: RewardTier.COMMON,
|
[MoveId.SNOWSCAPE]: RarityTier.COMMON,
|
||||||
[MoveId.POUNCE]: RewardTier.COMMON,
|
[MoveId.POUNCE]: RarityTier.COMMON,
|
||||||
[MoveId.TRAILBLAZE]: RewardTier.COMMON,
|
[MoveId.TRAILBLAZE]: RarityTier.COMMON,
|
||||||
[MoveId.CHILLING_WATER]: RewardTier.COMMON,
|
[MoveId.CHILLING_WATER]: RarityTier.COMMON,
|
||||||
[MoveId.HARD_PRESS]: RewardTier.GREAT,
|
[MoveId.HARD_PRESS]: RarityTier.GREAT,
|
||||||
[MoveId.DRAGON_CHEER]: RewardTier.COMMON,
|
[MoveId.DRAGON_CHEER]: RarityTier.COMMON,
|
||||||
[MoveId.ALLURING_VOICE]: RewardTier.GREAT,
|
[MoveId.ALLURING_VOICE]: RarityTier.GREAT,
|
||||||
[MoveId.TEMPER_FLARE]: RewardTier.GREAT,
|
[MoveId.TEMPER_FLARE]: RarityTier.GREAT,
|
||||||
[MoveId.SUPERCELL_SLAM]: RewardTier.GREAT,
|
[MoveId.SUPERCELL_SLAM]: RarityTier.GREAT,
|
||||||
[MoveId.PSYCHIC_NOISE]: RewardTier.GREAT,
|
[MoveId.PSYCHIC_NOISE]: RarityTier.GREAT,
|
||||||
[MoveId.UPPER_HAND]: RewardTier.COMMON,
|
[MoveId.UPPER_HAND]: RarityTier.COMMON,
|
||||||
};
|
};
|
||||||
|
@ -16,7 +16,7 @@ import type { MoveId } from "#enums/move-id";
|
|||||||
import type { MoveSourceType } from "#enums/move-source-type";
|
import type { MoveSourceType } from "#enums/move-source-type";
|
||||||
import { Nature } from "#enums/nature";
|
import { Nature } from "#enums/nature";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { TrainerVariant } from "#enums/trainer-variant";
|
import { TrainerVariant } from "#enums/trainer-variant";
|
||||||
@ -457,13 +457,13 @@ export class SingleGenerationChallenge extends Challenge {
|
|||||||
.setBattleType(BattleType.TRAINER)
|
.setBattleType(BattleType.TRAINER)
|
||||||
.setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1)
|
.setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc(trainerTypes, true))
|
.setGetTrainerFunc(getRandomTrainerFunc(trainerTypes, true))
|
||||||
.setCustomModifierRewards({
|
.setCustomRewards({
|
||||||
guaranteedModifierTiers: [
|
guaranteedRarityTiers: [
|
||||||
RewardTier.ROGUE,
|
RarityTier.ROGUE,
|
||||||
RewardTier.ROGUE,
|
RarityTier.ROGUE,
|
||||||
RewardTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
RewardTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
RewardTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
],
|
],
|
||||||
allowLuckUpgrades: false,
|
allowLuckUpgrades: false,
|
||||||
});
|
});
|
||||||
@ -474,14 +474,14 @@ export class SingleGenerationChallenge extends Challenge {
|
|||||||
.setBattleType(BattleType.TRAINER)
|
.setBattleType(BattleType.TRAINER)
|
||||||
.setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1)
|
.setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc(trainerTypes, true))
|
.setGetTrainerFunc(getRandomTrainerFunc(trainerTypes, true))
|
||||||
.setCustomModifierRewards({
|
.setCustomRewards({
|
||||||
guaranteedModifierTiers: [
|
guaranteedRarityTiers: [
|
||||||
RewardTier.ROGUE,
|
RarityTier.ROGUE,
|
||||||
RewardTier.ROGUE,
|
RarityTier.ROGUE,
|
||||||
RewardTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
RewardTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
RewardTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
RewardTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
],
|
],
|
||||||
allowLuckUpgrades: false,
|
allowLuckUpgrades: false,
|
||||||
});
|
});
|
||||||
|
@ -3,8 +3,8 @@ import type { PokemonSpecies } from "#data/pokemon-species";
|
|||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import type { TrainerItemId } from "#enums/trainer-item-id";
|
import type { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import type { HeldItem } from "#items/held-item";
|
import type { HeldItem } from "#items/held-item";
|
||||||
|
import type { Rewards } from "#items/reward";
|
||||||
import type { TrainerItem } from "#items/trainer-item";
|
import type { TrainerItem } from "#items/trainer-item";
|
||||||
import type { ModifierTypes } from "#modifiers/modifier-type";
|
|
||||||
import type { Move } from "#moves/move";
|
import type { Move } from "#moves/move";
|
||||||
|
|
||||||
export const allAbilities: Ability[] = [];
|
export const allAbilities: Ability[] = [];
|
||||||
@ -15,4 +15,4 @@ export const allHeldItems: Record<HeldItemId, HeldItem> = {};
|
|||||||
export const allTrainerItems: Record<TrainerItemId, TrainerItem> = {};
|
export const allTrainerItems: Record<TrainerItemId, TrainerItem> = {};
|
||||||
|
|
||||||
// TODO: Figure out what this is used for and provide an appropriate tsdoc comment
|
// TODO: Figure out what this is used for and provide an appropriate tsdoc comment
|
||||||
export const modifierTypes = {} as ModifierTypes;
|
export const allRewards = {} as Rewards;
|
||||||
|
@ -69,7 +69,7 @@ import { MoveUsedEvent } from "#events/battle-scene";
|
|||||||
import type { EnemyPokemon, Pokemon } from "#field/pokemon";
|
import type { EnemyPokemon, Pokemon } from "#field/pokemon";
|
||||||
import { applyHeldItems } from "#items/all-held-items";
|
import { applyHeldItems } from "#items/all-held-items";
|
||||||
import { BerryHeldItem, berryTypeToHeldItem } from "#items/berry";
|
import { BerryHeldItem, berryTypeToHeldItem } from "#items/berry";
|
||||||
import { HeldItemEffect } from "#items/held-item";
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { TrainerItemEffect } from "#items/trainer-item";
|
import { TrainerItemEffect } from "#items/trainer-item";
|
||||||
import { applyMoveAttrs } from "#moves/apply-attrs";
|
import { applyMoveAttrs } from "#moves/apply-attrs";
|
||||||
import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSketchMoves, invalidSleepTalkMoves } from "#moves/invalid-moves";
|
import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSketchMoves, invalidSleepTalkMoves } from "#moves/invalid-moves";
|
||||||
@ -2775,7 +2775,7 @@ export class EatBerryAttr extends MoveEffectAttr {
|
|||||||
// check for berry pouch preservation
|
// check for berry pouch preservation
|
||||||
globalScene.applyPlayerItems(TrainerItemEffect.PRESERVE_BERRY, {pokemon: pokemon, doPreserve: preserve});
|
globalScene.applyPlayerItems(TrainerItemEffect.PRESERVE_BERRY, {pokemon: pokemon, doPreserve: preserve});
|
||||||
if (!preserve.value) {
|
if (!preserve.value) {
|
||||||
this.reduceBerryModifier(pokemon);
|
this.reduceBerryItem(pokemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't update harvest for berries preserved via Berry pouch (no item dupes lol)
|
// Don't update harvest for berries preserved via Berry pouch (no item dupes lol)
|
||||||
@ -2788,7 +2788,7 @@ export class EatBerryAttr extends MoveEffectAttr {
|
|||||||
return target.getHeldItems().filter(m => isItemInCategory(m, HeldItemCategoryId.BERRY));
|
return target.getHeldItems().filter(m => isItemInCategory(m, HeldItemCategoryId.BERRY));
|
||||||
}
|
}
|
||||||
|
|
||||||
reduceBerryModifier(target: Pokemon) {
|
reduceBerryItem(target: Pokemon) {
|
||||||
if (this.chosenBerry) {
|
if (this.chosenBerry) {
|
||||||
target.loseHeldItem(this.chosenBerry);
|
target.loseHeldItem(this.chosenBerry);
|
||||||
}
|
}
|
||||||
@ -2850,7 +2850,7 @@ export class StealEatBerryAttr extends EatBerryAttr {
|
|||||||
applyAbAttrs("PostItemLostAbAttr", {pokemon: target});
|
applyAbAttrs("PostItemLostAbAttr", {pokemon: target});
|
||||||
const message = i18next.t("battle:stealEatBerry", { pokemonName: user.name, targetName: target.name, berryName: allHeldItems[this.chosenBerry].name });
|
const message = i18next.t("battle:stealEatBerry", { pokemonName: user.name, targetName: target.name, berryName: allHeldItems[this.chosenBerry].name });
|
||||||
globalScene.phaseManager.queueMessage(message);
|
globalScene.phaseManager.queueMessage(message);
|
||||||
this.reduceBerryModifier(target);
|
this.reduceBerryItem(target);
|
||||||
this.eatBerry(user, target);
|
this.eatBerry(user, target);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import type { IEggOptions } from "#data/egg";
|
import type { IEggOptions } from "#data/egg";
|
||||||
import { EggSourceType } from "#enums/egg-source-types";
|
import { EggSourceType } from "#enums/egg-source-types";
|
||||||
import { EggTier } from "#enums/egg-type";
|
import { EggTier } from "#enums/egg-type";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||||
@ -150,7 +150,7 @@ export const ATrainersTestEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
|||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||||
// Battle the stat trainer for an Egg and great rewards
|
// Battle the stat trainer for an Egg and great allRewards
|
||||||
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
|
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
|
||||||
|
|
||||||
await transitionMysteryEncounterIntroVisuals();
|
await transitionMysteryEncounterIntroVisuals();
|
||||||
@ -164,8 +164,8 @@ export const ATrainersTestEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
|||||||
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.epic`));
|
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.epic`));
|
||||||
setEncounterRewards(
|
setEncounterRewards(
|
||||||
{
|
{
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.SACRED_ASH],
|
guaranteedRewardFuncs: [allRewards.SACRED_ASH],
|
||||||
guaranteedModifierTiers: [RewardTier.ROGUE, RewardTier.ULTRA],
|
guaranteedRarityTiers: [RarityTier.ROGUE, RarityTier.ULTRA],
|
||||||
fillRemaining: true,
|
fillRemaining: true,
|
||||||
},
|
},
|
||||||
[eggOptions],
|
[eggOptions],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { speciesStarterCosts } from "#balance/starters";
|
import { speciesStarterCosts } from "#balance/starters";
|
||||||
import { allTrainerItems, modifierTypes } from "#data/data-lists";
|
import { allRewards, allTrainerItems } from "#data/data-lists";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
@ -136,7 +136,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter = MysteryEncounterB
|
|||||||
})
|
})
|
||||||
.withOptionPhase(async () => {
|
.withOptionPhase(async () => {
|
||||||
// Give the player a Shiny Charm
|
// Give the player a Shiny Charm
|
||||||
globalScene.phaseManager.unshiftNew("RewardPhase", modifierTypes.SHINY_CHARM);
|
globalScene.phaseManager.unshiftNew("RewardPhase", allRewards.SHINY_CHARM);
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
})
|
})
|
||||||
.build(),
|
.build(),
|
||||||
@ -184,7 +184,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter = MysteryEncounterB
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Leave encounter with no rewards or exp
|
// Leave encounter with no allRewards or exp
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { BerryType } from "#enums/berry-type";
|
import { BerryType } from "#enums/berry-type";
|
||||||
import { ModifierPoolType } from "#enums/modifier-pool-type";
|
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import { RewardPoolType } from "#enums/reward-pool-type";
|
||||||
import { PERMANENT_STATS, Stat } from "#enums/stat";
|
import { PERMANENT_STATS, Stat } from "#enums/stat";
|
||||||
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
import { berryTypeToHeldItem } from "#items/berry";
|
import { berryTypeToHeldItem } from "#items/berry";
|
||||||
import type { ModifierTypeOption } from "#modifiers/modifier-type";
|
import type { RewardOption } from "#items/reward";
|
||||||
import { regenerateModifierPoolThresholds } from "#modifiers/modifier-type";
|
import { generateRewardPoolWeights, getRewardPoolForType } from "#items/reward-pool-utils";
|
||||||
|
import { generateRewardOption } from "#items/reward-utils";
|
||||||
import { queueEncounterMessage, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
import { queueEncounterMessage, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||||
import {
|
import {
|
||||||
generateModifierTypeOption,
|
|
||||||
getRandomEncounterSpecies,
|
getRandomEncounterSpecies,
|
||||||
initBattleWithEnemyConfig,
|
initBattleWithEnemyConfig,
|
||||||
leaveEncounterWithoutBattle,
|
leaveEncounterWithoutBattle,
|
||||||
@ -88,7 +88,7 @@ export const BerriesAboundEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
|||||||
: globalScene.currentBattle.waveIndex > 40
|
: globalScene.currentBattle.waveIndex > 40
|
||||||
? 4
|
? 4
|
||||||
: 2;
|
: 2;
|
||||||
regenerateModifierPoolThresholds(globalScene.getPlayerParty(), ModifierPoolType.PLAYER, 0);
|
generateRewardPoolWeights(getRewardPoolForType(RewardPoolType.PLAYER), globalScene.getPlayerParty(), 0);
|
||||||
encounter.misc = { numBerries };
|
encounter.misc = { numBerries };
|
||||||
|
|
||||||
const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(bossPokemon);
|
const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(bossPokemon);
|
||||||
@ -159,20 +159,16 @@ export const BerriesAboundEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const shopOptions: ModifierTypeOption[] = [];
|
const shopOptions: RewardOption[] = [];
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
// Generate shop berries
|
// Generate shop berries
|
||||||
const mod = generateModifierTypeOption(modifierTypes.BERRY);
|
const mod = generateRewardOption(allRewards.BERRY);
|
||||||
if (mod) {
|
if (mod) {
|
||||||
shopOptions.push(mod);
|
shopOptions.push(mod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setEncounterRewards(
|
setEncounterRewards({ guaranteedRewardOptions: shopOptions, fillRemaining: false }, undefined, doBerryRewards);
|
||||||
{ guaranteedModifierTypeOptions: shopOptions, fillRemaining: false },
|
|
||||||
undefined,
|
|
||||||
doBerryRewards,
|
|
||||||
);
|
|
||||||
await initBattleWithEnemyConfig(globalScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
|
await initBattleWithEnemyConfig(globalScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -190,10 +186,10 @@ export const BerriesAboundEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
|||||||
const speedDiff = fastestPokemon.getStat(Stat.SPD) / (enemySpeed * 1.1);
|
const speedDiff = fastestPokemon.getStat(Stat.SPD) / (enemySpeed * 1.1);
|
||||||
const numBerries: number = encounter.misc.numBerries;
|
const numBerries: number = encounter.misc.numBerries;
|
||||||
|
|
||||||
const shopOptions: ModifierTypeOption[] = [];
|
const shopOptions: RewardOption[] = [];
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
// Generate shop berries
|
// Generate shop berries
|
||||||
const mod = generateModifierTypeOption(modifierTypes.BERRY);
|
const mod = generateRewardOption(allRewards.BERRY);
|
||||||
if (mod) {
|
if (mod) {
|
||||||
shopOptions.push(mod);
|
shopOptions.push(mod);
|
||||||
}
|
}
|
||||||
@ -246,7 +242,7 @@ export const BerriesAboundEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
|||||||
};
|
};
|
||||||
setEncounterRewards(
|
setEncounterRewards(
|
||||||
{
|
{
|
||||||
guaranteedModifierTypeOptions: shopOptions,
|
guaranteedRewardOptions: shopOptions,
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
},
|
},
|
||||||
undefined,
|
undefined,
|
||||||
@ -279,7 +275,7 @@ export const BerriesAboundEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
|||||||
setEncounterExp(fastestPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs![0].species.baseExp);
|
setEncounterExp(fastestPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs![0].species.baseExp);
|
||||||
setEncounterRewards(
|
setEncounterRewards(
|
||||||
{
|
{
|
||||||
guaranteedModifierTypeOptions: shopOptions,
|
guaranteedRewardOptions: shopOptions,
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
},
|
},
|
||||||
undefined,
|
undefined,
|
||||||
@ -301,7 +297,7 @@ export const BerriesAboundEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Leave encounter with no rewards or exp
|
// Leave encounter with no allRewards or exp
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { allHeldItems, allMoves, modifierTypes } from "#data/data-lists";
|
import { allHeldItems, allMoves, allRewards } from "#data/data-lists";
|
||||||
import { HeldItemId } from "#enums/held-item-id";
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
import { MoveId } from "#enums/move-id";
|
import { MoveId } from "#enums/move-id";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
@ -8,18 +8,18 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||||||
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 { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { TrainerItemId } from "#enums/trainer-item-id";
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import { TrainerSlot } from "#enums/trainer-slot";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
import type { ModifierTypeOption } from "#modifiers/modifier-type";
|
import type { RewardOption } from "#items/reward";
|
||||||
|
import { generateRewardOption } from "#items/reward-utils";
|
||||||
import { PokemonMove } from "#moves/pokemon-move";
|
import { PokemonMove } from "#moves/pokemon-move";
|
||||||
import { getEncounterText, showEncounterDialogue } from "#mystery-encounters/encounter-dialogue-utils";
|
import { getEncounterText, showEncounterDialogue } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||||
import {
|
import {
|
||||||
generateModifierTypeOption,
|
|
||||||
initBattleWithEnemyConfig,
|
initBattleWithEnemyConfig,
|
||||||
leaveEncounterWithoutBattle,
|
leaveEncounterWithoutBattle,
|
||||||
selectOptionThenPokemon,
|
selectOptionThenPokemon,
|
||||||
@ -285,7 +285,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
moveTutorOptions,
|
moveTutorOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Assigns callback that teaches move before continuing to rewards
|
// Assigns callback that teaches move before continuing to allRewards
|
||||||
encounter.onRewards = doBugTypeMoveTutor;
|
encounter.onRewards = doBugTypeMoveTutor;
|
||||||
|
|
||||||
setEncounterRewards({ fillRemaining: true });
|
setEncounterRewards({ fillRemaining: true });
|
||||||
@ -305,7 +305,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
// Player shows off their bug types
|
// Player shows off their bug types
|
||||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
// Player gets different rewards depending on the number of bug types they have
|
// Player gets different allRewards depending on the number of bug types they have
|
||||||
const numBugTypes = globalScene.getPlayerParty().filter(p => p.isOfType(PokemonType.BUG, true)).length;
|
const numBugTypes = globalScene.getPlayerParty().filter(p => p.isOfType(PokemonType.BUG, true)).length;
|
||||||
const numBugTypesText = i18next.t(`${namespace}:numBugTypes`, {
|
const numBugTypesText = i18next.t(`${namespace}:numBugTypes`, {
|
||||||
count: numBugTypes,
|
count: numBugTypes,
|
||||||
@ -314,7 +314,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
|
|
||||||
if (numBugTypes < 2) {
|
if (numBugTypes < 2) {
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.SUPER_LURE, modifierTypes.GREAT_BALL],
|
guaranteedRewardFuncs: [allRewards.SUPER_LURE, allRewards.GREAT_BALL],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
@ -325,7 +325,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
];
|
];
|
||||||
} else if (numBugTypes < 4) {
|
} else if (numBugTypes < 4) {
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.QUICK_CLAW, modifierTypes.MAX_LURE, modifierTypes.ULTRA_BALL],
|
guaranteedRewardFuncs: [allRewards.QUICK_CLAW, allRewards.MAX_LURE, allRewards.ULTRA_BALL],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
@ -336,7 +336,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
];
|
];
|
||||||
} else if (numBugTypes < 6) {
|
} else if (numBugTypes < 6) {
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.GRIP_CLAW, modifierTypes.MAX_LURE, modifierTypes.ROGUE_BALL],
|
guaranteedRewardFuncs: [allRewards.GRIP_CLAW, allRewards.MAX_LURE, allRewards.ROGUE_BALL],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
@ -348,38 +348,38 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
} else {
|
} else {
|
||||||
// If the player has any evolution/form change items that are valid for their party,
|
// If the player has any evolution/form change items that are valid for their party,
|
||||||
// spawn one of those items in addition to Dynamax Band, Mega Band, and Master Ball
|
// spawn one of those items in addition to Dynamax Band, Mega Band, and Master Ball
|
||||||
const modifierOptions: ModifierTypeOption[] = [generateModifierTypeOption(modifierTypes.MASTER_BALL)!];
|
const rewardOptions: RewardOption[] = [generateRewardOption(allRewards.MASTER_BALL)!];
|
||||||
const specialOptions: ModifierTypeOption[] = [];
|
const specialOptions: RewardOption[] = [];
|
||||||
|
|
||||||
if (!globalScene.trainerItems.hasItem(TrainerItemId.MEGA_BRACELET)) {
|
if (!globalScene.trainerItems.hasItem(TrainerItemId.MEGA_BRACELET)) {
|
||||||
modifierOptions.push(generateModifierTypeOption(modifierTypes.MEGA_BRACELET)!);
|
rewardOptions.push(generateRewardOption(allRewards.MEGA_BRACELET)!);
|
||||||
}
|
}
|
||||||
if (!globalScene.trainerItems.hasItem(TrainerItemId.DYNAMAX_BAND)) {
|
if (!globalScene.trainerItems.hasItem(TrainerItemId.DYNAMAX_BAND)) {
|
||||||
modifierOptions.push(generateModifierTypeOption(modifierTypes.DYNAMAX_BAND)!);
|
rewardOptions.push(generateRewardOption(allRewards.DYNAMAX_BAND)!);
|
||||||
}
|
}
|
||||||
const nonRareEvolutionModifier = generateModifierTypeOption(modifierTypes.EVOLUTION_ITEM);
|
const nonRareEvolutionReward = generateRewardOption(allRewards.EVOLUTION_ITEM);
|
||||||
if (nonRareEvolutionModifier) {
|
if (nonRareEvolutionReward) {
|
||||||
specialOptions.push(nonRareEvolutionModifier);
|
specialOptions.push(nonRareEvolutionReward);
|
||||||
}
|
}
|
||||||
const rareEvolutionModifier = generateModifierTypeOption(modifierTypes.RARE_EVOLUTION_ITEM);
|
const rareEvolutionReward = generateRewardOption(allRewards.RARE_EVOLUTION_ITEM);
|
||||||
if (rareEvolutionModifier) {
|
if (rareEvolutionReward) {
|
||||||
specialOptions.push(rareEvolutionModifier);
|
specialOptions.push(rareEvolutionReward);
|
||||||
}
|
}
|
||||||
const formChangeModifier = generateModifierTypeOption(modifierTypes.FORM_CHANGE_ITEM);
|
const formChangeReward = generateRewardOption(allRewards.FORM_CHANGE_ITEM);
|
||||||
if (formChangeModifier) {
|
if (formChangeReward) {
|
||||||
specialOptions.push(formChangeModifier);
|
specialOptions.push(formChangeReward);
|
||||||
}
|
}
|
||||||
const rareFormChangeModifier = generateModifierTypeOption(modifierTypes.RARE_FORM_CHANGE_ITEM);
|
const rareFormChangeReward = generateRewardOption(allRewards.RARE_FORM_CHANGE_ITEM);
|
||||||
if (rareFormChangeModifier) {
|
if (rareFormChangeReward) {
|
||||||
specialOptions.push(rareFormChangeModifier);
|
specialOptions.push(rareFormChangeReward);
|
||||||
}
|
}
|
||||||
if (specialOptions.length > 0) {
|
if (specialOptions.length > 0) {
|
||||||
// TODO: should this use `randSeedItem`?
|
// TODO: should this use `randSeedItem`?
|
||||||
modifierOptions.push(specialOptions[randSeedInt(specialOptions.length)]);
|
rewardOptions.push(specialOptions[randSeedInt(specialOptions.length)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeOptions: modifierOptions,
|
guaranteedRewardOptions: rewardOptions,
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
@ -465,12 +465,12 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
chosenPokemon.loseHeldItem(lostItem, false);
|
chosenPokemon.loseHeldItem(lostItem, false);
|
||||||
globalScene.updateItems(true);
|
globalScene.updateItems(true);
|
||||||
|
|
||||||
const bugNet = generateModifierTypeOption(modifierTypes.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET)!;
|
const bugNet = generateRewardOption(allRewards.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET)!;
|
||||||
bugNet.type.tier = RewardTier.ROGUE;
|
bugNet.type.tier = RarityTier.ROGUE;
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeOptions: [bugNet],
|
guaranteedRewardOptions: [bugNet],
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.REVIVER_SEED],
|
guaranteedRewardFuncs: [allRewards.REVIVER_SEED],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
@ -744,7 +744,7 @@ function doBugTypeMoveTutor(): Promise<void> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete battle and go to rewards
|
// Complete battle and go to allRewards
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,13 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||||||
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 { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { UiMode } from "#enums/ui-mode";
|
import { UiMode } from "#enums/ui-mode";
|
||||||
import type { PlayerPokemon } from "#field/pokemon";
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import { getHeldItemTier } from "#items/held-item-default-tiers";
|
||||||
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
||||||
import { getHeldItemTier } from "#items/held-item-tiers";
|
|
||||||
import { PokemonMove } from "#moves/pokemon-move";
|
import { PokemonMove } from "#moves/pokemon-move";
|
||||||
import { showEncounterDialogue, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
import { showEncounterDialogue, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||||
@ -329,11 +329,11 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
|
|||||||
let numRogue = 0;
|
let numRogue = 0;
|
||||||
|
|
||||||
for (const m of items) {
|
for (const m of items) {
|
||||||
const tier = getHeldItemTier(m) ?? RewardTier.ULTRA;
|
const tier = getHeldItemTier(m) ?? RarityTier.ULTRA;
|
||||||
const stack = mostHeldItemsPokemon.heldItemManager.getStack(m);
|
const stack = mostHeldItemsPokemon.heldItemManager.getStack(m);
|
||||||
if (tier === RewardTier.ROGUE) {
|
if (tier === RarityTier.ROGUE) {
|
||||||
numRogue += stack;
|
numRogue += stack;
|
||||||
} else if (tier === RewardTier.ULTRA) {
|
} else if (tier === RarityTier.ULTRA) {
|
||||||
numUltra += stack;
|
numUltra += stack;
|
||||||
}
|
}
|
||||||
mostHeldItemsPokemon.heldItemManager.remove(m, stack);
|
mostHeldItemsPokemon.heldItemManager.remove(m, stack);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { EncounterBattleAnim } from "#data/battle-anims";
|
import { EncounterBattleAnim } from "#data/battle-anims";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import { BattlerIndex } from "#enums/battler-index";
|
import { BattlerIndex } from "#enums/battler-index";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { BiomeId } from "#enums/biome-id";
|
import { BiomeId } from "#enums/biome-id";
|
||||||
@ -219,7 +219,7 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
|
|||||||
|
|
||||||
await hideOricorioPokemon();
|
await hideOricorioPokemon();
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.BATON],
|
guaranteedRewardFuncs: [allRewards.BATON],
|
||||||
fillRemaining: true,
|
fillRemaining: true,
|
||||||
});
|
});
|
||||||
await initBattleWithEnemyConfig(encounter.enemyPartyConfigs[0]);
|
await initBattleWithEnemyConfig(encounter.enemyPartyConfigs[0]);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import { Challenges } from "#enums/challenges";
|
import { Challenges } from "#enums/challenges";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
@ -160,7 +160,7 @@ export const DarkDealEncounter: MysteryEncounter = MysteryEncounterBuilder.withE
|
|||||||
.withOptionPhase(async () => {
|
.withOptionPhase(async () => {
|
||||||
// Give the player 5 Rogue Balls
|
// Give the player 5 Rogue Balls
|
||||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||||
globalScene.phaseManager.unshiftNew("RewardPhase", modifierTypes.ROGUE_BALL);
|
globalScene.phaseManager.unshiftNew("RewardPhase", allRewards.ROGUE_BALL);
|
||||||
|
|
||||||
// Start encounter with random legendary (7-10 starter strength) that has level additive
|
// Start encounter with random legendary (7-10 starter strength) that has level additive
|
||||||
// If this is a mono-type challenge, always ensure the required type is filtered for
|
// If this is a mono-type challenge, always ensure the required type is filtered for
|
||||||
@ -204,7 +204,7 @@ export const DarkDealEncounter: MysteryEncounter = MysteryEncounterBuilder.withE
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Leave encounter with no rewards or exp
|
// Leave encounter with no allRewards or exp
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { timedEventManager } from "#app/global-event-manager";
|
import { timedEventManager } from "#app/global-event-manager";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { allHeldItems, modifierTypes } from "#data/data-lists";
|
import { allHeldItems, allRewards } from "#data/data-lists";
|
||||||
import { HeldItemCategoryId, HeldItemId, isItemInCategory } from "#enums/held-item-id";
|
import { HeldItemCategoryId, HeldItemId, isItemInCategory } from "#enums/held-item-id";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
@ -34,7 +34,7 @@ const namespace = "mysteryEncounters/delibirdy";
|
|||||||
/** Berries only */
|
/** Berries only */
|
||||||
const OPTION_2_ALLOWED_HELD_ITEMS = [HeldItemCategoryId.BERRY, HeldItemId.REVIVER_SEED];
|
const OPTION_2_ALLOWED_HELD_ITEMS = [HeldItemCategoryId.BERRY, HeldItemId.REVIVER_SEED];
|
||||||
|
|
||||||
/** Disallowed items are berries, Reviver Seeds, and Vitamins (form change items and fusion items are not PokemonHeldItemModifiers) */
|
/** Disallowed items are berries, Reviver Seeds, and Vitamins */
|
||||||
const OPTION_3_DISALLOWED_HELD_ITEMS = [HeldItemCategoryId.BERRY, HeldItemId.REVIVER_SEED];
|
const OPTION_3_DISALLOWED_HELD_ITEMS = [HeldItemCategoryId.BERRY, HeldItemId.REVIVER_SEED];
|
||||||
|
|
||||||
const DELIBIRDY_MONEY_PRICE_MULTIPLIER = 2;
|
const DELIBIRDY_MONEY_PRICE_MULTIPLIER = 2;
|
||||||
@ -61,10 +61,10 @@ const doEventReward = () => {
|
|||||||
return !fullStack;
|
return !fullStack;
|
||||||
});
|
});
|
||||||
if (candidates.length > 0) {
|
if (candidates.length > 0) {
|
||||||
globalScene.phaseManager.unshiftNew("RewardPhase", modifierTypes[randSeedItem(candidates)]);
|
globalScene.phaseManager.unshiftNew("RewardPhase", allRewards[randSeedItem(candidates)]);
|
||||||
} else {
|
} else {
|
||||||
// At max stacks, give a Voucher instead
|
// At max stacks, give a Voucher instead
|
||||||
globalScene.phaseManager.unshiftNew("RewardPhase", modifierTypes.VOUCHER);
|
globalScene.phaseManager.unshiftNew("RewardPhase", allRewards.VOUCHER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -168,7 +168,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
// At max stacks, give the first party pokemon a Shell Bell instead
|
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||||
backupOption();
|
backupOption();
|
||||||
} else {
|
} else {
|
||||||
globalScene.phaseManager.unshiftNew("RewardPhase", modifierTypes.AMULET_COIN);
|
globalScene.phaseManager.unshiftNew("RewardPhase", allRewards.AMULET_COIN);
|
||||||
doEventReward();
|
doEventReward();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +238,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
// At max stacks, give the first party pokemon a Shell Bell instead
|
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||||
backupOption();
|
backupOption();
|
||||||
} else {
|
} else {
|
||||||
globalScene.phaseManager.unshiftNew("RewardPhase", modifierTypes.CANDY_JAR);
|
globalScene.phaseManager.unshiftNew("RewardPhase", allRewards.CANDY_JAR);
|
||||||
doEventReward();
|
doEventReward();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -249,7 +249,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
// At max stacks, give the first party pokemon a Shell Bell instead
|
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||||
backupOption();
|
backupOption();
|
||||||
} else {
|
} else {
|
||||||
globalScene.phaseManager.unshiftNew("RewardPhase", modifierTypes.BERRY_POUCH);
|
globalScene.phaseManager.unshiftNew("RewardPhase", allRewards.BERRY_POUCH);
|
||||||
doEventReward();
|
doEventReward();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -321,7 +321,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
// At max stacks, give the first party pokemon a Shell Bell instead
|
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||||
backupOption();
|
backupOption();
|
||||||
} else {
|
} else {
|
||||||
globalScene.phaseManager.unshiftNew("RewardPhase", modifierTypes.HEALING_CHARM);
|
globalScene.phaseManager.unshiftNew("RewardPhase", allRewards.HEALING_CHARM);
|
||||||
doEventReward();
|
doEventReward();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { leaveEncounterWithoutBattle, setEncounterRewards } from "#mystery-encounters/encounter-phase-utils";
|
import { leaveEncounterWithoutBattle, setEncounterRewards } from "#mystery-encounters/encounter-phase-utils";
|
||||||
import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
||||||
import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
|
import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
|
||||||
import type { ModifierTypeFunc } from "#types/modifier-types";
|
import type { RewardFunc } from "#types/rewards";
|
||||||
import { randSeedInt } from "#utils/common";
|
import { randSeedInt } from "#utils/common";
|
||||||
|
|
||||||
/** i18n namespace for encounter */
|
/** i18n namespace for encounter */
|
||||||
@ -59,23 +59,23 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu
|
|||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Choose TMs
|
// Choose TMs
|
||||||
const modifiers: ModifierTypeFunc[] = [];
|
const rewards: RewardFunc[] = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < 5) {
|
while (i < 5) {
|
||||||
// 2/2/1 weight on TM rarity
|
// 2/2/1 weight on TM rarity
|
||||||
const roll = randSeedInt(5);
|
const roll = randSeedInt(5);
|
||||||
if (roll < 2) {
|
if (roll < 2) {
|
||||||
modifiers.push(modifierTypes.TM_COMMON);
|
rewards.push(allRewards.TM_COMMON);
|
||||||
} else if (roll < 4) {
|
} else if (roll < 4) {
|
||||||
modifiers.push(modifierTypes.TM_GREAT);
|
rewards.push(allRewards.TM_GREAT);
|
||||||
} else {
|
} else {
|
||||||
modifiers.push(modifierTypes.TM_ULTRA);
|
rewards.push(allRewards.TM_ULTRA);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: modifiers,
|
guaranteedRewardFuncs: rewards,
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
leaveEncounterWithoutBattle();
|
leaveEncounterWithoutBattle();
|
||||||
@ -88,21 +88,21 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu
|
|||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Choose Vitamins
|
// Choose Vitamins
|
||||||
const modifiers: ModifierTypeFunc[] = [];
|
const rewards: RewardFunc[] = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < 3) {
|
while (i < 3) {
|
||||||
// 2/1 weight on base stat booster vs PP Up
|
// 2/1 weight on base stat booster vs PP Up
|
||||||
const roll = randSeedInt(3);
|
const roll = randSeedInt(3);
|
||||||
if (roll === 0) {
|
if (roll === 0) {
|
||||||
modifiers.push(modifierTypes.PP_UP);
|
rewards.push(allRewards.PP_UP);
|
||||||
} else {
|
} else {
|
||||||
modifiers.push(modifierTypes.BASE_STAT_BOOSTER);
|
rewards.push(allRewards.BASE_STAT_BOOSTER);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: modifiers,
|
guaranteedRewardFuncs: rewards,
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
leaveEncounterWithoutBattle();
|
leaveEncounterWithoutBattle();
|
||||||
@ -115,21 +115,21 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu
|
|||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Choose X Items
|
// Choose X Items
|
||||||
const modifiers: ModifierTypeFunc[] = [];
|
const rewards: RewardFunc[] = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < 5) {
|
while (i < 5) {
|
||||||
// 4/1 weight on base stat booster vs Dire Hit
|
// 4/1 weight on base stat booster vs Dire Hit
|
||||||
const roll = randSeedInt(5);
|
const roll = randSeedInt(5);
|
||||||
if (roll === 0) {
|
if (roll === 0) {
|
||||||
modifiers.push(modifierTypes.DIRE_HIT);
|
rewards.push(allRewards.DIRE_HIT);
|
||||||
} else {
|
} else {
|
||||||
modifiers.push(modifierTypes.TEMP_STAT_STAGE_BOOSTER);
|
rewards.push(allRewards.TEMP_STAT_STAGE_BOOSTER);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: modifiers,
|
guaranteedRewardFuncs: rewards,
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
leaveEncounterWithoutBattle();
|
leaveEncounterWithoutBattle();
|
||||||
@ -142,25 +142,25 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu
|
|||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Choose Pokeballs
|
// Choose Pokeballs
|
||||||
const modifiers: ModifierTypeFunc[] = [];
|
const rewards: RewardFunc[] = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < 4) {
|
while (i < 4) {
|
||||||
// 10/30/20/5 weight on pokeballs
|
// 10/30/20/5 weight on pokeballs
|
||||||
const roll = randSeedInt(65);
|
const roll = randSeedInt(65);
|
||||||
if (roll < 10) {
|
if (roll < 10) {
|
||||||
modifiers.push(modifierTypes.POKEBALL);
|
rewards.push(allRewards.POKEBALL);
|
||||||
} else if (roll < 40) {
|
} else if (roll < 40) {
|
||||||
modifiers.push(modifierTypes.GREAT_BALL);
|
rewards.push(allRewards.GREAT_BALL);
|
||||||
} else if (roll < 60) {
|
} else if (roll < 60) {
|
||||||
modifiers.push(modifierTypes.ULTRA_BALL);
|
rewards.push(allRewards.ULTRA_BALL);
|
||||||
} else {
|
} else {
|
||||||
modifiers.push(modifierTypes.ROGUE_BALL);
|
rewards.push(allRewards.ROGUE_BALL);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: modifiers,
|
guaranteedRewardFuncs: rewards,
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
leaveEncounterWithoutBattle();
|
leaveEncounterWithoutBattle();
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import { MoveCategory } from "#enums/move-category";
|
import { MoveCategory } from "#enums/move-category";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import type { PlayerPokemon } from "#field/pokemon";
|
import type { PlayerPokemon } from "#field/pokemon";
|
||||||
|
import { generateRewardOption } from "#items/reward-utils";
|
||||||
import type { PokemonMove } from "#moves/pokemon-move";
|
import type { PokemonMove } from "#moves/pokemon-move";
|
||||||
import {
|
import {
|
||||||
generateModifierTypeOption,
|
|
||||||
leaveEncounterWithoutBattle,
|
leaveEncounterWithoutBattle,
|
||||||
selectPokemonForOption,
|
selectPokemonForOption,
|
||||||
setEncounterExp,
|
setEncounterExp,
|
||||||
@ -96,15 +96,15 @@ export const FieldTripEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||||
if (encounter.misc.correctMove) {
|
if (encounter.misc.correctMove) {
|
||||||
const modifiers = [
|
const modifiers = [
|
||||||
generateModifierTypeOption(modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.ATK])!,
|
generateRewardOption(allRewards.TEMP_STAT_STAGE_BOOSTER, [Stat.ATK])!,
|
||||||
generateModifierTypeOption(modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.DEF])!,
|
generateRewardOption(allRewards.TEMP_STAT_STAGE_BOOSTER, [Stat.DEF])!,
|
||||||
generateModifierTypeOption(modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
generateRewardOption(allRewards.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
||||||
generateModifierTypeOption(modifierTypes.DIRE_HIT)!,
|
generateRewardOption(allRewards.DIRE_HIT)!,
|
||||||
generateModifierTypeOption(modifierTypes.RARER_CANDY)!,
|
generateRewardOption(allRewards.RARER_CANDY)!,
|
||||||
];
|
];
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeOptions: modifiers,
|
guaranteedRewardOptions: modifiers,
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -144,15 +144,15 @@ export const FieldTripEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||||
if (encounter.misc.correctMove) {
|
if (encounter.misc.correctMove) {
|
||||||
const modifiers = [
|
const modifiers = [
|
||||||
generateModifierTypeOption(modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPATK])!,
|
generateRewardOption(allRewards.TEMP_STAT_STAGE_BOOSTER, [Stat.SPATK])!,
|
||||||
generateModifierTypeOption(modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPDEF])!,
|
generateRewardOption(allRewards.TEMP_STAT_STAGE_BOOSTER, [Stat.SPDEF])!,
|
||||||
generateModifierTypeOption(modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
generateRewardOption(allRewards.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
||||||
generateModifierTypeOption(modifierTypes.DIRE_HIT)!,
|
generateRewardOption(allRewards.DIRE_HIT)!,
|
||||||
generateModifierTypeOption(modifierTypes.RARER_CANDY)!,
|
generateRewardOption(allRewards.RARER_CANDY)!,
|
||||||
];
|
];
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeOptions: modifiers,
|
guaranteedRewardOptions: modifiers,
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -192,15 +192,15 @@ export const FieldTripEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||||
if (encounter.misc.correctMove) {
|
if (encounter.misc.correctMove) {
|
||||||
const modifiers = [
|
const modifiers = [
|
||||||
generateModifierTypeOption(modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.ACC])!,
|
generateRewardOption(allRewards.TEMP_STAT_STAGE_BOOSTER, [Stat.ACC])!,
|
||||||
generateModifierTypeOption(modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
generateRewardOption(allRewards.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
||||||
generateModifierTypeOption(modifierTypes.GREAT_BALL)!,
|
generateRewardOption(allRewards.GREAT_BALL)!,
|
||||||
generateModifierTypeOption(modifierTypes.IV_SCANNER)!,
|
generateRewardOption(allRewards.IV_SCANNER)!,
|
||||||
generateModifierTypeOption(modifierTypes.RARER_CANDY)!,
|
generateRewardOption(allRewards.RARER_CANDY)!,
|
||||||
];
|
];
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeOptions: modifiers,
|
guaranteedRewardOptions: modifiers,
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ export const FieryFalloutEncounter: MysteryEncounter = MysteryEncounterBuilder.w
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No rewards
|
// No allRewards
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { ModifierPoolType } from "#enums/modifier-pool-type";
|
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RewardPoolType } from "#enums/reward-pool-type";
|
||||||
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import type { ModifierTypeOption } from "#modifiers/modifier-type";
|
import type { RewardOption, TrainerItemReward } from "#items/reward";
|
||||||
import { getPlayerModifierTypeOptions, regenerateModifierPoolThresholds } from "#modifiers/modifier-type";
|
import { generatePlayerRewardOptions, generateRewardPoolWeights, getRewardPoolForType } from "#items/reward-pool-utils";
|
||||||
|
import { isTmReward } from "#items/reward-utils";
|
||||||
import { queueEncounterMessage } from "#mystery-encounters/encounter-dialogue-utils";
|
import { queueEncounterMessage } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||||
import {
|
import {
|
||||||
@ -89,18 +91,18 @@ export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
|||||||
// Waves 10-40 GREAT, 60-120 ULTRA, 120-160 ROGUE, 160-180 MASTER
|
// Waves 10-40 GREAT, 60-120 ULTRA, 120-160 ROGUE, 160-180 MASTER
|
||||||
const tier =
|
const tier =
|
||||||
globalScene.currentBattle.waveIndex > 160
|
globalScene.currentBattle.waveIndex > 160
|
||||||
? RewardTier.MASTER
|
? RarityTier.MASTER
|
||||||
: globalScene.currentBattle.waveIndex > 120
|
: globalScene.currentBattle.waveIndex > 120
|
||||||
? RewardTier.ROGUE
|
? RarityTier.ROGUE
|
||||||
: globalScene.currentBattle.waveIndex > 40
|
: globalScene.currentBattle.waveIndex > 40
|
||||||
? RewardTier.ULTRA
|
? RarityTier.ULTRA
|
||||||
: RewardTier.GREAT;
|
: RarityTier.GREAT;
|
||||||
regenerateModifierPoolThresholds(globalScene.getPlayerParty(), ModifierPoolType.PLAYER, 0);
|
generateRewardPoolWeights(getRewardPoolForType(RewardPoolType.PLAYER), globalScene.getPlayerParty(), 0);
|
||||||
let item: ModifierTypeOption | null = null;
|
let item: RewardOption | null = null;
|
||||||
// TMs and Candy Jar excluded from possible rewards as they're too swingy in value for a singular item reward
|
// TMs and Candy Jar excluded from possible allRewards as they're too swingy in value for a singular item reward
|
||||||
while (!item || item.type.id.includes("TM_") || item.type.id === "CANDY_JAR") {
|
while (!item || isTmReward(item.type) || (item.type as TrainerItemReward).itemId === TrainerItemId.CANDY_JAR) {
|
||||||
item = getPlayerModifierTypeOptions(1, globalScene.getPlayerParty(), [], {
|
item = generatePlayerRewardOptions(1, globalScene.getPlayerParty(), [], {
|
||||||
guaranteedModifierTiers: [tier],
|
guaranteedRarityTiers: [tier],
|
||||||
allowLuckUpgrades: false,
|
allowLuckUpgrades: false,
|
||||||
})[0];
|
})[0];
|
||||||
}
|
}
|
||||||
@ -151,9 +153,9 @@ export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
|||||||
async () => {
|
async () => {
|
||||||
// Pick battle
|
// Pick battle
|
||||||
// Pokemon will randomly boost 1 stat by 2 stages
|
// Pokemon will randomly boost 1 stat by 2 stages
|
||||||
const item = globalScene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
|
const item = globalScene.currentBattle.mysteryEncounter!.misc as RewardOption;
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeOptions: [item],
|
guaranteedRewardOptions: [item],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
await initBattleWithEnemyConfig(globalScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
|
await initBattleWithEnemyConfig(globalScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
|
||||||
@ -175,9 +177,9 @@ export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
|||||||
.withOptionPhase(async () => {
|
.withOptionPhase(async () => {
|
||||||
// Pick steal
|
// Pick steal
|
||||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||||
const item = globalScene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
|
const item = globalScene.currentBattle.mysteryEncounter!.misc as RewardOption;
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeOptions: [item],
|
guaranteedRewardOptions: [item],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -199,7 +201,7 @@ export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Leave encounter with no rewards or exp
|
// Leave encounter with no allRewards or exp
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import { SpeciesFormChangeActiveTrigger } from "#data/form-change-triggers";
|
import { SpeciesFormChangeActiveTrigger } from "#data/form-change-triggers";
|
||||||
import { getPokeballAtlasKey, getPokeballTintColor } from "#data/pokeball";
|
import { getPokeballAtlasKey, getPokeballTintColor } from "#data/pokeball";
|
||||||
import { FieldPosition } from "#enums/field-position";
|
import { FieldPosition } from "#enums/field-position";
|
||||||
@ -160,7 +160,7 @@ export const FunAndGamesEncounter: MysteryEncounter = MysteryEncounterBuilder.wi
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Leave encounter with no rewards or exp
|
// Leave encounter with no allRewards or exp
|
||||||
await transitionMysteryEncounterIntroVisuals(true, true);
|
await transitionMysteryEncounterIntroVisuals(true, true);
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
return true;
|
return true;
|
||||||
@ -281,21 +281,21 @@ function handleNextTurn() {
|
|||||||
if (healthRatio < 0.03) {
|
if (healthRatio < 0.03) {
|
||||||
// Grand prize
|
// Grand prize
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.MULTI_LENS],
|
guaranteedRewardFuncs: [allRewards.MULTI_LENS],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
resultMessageKey = `${namespace}:best_result`;
|
resultMessageKey = `${namespace}:best_result`;
|
||||||
} else if (healthRatio < 0.15) {
|
} else if (healthRatio < 0.15) {
|
||||||
// 2nd prize
|
// 2nd prize
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.SCOPE_LENS],
|
guaranteedRewardFuncs: [allRewards.SCOPE_LENS],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
resultMessageKey = `${namespace}:great_result`;
|
resultMessageKey = `${namespace}:great_result`;
|
||||||
} else if (healthRatio < 0.33) {
|
} else if (healthRatio < 0.33) {
|
||||||
// 3rd prize
|
// 3rd prize
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.WIDE_LENS],
|
guaranteedRewardFuncs: [allRewards.WIDE_LENS],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
resultMessageKey = `${namespace}:good_result`;
|
resultMessageKey = `${namespace}:good_result`;
|
||||||
|
@ -8,22 +8,23 @@ import { getPokeballAtlasKey, getPokeballTintColor } from "#data/pokeball";
|
|||||||
import type { PokemonSpecies } from "#data/pokemon-species";
|
import type { PokemonSpecies } from "#data/pokemon-species";
|
||||||
import { getTypeRgb } from "#data/type";
|
import { getTypeRgb } from "#data/type";
|
||||||
import { HeldItemCategoryId, type HeldItemId, isItemInCategory } from "#enums/held-item-id";
|
import { HeldItemCategoryId, type HeldItemId, isItemInCategory } from "#enums/held-item-id";
|
||||||
import { ModifierPoolType } from "#enums/modifier-pool-type";
|
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import type { PokeballType } from "#enums/pokeball";
|
import type { PokeballType } from "#enums/pokeball";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RewardPoolType } from "#enums/reward-pool-type";
|
||||||
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { TrainerSlot } from "#enums/trainer-slot";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { doShinySparkleAnim } from "#field/anims";
|
import { doShinySparkleAnim } from "#field/anims";
|
||||||
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
import { EnemyPokemon } from "#field/pokemon";
|
import { EnemyPokemon } from "#field/pokemon";
|
||||||
import { getHeldItemTier } from "#items/held-item-tiers";
|
import { getHeldItemTier } from "#items/held-item-default-tiers";
|
||||||
|
import type { RewardOption } from "#items/reward";
|
||||||
|
import { generatePlayerRewardOptions, generateRewardPoolWeights, getRewardPoolForType } from "#items/reward-pool-utils";
|
||||||
|
import { isTmReward } from "#items/reward-utils";
|
||||||
import { TrainerItemEffect } from "#items/trainer-item";
|
import { TrainerItemEffect } from "#items/trainer-item";
|
||||||
import type { ModifierTypeOption } from "#modifiers/modifier-type";
|
|
||||||
import { getPlayerModifierTypeOptions, regenerateModifierPoolThresholds } from "#modifiers/modifier-type";
|
|
||||||
import { PokemonMove } from "#moves/pokemon-move";
|
import { PokemonMove } from "#moves/pokemon-move";
|
||||||
import { getEncounterText, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
import { getEncounterText, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
import {
|
import {
|
||||||
@ -413,26 +414,26 @@ 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 = getHeldItemTier(heldItemId) ?? RewardTier.GREAT;
|
let tier = getHeldItemTier(heldItemId) ?? RarityTier.GREAT;
|
||||||
|
|
||||||
// Increment tier by 1
|
// Increment tier by 1
|
||||||
if (tier < RewardTier.MASTER) {
|
if (tier < RarityTier.MASTER) {
|
||||||
tier++;
|
tier++;
|
||||||
}
|
}
|
||||||
|
|
||||||
regenerateModifierPoolThresholds(party, ModifierPoolType.PLAYER, 0);
|
generateRewardPoolWeights(getRewardPoolForType(RewardPoolType.PLAYER), party, 0);
|
||||||
let item: ModifierTypeOption | null = null;
|
let item: RewardOption | null = null;
|
||||||
// TMs excluded from possible rewards
|
// TMs excluded from possible allRewards
|
||||||
while (!item || item.type.id.includes("TM_")) {
|
while (!item || isTmReward(item.type)) {
|
||||||
item = getPlayerModifierTypeOptions(1, party, [], {
|
item = generatePlayerRewardOptions(1, party, [], {
|
||||||
guaranteedModifierTiers: [tier],
|
guaranteedRarityTiers: [tier],
|
||||||
allowLuckUpgrades: false,
|
allowLuckUpgrades: false,
|
||||||
})[0];
|
})[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
encounter.setDialogueToken("itemName", item.type.name);
|
encounter.setDialogueToken("itemName", item.type.name);
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeOptions: [item],
|
guaranteedRewardOptions: [item],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -458,7 +459,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Leave encounter with no rewards or exp
|
// Leave encounter with no allRewards or exp
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
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 { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||||
import { initBattleWithEnemyConfig, setEncounterRewards } from "#mystery-encounters/encounter-phase-utils";
|
import { initBattleWithEnemyConfig, setEncounterRewards } from "#mystery-encounters/encounter-phase-utils";
|
||||||
import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
||||||
@ -147,7 +147,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = MysteryEncounter
|
|||||||
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
|
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.TM_COMMON, modifierTypes.TM_GREAT, modifierTypes.MEMORY_MUSHROOM],
|
guaranteedRewardFuncs: [allRewards.TM_COMMON, allRewards.TM_GREAT, allRewards.MEMORY_MUSHROOM],
|
||||||
fillRemaining: true,
|
fillRemaining: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = MysteryEncounter
|
|||||||
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1];
|
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1];
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTiers: [RewardTier.ULTRA, RewardTier.ULTRA, RewardTier.GREAT, RewardTier.GREAT],
|
guaranteedRarityTiers: [RarityTier.ULTRA, RarityTier.ULTRA, RarityTier.GREAT, RarityTier.GREAT],
|
||||||
fillRemaining: true,
|
fillRemaining: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter = MysteryEncounter
|
|||||||
encounter.expMultiplier = 0.9;
|
encounter.expMultiplier = 0.9;
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTiers: [RewardTier.ROGUE, RewardTier.ROGUE, RewardTier.ULTRA, RewardTier.GREAT],
|
guaranteedRarityTiers: [RarityTier.ROGUE, RarityTier.ROGUE, RarityTier.ULTRA, RarityTier.GREAT],
|
||||||
fillRemaining: true,
|
fillRemaining: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import { MoveId } from "#enums/move-id";
|
|||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { queueEncounterMessage, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
import { queueEncounterMessage, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||||
@ -141,25 +141,25 @@ export const MysteriousChestEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT) {
|
if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT) {
|
||||||
// Choose between 2 COMMON / 2 GREAT tier items (20%)
|
// Choose between 2 COMMON / 2 GREAT tier items (20%)
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTiers: [RewardTier.COMMON, RewardTier.COMMON, RewardTier.GREAT, RewardTier.GREAT],
|
guaranteedRarityTiers: [RarityTier.COMMON, RarityTier.COMMON, RarityTier.GREAT, RarityTier.GREAT],
|
||||||
});
|
});
|
||||||
// Display result message then proceed to rewards
|
// Display result message then proceed to allRewards
|
||||||
queueEncounterMessage(`${namespace}:option.1.normal`);
|
queueEncounterMessage(`${namespace}:option.1.normal`);
|
||||||
leaveEncounterWithoutBattle();
|
leaveEncounterWithoutBattle();
|
||||||
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT) {
|
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT) {
|
||||||
// Choose between 3 ULTRA tier items (30%)
|
// Choose between 3 ULTRA tier items (30%)
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTiers: [RewardTier.ULTRA, RewardTier.ULTRA, RewardTier.ULTRA],
|
guaranteedRarityTiers: [RarityTier.ULTRA, RarityTier.ULTRA, RarityTier.ULTRA],
|
||||||
});
|
});
|
||||||
// Display result message then proceed to rewards
|
// Display result message then proceed to allRewards
|
||||||
queueEncounterMessage(`${namespace}:option.1.good`);
|
queueEncounterMessage(`${namespace}:option.1.good`);
|
||||||
leaveEncounterWithoutBattle();
|
leaveEncounterWithoutBattle();
|
||||||
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT) {
|
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT) {
|
||||||
// Choose between 2 ROGUE tier items (10%)
|
// Choose between 2 ROGUE tier items (10%)
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTiers: [RewardTier.ROGUE, RewardTier.ROGUE],
|
guaranteedRarityTiers: [RarityTier.ROGUE, RarityTier.ROGUE],
|
||||||
});
|
});
|
||||||
// Display result message then proceed to rewards
|
// Display result message then proceed to allRewards
|
||||||
queueEncounterMessage(`${namespace}:option.1.great`);
|
queueEncounterMessage(`${namespace}:option.1.great`);
|
||||||
leaveEncounterWithoutBattle();
|
leaveEncounterWithoutBattle();
|
||||||
} else if (
|
} else if (
|
||||||
@ -168,9 +168,9 @@ export const MysteriousChestEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
) {
|
) {
|
||||||
// Choose 1 MASTER tier item (5%)
|
// Choose 1 MASTER tier item (5%)
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTiers: [RewardTier.MASTER],
|
guaranteedRarityTiers: [RarityTier.MASTER],
|
||||||
});
|
});
|
||||||
// Display result message then proceed to rewards
|
// Display result message then proceed to allRewards
|
||||||
queueEncounterMessage(`${namespace}:option.1.amazing`);
|
queueEncounterMessage(`${namespace}:option.1.amazing`);
|
||||||
leaveEncounterWithoutBattle();
|
leaveEncounterWithoutBattle();
|
||||||
} else {
|
} else {
|
||||||
@ -208,7 +208,7 @@ export const MysteriousChestEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Leave encounter with no rewards or exp
|
// Leave encounter with no allRewards or exp
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -125,7 +125,7 @@ export const SafariZoneEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Leave encounter with no rewards or exp
|
// Leave encounter with no allRewards or exp
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -227,7 +227,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = MysteryEncounterBui
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Leave encounter with no rewards or exp
|
// Leave encounter with no allRewards or exp
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import { CustomPokemonData } from "#data/pokemon-data";
|
import { CustomPokemonData } from "#data/pokemon-data";
|
||||||
import { AiType } from "#enums/ai-type";
|
import { AiType } from "#enums/ai-type";
|
||||||
import { BattlerIndex } from "#enums/battler-index";
|
import { BattlerIndex } from "#enums/battler-index";
|
||||||
@ -116,7 +116,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil
|
|||||||
// Pick battle
|
// Pick battle
|
||||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS],
|
guaranteedRewardFuncs: [allRewards.LEFTOVERS],
|
||||||
fillRemaining: true,
|
fillRemaining: true,
|
||||||
});
|
});
|
||||||
encounter.startOfBattleEffects.push({
|
encounter.startOfBattleEffects.push({
|
||||||
@ -163,7 +163,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil
|
|||||||
// Steal the Snorlax's Leftovers
|
// Steal the Snorlax's Leftovers
|
||||||
const instance = globalScene.currentBattle.mysteryEncounter!;
|
const instance = globalScene.currentBattle.mysteryEncounter!;
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS],
|
guaranteedRewardFuncs: [allRewards.LEFTOVERS],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
// Snorlax exp to Pokemon that did the stealing
|
// Snorlax exp to Pokemon that did the stealing
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { BiomeId } from "#enums/biome-id";
|
import { BiomeId } from "#enums/biome-id";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
@ -13,11 +13,10 @@ import { TrainerSlot } from "#enums/trainer-slot";
|
|||||||
import { getBiomeKey } from "#field/arena";
|
import { getBiomeKey } from "#field/arena";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { EnemyPokemon } from "#field/pokemon";
|
import { EnemyPokemon } from "#field/pokemon";
|
||||||
import { getPartyLuckValue } from "#modifiers/modifier-type";
|
import { generateRewardOption } from "#items/reward-utils";
|
||||||
import { queueEncounterMessage, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
import { queueEncounterMessage, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||||
import {
|
import {
|
||||||
generateModifierTypeOption,
|
|
||||||
initBattleWithEnemyConfig,
|
initBattleWithEnemyConfig,
|
||||||
setEncounterExp,
|
setEncounterExp,
|
||||||
setEncounterRewards,
|
setEncounterRewards,
|
||||||
@ -34,6 +33,7 @@ import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encou
|
|||||||
import { MoneyRequirement, WaveModulusRequirement } from "#mystery-encounters/mystery-encounter-requirements";
|
import { MoneyRequirement, WaveModulusRequirement } from "#mystery-encounters/mystery-encounter-requirements";
|
||||||
import { PokemonData } from "#system/pokemon-data";
|
import { PokemonData } from "#system/pokemon-data";
|
||||||
import { randSeedInt } from "#utils/common";
|
import { randSeedInt } from "#utils/common";
|
||||||
|
import { getPartyLuckValue } from "#utils/party";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounters/teleportingHijinks";
|
const namespace = "mysteryEncounters/teleportingHijinks";
|
||||||
@ -173,10 +173,10 @@ export const TeleportingHijinksEncounter: MysteryEncounter = MysteryEncounterBui
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const magnet = generateModifierTypeOption(modifierTypes.ATTACK_TYPE_BOOSTER, [PokemonType.STEEL])!;
|
const magnet = generateRewardOption(allRewards.ATTACK_TYPE_BOOSTER, [PokemonType.STEEL])!;
|
||||||
const metalCoat = generateModifierTypeOption(modifierTypes.ATTACK_TYPE_BOOSTER, [PokemonType.ELECTRIC])!;
|
const metalCoat = generateRewardOption(allRewards.ATTACK_TYPE_BOOSTER, [PokemonType.ELECTRIC])!;
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeOptions: [magnet, metalCoat],
|
guaranteedRewardOptions: [magnet, metalCoat],
|
||||||
fillRemaining: true,
|
fillRemaining: true,
|
||||||
});
|
});
|
||||||
await transitionMysteryEncounterIntroVisuals(true, true);
|
await transitionMysteryEncounterIntroVisuals(true, true);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { speciesStarterCosts } from "#balance/starters";
|
import { speciesStarterCosts } from "#balance/starters";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import type { IEggOptions } from "#data/egg";
|
import type { IEggOptions } from "#data/egg";
|
||||||
import { getPokeballTintColor } from "#data/pokeball";
|
import { getPokeballTintColor } from "#data/pokeball";
|
||||||
import { BiomeId } from "#enums/biome-id";
|
import { BiomeId } from "#enums/biome-id";
|
||||||
@ -294,7 +294,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
|||||||
const eggOptions = getEggOptions(pokemon1CommonEggs, pokemon1RareEggs);
|
const eggOptions = getEggOptions(pokemon1CommonEggs, pokemon1RareEggs);
|
||||||
setEncounterRewards(
|
setEncounterRewards(
|
||||||
{
|
{
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.SOOTHE_BELL],
|
guaranteedRewardFuncs: [allRewards.SOOTHE_BELL],
|
||||||
fillRemaining: true,
|
fillRemaining: true,
|
||||||
},
|
},
|
||||||
eggOptions,
|
eggOptions,
|
||||||
@ -304,7 +304,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
|||||||
// Remove all Pokemon from the party except the chosen Pokemon
|
// Remove all Pokemon from the party except the chosen Pokemon
|
||||||
removePokemonFromPartyAndStoreHeldItems(encounter, pokemon1);
|
removePokemonFromPartyAndStoreHeldItems(encounter, pokemon1);
|
||||||
|
|
||||||
// Configure outro dialogue for egg rewards
|
// Configure outro dialogue for egg allRewards
|
||||||
encounter.dialogue.outro = [
|
encounter.dialogue.outro = [
|
||||||
{
|
{
|
||||||
speaker: trainerNameKey,
|
speaker: trainerNameKey,
|
||||||
@ -353,7 +353,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
|||||||
const eggOptions = getEggOptions(pokemon2CommonEggs, pokemon2RareEggs);
|
const eggOptions = getEggOptions(pokemon2CommonEggs, pokemon2RareEggs);
|
||||||
setEncounterRewards(
|
setEncounterRewards(
|
||||||
{
|
{
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.SOOTHE_BELL],
|
guaranteedRewardFuncs: [allRewards.SOOTHE_BELL],
|
||||||
fillRemaining: true,
|
fillRemaining: true,
|
||||||
},
|
},
|
||||||
eggOptions,
|
eggOptions,
|
||||||
@ -363,7 +363,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
|||||||
// Remove all Pokemon from the party except the chosen Pokemon
|
// Remove all Pokemon from the party except the chosen Pokemon
|
||||||
removePokemonFromPartyAndStoreHeldItems(encounter, pokemon2);
|
removePokemonFromPartyAndStoreHeldItems(encounter, pokemon2);
|
||||||
|
|
||||||
// Configure outro dialogue for egg rewards
|
// Configure outro dialogue for egg allRewards
|
||||||
encounter.dialogue.outro = [
|
encounter.dialogue.outro = [
|
||||||
{
|
{
|
||||||
speaker: trainerNameKey,
|
speaker: trainerNameKey,
|
||||||
@ -412,7 +412,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
|||||||
const eggOptions = getEggOptions(pokemon3CommonEggs, pokemon3RareEggs);
|
const eggOptions = getEggOptions(pokemon3CommonEggs, pokemon3RareEggs);
|
||||||
setEncounterRewards(
|
setEncounterRewards(
|
||||||
{
|
{
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.SOOTHE_BELL],
|
guaranteedRewardFuncs: [allRewards.SOOTHE_BELL],
|
||||||
fillRemaining: true,
|
fillRemaining: true,
|
||||||
},
|
},
|
||||||
eggOptions,
|
eggOptions,
|
||||||
@ -422,7 +422,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
|||||||
// Remove all Pokemon from the party except the chosen Pokemon
|
// Remove all Pokemon from the party except the chosen Pokemon
|
||||||
removePokemonFromPartyAndStoreHeldItems(encounter, pokemon3);
|
removePokemonFromPartyAndStoreHeldItems(encounter, pokemon3);
|
||||||
|
|
||||||
// Configure outro dialogue for egg rewards
|
// Configure outro dialogue for egg allRewards
|
||||||
encounter.dialogue.outro = [
|
encounter.dialogue.outro = [
|
||||||
{
|
{
|
||||||
speaker: trainerNameKey,
|
speaker: trainerNameKey,
|
||||||
@ -640,7 +640,7 @@ function onGameOver() {
|
|||||||
const chosenPokemon = encounter.misc.chosenPokemon;
|
const chosenPokemon = encounter.misc.chosenPokemon;
|
||||||
chosenPokemon.friendship = 0;
|
chosenPokemon.friendship = 0;
|
||||||
|
|
||||||
// Clear all rewards that would have been earned
|
// Clear all allRewards that would have been earned
|
||||||
encounter.doEncounterRewards = undefined;
|
encounter.doEncounterRewards = undefined;
|
||||||
|
|
||||||
// Set flag that encounter was failed
|
// Set flag that encounter was failed
|
||||||
|
@ -238,7 +238,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Leave encounter with no rewards or exp
|
// Leave encounter with no allRewards or exp
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import { CustomPokemonData } from "#data/pokemon-data";
|
import { CustomPokemonData } from "#data/pokemon-data";
|
||||||
import { BattlerIndex } from "#enums/battler-index";
|
import { BattlerIndex } from "#enums/battler-index";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
@ -193,7 +193,7 @@ export const TheStrongStuffEncounter: MysteryEncounter = MysteryEncounterBuilder
|
|||||||
// Pick battle
|
// Pick battle
|
||||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.SOUL_DEW],
|
guaranteedRewardFuncs: [allRewards.SOUL_DEW],
|
||||||
fillRemaining: true,
|
fillRemaining: true,
|
||||||
});
|
});
|
||||||
encounter.startOfBattleEffects.push(
|
encounter.startOfBattleEffects.push(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { applyAbAttrs } from "#abilities/apply-ab-attrs";
|
import { applyAbAttrs } from "#abilities/apply-ab-attrs";
|
||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import { SpeciesFormChangeAbilityTrigger } from "#data/form-change-triggers";
|
import { SpeciesFormChangeAbilityTrigger } from "#data/form-change-triggers";
|
||||||
import { AbilityId } from "#enums/ability-id";
|
import { AbilityId } from "#enums/ability-id";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
@ -11,13 +11,13 @@ import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
|||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { Nature } from "#enums/nature";
|
import { Nature } from "#enums/nature";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
|
import { generateRewardOption } from "#items/reward-utils";
|
||||||
import { showEncounterDialogue, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
import { showEncounterDialogue, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||||
import {
|
import {
|
||||||
generateModifierTypeOption,
|
|
||||||
initBattleWithEnemyConfig,
|
initBattleWithEnemyConfig,
|
||||||
leaveEncounterWithoutBattle,
|
leaveEncounterWithoutBattle,
|
||||||
setEncounterRewards,
|
setEncounterRewards,
|
||||||
@ -117,7 +117,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter = MysteryEncounter
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Spawn 5 trainer battles back to back with Macho Brace in rewards
|
// Spawn 5 trainer battles back to back with Macho Brace in allRewards
|
||||||
globalScene.currentBattle.mysteryEncounter!.doContinueEncounter = async () => {
|
globalScene.currentBattle.mysteryEncounter!.doContinueEncounter = async () => {
|
||||||
await endTrainerBattleAndShowDialogue();
|
await endTrainerBattleAndShowDialogue();
|
||||||
};
|
};
|
||||||
@ -140,7 +140,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter = MysteryEncounter
|
|||||||
// Refuse the challenge, they full heal the party and give the player a Rarer Candy
|
// Refuse the challenge, they full heal the party and give the player a Rarer Candy
|
||||||
globalScene.phaseManager.unshiftNew("PartyHealPhase", true);
|
globalScene.phaseManager.unshiftNew("PartyHealPhase", true);
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.RARER_CANDY],
|
guaranteedRewardFuncs: [allRewards.RARER_CANDY],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
leaveEncounterWithoutBattle();
|
leaveEncounterWithoutBattle();
|
||||||
@ -156,17 +156,17 @@ async function spawnNextTrainerOrEndEncounter() {
|
|||||||
await showEncounterDialogue(`${namespace}:victory`, `${namespace}:speaker`);
|
await showEncounterDialogue(`${namespace}:victory`, `${namespace}:speaker`);
|
||||||
|
|
||||||
// Give 10x Voucher
|
// Give 10x Voucher
|
||||||
const newModifier = modifierTypes.VOUCHER_PREMIUM().newModifier();
|
const reward = allRewards.VOUCHER_PREMIUM();
|
||||||
globalScene.addModifier(newModifier);
|
globalScene.applyReward(reward, {});
|
||||||
globalScene.playSound("item_fanfare");
|
globalScene.playSound("item_fanfare");
|
||||||
await showEncounterText(i18next.t("battle:rewardGain", { modifierName: newModifier?.type.name }));
|
await showEncounterText(i18next.t("battle:rewardGain", { modifierName: reward.name }));
|
||||||
|
|
||||||
await showEncounterDialogue(`${namespace}:victory_2`, `${namespace}:speaker`);
|
await showEncounterDialogue(`${namespace}:victory_2`, `${namespace}:speaker`);
|
||||||
globalScene.ui.clearText(); // Clears "Winstrate" title from screen as rewards get animated in
|
globalScene.ui.clearText(); // Clears "Winstrate" title from screen as allRewards get animated in
|
||||||
const machoBrace = generateModifierTypeOption(modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE)!;
|
const machoBrace = generateRewardOption(allRewards.MYSTERY_ENCOUNTER_MACHO_BRACE)!;
|
||||||
machoBrace.type.tier = RewardTier.MASTER;
|
machoBrace.type.tier = RarityTier.MASTER;
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeOptions: [machoBrace],
|
guaranteedRewardOptions: [machoBrace],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
encounter.doContinueEncounter = undefined;
|
encounter.doContinueEncounter = undefined;
|
||||||
|
@ -346,7 +346,7 @@ export const TrainingSessionEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Leave encounter with no rewards or exp
|
// Leave encounter with no allRewards or exp
|
||||||
leaveEncounterWithoutBattle(true);
|
leaveEncounterWithoutBattle(true);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -8,7 +8,7 @@ import { MoveUseMode } from "#enums/move-use-mode";
|
|||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { TrainerItemId } from "#enums/trainer-item-id";
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import { assignItemToFirstFreePokemon } from "#items/item-utility";
|
import { assignItemToFirstFreePokemon } from "#items/item-utility";
|
||||||
@ -167,7 +167,7 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTiers: [RewardTier.ROGUE, RewardTier.ROGUE, RewardTier.ULTRA, RewardTier.GREAT],
|
guaranteedRarityTiers: [RarityTier.ROGUE, RarityTier.ROGUE, RarityTier.ULTRA, RarityTier.GREAT],
|
||||||
fillRemaining: true,
|
fillRemaining: true,
|
||||||
});
|
});
|
||||||
encounter.startOfBattleEffects.push(
|
encounter.startOfBattleEffects.push(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { allSpecies, modifierTypes } from "#data/data-lists";
|
import { allRewards, allSpecies } from "#data/data-lists";
|
||||||
import { getLevelTotalExp } from "#data/exp";
|
import { getLevelTotalExp } from "#data/exp";
|
||||||
import type { PokemonSpecies } from "#data/pokemon-species";
|
import type { PokemonSpecies } from "#data/pokemon-species";
|
||||||
import { Challenges } from "#enums/challenges";
|
import { Challenges } from "#enums/challenges";
|
||||||
@ -11,7 +11,7 @@ import { Nature } from "#enums/nature";
|
|||||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
import { PlayerGender } from "#enums/player-gender";
|
import { PlayerGender } from "#enums/player-gender";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
@ -218,12 +218,12 @@ export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
|||||||
|
|
||||||
await doNewTeamPostProcess(transformations);
|
await doNewTeamPostProcess(transformations);
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: [
|
guaranteedRewardFuncs: [
|
||||||
modifierTypes.MEMORY_MUSHROOM,
|
allRewards.MEMORY_MUSHROOM,
|
||||||
modifierTypes.ROGUE_BALL,
|
allRewards.ROGUE_BALL,
|
||||||
modifierTypes.MINT,
|
allRewards.MINT,
|
||||||
modifierTypes.MINT,
|
allRewards.MINT,
|
||||||
modifierTypes.MINT,
|
allRewards.MINT,
|
||||||
],
|
],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
@ -242,7 +242,7 @@ export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
// Battle your "future" team for some item rewards
|
// Battle your "future" team for some item allRewards
|
||||||
const transformations: PokemonTransformation[] =
|
const transformations: PokemonTransformation[] =
|
||||||
globalScene.currentBattle.mysteryEncounter!.misc.teamTransformations;
|
globalScene.currentBattle.mysteryEncounter!.misc.teamTransformations;
|
||||||
|
|
||||||
@ -293,7 +293,7 @@ export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onBeforeRewards = () => {
|
const onBeforeRewards = () => {
|
||||||
// Before battle rewards, unlock the passive on a pokemon in the player's team for the rest of the run (not permanently)
|
// Before battle allRewards, unlock the passive on a pokemon in the player's team for the rest of the run (not permanently)
|
||||||
// One random pokemon will get its passive unlocked
|
// One random pokemon will get its passive unlocked
|
||||||
const passiveDisabledPokemon = globalScene.getPlayerParty().filter(p => !p.passive);
|
const passiveDisabledPokemon = globalScene.getPlayerParty().filter(p => !p.passive);
|
||||||
if (passiveDisabledPokemon?.length > 0) {
|
if (passiveDisabledPokemon?.length > 0) {
|
||||||
@ -306,13 +306,13 @@ export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
|||||||
|
|
||||||
setEncounterRewards(
|
setEncounterRewards(
|
||||||
{
|
{
|
||||||
guaranteedModifierTiers: [
|
guaranteedRarityTiers: [
|
||||||
RewardTier.ROGUE,
|
RarityTier.ROGUE,
|
||||||
RewardTier.ROGUE,
|
RarityTier.ROGUE,
|
||||||
RewardTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
RewardTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
RewardTier.GREAT,
|
RarityTier.GREAT,
|
||||||
RewardTier.GREAT,
|
RarityTier.GREAT,
|
||||||
],
|
],
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
},
|
},
|
||||||
|
@ -173,11 +173,11 @@ export class MysteryEncounter implements IMysteryEncounter {
|
|||||||
onVisualsStart?: () => boolean;
|
onVisualsStart?: () => boolean;
|
||||||
/** Event triggered prior to {@linkcode CommandPhase}, during {@linkcode TurnInitPhase} */
|
/** Event triggered prior to {@linkcode CommandPhase}, during {@linkcode TurnInitPhase} */
|
||||||
onTurnStart?: () => boolean;
|
onTurnStart?: () => boolean;
|
||||||
/** Event prior to any rewards logic in {@linkcode MysteryEncounterRewardsPhase} */
|
/** Event prior to any allRewards logic in {@linkcode MysteryEncounterRewardsPhase} */
|
||||||
onRewards?: () => Promise<void>;
|
onRewards?: () => Promise<void>;
|
||||||
/** Will provide the player party EXP before rewards are displayed for that wave */
|
/** Will provide the player party EXP before allRewards are displayed for that wave */
|
||||||
doEncounterExp?: () => boolean;
|
doEncounterExp?: () => boolean;
|
||||||
/** Will provide the player a rewards shop for that wave */
|
/** Will provide the player a allRewards shop for that wave */
|
||||||
doEncounterRewards?: () => boolean;
|
doEncounterRewards?: () => boolean;
|
||||||
/** Will execute callback during VictoryPhase of a continuousEncounter */
|
/** Will execute callback during VictoryPhase of a continuousEncounter */
|
||||||
doContinueEncounter?: () => Promise<void>;
|
doContinueEncounter?: () => Promise<void>;
|
||||||
@ -237,10 +237,10 @@ export class MysteryEncounter implements IMysteryEncounter {
|
|||||||
encounterMode: MysteryEncounterMode;
|
encounterMode: MysteryEncounterMode;
|
||||||
/**
|
/**
|
||||||
* Flag for checking if it's the first time a shop is being shown for an encounter.
|
* Flag for checking if it's the first time a shop is being shown for an encounter.
|
||||||
* Defaults to true so that the first shop does not override the specified rewards.
|
* Defaults to true so that the first shop does not override the specified allRewards.
|
||||||
* Will be set to false after a shop is shown (so can't reroll same rarity items for free)
|
* Will be set to false after a shop is shown (so can't reroll same rarity items for free)
|
||||||
*/
|
*/
|
||||||
lockEncounterRewardTiers: boolean;
|
lockEncounterRarityTiers: boolean;
|
||||||
/**
|
/**
|
||||||
* Will be set automatically, indicates special moves in startOfBattleEffects are complete (so will not repeat)
|
* Will be set automatically, indicates special moves in startOfBattleEffects are complete (so will not repeat)
|
||||||
*/
|
*/
|
||||||
@ -295,7 +295,7 @@ export class MysteryEncounter implements IMysteryEncounter {
|
|||||||
|
|
||||||
// Reset any dirty flags or encounter data
|
// Reset any dirty flags or encounter data
|
||||||
this.startOfBattleEffectsComplete = false;
|
this.startOfBattleEffectsComplete = false;
|
||||||
this.lockEncounterRewardTiers = true;
|
this.lockEncounterRarityTiers = true;
|
||||||
this.dialogueTokens = {};
|
this.dialogueTokens = {};
|
||||||
this.enemyPartyConfigs = [];
|
this.enemyPartyConfigs = [];
|
||||||
this.startOfBattleEffects = [];
|
this.startOfBattleEffects = [];
|
||||||
@ -561,7 +561,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
continuousEncounter = false;
|
continuousEncounter = false;
|
||||||
catchAllowed = false;
|
catchAllowed = false;
|
||||||
fleeAllowed = true;
|
fleeAllowed = true;
|
||||||
lockEncounterRewardTiers = false;
|
lockEncounterRarityTiers = false;
|
||||||
startOfBattleEffectsComplete = false;
|
startOfBattleEffectsComplete = false;
|
||||||
hasBattleAnimationsWithoutTargets = false;
|
hasBattleAnimationsWithoutTargets = false;
|
||||||
skipEnemyBattleTurns = false;
|
skipEnemyBattleTurns = false;
|
||||||
@ -928,13 +928,13 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can set custom encounter rewards via this callback function
|
* Can set custom encounter allRewards via this callback function
|
||||||
* If rewards are always deterministic for an encounter, this is a good way to set them
|
* If allRewards are always deterministic for an encounter, this is a good way to set them
|
||||||
*
|
*
|
||||||
* NOTE: If rewards are dependent on options selected, runtime data, etc.,
|
* NOTE: If allRewards are dependent on options selected, runtime data, etc.,
|
||||||
* It may be better to programmatically set doEncounterRewards elsewhere.
|
* It may be better to programmatically set doEncounterRewards elsewhere.
|
||||||
* There is a helper function in mystery-encounter utils, setEncounterRewards(), which can be called programmatically to set rewards
|
* There is a helper function in mystery-encounter utils, setEncounterRewards(), which can be called programmatically to set allRewards
|
||||||
* @param doEncounterRewards Synchronous callback function to perform during rewards phase of the encounter
|
* @param doEncounterRewards Synchronous callback function to perform during allRewards phase of the encounter
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withRewards(doEncounterRewards: () => boolean): this & Required<Pick<IMysteryEncounter, "doEncounterRewards">> {
|
withRewards(doEncounterRewards: () => boolean): this & Required<Pick<IMysteryEncounter, "doEncounterRewards">> {
|
||||||
@ -945,10 +945,10 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
* Can set custom encounter exp via this callback function
|
* Can set custom encounter exp via this callback function
|
||||||
* If exp always deterministic for an encounter, this is a good way to set them
|
* If exp always deterministic for an encounter, this is a good way to set them
|
||||||
*
|
*
|
||||||
* NOTE: If rewards are dependent on options selected, runtime data, etc.,
|
* NOTE: If allRewards are dependent on options selected, runtime data, etc.,
|
||||||
* It may be better to programmatically set doEncounterExp elsewhere.
|
* It may be better to programmatically set doEncounterExp elsewhere.
|
||||||
* There is a helper function in mystery-encounter utils, setEncounterExp(), which can be called programmatically to set rewards
|
* There is a helper function in mystery-encounter utils, setEncounterExp(), which can be called programmatically to set allRewards
|
||||||
* @param doEncounterExp Synchronous callback function to perform during rewards phase of the encounter
|
* @param doEncounterExp Synchronous callback function to perform during allRewards phase of the encounter
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withExp(doEncounterExp: () => boolean): this & Required<Pick<IMysteryEncounter, "doEncounterExp">> {
|
withExp(doEncounterExp: () => boolean): this & Required<Pick<IMysteryEncounter, "doEncounterExp">> {
|
||||||
|
@ -5,7 +5,6 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { BiomePoolTier, biomeLinks } from "#balance/biomes";
|
import { BiomePoolTier, biomeLinks } from "#balance/biomes";
|
||||||
import { initMoveAnim, loadMoveAnimAssets } from "#data/battle-anims";
|
import { initMoveAnim, loadMoveAnimAssets } from "#data/battle-anims";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
|
||||||
import type { IEggOptions } from "#data/egg";
|
import type { IEggOptions } from "#data/egg";
|
||||||
import { Egg } from "#data/egg";
|
import { Egg } from "#data/egg";
|
||||||
import type { Gender } from "#data/gender";
|
import type { Gender } from "#data/gender";
|
||||||
@ -17,7 +16,6 @@ import type { AiType } from "#enums/ai-type";
|
|||||||
import type { BattlerTagType } from "#enums/battler-tag-type";
|
import type { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { BiomeId } from "#enums/biome-id";
|
import { BiomeId } from "#enums/biome-id";
|
||||||
import { FieldPosition } from "#enums/field-position";
|
import { FieldPosition } from "#enums/field-position";
|
||||||
import { ModifierPoolType } from "#enums/modifier-pool-type";
|
|
||||||
import type { MoveId } from "#enums/move-id";
|
import type { MoveId } from "#enums/move-id";
|
||||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||||
import type { Nature } from "#enums/nature";
|
import type { Nature } from "#enums/nature";
|
||||||
@ -31,8 +29,7 @@ import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
|||||||
import { EnemyPokemon } from "#field/pokemon";
|
import { EnemyPokemon } from "#field/pokemon";
|
||||||
import { Trainer } from "#field/trainer";
|
import { Trainer } from "#field/trainer";
|
||||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
||||||
import type { CustomModifierSettings, ModifierType } from "#modifiers/modifier-type";
|
import type { CustomRewardSettings } from "#items/reward-pool-utils";
|
||||||
import { getPartyLuckValue, ModifierTypeGenerator, ModifierTypeOption } from "#modifiers/modifier-type";
|
|
||||||
import { PokemonMove } from "#moves/pokemon-move";
|
import { PokemonMove } from "#moves/pokemon-move";
|
||||||
import { showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
import { showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
||||||
import type { MysteryEncounterOption } from "#mystery-encounters/mystery-encounter-option";
|
import type { MysteryEncounterOption } from "#mystery-encounters/mystery-encounter-option";
|
||||||
@ -44,6 +41,7 @@ import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstact-option-se
|
|||||||
import type { PartyOption, PokemonSelectFilter } from "#ui/party-ui-handler";
|
import type { PartyOption, PokemonSelectFilter } from "#ui/party-ui-handler";
|
||||||
import { PartyUiMode } from "#ui/party-ui-handler";
|
import { PartyUiMode } from "#ui/party-ui-handler";
|
||||||
import { coerceArray, isNullOrUndefined, randomString, randSeedInt, randSeedItem } from "#utils/common";
|
import { coerceArray, isNullOrUndefined, randomString, randSeedInt, randSeedItem } from "#utils/common";
|
||||||
|
import { getPartyLuckValue } from "#utils/party";
|
||||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
@ -474,45 +472,6 @@ export function updatePlayerMoney(changeValue: number, playSound = true, showMes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts modifier bullshit to an actual item
|
|
||||||
* @param modifier
|
|
||||||
* @param pregenArgs Can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc.
|
|
||||||
*/
|
|
||||||
export function generateModifierType(modifier: () => ModifierType, pregenArgs?: any[]): ModifierType | null {
|
|
||||||
const modifierId = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifier);
|
|
||||||
if (!modifierId) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let result: ModifierType = modifierTypes[modifierId]();
|
|
||||||
|
|
||||||
// Populates item id and tier (order matters)
|
|
||||||
result = result
|
|
||||||
.withIdFromFunc(modifierTypes[modifierId])
|
|
||||||
.withTierFromPool(ModifierPoolType.PLAYER, globalScene.getPlayerParty());
|
|
||||||
|
|
||||||
return result instanceof ModifierTypeGenerator
|
|
||||||
? result.generateType(globalScene.getPlayerParty(), pregenArgs)
|
|
||||||
: result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts modifier bullshit to an actual item
|
|
||||||
* @param modifier
|
|
||||||
* @param pregenArgs - can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc.
|
|
||||||
*/
|
|
||||||
export function generateModifierTypeOption(
|
|
||||||
modifier: () => ModifierType,
|
|
||||||
pregenArgs?: any[],
|
|
||||||
): ModifierTypeOption | null {
|
|
||||||
const result = generateModifierType(modifier, pregenArgs);
|
|
||||||
if (result) {
|
|
||||||
return new ModifierTypeOption(result, 0);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is intended for use inside onPreOptionPhase() of an encounter option
|
* This function is intended for use inside onPreOptionPhase() of an encounter option
|
||||||
* @param onPokemonSelected - Any logic that needs to be performed when Pokemon is chosen
|
* @param onPokemonSelected - Any logic that needs to be performed when Pokemon is chosen
|
||||||
@ -727,12 +686,12 @@ export function selectOptionThenPokemon(
|
|||||||
/**
|
/**
|
||||||
* Will initialize reward phases to follow the mystery encounter
|
* Will initialize reward phases to follow the mystery encounter
|
||||||
* Can have shop displayed or skipped
|
* Can have shop displayed or skipped
|
||||||
* @param customShopRewards - adds a shop phase with the specified rewards / reward tiers
|
* @param customShopRewards - adds a shop phase with the specified allRewards / reward tiers
|
||||||
* @param eggRewards
|
* @param eggRewards
|
||||||
* @param preRewardsCallback - can execute an arbitrary callback before the new phases if necessary (useful for updating items/party/injecting new phases before {@linkcode MysteryEncounterRewardsPhase})
|
* @param preRewardsCallback - can execute an arbitrary callback before the new phases if necessary (useful for updating items/party/injecting new phases before {@linkcode MysteryEncounterRewardsPhase})
|
||||||
*/
|
*/
|
||||||
export function setEncounterRewards(
|
export function setEncounterRewards(
|
||||||
customShopRewards?: CustomModifierSettings,
|
customShopRewards?: CustomRewardSettings,
|
||||||
eggRewards?: IEggOptions[],
|
eggRewards?: IEggOptions[],
|
||||||
preRewardsCallback?: Function,
|
preRewardsCallback?: Function,
|
||||||
) {
|
) {
|
||||||
@ -809,8 +768,8 @@ export function initSubsequentOptionSelect(optionSelectSettings: OptionSelectSet
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Can be used to exit an encounter without any battles or followup
|
* Can be used to exit an encounter without any battles or followup
|
||||||
* Will skip any shops and rewards, and queue the next encounter phase as normal
|
* Will skip any shops and allRewards, and queue the next encounter phase as normal
|
||||||
* @param addHealPhase - when true, will add a shop phase to end of encounter with 0 rewards but healing items are available
|
* @param addHealPhase - when true, will add a shop phase to end of encounter with 0 allRewards but healing items are available
|
||||||
* @param encounterMode - Can set custom encounter mode if necessary (may be required for forcing Pokemon to return before next phase)
|
* @param encounterMode - Can set custom encounter mode if necessary (may be required for forcing Pokemon to return before next phase)
|
||||||
*/
|
*/
|
||||||
export function leaveEncounterWithoutBattle(
|
export function leaveEncounterWithoutBattle(
|
||||||
|
@ -4,8 +4,8 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import { randSeedInt } from "#app/utils/common";
|
import { randSeedInt } from "#app/utils/common";
|
||||||
import { BattleType } from "#enums/battle-type";
|
import { BattleType } from "#enums/battle-type";
|
||||||
import { ClassicFixedBossWaves } from "#enums/fixed-boss-waves";
|
import { ClassicFixedBossWaves } from "#enums/fixed-boss-waves";
|
||||||
import { ModifierTier } from "#enums/modifier-tier";
|
|
||||||
import { PlayerGender } from "#enums/player-gender";
|
import { PlayerGender } from "#enums/player-gender";
|
||||||
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { TrainerVariant } from "#enums/trainer-variant";
|
import { TrainerVariant } from "#enums/trainer-variant";
|
||||||
|
|
||||||
@ -45,8 +45,8 @@ export const classicFixedBattles: FixedBattleConfigs = {
|
|||||||
globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT,
|
globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.setCustomModifierRewards({
|
.setCustomRewards({
|
||||||
guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT],
|
guaranteedRarityTiers: [RarityTier.ULTRA, RarityTier.GREAT, RarityTier.GREAT],
|
||||||
allowLuckUpgrades: false,
|
allowLuckUpgrades: false,
|
||||||
}),
|
}),
|
||||||
[ClassicFixedBossWaves.EVIL_GRUNT_1]: new FixedBattleConfig()
|
[ClassicFixedBossWaves.EVIL_GRUNT_1]: new FixedBattleConfig()
|
||||||
@ -77,8 +77,8 @@ export const classicFixedBattles: FixedBattleConfigs = {
|
|||||||
globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT,
|
globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.setCustomModifierRewards({
|
.setCustomRewards({
|
||||||
guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT],
|
guaranteedRarityTiers: [RarityTier.ULTRA, RarityTier.ULTRA, RarityTier.GREAT, RarityTier.GREAT],
|
||||||
allowLuckUpgrades: false,
|
allowLuckUpgrades: false,
|
||||||
}),
|
}),
|
||||||
[ClassicFixedBossWaves.EVIL_GRUNT_2]: new FixedBattleConfig()
|
[ClassicFixedBossWaves.EVIL_GRUNT_2]: new FixedBattleConfig()
|
||||||
@ -150,8 +150,8 @@ export const classicFixedBattles: FixedBattleConfigs = {
|
|||||||
globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT,
|
globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.setCustomModifierRewards({
|
.setCustomRewards({
|
||||||
guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA],
|
guaranteedRarityTiers: [RarityTier.ULTRA, RarityTier.ULTRA, RarityTier.ULTRA, RarityTier.ULTRA],
|
||||||
allowLuckUpgrades: false,
|
allowLuckUpgrades: false,
|
||||||
}),
|
}),
|
||||||
[ClassicFixedBossWaves.EVIL_GRUNT_4]: new FixedBattleConfig()
|
[ClassicFixedBossWaves.EVIL_GRUNT_4]: new FixedBattleConfig()
|
||||||
@ -212,14 +212,8 @@ export const classicFixedBattles: FixedBattleConfigs = {
|
|||||||
TrainerType.PENNY,
|
TrainerType.PENNY,
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
.setCustomModifierRewards({
|
.setCustomRewards({
|
||||||
guaranteedModifierTiers: [
|
guaranteedRarityTiers: [RarityTier.ROGUE, RarityTier.ROGUE, RarityTier.ULTRA, RarityTier.ULTRA, RarityTier.ULTRA],
|
||||||
ModifierTier.ROGUE,
|
|
||||||
ModifierTier.ROGUE,
|
|
||||||
ModifierTier.ULTRA,
|
|
||||||
ModifierTier.ULTRA,
|
|
||||||
ModifierTier.ULTRA,
|
|
||||||
],
|
|
||||||
allowLuckUpgrades: false,
|
allowLuckUpgrades: false,
|
||||||
}),
|
}),
|
||||||
[ClassicFixedBossWaves.RIVAL_5]: new FixedBattleConfig()
|
[ClassicFixedBossWaves.RIVAL_5]: new FixedBattleConfig()
|
||||||
@ -231,14 +225,8 @@ export const classicFixedBattles: FixedBattleConfigs = {
|
|||||||
globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT,
|
globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.setCustomModifierRewards({
|
.setCustomRewards({
|
||||||
guaranteedModifierTiers: [
|
guaranteedRarityTiers: [RarityTier.ROGUE, RarityTier.ROGUE, RarityTier.ROGUE, RarityTier.ULTRA, RarityTier.ULTRA],
|
||||||
ModifierTier.ROGUE,
|
|
||||||
ModifierTier.ROGUE,
|
|
||||||
ModifierTier.ROGUE,
|
|
||||||
ModifierTier.ULTRA,
|
|
||||||
ModifierTier.ULTRA,
|
|
||||||
],
|
|
||||||
allowLuckUpgrades: false,
|
allowLuckUpgrades: false,
|
||||||
}),
|
}),
|
||||||
[ClassicFixedBossWaves.EVIL_BOSS_2]: new FixedBattleConfig()
|
[ClassicFixedBossWaves.EVIL_BOSS_2]: new FixedBattleConfig()
|
||||||
@ -258,14 +246,14 @@ export const classicFixedBattles: FixedBattleConfigs = {
|
|||||||
TrainerType.PENNY_2,
|
TrainerType.PENNY_2,
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
.setCustomModifierRewards({
|
.setCustomRewards({
|
||||||
guaranteedModifierTiers: [
|
guaranteedRarityTiers: [
|
||||||
ModifierTier.ROGUE,
|
RarityTier.ROGUE,
|
||||||
ModifierTier.ROGUE,
|
RarityTier.ROGUE,
|
||||||
ModifierTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
ModifierTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
ModifierTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
ModifierTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
],
|
],
|
||||||
allowLuckUpgrades: false,
|
allowLuckUpgrades: false,
|
||||||
}),
|
}),
|
||||||
@ -362,14 +350,14 @@ export const classicFixedBattles: FixedBattleConfigs = {
|
|||||||
globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT,
|
globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.setCustomModifierRewards({
|
.setCustomRewards({
|
||||||
guaranteedModifierTiers: [
|
guaranteedRarityTiers: [
|
||||||
ModifierTier.ROGUE,
|
RarityTier.ROGUE,
|
||||||
ModifierTier.ROGUE,
|
RarityTier.ROGUE,
|
||||||
ModifierTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
ModifierTier.ULTRA,
|
RarityTier.ULTRA,
|
||||||
ModifierTier.GREAT,
|
RarityTier.GREAT,
|
||||||
ModifierTier.GREAT,
|
RarityTier.GREAT,
|
||||||
],
|
],
|
||||||
allowLuckUpgrades: false,
|
allowLuckUpgrades: false,
|
||||||
}),
|
}),
|
||||||
|
@ -3,7 +3,7 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import { pokemonEvolutions, pokemonPrevolutions } from "#balance/pokemon-evolutions";
|
import { pokemonEvolutions, pokemonPrevolutions } from "#balance/pokemon-evolutions";
|
||||||
import { signatureSpecies } from "#balance/signature-species";
|
import { signatureSpecies } from "#balance/signature-species";
|
||||||
import { tmSpecies } from "#balance/tms";
|
import { tmSpecies } from "#balance/tms";
|
||||||
import { modifierTypes } from "#data/data-lists";
|
import { allRewards } from "#data/data-lists";
|
||||||
import { doubleBattleDialogue } from "#data/double-battle-dialogue";
|
import { doubleBattleDialogue } from "#data/double-battle-dialogue";
|
||||||
import { Gender } from "#data/gender";
|
import { Gender } from "#data/gender";
|
||||||
import type { PokemonSpecies, PokemonSpeciesFilter } from "#data/pokemon-species";
|
import type { PokemonSpecies, PokemonSpeciesFilter } from "#data/pokemon-species";
|
||||||
@ -31,7 +31,7 @@ import {
|
|||||||
TrainerPartyTemplate,
|
TrainerPartyTemplate,
|
||||||
trainerPartyTemplates,
|
trainerPartyTemplates,
|
||||||
} from "#trainers/trainer-party-template";
|
} from "#trainers/trainer-party-template";
|
||||||
import type { ModifierTypeFunc } from "#types/modifier-types";
|
import type { RewardFunc } from "#types/rewards";
|
||||||
import type {
|
import type {
|
||||||
GenAIFunc,
|
GenAIFunc,
|
||||||
GenTrainerItemsFunc,
|
GenTrainerItemsFunc,
|
||||||
@ -113,9 +113,9 @@ export class TrainerConfig {
|
|||||||
public femaleEncounterBgm: string;
|
public femaleEncounterBgm: string;
|
||||||
public doubleEncounterBgm: string;
|
public doubleEncounterBgm: string;
|
||||||
public victoryBgm: string;
|
public victoryBgm: string;
|
||||||
public genModifiersFunc: GenTrainerItemsFunc;
|
public genTrainerItemsFunc: GenTrainerItemsFunc;
|
||||||
public genAIFuncs: GenAIFunc[] = [];
|
public genAIFuncs: GenAIFunc[] = [];
|
||||||
public modifierRewardFuncs: ModifierTypeFunc[] = [];
|
public rewardFuncs: RewardFunc[] = [];
|
||||||
public partyTemplates: TrainerPartyTemplate[];
|
public partyTemplates: TrainerPartyTemplate[];
|
||||||
public partyTemplateFunc: PartyTemplateFunc;
|
public partyTemplateFunc: PartyTemplateFunc;
|
||||||
public partyMemberFuncs: PartyMemberFuncs = {};
|
public partyMemberFuncs: PartyMemberFuncs = {};
|
||||||
@ -465,8 +465,8 @@ export class TrainerConfig {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
setGenModifiersFunc(genModifiersFunc: GenTrainerItemsFunc): TrainerConfig {
|
setGenTrainerItemsFunc(genTrainerItemsFunc: GenTrainerItemsFunc): TrainerConfig {
|
||||||
this.genModifiersFunc = genModifiersFunc;
|
this.genTrainerItemsFunc = genTrainerItemsFunc;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +476,7 @@ export class TrainerConfig {
|
|||||||
* @param slot Optional, a specified slot that should be terastallized. Wraps to match party size (-1 will get the last slot and so on).
|
* @param slot Optional, a specified slot that should be terastallized. Wraps to match party size (-1 will get the last slot and so on).
|
||||||
* @returns this
|
* @returns this
|
||||||
*/
|
*/
|
||||||
setRandomTeraModifiers(count: () => number, slot?: number): TrainerConfig {
|
setRandomTeraType(count: () => number, slot?: number): TrainerConfig {
|
||||||
this.genAIFuncs.push((party: EnemyPokemon[]) => {
|
this.genAIFuncs.push((party: EnemyPokemon[]) => {
|
||||||
const shedinjaCanTera = !this.hasSpecialtyType() || this.specialtyType === PokemonType.BUG; // Better to check one time than 6
|
const shedinjaCanTera = !this.hasSpecialtyType() || this.specialtyType === PokemonType.BUG; // Better to check one time than 6
|
||||||
const partyMemberIndexes = new Array(party.length)
|
const partyMemberIndexes = new Array(party.length)
|
||||||
@ -507,23 +507,11 @@ export class TrainerConfig {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// function getRandomTeraModifiers(party: EnemyPokemon[], count: integer, types?: Type[]): PersistentModifier[] {
|
setRewardFuncs(...rewardFuncs: (() => RewardFunc)[]): TrainerConfig {
|
||||||
// const ret: PersistentModifier[] = [];
|
this.rewardFuncs = rewardFuncs.map(func => () => {
|
||||||
// const partyMemberIndexes = new Array(party.length).fill(null).map((_, i) => i);
|
const rewardFunc = func();
|
||||||
// for (let t = 0; t < Math.min(count, party.length); t++) {
|
const reward = rewardFunc();
|
||||||
// const randomIndex = Utils.randSeedItem(partyMemberIndexes);
|
return reward;
|
||||||
// partyMemberIndexes.splice(partyMemberIndexes.indexOf(randomIndex), 1);
|
|
||||||
// ret.push(modifierTypes.TERA_SHARD().generateType([], [ Utils.randSeedItem(types ? types : party[randomIndex].getTypes()) ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(party[randomIndex]) as PersistentModifier); // TODO: is the bang correct?
|
|
||||||
// }
|
|
||||||
// return ret;
|
|
||||||
// }
|
|
||||||
|
|
||||||
setModifierRewardFuncs(...modifierTypeFuncs: (() => ModifierTypeFunc)[]): TrainerConfig {
|
|
||||||
this.modifierRewardFuncs = modifierTypeFuncs.map(func => () => {
|
|
||||||
const modifierTypeFunc = func();
|
|
||||||
const modifierType = modifierTypeFunc();
|
|
||||||
modifierType.withIdFromFunc(modifierTypeFunc);
|
|
||||||
return modifierType;
|
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -689,7 +677,7 @@ export class TrainerConfig {
|
|||||||
this.setHasVoucher(true);
|
this.setHasVoucher(true);
|
||||||
this.setBattleBgm("battle_unova_gym");
|
this.setBattleBgm("battle_unova_gym");
|
||||||
this.setVictoryBgm("victory_gym");
|
this.setVictoryBgm("victory_gym");
|
||||||
this.setRandomTeraModifiers(
|
this.setRandomTeraType(
|
||||||
() => (ignoreMinTeraWave || globalScene.currentBattle.waveIndex >= GYM_LEADER_TERA_WAVE ? 1 : 0),
|
() => (ignoreMinTeraWave || globalScene.currentBattle.waveIndex >= GYM_LEADER_TERA_WAVE ? 1 : 0),
|
||||||
teraSlot,
|
teraSlot,
|
||||||
);
|
);
|
||||||
@ -750,7 +738,7 @@ export class TrainerConfig {
|
|||||||
this.setHasVoucher(true);
|
this.setHasVoucher(true);
|
||||||
this.setBattleBgm("battle_unova_elite");
|
this.setBattleBgm("battle_unova_elite");
|
||||||
this.setVictoryBgm("victory_gym");
|
this.setVictoryBgm("victory_gym");
|
||||||
this.setRandomTeraModifiers(() => 1, teraSlot);
|
this.setRandomTeraType(() => 1, teraSlot);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -927,11 +915,11 @@ export class TrainerConfig {
|
|||||||
clone = this.battleBgm ? clone.setBattleBgm(this.battleBgm) : clone;
|
clone = this.battleBgm ? clone.setBattleBgm(this.battleBgm) : clone;
|
||||||
clone = this.encounterBgm ? clone.setEncounterBgm(this.encounterBgm) : clone;
|
clone = this.encounterBgm ? clone.setEncounterBgm(this.encounterBgm) : clone;
|
||||||
clone = this.victoryBgm ? clone.setVictoryBgm(this.victoryBgm) : clone;
|
clone = this.victoryBgm ? clone.setVictoryBgm(this.victoryBgm) : clone;
|
||||||
clone = this.genModifiersFunc ? clone.setGenModifiersFunc(this.genModifiersFunc) : clone;
|
clone = this.genTrainerItemsFunc ? clone.setGenTrainerItemsFunc(this.genTrainerItemsFunc) : clone;
|
||||||
|
|
||||||
if (this.modifierRewardFuncs) {
|
if (this.rewardFuncs) {
|
||||||
// Clones array instead of passing ref
|
// Clones array instead of passing ref
|
||||||
clone.modifierRewardFuncs = this.modifierRewardFuncs.slice(0);
|
clone.rewardFuncs = this.rewardFuncs.slice(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.partyTemplates) {
|
if (this.partyTemplates) {
|
||||||
@ -4443,9 +4431,9 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
.setBattleBgm("battle_rival")
|
.setBattleBgm("battle_rival")
|
||||||
.setMixedBattleBgm("battle_rival")
|
.setMixedBattleBgm("battle_rival")
|
||||||
.setPartyTemplates(trainerPartyTemplates.RIVAL)
|
.setPartyTemplates(trainerPartyTemplates.RIVAL)
|
||||||
.setModifierRewardFuncs(
|
.setRewardFuncs(
|
||||||
() => modifierTypes.SUPER_EXP_CHARM,
|
() => allRewards.SUPER_EXP_CHARM,
|
||||||
() => modifierTypes.EXP_SHARE,
|
() => allRewards.EXP_SHARE,
|
||||||
)
|
)
|
||||||
.setPartyMemberFunc(
|
.setPartyMemberFunc(
|
||||||
0,
|
0,
|
||||||
@ -4513,7 +4501,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
.setBattleBgm("battle_rival")
|
.setBattleBgm("battle_rival")
|
||||||
.setMixedBattleBgm("battle_rival")
|
.setMixedBattleBgm("battle_rival")
|
||||||
.setPartyTemplates(trainerPartyTemplates.RIVAL_2)
|
.setPartyTemplates(trainerPartyTemplates.RIVAL_2)
|
||||||
.setModifierRewardFuncs(() => modifierTypes.EXP_SHARE)
|
.setRewardFuncs(() => allRewards.EXP_SHARE)
|
||||||
.setPartyMemberFunc(
|
.setPartyMemberFunc(
|
||||||
0,
|
0,
|
||||||
getRandomPartyMemberFunc(
|
getRandomPartyMemberFunc(
|
||||||
@ -4666,7 +4654,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
.setBattleBgm("battle_rival_2")
|
.setBattleBgm("battle_rival_2")
|
||||||
.setMixedBattleBgm("battle_rival_2")
|
.setMixedBattleBgm("battle_rival_2")
|
||||||
.setPartyTemplates(trainerPartyTemplates.RIVAL_4)
|
.setPartyTemplates(trainerPartyTemplates.RIVAL_4)
|
||||||
.setModifierRewardFuncs(() => modifierTypes.TERA_ORB)
|
.setRewardFuncs(() => allRewards.TERA_ORB)
|
||||||
.setPartyMemberFunc(
|
.setPartyMemberFunc(
|
||||||
0,
|
0,
|
||||||
getRandomPartyMemberFunc(
|
getRandomPartyMemberFunc(
|
||||||
|
37
src/enums/held-item-effect.ts
Normal file
37
src/enums/held-item-effect.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import type { EnumValues } from "#types/enum-types";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum representing the various "classes" of item effects that can be applied.
|
||||||
|
*/
|
||||||
|
export const HeldItemEffect = {
|
||||||
|
ATTACK_TYPE_BOOST: 1,
|
||||||
|
TURN_END_HEAL: 2,
|
||||||
|
HIT_HEAL: 3,
|
||||||
|
RESET_NEGATIVE_STAT_STAGE: 4,
|
||||||
|
EXP_BOOSTER: 5,
|
||||||
|
// Should we actually distinguish different berry effects?
|
||||||
|
BERRY: 6,
|
||||||
|
BASE_STAT_BOOSTER: 7,
|
||||||
|
INSTANT_REVIVE: 8,
|
||||||
|
STAT_BOOST: 9,
|
||||||
|
CRIT_BOOST: 10,
|
||||||
|
TURN_END_STATUS: 11,
|
||||||
|
SURVIVE_CHANCE: 12,
|
||||||
|
BYPASS_SPEED_CHANCE: 13,
|
||||||
|
FLINCH_CHANCE: 14,
|
||||||
|
FIELD_EFFECT: 15,
|
||||||
|
FRIENDSHIP_BOOSTER: 16,
|
||||||
|
NATURE_WEIGHT_BOOSTER: 17,
|
||||||
|
ACCURACY_BOOSTER: 18,
|
||||||
|
MULTI_HIT: 19,
|
||||||
|
DAMAGE_MONEY_REWARD: 20,
|
||||||
|
BATON: 21,
|
||||||
|
TURN_END_ITEM_STEAL: 22,
|
||||||
|
CONTACT_ITEM_STEAL_CHANCE: 23,
|
||||||
|
EVO_TRACKER: 40,
|
||||||
|
BASE_STAT_TOTAL: 50,
|
||||||
|
BASE_STAT_FLAT: 51,
|
||||||
|
INCREMENTING_STAT: 52,
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type HeldItemEffect = EnumValues<typeof HeldItemEffect>;
|
@ -1,3 +1,5 @@
|
|||||||
|
import type { EnumValues } from "#types/enum-types";
|
||||||
|
|
||||||
// TODO: make category the lower 2 bytes
|
// TODO: make category the lower 2 bytes
|
||||||
export const HeldItemId = {
|
export const HeldItemId = {
|
||||||
NONE: 0x0000,
|
NONE: 0x0000,
|
||||||
@ -92,19 +94,24 @@ export const HeldItemId = {
|
|||||||
GIMMIGHOUL_EVO_TRACKER: 0x0A01,
|
GIMMIGHOUL_EVO_TRACKER: 0x0A01,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type HeldItemId = (typeof HeldItemId)[keyof typeof HeldItemId];
|
export type HeldItemId = EnumValues<typeof HeldItemId>;
|
||||||
|
|
||||||
|
type HeldItemNameMap = {
|
||||||
|
[k in HeldItemName as (typeof HeldItemId)[k]]: k
|
||||||
|
}
|
||||||
|
|
||||||
type HeldItemName = keyof typeof HeldItemId;
|
type HeldItemName = keyof typeof HeldItemId;
|
||||||
type HeldItemValue = typeof HeldItemId[HeldItemName]; // equivalent to `HeldItemId`
|
|
||||||
|
|
||||||
// Use a type-safe reducer to force number keys and values
|
/** `const object` mapping all held item IDs to their respective names. */
|
||||||
export const HeldItemNames: Record<HeldItemValue, HeldItemName> = Object.entries(HeldItemId).reduce(
|
// TODO: This stores names as UPPER_SNAKE_CASE, but the locales are in PascalCase...
|
||||||
|
export const HeldItemNames = Object.freeze(Object.entries(HeldItemId).reduce(
|
||||||
|
// Use a type-safe reducer to force number keys and values
|
||||||
(acc, [key, value]) => {
|
(acc, [key, value]) => {
|
||||||
acc[value as HeldItemValue] = key as HeldItemName;
|
acc[value] = key;
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{} as Record<HeldItemValue, HeldItemName>
|
{}
|
||||||
);
|
)) as HeldItemNameMap;
|
||||||
|
|
||||||
export const HeldItemCategoryId = {
|
export const HeldItemCategoryId = {
|
||||||
NONE: 0x0000,
|
NONE: 0x0000,
|
||||||
@ -120,7 +127,7 @@ export const HeldItemCategoryId = {
|
|||||||
EVO_TRACKER: 0x0A00,
|
EVO_TRACKER: 0x0A00,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type HeldItemCategoryId = (typeof HeldItemCategoryId)[keyof typeof HeldItemCategoryId];
|
export type HeldItemCategoryId = EnumValues<typeof HeldItemCategoryId>;
|
||||||
|
|
||||||
const ITEM_CATEGORY_MASK = 0xFF00
|
const ITEM_CATEGORY_MASK = 0xFF00
|
||||||
|
|
||||||
|
99
src/enums/reward-id.ts
Normal file
99
src/enums/reward-id.ts
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import type { EnumValues } from "#types/enum-types";
|
||||||
|
|
||||||
|
export const RewardId = {
|
||||||
|
NONE: 0x0000,
|
||||||
|
|
||||||
|
POKEBALL: 0x2001,
|
||||||
|
GREAT_BALL: 0x2002,
|
||||||
|
ULTRA_BALL: 0x2003,
|
||||||
|
ROGUE_BALL: 0x2004,
|
||||||
|
MASTER_BALL: 0x2005,
|
||||||
|
|
||||||
|
VOUCHER: 0x2101,
|
||||||
|
VOUCHER_PLUS: 0x2102,
|
||||||
|
VOUCHER_PREMIUM: 0x2103,
|
||||||
|
|
||||||
|
NUGGET: 0x2201,
|
||||||
|
BIG_NUGGET: 0x2202,
|
||||||
|
RELIC_GOLD: 0x2203,
|
||||||
|
|
||||||
|
RARE_CANDY: 0x2301,
|
||||||
|
RARER_CANDY: 0x2302,
|
||||||
|
|
||||||
|
EVOLUTION_ITEM: 0x2401,
|
||||||
|
RARE_EVOLUTION_ITEM: 0x2402,
|
||||||
|
|
||||||
|
POTION: 0x2501,
|
||||||
|
SUPER_POTION: 0x2502,
|
||||||
|
HYPER_POTION: 0x2503,
|
||||||
|
MAX_POTION: 0x2504,
|
||||||
|
FULL_HEAL: 0x2505,
|
||||||
|
FULL_RESTORE: 0x2506,
|
||||||
|
|
||||||
|
REVIVE: 0x2601,
|
||||||
|
MAX_REVIVE: 0x2602,
|
||||||
|
SACRED_ASH: 0x2603,
|
||||||
|
|
||||||
|
ETHER: 0x2701,
|
||||||
|
MAX_ETHER: 0x2702,
|
||||||
|
|
||||||
|
ELIXIR: 0x2801,
|
||||||
|
MAX_ELIXIR: 0x2802,
|
||||||
|
|
||||||
|
PP_UP: 0x2901,
|
||||||
|
PP_MAX: 0x2902,
|
||||||
|
|
||||||
|
TM_COMMON: 0x2A01,
|
||||||
|
TM_GREAT: 0x2A02,
|
||||||
|
TM_ULTRA: 0x2A03,
|
||||||
|
|
||||||
|
MINT: 0x2B01,
|
||||||
|
TERA_SHARD: 0x2B02,
|
||||||
|
MEMORY_MUSHROOM: 0x2B03,
|
||||||
|
DNA_SPLICERS: 0x2B04,
|
||||||
|
|
||||||
|
HELD_ITEM: 0x2C01,
|
||||||
|
SPECIES_STAT_BOOSTER: 0x2C02,
|
||||||
|
RARE_SPECIES_STAT_BOOSTER: 0x2C03,
|
||||||
|
BASE_STAT_BOOSTER: 0x2C04,
|
||||||
|
ATTACK_TYPE_BOOSTER: 0x2C05,
|
||||||
|
BERRY: 0x2C06,
|
||||||
|
|
||||||
|
TRAINER_ITEM: 0x2D01,
|
||||||
|
TEMP_STAT_STAGE_BOOSTER: 0x2D02,
|
||||||
|
LURE: 0x2D03,
|
||||||
|
SUPER_LURE: 0x2D04,
|
||||||
|
MAX_LURE: 0x2D05,
|
||||||
|
|
||||||
|
FORM_CHANGE_ITEM: 0x2E01,
|
||||||
|
RARE_FORM_CHANGE_ITEM: 0x2E02,
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type RewardId = EnumValues<typeof RewardId>;
|
||||||
|
|
||||||
|
export const RewardCategoryId = {
|
||||||
|
NONE: 0x0000,
|
||||||
|
POKEBALL: 0x0100,
|
||||||
|
VOUCHER: 0x0200,
|
||||||
|
MONEY: 0x0300,
|
||||||
|
CANDY: 0x0400,
|
||||||
|
EVOLUTION_ITEM: 0x0500,
|
||||||
|
HEALING: 0x0600,
|
||||||
|
REVIVE: 0x0700,
|
||||||
|
ETHER: 0x0800,
|
||||||
|
ELIXIR: 0x0900,
|
||||||
|
PP_UP: 0x0A00,
|
||||||
|
TM: 0x0B00,
|
||||||
|
OTHER: 0x0C00,
|
||||||
|
HELD_ITEM: 0x0D00,
|
||||||
|
TRAINER_ITEM: 0x0E00,
|
||||||
|
FORM_CHANGE_ITEM: 0x0F00,
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type RewardCategoryId = EnumValues<typeof RewardCategoryId>;
|
||||||
|
|
||||||
|
const ITEM_CATEGORY_MASK = 0xFF00
|
||||||
|
|
||||||
|
export function getRewardCategory(itemId: RewardId): RewardCategoryId {
|
||||||
|
return (itemId & ITEM_CATEGORY_MASK) as RewardCategoryId;
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
export enum ModifierPoolType {
|
export enum RewardPoolType {
|
||||||
PLAYER,
|
PLAYER,
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
export enum RewardTier {
|
export enum RarityTier {
|
||||||
COMMON,
|
COMMON,
|
||||||
GREAT,
|
GREAT,
|
||||||
ULTRA,
|
ULTRA,
|
||||||
|
@ -1,56 +1,56 @@
|
|||||||
export const TrainerItemId = {
|
export const TrainerItemId = {
|
||||||
NONE: 0x0000,
|
NONE: 0x0000,
|
||||||
|
|
||||||
MAP: 0x0B01,
|
MAP: 0x1001,
|
||||||
IV_SCANNER: 0x0B02,
|
IV_SCANNER: 0x1002,
|
||||||
LOCK_CAPSULE: 0x0B03,
|
LOCK_CAPSULE: 0x1003,
|
||||||
MEGA_BRACELET: 0x0B04,
|
MEGA_BRACELET: 0x1004,
|
||||||
DYNAMAX_BAND: 0x0B05,
|
DYNAMAX_BAND: 0x1005,
|
||||||
TERA_ORB: 0x0B06,
|
TERA_ORB: 0x1006,
|
||||||
|
|
||||||
GOLDEN_POKEBALL: 0x0B07,
|
GOLDEN_POKEBALL: 0x1007,
|
||||||
|
|
||||||
OVAL_CHARM: 0x0B08,
|
OVAL_CHARM: 0x1008,
|
||||||
EXP_SHARE: 0x0B09,
|
EXP_SHARE: 0x1009,
|
||||||
EXP_BALANCE: 0x0B0A,
|
EXP_BALANCE: 0x100A,
|
||||||
|
|
||||||
CANDY_JAR: 0x0B0B,
|
CANDY_JAR: 0x100B,
|
||||||
BERRY_POUCH: 0x0B0C,
|
BERRY_POUCH: 0x100C,
|
||||||
|
|
||||||
HEALING_CHARM: 0x0B0D,
|
HEALING_CHARM: 0x100D,
|
||||||
EXP_CHARM: 0x0B0E,
|
EXP_CHARM: 0x100E,
|
||||||
SUPER_EXP_CHARM: 0x0B0F,
|
SUPER_EXP_CHARM: 0x100F,
|
||||||
GOLDEN_EXP_CHARM: 0x0B10,
|
GOLDEN_EXP_CHARM: 0x1010,
|
||||||
AMULET_COIN: 0x0B11,
|
AMULET_COIN: 0x1011,
|
||||||
|
|
||||||
ABILITY_CHARM: 0x0B12,
|
ABILITY_CHARM: 0x1012,
|
||||||
SHINY_CHARM: 0x0B13,
|
SHINY_CHARM: 0x1013,
|
||||||
CATCHING_CHARM: 0x0B14,
|
CATCHING_CHARM: 0x1014,
|
||||||
|
|
||||||
BLACK_SLUDGE: 0x0B15,
|
BLACK_SLUDGE: 0x1015,
|
||||||
GOLDEN_BUG_NET: 0x0B16,
|
GOLDEN_BUG_NET: 0x1016,
|
||||||
|
|
||||||
LURE: 0x0C01,
|
LURE: 0x1101,
|
||||||
SUPER_LURE: 0x0C02,
|
SUPER_LURE: 0x1102,
|
||||||
MAX_LURE: 0x0C03,
|
MAX_LURE: 0x1103,
|
||||||
|
|
||||||
X_ATTACK: 0x0D01,
|
X_ATTACK: 0x1201,
|
||||||
X_DEFENSE: 0x0D02,
|
X_DEFENSE: 0x1202,
|
||||||
X_SP_ATK: 0x0D03,
|
X_SP_ATK: 0x1203,
|
||||||
X_SP_DEF: 0x0D04,
|
X_SP_DEF: 0x1204,
|
||||||
X_SPEED: 0x0D05,
|
X_SPEED: 0x1205,
|
||||||
X_ACCURACY: 0x0D06,
|
X_ACCURACY: 0x1206,
|
||||||
DIRE_HIT: 0x0D07,
|
DIRE_HIT: 0x1207,
|
||||||
|
|
||||||
ENEMY_DAMAGE_BOOSTER: 0x0E01,
|
ENEMY_DAMAGE_BOOSTER: 0x1301,
|
||||||
ENEMY_DAMAGE_REDUCTION: 0x0E02,
|
ENEMY_DAMAGE_REDUCTION: 0x1302,
|
||||||
ENEMY_HEAL: 0x0E03,
|
ENEMY_HEAL: 0x1303,
|
||||||
ENEMY_ATTACK_POISON_CHANCE: 0x0E04,
|
ENEMY_ATTACK_POISON_CHANCE: 0x1304,
|
||||||
ENEMY_ATTACK_PARALYZE_CHANCE: 0x0E05,
|
ENEMY_ATTACK_PARALYZE_CHANCE: 0x1305,
|
||||||
ENEMY_ATTACK_BURN_CHANCE: 0x0E06,
|
ENEMY_ATTACK_BURN_CHANCE: 0x1306,
|
||||||
ENEMY_STATUS_EFFECT_HEAL_CHANCE: 0x0E07,
|
ENEMY_STATUS_EFFECT_HEAL_CHANCE: 0x1307,
|
||||||
ENEMY_ENDURE_CHANCE: 0x0E08,
|
ENEMY_ENDURE_CHANCE: 0x1308,
|
||||||
ENEMY_FUSED_CHANCE: 0x0E09,
|
ENEMY_FUSED_CHANCE: 0x1309,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type TrainerItemId = (typeof TrainerItemId)[keyof typeof TrainerItemId];
|
export type TrainerItemId = (typeof TrainerItemId)[keyof typeof TrainerItemId];
|
||||||
|
@ -5,7 +5,7 @@ export enum UiMode {
|
|||||||
FIGHT,
|
FIGHT,
|
||||||
BALL,
|
BALL,
|
||||||
TARGET_SELECT,
|
TARGET_SELECT,
|
||||||
MODIFIER_SELECT,
|
REWARD_SELECT,
|
||||||
SAVE_SLOT,
|
SAVE_SLOT,
|
||||||
PARTY,
|
PARTY,
|
||||||
SUMMARY,
|
SUMMARY,
|
||||||
|
@ -19,6 +19,7 @@ import { ArenaTagSide } from "#enums/arena-tag-side";
|
|||||||
import type { ArenaTagType } from "#enums/arena-tag-type";
|
import type { ArenaTagType } from "#enums/arena-tag-type";
|
||||||
import type { BattlerIndex } from "#enums/battler-index";
|
import type { BattlerIndex } from "#enums/battler-index";
|
||||||
import { BiomeId } from "#enums/biome-id";
|
import { BiomeId } from "#enums/biome-id";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { CommonAnim } from "#enums/move-anims-common";
|
import { CommonAnim } from "#enums/move-anims-common";
|
||||||
import type { MoveId } from "#enums/move-id";
|
import type { MoveId } from "#enums/move-id";
|
||||||
import type { PokemonType } from "#enums/pokemon-type";
|
import type { PokemonType } from "#enums/pokemon-type";
|
||||||
@ -29,7 +30,6 @@ import { WeatherType } from "#enums/weather-type";
|
|||||||
import { TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#events/arena";
|
import { TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#events/arena";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { applyHeldItems } from "#items/all-held-items";
|
import { applyHeldItems } from "#items/all-held-items";
|
||||||
import { HeldItemEffect } from "#items/held-item";
|
|
||||||
import type { Move } from "#moves/move";
|
import type { Move } from "#moves/move";
|
||||||
import type { AbstractConstructor } from "#types/type-helpers";
|
import type { AbstractConstructor } from "#types/type-helpers";
|
||||||
import { type Constructor, isNullOrUndefined, NumberHolder, randSeedInt } from "#utils/common";
|
import { type Constructor, isNullOrUndefined, NumberHolder, randSeedInt } from "#utils/common";
|
||||||
|
@ -80,6 +80,7 @@ import { ChallengeType } from "#enums/challenge-type";
|
|||||||
import { Challenges } from "#enums/challenges";
|
import { Challenges } from "#enums/challenges";
|
||||||
import { DexAttr } from "#enums/dex-attr";
|
import { DexAttr } from "#enums/dex-attr";
|
||||||
import { FieldPosition } from "#enums/field-position";
|
import { FieldPosition } from "#enums/field-position";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItemId } from "#enums/held-item-id";
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
import { HitResult } from "#enums/hit-result";
|
import { HitResult } from "#enums/hit-result";
|
||||||
import { LearnMoveSituation } from "#enums/learn-move-situation";
|
import { LearnMoveSituation } from "#enums/learn-move-situation";
|
||||||
@ -92,7 +93,7 @@ import { Nature } from "#enums/nature";
|
|||||||
import { PokeballType } from "#enums/pokeball";
|
import { PokeballType } from "#enums/pokeball";
|
||||||
import { PokemonAnimType } from "#enums/pokemon-anim-type";
|
import { PokemonAnimType } from "#enums/pokemon-anim-type";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { SpeciesFormKey } from "#enums/species-form-key";
|
import { SpeciesFormKey } from "#enums/species-form-key";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import {
|
import {
|
||||||
@ -111,7 +112,6 @@ import { UiMode } from "#enums/ui-mode";
|
|||||||
import { WeatherType } from "#enums/weather-type";
|
import { WeatherType } from "#enums/weather-type";
|
||||||
import { doShinySparkleAnim } from "#field/anims";
|
import { doShinySparkleAnim } from "#field/anims";
|
||||||
import { applyHeldItems } from "#items/all-held-items";
|
import { applyHeldItems } from "#items/all-held-items";
|
||||||
import { HeldItemEffect } from "#items/held-item";
|
|
||||||
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
||||||
import { HeldItemManager } from "#items/held-item-manager";
|
import { HeldItemManager } from "#items/held-item-manager";
|
||||||
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
||||||
@ -2882,13 +2882,13 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
*
|
*
|
||||||
* The base shiny odds are {@linkcode BASE_SHINY_CHANCE} / `65536`
|
* The base shiny odds are {@linkcode BASE_SHINY_CHANCE} / `65536`
|
||||||
* @param thresholdOverride number that is divided by `2^16` (`65536`) to get the shiny chance, overrides {@linkcode shinyThreshold} if set (bypassing shiny rate modifiers such as Shiny Charm)
|
* @param thresholdOverride number that is divided by `2^16` (`65536`) to get the shiny chance, overrides {@linkcode shinyThreshold} if set (bypassing shiny rate modifiers such as Shiny Charm)
|
||||||
* @param applyModifiersToOverride If {@linkcode thresholdOverride} is set and this is true, will apply Shiny Charm and event modifiers to {@linkcode thresholdOverride}
|
* @param applyItemsToOverride If {@linkcode thresholdOverride} is set and this is true, will apply Shiny Charm and event modifiers to {@linkcode thresholdOverride}
|
||||||
* @returns `true` if the Pokemon has been set as a shiny, `false` otherwise
|
* @returns `true` if the Pokemon has been set as a shiny, `false` otherwise
|
||||||
*/
|
*/
|
||||||
public trySetShinySeed(thresholdOverride?: number, applyModifiersToOverride?: boolean): boolean {
|
public trySetShinySeed(thresholdOverride?: number, applyItemsToOverride?: boolean): boolean {
|
||||||
if (!this.shiny) {
|
if (!this.shiny) {
|
||||||
const shinyThreshold = new NumberHolder(thresholdOverride ?? BASE_SHINY_CHANCE);
|
const shinyThreshold = new NumberHolder(thresholdOverride ?? BASE_SHINY_CHANCE);
|
||||||
if (applyModifiersToOverride) {
|
if (applyItemsToOverride) {
|
||||||
if (timedEventManager.isEventActive()) {
|
if (timedEventManager.isEventActive()) {
|
||||||
shinyThreshold.value *= timedEventManager.getShinyMultiplier();
|
shinyThreshold.value *= timedEventManager.getShinyMultiplier();
|
||||||
}
|
}
|
||||||
@ -2954,15 +2954,15 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
*
|
*
|
||||||
* The base hidden ability odds are {@linkcode BASE_HIDDEN_ABILITY_CHANCE} / `65536`
|
* The base hidden ability odds are {@linkcode BASE_HIDDEN_ABILITY_CHANCE} / `65536`
|
||||||
* @param thresholdOverride number that is divided by `2^16` (`65536`) to get the HA chance, overrides {@linkcode haThreshold} if set (bypassing HA rate modifiers such as Ability Charm)
|
* @param thresholdOverride number that is divided by `2^16` (`65536`) to get the HA chance, overrides {@linkcode haThreshold} if set (bypassing HA rate modifiers such as Ability Charm)
|
||||||
* @param applyModifiersToOverride If {@linkcode thresholdOverride} is set and this is true, will apply Ability Charm to {@linkcode thresholdOverride}
|
* @param applyItemsToOverride If {@linkcode thresholdOverride} is set and this is true, will apply Ability Charm to {@linkcode thresholdOverride}
|
||||||
* @returns `true` if the Pokemon has been set to have its hidden ability, `false` otherwise
|
* @returns `true` if the Pokemon has been set to have its hidden ability, `false` otherwise
|
||||||
*/
|
*/
|
||||||
public tryRerollHiddenAbilitySeed(thresholdOverride?: number, applyModifiersToOverride?: boolean): boolean {
|
public tryRerollHiddenAbilitySeed(thresholdOverride?: number, applyItemsToOverride?: boolean): boolean {
|
||||||
if (!this.species.abilityHidden) {
|
if (!this.species.abilityHidden) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const haThreshold = new NumberHolder(thresholdOverride ?? BASE_HIDDEN_ABILITY_CHANCE);
|
const haThreshold = new NumberHolder(thresholdOverride ?? BASE_HIDDEN_ABILITY_CHANCE);
|
||||||
if (applyModifiersToOverride) {
|
if (applyItemsToOverride) {
|
||||||
if (!this.hasTrainer()) {
|
if (!this.hasTrainer()) {
|
||||||
globalScene.applyPlayerItems(TrainerItemEffect.HIDDEN_ABILITY_CHANCE_BOOSTER, { numberHolder: haThreshold });
|
globalScene.applyPlayerItems(TrainerItemEffect.HIDDEN_ABILITY_CHANCE_BOOSTER, { numberHolder: haThreshold });
|
||||||
}
|
}
|
||||||
@ -3108,11 +3108,11 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compatible && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) {
|
if (compatible && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) {
|
||||||
if (tmPoolTiers[moveId] === RewardTier.COMMON && this.level >= 15) {
|
if (tmPoolTiers[moveId] === RarityTier.COMMON && this.level >= 15) {
|
||||||
movePool.push([moveId, 4]);
|
movePool.push([moveId, 4]);
|
||||||
} else if (tmPoolTiers[moveId] === RewardTier.GREAT && this.level >= 30) {
|
} else if (tmPoolTiers[moveId] === RarityTier.GREAT && this.level >= 30) {
|
||||||
movePool.push([moveId, 8]);
|
movePool.push([moveId, 8]);
|
||||||
} else if (tmPoolTiers[moveId] === RewardTier.ULTRA && this.level >= 50) {
|
} else if (tmPoolTiers[moveId] === RarityTier.ULTRA && this.level >= 50) {
|
||||||
movePool.push([moveId, 14]);
|
movePool.push([moveId, 14]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -634,7 +634,7 @@ export class Trainer extends Phaser.GameObjects.Container {
|
|||||||
return maxScorePartyMemberIndexes[0];
|
return maxScorePartyMemberIndexes[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
getPartyMemberModifierChanceMultiplier(index: number): number {
|
getPartyMemberItemChanceMultiplier(index: number): number {
|
||||||
switch (this.getPartyTemplate().getStrength(index)) {
|
switch (this.getPartyTemplate().getStrength(index)) {
|
||||||
case PartyMemberStrength.WEAKER:
|
case PartyMemberStrength.WEAKER:
|
||||||
return 0.75;
|
return 0.75;
|
||||||
@ -647,14 +647,14 @@ export class Trainer extends Phaser.GameObjects.Container {
|
|||||||
case PartyMemberStrength.STRONGER:
|
case PartyMemberStrength.STRONGER:
|
||||||
return 0.375;
|
return 0.375;
|
||||||
default:
|
default:
|
||||||
console.warn("getPartyMemberModifierChanceMultiplier not defined. Using default 0");
|
console.warn("getPartyMemberItemChanceMultiplier not defined. Using default 0");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
genTrainerItems(party: EnemyPokemon[]): TrainerItemConfiguration {
|
genTrainerItems(party: EnemyPokemon[]): TrainerItemConfiguration {
|
||||||
if (this.config.genModifiersFunc) {
|
if (this.config.genTrainerItemsFunc) {
|
||||||
return this.config.genModifiersFunc(party);
|
return this.config.genTrainerItemsFunc(party);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -323,7 +323,7 @@ export class GameMode implements GameModeConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getEnemyModifierChance(isBoss: boolean): number {
|
getEnemyItemChance(isBoss: boolean): number {
|
||||||
switch (this.modeId) {
|
switch (this.modeId) {
|
||||||
case GameModes.CLASSIC:
|
case GameModes.CLASSIC:
|
||||||
case GameModes.CHALLENGE:
|
case GameModes.CHALLENGE:
|
||||||
|
@ -24,7 +24,6 @@ import { ExpBoosterHeldItem, type ExpBoostParams } from "#items/exp-booster";
|
|||||||
import { FieldEffectHeldItem, type FieldEffectParams } from "#items/field-effect";
|
import { FieldEffectHeldItem, type FieldEffectParams } from "#items/field-effect";
|
||||||
import { FlinchChanceHeldItem, type FlinchChanceParams } from "#items/flinch-chance";
|
import { FlinchChanceHeldItem, type FlinchChanceParams } from "#items/flinch-chance";
|
||||||
import { FriendshipBoosterHeldItem, type FriendshipBoostParams } from "#items/friendship-booster";
|
import { FriendshipBoosterHeldItem, type FriendshipBoostParams } from "#items/friendship-booster";
|
||||||
import { HeldItemEffect } from "#items/held-item";
|
|
||||||
import { HitHealHeldItem, type HitHealParams } from "#items/hit-heal";
|
import { HitHealHeldItem, type HitHealParams } from "#items/hit-heal";
|
||||||
import { IncrementingStatHeldItem, type IncrementingStatParams } from "#items/incrementing-stat";
|
import { IncrementingStatHeldItem, type IncrementingStatParams } from "#items/incrementing-stat";
|
||||||
import { InstantReviveHeldItem, type InstantReviveParams } from "#items/instant-revive";
|
import { InstantReviveHeldItem, type InstantReviveParams } from "#items/instant-revive";
|
||||||
@ -36,7 +35,8 @@ import { EvolutionStatBoostHeldItem, SpeciesStatBoostHeldItem, type StatBoostPar
|
|||||||
import { SurviveChanceHeldItem, type SurviveChanceParams } from "#items/survive-chance";
|
import { SurviveChanceHeldItem, type SurviveChanceParams } from "#items/survive-chance";
|
||||||
import { TurnEndHealHeldItem, type TurnEndHealParams } from "#items/turn-end-heal";
|
import { TurnEndHealHeldItem, type TurnEndHealParams } from "#items/turn-end-heal";
|
||||||
import { TurnEndStatusHeldItem, type TurnEndStatusParams } from "#items/turn-end-status";
|
import { TurnEndStatusHeldItem, type TurnEndStatusParams } from "#items/turn-end-status";
|
||||||
import { getEnumValues } from "#utils/common";
|
import { getEnumValues } from "#utils/enums";
|
||||||
|
import { HeldItemEffect } from "./HeldItemEffect";
|
||||||
|
|
||||||
export function initHeldItems() {
|
export function initHeldItems() {
|
||||||
for (const berry of getEnumValues(BerryType)) {
|
for (const berry of getEnumValues(BerryType)) {
|
||||||
|
@ -43,7 +43,7 @@ export function initTrainerItems() {
|
|||||||
allTrainerItems[TrainerItemId.CANDY_JAR] = new LevelIncrementBoosterTrainerItem(TrainerItemId.CANDY_JAR, 99);
|
allTrainerItems[TrainerItemId.CANDY_JAR] = new LevelIncrementBoosterTrainerItem(TrainerItemId.CANDY_JAR, 99);
|
||||||
allTrainerItems[TrainerItemId.BERRY_POUCH] = new PreserveBerryTrainerItem(TrainerItemId.BERRY_POUCH, 3);
|
allTrainerItems[TrainerItemId.BERRY_POUCH] = new PreserveBerryTrainerItem(TrainerItemId.BERRY_POUCH, 3);
|
||||||
|
|
||||||
allTrainerItems[TrainerItemId.HEALING_CHARM] = new HealingBoosterTrainerItem(TrainerItemId.HEALING_CHARM, 1.1, 5);
|
allTrainerItems[TrainerItemId.HEALING_CHARM] = new HealingBoosterTrainerItem(TrainerItemId.HEALING_CHARM, 0.1, 5);
|
||||||
allTrainerItems[TrainerItemId.EXP_CHARM] = new ExpBoosterTrainerItem(TrainerItemId.EXP_CHARM, 25, 99);
|
allTrainerItems[TrainerItemId.EXP_CHARM] = new ExpBoosterTrainerItem(TrainerItemId.EXP_CHARM, 25, 99);
|
||||||
allTrainerItems[TrainerItemId.SUPER_EXP_CHARM] = new ExpBoosterTrainerItem(TrainerItemId.SUPER_EXP_CHARM, 60, 30);
|
allTrainerItems[TrainerItemId.SUPER_EXP_CHARM] = new ExpBoosterTrainerItem(TrainerItemId.SUPER_EXP_CHARM, 60, 30);
|
||||||
allTrainerItems[TrainerItemId.GOLDEN_EXP_CHARM] = new ExpBoosterTrainerItem(TrainerItemId.GOLDEN_EXP_CHARM, 100, 10);
|
allTrainerItems[TrainerItemId.GOLDEN_EXP_CHARM] = new ExpBoosterTrainerItem(TrainerItemId.GOLDEN_EXP_CHARM, 100, 10);
|
||||||
|
@ -1,13 +1,21 @@
|
|||||||
// TODO: move to `src/@types/`
|
// TODO: move all types to `src/@types/` and all functions to a utility place
|
||||||
|
|
||||||
import type { FormChangeItem } from "#enums/form-change-item";
|
import type { FormChangeItem } from "#enums/form-change-item";
|
||||||
import type { HeldItemCategoryId, HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemCategoryId, HeldItemId } from "#enums/held-item-id";
|
||||||
import type { RewardTier } from "#enums/reward-tier";
|
import type { RarityTier } from "#enums/reward-tier";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
|
|
||||||
export type HeldItemData = {
|
export type HeldItemData = {
|
||||||
stack: number;
|
stack: number;
|
||||||
|
/**
|
||||||
|
* Whether this item is currently disabled.
|
||||||
|
* @defaultValue `false`
|
||||||
|
*/
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
/**
|
||||||
|
* The item's current cooldown.
|
||||||
|
* @defaultValue `0`
|
||||||
|
*/
|
||||||
cooldown?: number;
|
cooldown?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,7 +75,7 @@ export function isHeldItemPool(value: any): value is HeldItemPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type HeldItemTieredPool = {
|
export type HeldItemTieredPool = {
|
||||||
[key in RewardTier]?: HeldItemPool;
|
[key in RarityTier]?: HeldItemPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
type HeldItemConfigurationEntry = {
|
type HeldItemConfigurationEntry = {
|
||||||
|
47
src/items/held-item-default-tiers.ts
Normal file
47
src/items/held-item-default-tiers.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { getHeldItemCategory, HeldItemCategoryId, HeldItemId } from "#enums/held-item-id";
|
||||||
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
|
|
||||||
|
export const heldItemRarities = {
|
||||||
|
[HeldItemCategoryId.BERRY]: RarityTier.COMMON,
|
||||||
|
|
||||||
|
[HeldItemCategoryId.BASE_STAT_BOOST]: RarityTier.GREAT,
|
||||||
|
[HeldItemId.WHITE_HERB]: RarityTier.GREAT,
|
||||||
|
[HeldItemId.METAL_POWDER]: RarityTier.GREAT,
|
||||||
|
[HeldItemId.QUICK_POWDER]: RarityTier.GREAT,
|
||||||
|
[HeldItemId.DEEP_SEA_SCALE]: RarityTier.GREAT,
|
||||||
|
[HeldItemId.DEEP_SEA_TOOTH]: RarityTier.GREAT,
|
||||||
|
[HeldItemId.SOOTHE_BELL]: RarityTier.GREAT,
|
||||||
|
|
||||||
|
[HeldItemCategoryId.TYPE_ATTACK_BOOSTER]: RarityTier.ULTRA,
|
||||||
|
[HeldItemId.REVIVER_SEED]: RarityTier.ULTRA,
|
||||||
|
[HeldItemId.LIGHT_BALL]: RarityTier.ULTRA,
|
||||||
|
[HeldItemId.EVIOLITE]: RarityTier.ULTRA,
|
||||||
|
[HeldItemId.QUICK_CLAW]: RarityTier.ULTRA,
|
||||||
|
[HeldItemId.MYSTICAL_ROCK]: RarityTier.ULTRA,
|
||||||
|
[HeldItemId.WIDE_LENS]: RarityTier.ULTRA,
|
||||||
|
[HeldItemId.GOLDEN_PUNCH]: RarityTier.ULTRA,
|
||||||
|
[HeldItemId.TOXIC_ORB]: RarityTier.ULTRA,
|
||||||
|
[HeldItemId.FLAME_ORB]: RarityTier.ULTRA,
|
||||||
|
[HeldItemId.LUCKY_EGG]: RarityTier.ULTRA,
|
||||||
|
|
||||||
|
[HeldItemId.FOCUS_BAND]: RarityTier.ROGUE,
|
||||||
|
[HeldItemId.KINGS_ROCK]: RarityTier.ROGUE,
|
||||||
|
[HeldItemId.LEFTOVERS]: RarityTier.ROGUE,
|
||||||
|
[HeldItemId.SHELL_BELL]: RarityTier.ROGUE,
|
||||||
|
[HeldItemId.GRIP_CLAW]: RarityTier.ROGUE,
|
||||||
|
[HeldItemId.SOUL_DEW]: RarityTier.ROGUE,
|
||||||
|
[HeldItemId.BATON]: RarityTier.ROGUE,
|
||||||
|
[HeldItemId.GOLDEN_EGG]: RarityTier.ULTRA,
|
||||||
|
|
||||||
|
[HeldItemId.MINI_BLACK_HOLE]: RarityTier.MASTER,
|
||||||
|
[HeldItemId.MULTI_LENS]: RarityTier.MASTER,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getHeldItemTier(item: HeldItemId): RarityTier {
|
||||||
|
let tier = heldItemRarities[item];
|
||||||
|
if (!tier) {
|
||||||
|
const category = getHeldItemCategory(item);
|
||||||
|
tier = heldItemRarities[category];
|
||||||
|
}
|
||||||
|
return tier ?? RarityTier.LUXURY;
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
import { allHeldItems } from "#data/data-lists";
|
import { allHeldItems } from "#data/data-lists";
|
||||||
import { BerryType } from "#enums/berry-type";
|
import { BerryType } from "#enums/berry-type";
|
||||||
import { HeldItemCategoryId, HeldItemId, HeldItemNames, isCategoryId } from "#enums/held-item-id";
|
import { HeldItemCategoryId, HeldItemId, HeldItemNames, isCategoryId } from "#enums/held-item-id";
|
||||||
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 { HeldItemPoolType } from "#enums/reward-pool-type";
|
||||||
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { PERMANENT_STATS } from "#enums/stat";
|
import { PERMANENT_STATS } from "#enums/stat";
|
||||||
import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
import { attackTypeToHeldItem } from "#items/attack-type-booster";
|
import { attackTypeToHeldItem } from "#items/attack-type-booster";
|
||||||
@ -21,7 +21,8 @@ import {
|
|||||||
isHeldItemPool,
|
isHeldItemPool,
|
||||||
isHeldItemSpecs,
|
isHeldItemSpecs,
|
||||||
} from "#items/held-item-data-types";
|
} from "#items/held-item-data-types";
|
||||||
import { coerceArray, getEnumValues, isNullOrUndefined, pickWeightedIndex, randSeedInt } from "#utils/common";
|
import { coerceArray, isNullOrUndefined, pickWeightedIndex, randSeedInt } from "#utils/common";
|
||||||
|
import { getEnumValues } from "#utils/enums";
|
||||||
|
|
||||||
export const wildHeldItemPool: HeldItemTieredPool = {};
|
export const wildHeldItemPool: HeldItemTieredPool = {};
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ export function assignDailyRunStarterHeldItems(party: PlayerPokemon[]) {
|
|||||||
for (let m = 0; m < 3; m++) {
|
for (let m = 0; m < 3; m++) {
|
||||||
const tierValue = randSeedInt(64);
|
const tierValue = randSeedInt(64);
|
||||||
|
|
||||||
const tier = getDailyRewardTier(tierValue);
|
const tier = getDailyRarityTier(tierValue);
|
||||||
|
|
||||||
const item = getNewHeldItemFromPool(
|
const item = getNewHeldItemFromPool(
|
||||||
getHeldItemPool(HeldItemPoolType.DAILY_STARTER)[tier] as HeldItemPool,
|
getHeldItemPool(HeldItemPoolType.DAILY_STARTER)[tier] as HeldItemPool,
|
||||||
@ -46,20 +47,20 @@ export function assignDailyRunStarterHeldItems(party: PlayerPokemon[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDailyRewardTier(tierValue: number): RewardTier {
|
function getDailyRarityTier(tierValue: number): RarityTier {
|
||||||
if (tierValue > 25) {
|
if (tierValue > 25) {
|
||||||
return RewardTier.COMMON;
|
return RarityTier.COMMON;
|
||||||
}
|
}
|
||||||
if (tierValue > 12) {
|
if (tierValue > 12) {
|
||||||
return RewardTier.GREAT;
|
return RarityTier.GREAT;
|
||||||
}
|
}
|
||||||
if (tierValue > 4) {
|
if (tierValue > 4) {
|
||||||
return RewardTier.ULTRA;
|
return RarityTier.ULTRA;
|
||||||
}
|
}
|
||||||
if (tierValue > 0) {
|
if (tierValue > 0) {
|
||||||
return RewardTier.ROGUE;
|
return RarityTier.ROGUE;
|
||||||
}
|
}
|
||||||
return RewardTier.MASTER;
|
return RarityTier.MASTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHeldItemPool(poolType: HeldItemPoolType): HeldItemTieredPool {
|
function getHeldItemPool(poolType: HeldItemPoolType): HeldItemTieredPool {
|
||||||
@ -101,25 +102,25 @@ export function assignEnemyHeldItemsForWave(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomTier(): RewardTier {
|
function getRandomTier(): RarityTier {
|
||||||
const tierValue = randSeedInt(1024);
|
const tierValue = randSeedInt(1024);
|
||||||
|
|
||||||
if (tierValue > 255) {
|
if (tierValue > 255) {
|
||||||
return RewardTier.COMMON;
|
return RarityTier.COMMON;
|
||||||
}
|
}
|
||||||
if (tierValue > 60) {
|
if (tierValue > 60) {
|
||||||
return RewardTier.GREAT;
|
return RarityTier.GREAT;
|
||||||
}
|
}
|
||||||
if (tierValue > 12) {
|
if (tierValue > 12) {
|
||||||
return RewardTier.ULTRA;
|
return RarityTier.ULTRA;
|
||||||
}
|
}
|
||||||
if (tierValue) {
|
if (tierValue) {
|
||||||
return RewardTier.ROGUE;
|
return RarityTier.ROGUE;
|
||||||
}
|
}
|
||||||
return RewardTier.MASTER;
|
return RarityTier.MASTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
function determineItemPoolTier(pool: HeldItemTieredPool, upgradeCount?: number): RewardTier {
|
function determineItemPoolTier(pool: HeldItemTieredPool, upgradeCount?: number): RarityTier {
|
||||||
let tier = getRandomTier();
|
let tier = getRandomTier();
|
||||||
|
|
||||||
if (!upgradeCount) {
|
if (!upgradeCount) {
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
@ -4,42 +4,9 @@ import { type HeldItemId, HeldItemNames } from "#enums/held-item-id";
|
|||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
// TODO: this should be moved to its own file
|
|
||||||
export const HeldItemEffect = {
|
|
||||||
ATTACK_TYPE_BOOST: 1,
|
|
||||||
TURN_END_HEAL: 2,
|
|
||||||
HIT_HEAL: 3,
|
|
||||||
RESET_NEGATIVE_STAT_STAGE: 4,
|
|
||||||
EXP_BOOSTER: 5,
|
|
||||||
// Should we actually distinguish different berry effects?
|
|
||||||
BERRY: 6,
|
|
||||||
BASE_STAT_BOOSTER: 7,
|
|
||||||
INSTANT_REVIVE: 8,
|
|
||||||
STAT_BOOST: 9,
|
|
||||||
CRIT_BOOST: 10,
|
|
||||||
TURN_END_STATUS: 11,
|
|
||||||
SURVIVE_CHANCE: 12,
|
|
||||||
BYPASS_SPEED_CHANCE: 13,
|
|
||||||
FLINCH_CHANCE: 14,
|
|
||||||
FIELD_EFFECT: 15,
|
|
||||||
FRIENDSHIP_BOOSTER: 16,
|
|
||||||
NATURE_WEIGHT_BOOSTER: 17,
|
|
||||||
ACCURACY_BOOSTER: 18,
|
|
||||||
MULTI_HIT: 19,
|
|
||||||
DAMAGE_MONEY_REWARD: 20,
|
|
||||||
BATON: 21,
|
|
||||||
TURN_END_ITEM_STEAL: 22,
|
|
||||||
CONTACT_ITEM_STEAL_CHANCE: 23,
|
|
||||||
EVO_TRACKER: 40,
|
|
||||||
BASE_STAT_TOTAL: 50,
|
|
||||||
BASE_STAT_FLAT: 51,
|
|
||||||
INCREMENTING_STAT: 52,
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export type HeldItemEffect = (typeof HeldItemEffect)[keyof typeof HeldItemEffect];
|
|
||||||
|
|
||||||
export class HeldItem {
|
export class HeldItem {
|
||||||
// public pokemonId: number;
|
// public pokemonId: number;
|
||||||
|
// TODO: Should this be readonly?
|
||||||
public type: HeldItemId;
|
public type: HeldItemId;
|
||||||
public readonly maxStackCount: number;
|
public readonly maxStackCount: number;
|
||||||
public isTransferable = true;
|
public isTransferable = true;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { NumberHolder } from "#utils/common";
|
import type { NumberHolder } from "#utils/common";
|
||||||
|
|
||||||
export interface AccuracyBoostParams {
|
export interface AccuracyBoostParams {
|
||||||
@ -24,17 +25,17 @@ export class AccuracyBoosterHeldItem extends HeldItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if {@linkcode PokemonMoveAccuracyBoosterModifier} should be applied
|
* Checks if {@linkcode PokemonMoveAccuracyBoosterHeldItem} should be applied
|
||||||
* @param pokemon - The {@linkcode Pokemon} to apply the move accuracy boost to
|
* @param pokemon - The {@linkcode Pokemon} to apply the move accuracy boost to
|
||||||
* @param moveAccuracy - {@linkcode NumberHolder} holding the move accuracy boost
|
* @param moveAccuracy - {@linkcode NumberHolder} holding the move accuracy boost
|
||||||
* @returns `true` if {@linkcode PokemonMoveAccuracyBoosterModifier} should be applied
|
* @returns `true` if {@linkcode PokemonMoveAccuracyBoosterHeldItem} should be applied
|
||||||
*/
|
*/
|
||||||
// override shouldApply(pokemon?: Pokemon, moveAccuracy?: NumberHolder): boolean {
|
// override shouldApply(pokemon?: Pokemon, moveAccuracy?: NumberHolder): boolean {
|
||||||
// return super.shouldApply(pokemon, moveAccuracy) && !!moveAccuracy;
|
// return super.shouldApply(pokemon, moveAccuracy) && !!moveAccuracy;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies {@linkcode PokemonMoveAccuracyBoosterModifier}
|
* Applies {@linkcode PokemonMoveAccuracyBoosterHeldItem}
|
||||||
*/
|
*/
|
||||||
apply({ pokemon, moveAccuracy }: AccuracyBoostParams): true {
|
apply({ pokemon, moveAccuracy }: AccuracyBoostParams): true {
|
||||||
const stackCount = pokemon.heldItemManager.getStack(this.type);
|
const stackCount = pokemon.heldItemManager.getStack(this.type);
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItemId, HeldItemNames } from "#enums/held-item-id";
|
import { HeldItemId, HeldItemNames } from "#enums/held-item-id";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { NumberHolder } from "#utils/common";
|
import type { NumberHolder } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItemId } from "#enums/held-item-id";
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
import { getStatKey, type PermanentStat, Stat } from "#enums/stat";
|
import { getStatKey, type PermanentStat, Stat } from "#enums/stat";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export interface BaseStatBoosterParams {
|
export interface BaseStatBoosterParams {
|
||||||
@ -11,9 +12,9 @@ export interface BaseStatBoosterParams {
|
|||||||
baseStats: number[];
|
baseStats: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PermanentStatToHeldItemMap {
|
type PermanentStatToHeldItemMap = {
|
||||||
[key: number]: HeldItemId;
|
[key in PermanentStat]: HeldItemId;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const permanentStatToHeldItem: PermanentStatToHeldItemMap = {
|
export const permanentStatToHeldItem: PermanentStatToHeldItemMap = {
|
||||||
[Stat.HP]: HeldItemId.HP_UP,
|
[Stat.HP]: HeldItemId.HP_UP,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export interface BaseStatFlatParams {
|
export interface BaseStatFlatParams {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export interface BaseStatTotalParams {
|
export interface BaseStatTotalParams {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { NumberHolder } from "#utils/common";
|
import type { NumberHolder } from "#utils/common";
|
||||||
|
|
||||||
export interface BatonParams {
|
export interface BatonParams {
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { getBerryEffectDescription, getBerryEffectFunc, getBerryName, getBerryPredicate } from "#data/berry";
|
import { getBerryEffectDescription, getBerryEffectFunc, getBerryName, getBerryPredicate } from "#data/berry";
|
||||||
import { BerryType } from "#enums/berry-type";
|
import { BerryType } from "#enums/berry-type";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItemId } from "#enums/held-item-id";
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
import { BerryUsedEvent } from "#events/battle-scene";
|
import { BerryUsedEvent } from "#events/battle-scene";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { ConsumableHeldItem, HeldItemEffect } from "#items/held-item";
|
import { ConsumableHeldItem } from "#items/held-item";
|
||||||
import { TrainerItemEffect } from "#items/trainer-item";
|
import { TrainerItemEffect } from "#items/trainer-item";
|
||||||
|
import type { EnumValues } from "#types/enum-types";
|
||||||
import { BooleanHolder } from "#utils/common";
|
import { BooleanHolder } from "#utils/common";
|
||||||
|
|
||||||
interface BerryTypeToHeldItemMap {
|
type BerryTypeToHeldItemMap = {
|
||||||
[key: number]: HeldItemId;
|
[key in EnumValues<typeof BerryType>]: HeldItemId;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const berryTypeToHeldItem: BerryTypeToHeldItemMap = {
|
// TODO: Rework this to use a bitwise XOR
|
||||||
|
export const berryTypeToHeldItem = {
|
||||||
[BerryType.SITRUS]: HeldItemId.SITRUS_BERRY,
|
[BerryType.SITRUS]: HeldItemId.SITRUS_BERRY,
|
||||||
[BerryType.LUM]: HeldItemId.LUM_BERRY,
|
[BerryType.LUM]: HeldItemId.LUM_BERRY,
|
||||||
[BerryType.ENIGMA]: HeldItemId.ENIGMA_BERRY,
|
[BerryType.ENIGMA]: HeldItemId.ENIGMA_BERRY,
|
||||||
@ -24,7 +27,7 @@ export const berryTypeToHeldItem: BerryTypeToHeldItemMap = {
|
|||||||
[BerryType.LANSAT]: HeldItemId.LANSAT_BERRY,
|
[BerryType.LANSAT]: HeldItemId.LANSAT_BERRY,
|
||||||
[BerryType.STARF]: HeldItemId.STARF_BERRY,
|
[BerryType.STARF]: HeldItemId.STARF_BERRY,
|
||||||
[BerryType.LEPPA]: HeldItemId.LEPPA_BERRY,
|
[BerryType.LEPPA]: HeldItemId.LEPPA_BERRY,
|
||||||
};
|
} satisfies BerryTypeToHeldItemMap;
|
||||||
|
|
||||||
export interface BerryParams {
|
export interface BerryParams {
|
||||||
/** The pokemon with the berry */
|
/** The pokemon with the berry */
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { Command } from "#enums/command";
|
import { Command } from "#enums/command";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { BooleanHolder } from "#utils/common";
|
import type { BooleanHolder } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import type { SpeciesId } from "#enums/species-id";
|
import type { SpeciesId } from "#enums/species-id";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { NumberHolder } from "#utils/common";
|
import type { NumberHolder } from "#utils/common";
|
||||||
|
|
||||||
export interface CritBoostParams {
|
export interface CritBoostParams {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import { TrainerItemEffect } from "#items/trainer-item";
|
import { TrainerItemEffect } from "#items/trainer-item";
|
||||||
import { NumberHolder } from "#utils/common";
|
import { NumberHolder } from "#utils/common";
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItemId } from "#enums/held-item-id";
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
import type { SpeciesId } from "#enums/species-id";
|
import type { SpeciesId } from "#enums/species-id";
|
||||||
import { TrainerItemId } from "#enums/trainer-item-id";
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export interface EvoTrackerParams {
|
export interface EvoTrackerParams {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { NumberHolder } from "#utils/common";
|
import type { NumberHolder } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { NumberHolder } from "#utils/common";
|
import type { NumberHolder } from "#utils/common";
|
||||||
|
|
||||||
export interface FieldEffectParams {
|
export interface FieldEffectParams {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { BooleanHolder } from "#utils/common";
|
import type { BooleanHolder } from "#utils/common";
|
||||||
|
|
||||||
export interface FlinchChanceParams {
|
export interface FlinchChanceParams {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { NumberHolder } from "#utils/common";
|
import type { NumberHolder } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
||||||
import { toDmgValue } from "#utils/common";
|
import { toDmgValue } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { NumberHolder } from "#utils/common";
|
import type { NumberHolder } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { applyAbAttrs } from "#abilities/apply-ab-attrs";
|
import { applyAbAttrs } from "#abilities/apply-ab-attrs";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { ConsumableHeldItem, HeldItemEffect } from "#items/held-item";
|
import { ConsumableHeldItem } from "#items/held-item";
|
||||||
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
||||||
import { toDmgValue } from "#utils/common";
|
import { toDmgValue } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { allHeldItems } from "#data/data-lists";
|
import { allHeldItems } from "#data/data-lists";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import { Pokemon } from "#field/pokemon";
|
import { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import { coerceArray, randSeedFloat } from "#utils/common";
|
import { coerceArray, randSeedFloat } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ export abstract class ItemTransferHeldItem extends HeldItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Change this logic to use held items
|
// TODO: Change this logic to use held items
|
||||||
const transferredModifierTypes: HeldItemId[] = [];
|
const transferredRewards: HeldItemId[] = [];
|
||||||
const heldItems = targetPokemon.heldItemManager.getTransferableHeldItems();
|
const heldItems = targetPokemon.heldItemManager.getTransferableHeldItems();
|
||||||
|
|
||||||
for (let i = 0; i < transferredItemCount; i++) {
|
for (let i = 0; i < transferredItemCount; i++) {
|
||||||
@ -58,16 +59,16 @@ export abstract class ItemTransferHeldItem extends HeldItem {
|
|||||||
const randItem = heldItems[randItemIndex];
|
const randItem = heldItems[randItemIndex];
|
||||||
// TODO: Fix this after updating the various methods in battle-scene.ts
|
// TODO: Fix this after updating the various methods in battle-scene.ts
|
||||||
if (globalScene.tryTransferHeldItem(randItem, targetPokemon, pokemon, false)) {
|
if (globalScene.tryTransferHeldItem(randItem, targetPokemon, pokemon, false)) {
|
||||||
transferredModifierTypes.push(randItem);
|
transferredRewards.push(randItem);
|
||||||
heldItems.splice(randItemIndex, 1);
|
heldItems.splice(randItemIndex, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const mt of transferredModifierTypes) {
|
for (const mt of transferredRewards) {
|
||||||
globalScene.phaseManager.queueMessage(this.getTransferMessage(params, mt));
|
globalScene.phaseManager.queueMessage(this.getTransferMessage(params, mt));
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!transferredModifierTypes.length;
|
return !!transferredRewards.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract getTargets(params: ItemStealParams): Pokemon[];
|
abstract getTargets(params: ItemStealParams): Pokemon[];
|
||||||
@ -80,7 +81,7 @@ export abstract class ItemTransferHeldItem extends HeldItem {
|
|||||||
/**
|
/**
|
||||||
* Modifier for held items that steal items from the enemy at the end of
|
* Modifier for held items that steal items from the enemy at the end of
|
||||||
* each turn.
|
* each turn.
|
||||||
* @see {@linkcode modifierTypes[MINI_BLACK_HOLE]}
|
* @see {@linkcode allRewards[MINI_BLACK_HOLE]}
|
||||||
*/
|
*/
|
||||||
export class TurnEndItemStealHeldItem extends ItemTransferHeldItem {
|
export class TurnEndItemStealHeldItem extends ItemTransferHeldItem {
|
||||||
public effects: HeldItemEffect[] = [HeldItemEffect.TURN_END_ITEM_STEAL];
|
public effects: HeldItemEffect[] = [HeldItemEffect.TURN_END_ITEM_STEAL];
|
||||||
@ -121,7 +122,7 @@ export class TurnEndItemStealHeldItem extends ItemTransferHeldItem {
|
|||||||
/**
|
/**
|
||||||
* Modifier for held items that add a chance to steal items from the target of a
|
* Modifier for held items that add a chance to steal items from the target of a
|
||||||
* successful attack.
|
* successful attack.
|
||||||
* @see {@linkcode modifierTypes[GRIP_CLAW]}
|
* @see {@linkcode allRewards[GRIP_CLAW]}
|
||||||
* @see {@linkcode HeldItemTransferModifier}
|
* @see {@linkcode HeldItemTransferModifier}
|
||||||
*/
|
*/
|
||||||
export class ContactItemStealChanceHeldItem extends ItemTransferHeldItem {
|
export class ContactItemStealChanceHeldItem extends ItemTransferHeldItem {
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { allMoves } from "#data/data-lists";
|
import { allMoves } from "#data/data-lists";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { MoveId } from "#enums/move-id";
|
import type { MoveId } from "#enums/move-id";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import { isNullOrUndefined, type NumberHolder } from "#utils/common";
|
import { isNullOrUndefined, type NumberHolder } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { NumberHolder } from "#utils/common";
|
import type { NumberHolder } from "#utils/common";
|
||||||
|
|
||||||
export interface NatureWeightBoostParams {
|
export interface NatureWeightBoostParams {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { BATTLE_STATS } from "#enums/stat";
|
import { BATTLE_STATS } from "#enums/stat";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { ConsumableHeldItem, HeldItemEffect } from "#items/held-item";
|
import { ConsumableHeldItem } from "#items/held-item";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export interface ResetNegativeStatStageParams {
|
export interface ResetNegativeStatStageParams {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { pokemonEvolutions } from "#balance/pokemon-evolutions";
|
import { pokemonEvolutions } from "#balance/pokemon-evolutions";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import { HeldItemId } from "#enums/held-item-id";
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
import type { SpeciesId } from "#enums/species-id";
|
import type { SpeciesId } from "#enums/species-id";
|
||||||
import type { Stat } from "#enums/stat";
|
import type { Stat } from "#enums/stat";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { NumberHolder } from "#utils/common";
|
import type { NumberHolder } from "#utils/common";
|
||||||
|
|
||||||
export interface StatBoostParams {
|
export interface StatBoostParams {
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import type { BooleanHolder } from "#utils/common";
|
import type { BooleanHolder } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
import { PokemonHealPhase } from "#phases/pokemon-heal-phase";
|
||||||
import { toDmgValue } from "#utils/common";
|
import { toDmgValue } from "#utils/common";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
import { HeldItemEffect } from "#enums/held-item-effect";
|
||||||
import type { HeldItemId } from "#enums/held-item-id";
|
import type { HeldItemId } from "#enums/held-item-id";
|
||||||
import type { StatusEffect } from "#enums/status-effect";
|
import type { StatusEffect } from "#enums/status-effect";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
import type { Pokemon } from "#field/pokemon";
|
||||||
import { HeldItem, HeldItemEffect } from "#items/held-item";
|
import { HeldItem } from "#items/held-item";
|
||||||
|
|
||||||
export interface TurnEndStatusParams {
|
export interface TurnEndStatusParams {
|
||||||
/** The pokemon with the item */
|
/** The pokemon with the item */
|
||||||
|
@ -1,42 +1,42 @@
|
|||||||
import { HeldItemCategoryId, HeldItemId } from "#enums/held-item-id";
|
import { HeldItemCategoryId, HeldItemId } from "#enums/held-item-id";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { dailyStarterHeldItemPool, trainerHeldItemPool, wildHeldItemPool } from "#items/held-item-pool";
|
import { dailyStarterHeldItemPool, trainerHeldItemPool, wildHeldItemPool } from "#items/held-item-pool";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the wild held item pool
|
* Initialize the wild held item pool
|
||||||
*/
|
*/
|
||||||
function initWildHeldItemPool() {
|
function initWildHeldItemPool() {
|
||||||
wildHeldItemPool[RewardTier.COMMON] = [{ entry: HeldItemCategoryId.BERRY, weight: 1 }];
|
wildHeldItemPool[RarityTier.COMMON] = [{ entry: HeldItemCategoryId.BERRY, weight: 1 }];
|
||||||
wildHeldItemPool[RewardTier.GREAT] = [{ entry: HeldItemCategoryId.BASE_STAT_BOOST, weight: 1 }];
|
wildHeldItemPool[RarityTier.GREAT] = [{ entry: HeldItemCategoryId.BASE_STAT_BOOST, weight: 1 }];
|
||||||
wildHeldItemPool[RewardTier.ULTRA] = [
|
wildHeldItemPool[RarityTier.ULTRA] = [
|
||||||
{ entry: HeldItemCategoryId.TYPE_ATTACK_BOOSTER, weight: 5 },
|
{ entry: HeldItemCategoryId.TYPE_ATTACK_BOOSTER, weight: 5 },
|
||||||
{ entry: HeldItemId.WHITE_HERB, weight: 0 },
|
{ entry: HeldItemId.WHITE_HERB, weight: 0 },
|
||||||
];
|
];
|
||||||
wildHeldItemPool[RewardTier.ROGUE] = [{ entry: HeldItemId.LUCKY_EGG, weight: 4 }];
|
wildHeldItemPool[RarityTier.ROGUE] = [{ entry: HeldItemId.LUCKY_EGG, weight: 4 }];
|
||||||
wildHeldItemPool[RewardTier.MASTER] = [{ entry: HeldItemId.GOLDEN_EGG, weight: 1 }];
|
wildHeldItemPool[RarityTier.MASTER] = [{ entry: HeldItemId.GOLDEN_EGG, weight: 1 }];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the trainer pokemon held item pool
|
* Initialize the trainer pokemon held item pool
|
||||||
*/
|
*/
|
||||||
function initTrainerHeldItemPool() {
|
function initTrainerHeldItemPool() {
|
||||||
trainerHeldItemPool[RewardTier.COMMON] = [
|
trainerHeldItemPool[RarityTier.COMMON] = [
|
||||||
{ entry: HeldItemCategoryId.BERRY, weight: 8 },
|
{ entry: HeldItemCategoryId.BERRY, weight: 8 },
|
||||||
{ entry: HeldItemCategoryId.BASE_STAT_BOOST, weight: 3 },
|
{ entry: HeldItemCategoryId.BASE_STAT_BOOST, weight: 3 },
|
||||||
];
|
];
|
||||||
trainerHeldItemPool[RewardTier.GREAT] = [{ entry: HeldItemCategoryId.BASE_STAT_BOOST, weight: 3 }];
|
trainerHeldItemPool[RarityTier.GREAT] = [{ entry: HeldItemCategoryId.BASE_STAT_BOOST, weight: 3 }];
|
||||||
trainerHeldItemPool[RewardTier.ULTRA] = [
|
trainerHeldItemPool[RarityTier.ULTRA] = [
|
||||||
{ entry: HeldItemCategoryId.TYPE_ATTACK_BOOSTER, weight: 10 },
|
{ entry: HeldItemCategoryId.TYPE_ATTACK_BOOSTER, weight: 10 },
|
||||||
{ entry: HeldItemId.WHITE_HERB, weight: 0 },
|
{ entry: HeldItemId.WHITE_HERB, weight: 0 },
|
||||||
];
|
];
|
||||||
trainerHeldItemPool[RewardTier.ROGUE] = [
|
trainerHeldItemPool[RarityTier.ROGUE] = [
|
||||||
{ entry: HeldItemId.FOCUS_BAND, weight: 2 },
|
{ entry: HeldItemId.FOCUS_BAND, weight: 2 },
|
||||||
{ entry: HeldItemId.LUCKY_EGG, weight: 4 },
|
{ entry: HeldItemId.LUCKY_EGG, weight: 4 },
|
||||||
{ entry: HeldItemId.QUICK_CLAW, weight: 1 },
|
{ entry: HeldItemId.QUICK_CLAW, weight: 1 },
|
||||||
{ entry: HeldItemId.GRIP_CLAW, weight: 1 },
|
{ entry: HeldItemId.GRIP_CLAW, weight: 1 },
|
||||||
{ entry: HeldItemId.WIDE_LENS, weight: 1 },
|
{ entry: HeldItemId.WIDE_LENS, weight: 1 },
|
||||||
];
|
];
|
||||||
trainerHeldItemPool[RewardTier.MASTER] = [
|
trainerHeldItemPool[RarityTier.MASTER] = [
|
||||||
{ entry: HeldItemId.KINGS_ROCK, weight: 1 },
|
{ entry: HeldItemId.KINGS_ROCK, weight: 1 },
|
||||||
{ entry: HeldItemId.LEFTOVERS, weight: 1 },
|
{ entry: HeldItemId.LEFTOVERS, weight: 1 },
|
||||||
{ entry: HeldItemId.SHELL_BELL, weight: 1 },
|
{ entry: HeldItemId.SHELL_BELL, weight: 1 },
|
||||||
@ -47,26 +47,26 @@ function initTrainerHeldItemPool() {
|
|||||||
/**
|
/**
|
||||||
* Initialize the daily starter held item pool
|
* Initialize the daily starter held item pool
|
||||||
*/
|
*/
|
||||||
function initDailyStarterModifierPool() {
|
function initDailyStarterRewardPool() {
|
||||||
dailyStarterHeldItemPool[RewardTier.COMMON] = [
|
dailyStarterHeldItemPool[RarityTier.COMMON] = [
|
||||||
{ entry: HeldItemCategoryId.BASE_STAT_BOOST, weight: 1 },
|
{ entry: HeldItemCategoryId.BASE_STAT_BOOST, weight: 1 },
|
||||||
{ entry: HeldItemCategoryId.BERRY, weight: 3 },
|
{ entry: HeldItemCategoryId.BERRY, weight: 3 },
|
||||||
];
|
];
|
||||||
dailyStarterHeldItemPool[RewardTier.GREAT] = [{ entry: HeldItemCategoryId.TYPE_ATTACK_BOOSTER, weight: 5 }];
|
dailyStarterHeldItemPool[RarityTier.GREAT] = [{ entry: HeldItemCategoryId.TYPE_ATTACK_BOOSTER, weight: 5 }];
|
||||||
dailyStarterHeldItemPool[RewardTier.ULTRA] = [
|
dailyStarterHeldItemPool[RarityTier.ULTRA] = [
|
||||||
{ entry: HeldItemId.REVIVER_SEED, weight: 4 },
|
{ entry: HeldItemId.REVIVER_SEED, weight: 4 },
|
||||||
{ entry: HeldItemId.SOOTHE_BELL, weight: 1 },
|
{ entry: HeldItemId.SOOTHE_BELL, weight: 1 },
|
||||||
{ entry: HeldItemId.SOUL_DEW, weight: 1 },
|
{ entry: HeldItemId.SOUL_DEW, weight: 1 },
|
||||||
{ entry: HeldItemId.GOLDEN_PUNCH, weight: 1 },
|
{ entry: HeldItemId.GOLDEN_PUNCH, weight: 1 },
|
||||||
];
|
];
|
||||||
dailyStarterHeldItemPool[RewardTier.ROGUE] = [
|
dailyStarterHeldItemPool[RarityTier.ROGUE] = [
|
||||||
{ entry: HeldItemId.GRIP_CLAW, weight: 5 },
|
{ entry: HeldItemId.GRIP_CLAW, weight: 5 },
|
||||||
{ entry: HeldItemId.BATON, weight: 2 },
|
{ entry: HeldItemId.BATON, weight: 2 },
|
||||||
{ entry: HeldItemId.FOCUS_BAND, weight: 5 },
|
{ entry: HeldItemId.FOCUS_BAND, weight: 5 },
|
||||||
{ entry: HeldItemId.QUICK_CLAW, weight: 3 },
|
{ entry: HeldItemId.QUICK_CLAW, weight: 3 },
|
||||||
{ entry: HeldItemId.KINGS_ROCK, weight: 3 },
|
{ entry: HeldItemId.KINGS_ROCK, weight: 3 },
|
||||||
];
|
];
|
||||||
dailyStarterHeldItemPool[RewardTier.MASTER] = [
|
dailyStarterHeldItemPool[RarityTier.MASTER] = [
|
||||||
{ entry: HeldItemId.LEFTOVERS, weight: 1 },
|
{ entry: HeldItemId.LEFTOVERS, weight: 1 },
|
||||||
{ entry: HeldItemId.SHELL_BELL, weight: 1 },
|
{ entry: HeldItemId.SHELL_BELL, weight: 1 },
|
||||||
];
|
];
|
||||||
@ -76,5 +76,5 @@ export function initHeldItemPools() {
|
|||||||
// Default held item pools for specific scenarios
|
// Default held item pools for specific scenarios
|
||||||
initWildHeldItemPool();
|
initWildHeldItemPool();
|
||||||
initTrainerHeldItemPool();
|
initTrainerHeldItemPool();
|
||||||
initDailyStarterModifierPool();
|
initDailyStarterRewardPool();
|
||||||
}
|
}
|
||||||
|
@ -1,37 +1,37 @@
|
|||||||
/* biome-ignore-start lint/correctness/noUnusedImports: tsdoc imports */
|
/* biome-ignore-start lint/correctness/noUnusedImports: tsdoc imports */
|
||||||
import type { initModifierTypes } from "#modifiers/modifier-type";
|
import type { initRewards, Reward } from "#items/reward";
|
||||||
/* biome-ignore-end lint/correctness/noUnusedImports: tsdoc imports */
|
/* biome-ignore-end lint/correctness/noUnusedImports: tsdoc imports */
|
||||||
|
|
||||||
import { timedEventManager } from "#app/global-event-manager";
|
import { timedEventManager } from "#app/global-event-manager";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { pokemonEvolutions } from "#balance/pokemon-evolutions";
|
import { pokemonEvolutions } from "#balance/pokemon-evolutions";
|
||||||
import { allHeldItems, allTrainerItems, modifierTypes } from "#data/data-lists";
|
import { allHeldItems, allRewards, allTrainerItems } from "#data/data-lists";
|
||||||
import { MAX_PER_TYPE_POKEBALLS } from "#data/pokeball";
|
import { MAX_PER_TYPE_POKEBALLS } from "#data/pokeball";
|
||||||
import { AbilityId } from "#enums/ability-id";
|
import { AbilityId } from "#enums/ability-id";
|
||||||
import { HeldItemId } from "#enums/held-item-id";
|
import { HeldItemId } from "#enums/held-item-id";
|
||||||
import { MoveId } from "#enums/move-id";
|
import { MoveId } from "#enums/move-id";
|
||||||
import { PokeballType } from "#enums/pokeball";
|
import { PokeballType } from "#enums/pokeball";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import { TrainerItemId } from "#enums/trainer-item-id";
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import { Unlockables } from "#enums/unlockables";
|
import { Unlockables } from "#enums/unlockables";
|
||||||
import type { Pokemon } from "#field/pokemon";
|
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 { TurnEndStatusHeldItem } from "#items/turn-end-status";
|
||||||
import { modifierPool } from "#modifiers/modifier-pools";
|
import type { WeightedRewardWeightFunc } from "#types/rewards";
|
||||||
import { WeightedModifierType } from "#modifiers/modifier-type";
|
|
||||||
import type { WeightedModifierTypeWeightFunc } from "#types/modifier-types";
|
|
||||||
import { isNullOrUndefined } from "#utils/common";
|
import { isNullOrUndefined } from "#utils/common";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the common modifier pool
|
* Initialize the common modifier pool
|
||||||
*/
|
*/
|
||||||
function initCommonModifierPool() {
|
function initCommonRewardPool() {
|
||||||
modifierPool[RewardTier.COMMON] = [
|
rewardPool[RarityTier.COMMON] = [
|
||||||
new WeightedModifierType(modifierTypes.POKEBALL, () => (hasMaximumBalls(PokeballType.POKEBALL) ? 0 : 6), 6),
|
new WeightedReward(allRewards.POKEBALL, () => (hasMaximumBalls(PokeballType.POKEBALL) ? 0 : 6), 6),
|
||||||
new WeightedModifierType(modifierTypes.RARE_CANDY, 2),
|
new WeightedReward(allRewards.RARE_CANDY, 2),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.POTION,
|
allRewards.POTION,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const thresholdPartyMemberCount = Math.min(
|
const thresholdPartyMemberCount = Math.min(
|
||||||
party.filter(p => p.getInverseHp() >= 10 && p.getHpRatio() <= 0.875 && !p.isFainted()).length,
|
party.filter(p => p.getInverseHp() >= 10 && p.getHpRatio() <= 0.875 && !p.isFainted()).length,
|
||||||
@ -41,8 +41,8 @@ function initCommonModifierPool() {
|
|||||||
},
|
},
|
||||||
9,
|
9,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.SUPER_POTION,
|
allRewards.SUPER_POTION,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const thresholdPartyMemberCount = Math.min(
|
const thresholdPartyMemberCount = Math.min(
|
||||||
party.filter(p => p.getInverseHp() >= 25 && p.getHpRatio() <= 0.75 && !p.isFainted()).length,
|
party.filter(p => p.getInverseHp() >= 25 && p.getHpRatio() <= 0.75 && !p.isFainted()).length,
|
||||||
@ -52,8 +52,8 @@ function initCommonModifierPool() {
|
|||||||
},
|
},
|
||||||
3,
|
3,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.ETHER,
|
allRewards.ETHER,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const thresholdPartyMemberCount = Math.min(
|
const thresholdPartyMemberCount = Math.min(
|
||||||
party.filter(
|
party.filter(
|
||||||
@ -71,8 +71,8 @@ function initCommonModifierPool() {
|
|||||||
},
|
},
|
||||||
9,
|
9,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.MAX_ETHER,
|
allRewards.MAX_ETHER,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const thresholdPartyMemberCount = Math.min(
|
const thresholdPartyMemberCount = Math.min(
|
||||||
party.filter(
|
party.filter(
|
||||||
@ -90,25 +90,22 @@ function initCommonModifierPool() {
|
|||||||
},
|
},
|
||||||
3,
|
3,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(modifierTypes.LURE, lureWeightFunc(TrainerItemId.LURE, 2)),
|
new WeightedReward(allRewards.LURE, lureWeightFunc(TrainerItemId.LURE, 2)),
|
||||||
new WeightedModifierType(modifierTypes.TEMP_STAT_STAGE_BOOSTER, 4),
|
new WeightedReward(allRewards.TEMP_STAT_STAGE_BOOSTER, 4),
|
||||||
new WeightedModifierType(modifierTypes.BERRY, 2),
|
new WeightedReward(allRewards.BERRY, 2),
|
||||||
new WeightedModifierType(modifierTypes.TM_COMMON, 2),
|
new WeightedReward(allRewards.TM_COMMON, 2),
|
||||||
].map(m => {
|
];
|
||||||
m.setTier(RewardTier.COMMON);
|
|
||||||
return m;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the Great modifier pool
|
* Initialize the Great modifier pool
|
||||||
*/
|
*/
|
||||||
function initGreatModifierPool() {
|
function initGreatRewardPool() {
|
||||||
modifierPool[RewardTier.GREAT] = [
|
rewardPool[RarityTier.GREAT] = [
|
||||||
new WeightedModifierType(modifierTypes.GREAT_BALL, () => (hasMaximumBalls(PokeballType.GREAT_BALL) ? 0 : 6), 6),
|
new WeightedReward(allRewards.GREAT_BALL, () => (hasMaximumBalls(PokeballType.GREAT_BALL) ? 0 : 6), 6),
|
||||||
new WeightedModifierType(modifierTypes.PP_UP, 2),
|
new WeightedReward(allRewards.PP_UP, 2),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.FULL_HEAL,
|
allRewards.FULL_HEAL,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const statusEffectPartyMemberCount = Math.min(
|
const statusEffectPartyMemberCount = Math.min(
|
||||||
party.filter(
|
party.filter(
|
||||||
@ -126,31 +123,31 @@ function initGreatModifierPool() {
|
|||||||
},
|
},
|
||||||
18,
|
18,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.REVIVE,
|
allRewards.REVIVE,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const faintedPartyMemberCount = Math.min(party.filter(p => p.isFainted()).length, 3);
|
const faintedPartyMemberCount = Math.min(party.filter(p => p.isFainted()).length, 3);
|
||||||
return faintedPartyMemberCount * 9;
|
return faintedPartyMemberCount * 9;
|
||||||
},
|
},
|
||||||
27,
|
27,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.MAX_REVIVE,
|
allRewards.MAX_REVIVE,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const faintedPartyMemberCount = Math.min(party.filter(p => p.isFainted()).length, 3);
|
const faintedPartyMemberCount = Math.min(party.filter(p => p.isFainted()).length, 3);
|
||||||
return faintedPartyMemberCount * 3;
|
return faintedPartyMemberCount * 3;
|
||||||
},
|
},
|
||||||
9,
|
9,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.SACRED_ASH,
|
allRewards.SACRED_ASH,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
return party.filter(p => p.isFainted()).length >= Math.ceil(party.length / 2) ? 1 : 0;
|
return party.filter(p => p.isFainted()).length >= Math.ceil(party.length / 2) ? 1 : 0;
|
||||||
},
|
},
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.HYPER_POTION,
|
allRewards.HYPER_POTION,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const thresholdPartyMemberCount = Math.min(
|
const thresholdPartyMemberCount = Math.min(
|
||||||
party.filter(p => p.getInverseHp() >= 100 && p.getHpRatio() <= 0.625 && !p.isFainted()).length,
|
party.filter(p => p.getInverseHp() >= 100 && p.getHpRatio() <= 0.625 && !p.isFainted()).length,
|
||||||
@ -160,8 +157,8 @@ function initGreatModifierPool() {
|
|||||||
},
|
},
|
||||||
9,
|
9,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.MAX_POTION,
|
allRewards.MAX_POTION,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const thresholdPartyMemberCount = Math.min(
|
const thresholdPartyMemberCount = Math.min(
|
||||||
party.filter(p => p.getInverseHp() >= 100 && p.getHpRatio() <= 0.5 && !p.isFainted()).length,
|
party.filter(p => p.getInverseHp() >= 100 && p.getHpRatio() <= 0.5 && !p.isFainted()).length,
|
||||||
@ -171,8 +168,8 @@ function initGreatModifierPool() {
|
|||||||
},
|
},
|
||||||
3,
|
3,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.FULL_RESTORE,
|
allRewards.FULL_RESTORE,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const statusEffectPartyMemberCount = Math.min(
|
const statusEffectPartyMemberCount = Math.min(
|
||||||
party.filter(
|
party.filter(
|
||||||
@ -195,8 +192,8 @@ function initGreatModifierPool() {
|
|||||||
},
|
},
|
||||||
3,
|
3,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.ELIXIR,
|
allRewards.ELIXIR,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const thresholdPartyMemberCount = Math.min(
|
const thresholdPartyMemberCount = Math.min(
|
||||||
party.filter(
|
party.filter(
|
||||||
@ -214,8 +211,8 @@ function initGreatModifierPool() {
|
|||||||
},
|
},
|
||||||
9,
|
9,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.MAX_ELIXIR,
|
allRewards.MAX_ELIXIR,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const thresholdPartyMemberCount = Math.min(
|
const thresholdPartyMemberCount = Math.min(
|
||||||
party.filter(
|
party.filter(
|
||||||
@ -233,26 +230,26 @@ function initGreatModifierPool() {
|
|||||||
},
|
},
|
||||||
3,
|
3,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(modifierTypes.DIRE_HIT, 4),
|
new WeightedReward(allRewards.DIRE_HIT, 4),
|
||||||
new WeightedModifierType(modifierTypes.SUPER_LURE, lureWeightFunc(TrainerItemId.SUPER_LURE, 4)),
|
new WeightedReward(allRewards.SUPER_LURE, lureWeightFunc(TrainerItemId.SUPER_LURE, 4)),
|
||||||
new WeightedModifierType(modifierTypes.NUGGET, skipInLastClassicWaveOrDefault(5)),
|
new WeightedReward(allRewards.NUGGET, skipInLastClassicWaveOrDefault(5)),
|
||||||
new WeightedModifierType(modifierTypes.SPECIES_STAT_BOOSTER, 4),
|
new WeightedReward(allRewards.SPECIES_STAT_BOOSTER, 4),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.EVOLUTION_ITEM,
|
allRewards.EVOLUTION_ITEM,
|
||||||
() => {
|
() => {
|
||||||
return Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 15), 8);
|
return Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 15), 8);
|
||||||
},
|
},
|
||||||
8,
|
8,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.MAP,
|
allRewards.MAP,
|
||||||
() => (globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex < 180 ? 2 : 0),
|
() => (globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex < 180 ? 2 : 0),
|
||||||
2,
|
2,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(modifierTypes.SOOTHE_BELL, 2),
|
new WeightedReward(allRewards.SOOTHE_BELL, 2),
|
||||||
new WeightedModifierType(modifierTypes.TM_GREAT, 3),
|
new WeightedReward(allRewards.TM_GREAT, 3),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.MEMORY_MUSHROOM,
|
allRewards.MEMORY_MUSHROOM,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
if (!party.find(p => p.getLearnableLevelMoves().length)) {
|
if (!party.find(p => p.getLearnableLevelMoves().length)) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -264,8 +261,8 @@ function initGreatModifierPool() {
|
|||||||
},
|
},
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3),
|
new WeightedReward(allRewards.BASE_STAT_BOOSTER, 3),
|
||||||
new WeightedModifierType(modifierTypes.TERA_SHARD, (party: Pokemon[]) =>
|
new WeightedReward(allRewards.TERA_SHARD, (party: Pokemon[]) =>
|
||||||
party.filter(
|
party.filter(
|
||||||
p =>
|
p =>
|
||||||
!(p.hasSpecies(SpeciesId.TERAPAGOS) || p.hasSpecies(SpeciesId.OGERPON) || p.hasSpecies(SpeciesId.SHEDINJA)),
|
!(p.hasSpecies(SpeciesId.TERAPAGOS) || p.hasSpecies(SpeciesId.OGERPON) || p.hasSpecies(SpeciesId.SHEDINJA)),
|
||||||
@ -273,8 +270,8 @@ function initGreatModifierPool() {
|
|||||||
? 1
|
? 1
|
||||||
: 0,
|
: 0,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.DNA_SPLICERS,
|
allRewards.DNA_SPLICERS,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
if (party.filter(p => !p.fusionSpecies).length > 1) {
|
if (party.filter(p => !p.fusionSpecies).length > 1) {
|
||||||
if (globalScene.gameMode.isSplicedOnly) {
|
if (globalScene.gameMode.isSplicedOnly) {
|
||||||
@ -288,39 +285,36 @@ function initGreatModifierPool() {
|
|||||||
},
|
},
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.VOUCHER,
|
allRewards.VOUCHER,
|
||||||
(_party: Pokemon[], rerollCount: number) => (!globalScene.gameMode.isDaily ? Math.max(1 - rerollCount, 0) : 0),
|
(_party: Pokemon[], rerollCount: number) => (!globalScene.gameMode.isDaily ? Math.max(1 - rerollCount, 0) : 0),
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
].map(m => {
|
];
|
||||||
m.setTier(RewardTier.GREAT);
|
|
||||||
return m;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the Ultra modifier pool
|
* Initialize the Ultra modifier pool
|
||||||
*/
|
*/
|
||||||
function initUltraModifierPool() {
|
function initUltraRewardPool() {
|
||||||
modifierPool[RewardTier.ULTRA] = [
|
rewardPool[RarityTier.ULTRA] = [
|
||||||
new WeightedModifierType(modifierTypes.ULTRA_BALL, () => (hasMaximumBalls(PokeballType.ULTRA_BALL) ? 0 : 15), 15),
|
new WeightedReward(allRewards.ULTRA_BALL, () => (hasMaximumBalls(PokeballType.ULTRA_BALL) ? 0 : 15), 15),
|
||||||
new WeightedModifierType(modifierTypes.MAX_LURE, lureWeightFunc(TrainerItemId.MAX_LURE, 4)),
|
new WeightedReward(allRewards.MAX_LURE, lureWeightFunc(TrainerItemId.MAX_LURE, 4)),
|
||||||
new WeightedModifierType(modifierTypes.BIG_NUGGET, skipInLastClassicWaveOrDefault(12)),
|
new WeightedReward(allRewards.BIG_NUGGET, skipInLastClassicWaveOrDefault(12)),
|
||||||
new WeightedModifierType(modifierTypes.PP_MAX, 3),
|
new WeightedReward(allRewards.PP_MAX, 3),
|
||||||
new WeightedModifierType(modifierTypes.MINT, 4),
|
new WeightedReward(allRewards.MINT, 4),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.RARE_EVOLUTION_ITEM,
|
allRewards.RARE_EVOLUTION_ITEM,
|
||||||
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 15) * 4, 32),
|
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 15) * 4, 32),
|
||||||
32,
|
32,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.FORM_CHANGE_ITEM,
|
allRewards.FORM_CHANGE_ITEM,
|
||||||
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 6,
|
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 6,
|
||||||
24,
|
24,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(modifierTypes.AMULET_COIN, skipInLastClassicWaveOrDefault(3)),
|
new WeightedReward(allRewards.AMULET_COIN, skipInLastClassicWaveOrDefault(3)),
|
||||||
new WeightedModifierType(modifierTypes.EVIOLITE, (party: Pokemon[]) => {
|
new WeightedReward(allRewards.EVIOLITE, (party: Pokemon[]) => {
|
||||||
const { gameMode, gameData } = globalScene;
|
const { gameMode, gameData } = globalScene;
|
||||||
if (gameMode.isDaily || (!gameMode.isFreshStartChallenge() && gameData.isUnlocked(Unlockables.EVIOLITE))) {
|
if (gameMode.isDaily || (!gameMode.isFreshStartChallenge() && gameData.isUnlocked(Unlockables.EVIOLITE))) {
|
||||||
return party.some(p => {
|
return party.some(p => {
|
||||||
@ -340,9 +334,9 @@ function initUltraModifierPool() {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}),
|
}),
|
||||||
new WeightedModifierType(modifierTypes.RARE_SPECIES_STAT_BOOSTER, 12),
|
new WeightedReward(allRewards.RARE_SPECIES_STAT_BOOSTER, 12),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.LEEK,
|
allRewards.LEEK,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
const checkedSpecies = [SpeciesId.FARFETCHD, SpeciesId.GALAR_FARFETCHD, SpeciesId.SIRFETCHD];
|
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
|
// If a party member doesn't already have a Leek and is one of the relevant species, Leek can appear
|
||||||
@ -357,8 +351,8 @@ function initUltraModifierPool() {
|
|||||||
},
|
},
|
||||||
12,
|
12,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.TOXIC_ORB,
|
allRewards.TOXIC_ORB,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
return party.some(p => {
|
return party.some(p => {
|
||||||
const isHoldingOrb = p.getHeldItems().some(i => i in [HeldItemId.FLAME_ORB, HeldItemId.TOXIC_ORB]);
|
const isHoldingOrb = p.getHeldItems().some(i => i in [HeldItemId.FLAME_ORB, HeldItemId.TOXIC_ORB]);
|
||||||
@ -403,8 +397,8 @@ function initUltraModifierPool() {
|
|||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.FLAME_ORB,
|
allRewards.FLAME_ORB,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
return party.some(p => {
|
return party.some(p => {
|
||||||
const isHoldingOrb = p.getHeldItems().some(i => i in [HeldItemId.FLAME_ORB, HeldItemId.TOXIC_ORB]);
|
const isHoldingOrb = p.getHeldItems().some(i => i in [HeldItemId.FLAME_ORB, HeldItemId.TOXIC_ORB]);
|
||||||
@ -449,8 +443,8 @@ function initUltraModifierPool() {
|
|||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.MYSTICAL_ROCK,
|
allRewards.MYSTICAL_ROCK,
|
||||||
(party: Pokemon[]) => {
|
(party: Pokemon[]) => {
|
||||||
return party.some(p => {
|
return party.some(p => {
|
||||||
const stack = p.heldItemManager.getStack(HeldItemId.MYSTICAL_ROCK);
|
const stack = p.heldItemManager.getStack(HeldItemId.MYSTICAL_ROCK);
|
||||||
@ -496,94 +490,88 @@ function initUltraModifierPool() {
|
|||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(modifierTypes.REVIVER_SEED, 4),
|
new WeightedReward(allRewards.REVIVER_SEED, 4),
|
||||||
new WeightedModifierType(modifierTypes.CANDY_JAR, skipInLastClassicWaveOrDefault(5)),
|
new WeightedReward(allRewards.CANDY_JAR, skipInLastClassicWaveOrDefault(5)),
|
||||||
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 9),
|
new WeightedReward(allRewards.ATTACK_TYPE_BOOSTER, 9),
|
||||||
new WeightedModifierType(modifierTypes.TM_ULTRA, 11),
|
new WeightedReward(allRewards.TM_ULTRA, 11),
|
||||||
new WeightedModifierType(modifierTypes.RARER_CANDY, 4),
|
new WeightedReward(allRewards.RARER_CANDY, 4),
|
||||||
new WeightedModifierType(modifierTypes.GOLDEN_PUNCH, skipInLastClassicWaveOrDefault(2)),
|
new WeightedReward(allRewards.GOLDEN_PUNCH, skipInLastClassicWaveOrDefault(2)),
|
||||||
new WeightedModifierType(modifierTypes.IV_SCANNER, skipInLastClassicWaveOrDefault(4)),
|
new WeightedReward(allRewards.IV_SCANNER, skipInLastClassicWaveOrDefault(4)),
|
||||||
new WeightedModifierType(modifierTypes.EXP_CHARM, skipInLastClassicWaveOrDefault(8)),
|
new WeightedReward(allRewards.EXP_CHARM, skipInLastClassicWaveOrDefault(8)),
|
||||||
new WeightedModifierType(modifierTypes.EXP_SHARE, skipInLastClassicWaveOrDefault(10)),
|
new WeightedReward(allRewards.EXP_SHARE, skipInLastClassicWaveOrDefault(10)),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.TERA_ORB,
|
allRewards.TERA_ORB,
|
||||||
() =>
|
() =>
|
||||||
!globalScene.gameMode.isClassic
|
!globalScene.gameMode.isClassic
|
||||||
? Math.min(Math.max(Math.floor(globalScene.currentBattle.waveIndex / 50) * 2, 1), 4)
|
? Math.min(Math.max(Math.floor(globalScene.currentBattle.waveIndex / 50) * 2, 1), 4)
|
||||||
: 0,
|
: 0,
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(modifierTypes.QUICK_CLAW, 3),
|
new WeightedReward(allRewards.QUICK_CLAW, 3),
|
||||||
new WeightedModifierType(modifierTypes.WIDE_LENS, 7),
|
new WeightedReward(allRewards.WIDE_LENS, 7),
|
||||||
].map(m => {
|
];
|
||||||
m.setTier(RewardTier.ULTRA);
|
|
||||||
return m;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initRogueModifierPool() {
|
function initRogueRewardPool() {
|
||||||
modifierPool[RewardTier.ROGUE] = [
|
rewardPool[RarityTier.ROGUE] = [
|
||||||
new WeightedModifierType(modifierTypes.ROGUE_BALL, () => (hasMaximumBalls(PokeballType.ROGUE_BALL) ? 0 : 16), 16),
|
new WeightedReward(allRewards.ROGUE_BALL, () => (hasMaximumBalls(PokeballType.ROGUE_BALL) ? 0 : 16), 16),
|
||||||
new WeightedModifierType(modifierTypes.RELIC_GOLD, skipInLastClassicWaveOrDefault(2)),
|
new WeightedReward(allRewards.RELIC_GOLD, skipInLastClassicWaveOrDefault(2)),
|
||||||
new WeightedModifierType(modifierTypes.LEFTOVERS, 3),
|
new WeightedReward(allRewards.LEFTOVERS, 3),
|
||||||
new WeightedModifierType(modifierTypes.SHELL_BELL, 3),
|
new WeightedReward(allRewards.SHELL_BELL, 3),
|
||||||
new WeightedModifierType(modifierTypes.BERRY_POUCH, 4),
|
new WeightedReward(allRewards.BERRY_POUCH, 4),
|
||||||
new WeightedModifierType(modifierTypes.GRIP_CLAW, 5),
|
new WeightedReward(allRewards.GRIP_CLAW, 5),
|
||||||
new WeightedModifierType(modifierTypes.SCOPE_LENS, 4),
|
new WeightedReward(allRewards.SCOPE_LENS, 4),
|
||||||
new WeightedModifierType(modifierTypes.BATON, 2),
|
new WeightedReward(allRewards.BATON, 2),
|
||||||
new WeightedModifierType(modifierTypes.SOUL_DEW, 7),
|
new WeightedReward(allRewards.SOUL_DEW, 7),
|
||||||
new WeightedModifierType(modifierTypes.CATCHING_CHARM, () => (!globalScene.gameMode.isClassic ? 4 : 0), 4),
|
new WeightedReward(allRewards.CATCHING_CHARM, () => (!globalScene.gameMode.isClassic ? 4 : 0), 4),
|
||||||
new WeightedModifierType(modifierTypes.ABILITY_CHARM, skipInClassicAfterWave(189, 6)),
|
new WeightedReward(allRewards.ABILITY_CHARM, skipInClassicAfterWave(189, 6)),
|
||||||
new WeightedModifierType(modifierTypes.FOCUS_BAND, 5),
|
new WeightedReward(allRewards.FOCUS_BAND, 5),
|
||||||
new WeightedModifierType(modifierTypes.KINGS_ROCK, 3),
|
new WeightedReward(allRewards.KINGS_ROCK, 3),
|
||||||
new WeightedModifierType(modifierTypes.LOCK_CAPSULE, () => (globalScene.gameMode.isClassic ? 0 : 3)),
|
new WeightedReward(allRewards.LOCK_CAPSULE, () => (globalScene.gameMode.isClassic ? 0 : 3)),
|
||||||
new WeightedModifierType(modifierTypes.SUPER_EXP_CHARM, skipInLastClassicWaveOrDefault(8)),
|
new WeightedReward(allRewards.SUPER_EXP_CHARM, skipInLastClassicWaveOrDefault(8)),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.RARE_FORM_CHANGE_ITEM,
|
allRewards.RARE_FORM_CHANGE_ITEM,
|
||||||
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 6,
|
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 6,
|
||||||
24,
|
24,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.MEGA_BRACELET,
|
allRewards.MEGA_BRACELET,
|
||||||
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 9,
|
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 9,
|
||||||
36,
|
36,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.DYNAMAX_BAND,
|
allRewards.DYNAMAX_BAND,
|
||||||
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 9,
|
() => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 9,
|
||||||
36,
|
36,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.VOUCHER_PLUS,
|
allRewards.VOUCHER_PLUS,
|
||||||
(_party: Pokemon[], rerollCount: number) =>
|
(_party: Pokemon[], rerollCount: number) =>
|
||||||
!globalScene.gameMode.isDaily ? Math.max(3 - rerollCount * 1, 0) : 0,
|
!globalScene.gameMode.isDaily ? Math.max(3 - rerollCount * 1, 0) : 0,
|
||||||
3,
|
3,
|
||||||
),
|
),
|
||||||
].map(m => {
|
];
|
||||||
m.setTier(RewardTier.ROGUE);
|
|
||||||
return m;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the Master modifier pool
|
* Initialize the Master modifier pool
|
||||||
*/
|
*/
|
||||||
function initMasterModifierPool() {
|
function initMasterRewardPool() {
|
||||||
modifierPool[RewardTier.MASTER] = [
|
rewardPool[RarityTier.MASTER] = [
|
||||||
new WeightedModifierType(modifierTypes.MASTER_BALL, () => (hasMaximumBalls(PokeballType.MASTER_BALL) ? 0 : 24), 24),
|
new WeightedReward(allRewards.MASTER_BALL, () => (hasMaximumBalls(PokeballType.MASTER_BALL) ? 0 : 24), 24),
|
||||||
new WeightedModifierType(modifierTypes.SHINY_CHARM, 14),
|
new WeightedReward(allRewards.SHINY_CHARM, 14),
|
||||||
new WeightedModifierType(modifierTypes.HEALING_CHARM, 18),
|
new WeightedReward(allRewards.HEALING_CHARM, 18),
|
||||||
new WeightedModifierType(modifierTypes.MULTI_LENS, 18),
|
new WeightedReward(allRewards.MULTI_LENS, 18),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.VOUCHER_PREMIUM,
|
allRewards.VOUCHER_PREMIUM,
|
||||||
(_party: Pokemon[], rerollCount: number) =>
|
(_party: Pokemon[], rerollCount: number) =>
|
||||||
!globalScene.gameMode.isDaily && !globalScene.gameMode.isEndless && !globalScene.gameMode.isSplicedOnly
|
!globalScene.gameMode.isDaily && !globalScene.gameMode.isEndless && !globalScene.gameMode.isSplicedOnly
|
||||||
? Math.max(5 - rerollCount * 2, 0)
|
? Math.max(5 - rerollCount * 2, 0)
|
||||||
: 0,
|
: 0,
|
||||||
5,
|
5,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.DNA_SPLICERS,
|
allRewards.DNA_SPLICERS,
|
||||||
(party: Pokemon[]) =>
|
(party: Pokemon[]) =>
|
||||||
!(globalScene.gameMode.isClassic && timedEventManager.areFusionsBoosted()) &&
|
!(globalScene.gameMode.isClassic && timedEventManager.areFusionsBoosted()) &&
|
||||||
!globalScene.gameMode.isSplicedOnly &&
|
!globalScene.gameMode.isSplicedOnly &&
|
||||||
@ -592,8 +580,8 @@ function initMasterModifierPool() {
|
|||||||
: 0,
|
: 0,
|
||||||
24,
|
24,
|
||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedReward(
|
||||||
modifierTypes.MINI_BLACK_HOLE,
|
allRewards.MINI_BLACK_HOLE,
|
||||||
() =>
|
() =>
|
||||||
globalScene.gameMode.isDaily ||
|
globalScene.gameMode.isDaily ||
|
||||||
(!globalScene.gameMode.isFreshStartChallenge() && globalScene.gameData.isUnlocked(Unlockables.MINI_BLACK_HOLE))
|
(!globalScene.gameMode.isFreshStartChallenge() && globalScene.gameData.isUnlocked(Unlockables.MINI_BLACK_HOLE))
|
||||||
@ -601,33 +589,30 @@ function initMasterModifierPool() {
|
|||||||
: 0,
|
: 0,
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
].map(m => {
|
];
|
||||||
m.setTier(RewardTier.MASTER);
|
|
||||||
return m;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize {@linkcode modifierPool} with the initial set of modifier types.
|
* Initialize {@linkcode rewardPool} with the initial set of modifier types.
|
||||||
* {@linkcode initModifierTypes} MUST be called before this function.
|
* {@linkcode initRewards} MUST be called before this function.
|
||||||
*/
|
*/
|
||||||
export function initModifierPools() {
|
export function initRewardPools() {
|
||||||
// The modifier pools the player chooses from during modifier selection
|
// The modifier pools the player chooses from during modifier selection
|
||||||
initCommonModifierPool();
|
initCommonRewardPool();
|
||||||
initGreatModifierPool();
|
initGreatRewardPool();
|
||||||
initUltraModifierPool();
|
initUltraRewardPool();
|
||||||
initRogueModifierPool();
|
initRogueRewardPool();
|
||||||
initMasterModifierPool();
|
initMasterRewardPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* High order function that returns a WeightedModifierTypeWeightFunc that will only be applied on
|
* High order function that returns a WeightedRewardWeightFunc that will only be applied on
|
||||||
* classic and skip an ModifierType if current wave is greater or equal to the one passed down
|
* classic and skip an Reward if current wave is greater or equal to the one passed down
|
||||||
* @param wave - Wave where we should stop showing the modifier
|
* @param wave - Wave where we should stop showing the modifier
|
||||||
* @param defaultWeight - ModifierType default weight
|
* @param defaultWeight - Reward default weight
|
||||||
* @returns A WeightedModifierTypeWeightFunc
|
* @returns A WeightedRewardWeightFunc
|
||||||
*/
|
*/
|
||||||
function skipInClassicAfterWave(wave: number, defaultWeight: number): WeightedModifierTypeWeightFunc {
|
function skipInClassicAfterWave(wave: number, defaultWeight: number): WeightedRewardWeightFunc {
|
||||||
return () => {
|
return () => {
|
||||||
const gameMode = globalScene.gameMode;
|
const gameMode = globalScene.gameMode;
|
||||||
const currentWave = globalScene.currentBattle.waveIndex;
|
const currentWave = globalScene.currentBattle.waveIndex;
|
||||||
@ -636,23 +621,23 @@ function skipInClassicAfterWave(wave: number, defaultWeight: number): WeightedMo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* High order function that returns a WeightedModifierTypeWeightFunc that will only be applied on
|
* High order function that returns a WeightedRewardWeightFunc that will only be applied on
|
||||||
* classic and it will skip a ModifierType if it is the last wave pull.
|
* classic and it will skip a Reward if it is the last wave pull.
|
||||||
* @param defaultWeight ModifierType default weight
|
* @param defaultWeight Reward default weight
|
||||||
* @returns A WeightedModifierTypeWeightFunc
|
* @returns A WeightedRewardWeightFunc
|
||||||
*/
|
*/
|
||||||
function skipInLastClassicWaveOrDefault(defaultWeight: number): WeightedModifierTypeWeightFunc {
|
function skipInLastClassicWaveOrDefault(defaultWeight: number): WeightedRewardWeightFunc {
|
||||||
return skipInClassicAfterWave(199, defaultWeight);
|
return skipInClassicAfterWave(199, defaultWeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* High order function that returns a WeightedModifierTypeWeightFunc to ensure Lures don't spawn on Classic 199
|
* High order function that returns a WeightedRewardWeightFunc to ensure Lures don't spawn on Classic 199
|
||||||
* or if the lure still has over 60% of its duration left
|
* or if the lure still has over 60% of its duration left
|
||||||
* @param lureId The id of the lure type in question.
|
* @param lureId The id of the lure type in question.
|
||||||
* @param weight The desired weight for the lure when it does spawn
|
* @param weight The desired weight for the lure when it does spawn
|
||||||
* @returns A WeightedModifierTypeWeightFunc
|
* @returns A WeightedRewardWeightFunc
|
||||||
*/
|
*/
|
||||||
function lureWeightFunc(lureId: TrainerItemId, weight: number): WeightedModifierTypeWeightFunc {
|
function lureWeightFunc(lureId: TrainerItemId, weight: number): WeightedRewardWeightFunc {
|
||||||
return () => {
|
return () => {
|
||||||
const lureCount = globalScene.trainerItems.getStack(lureId);
|
const lureCount = globalScene.trainerItems.getStack(lureId);
|
||||||
return !(globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex === 199) &&
|
return !(globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex === 199) &&
|
@ -1,4 +1,4 @@
|
|||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import { TrainerItemId } from "#enums/trainer-item-id";
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import { enemyBuffTokenPool } from "#items/trainer-item-pool";
|
import { enemyBuffTokenPool } from "#items/trainer-item-pool";
|
||||||
|
|
||||||
@ -6,7 +6,7 @@ import { enemyBuffTokenPool } from "#items/trainer-item-pool";
|
|||||||
* Initialize the enemy buff modifier pool
|
* Initialize the enemy buff modifier pool
|
||||||
*/
|
*/
|
||||||
function initEnemyBuffTokenPool() {
|
function initEnemyBuffTokenPool() {
|
||||||
enemyBuffTokenPool[RewardTier.COMMON] = [
|
enemyBuffTokenPool[RarityTier.COMMON] = [
|
||||||
{ entry: TrainerItemId.ENEMY_DAMAGE_BOOSTER, weight: 9 },
|
{ entry: TrainerItemId.ENEMY_DAMAGE_BOOSTER, weight: 9 },
|
||||||
{ entry: TrainerItemId.ENEMY_DAMAGE_REDUCTION, weight: 9 },
|
{ entry: TrainerItemId.ENEMY_DAMAGE_REDUCTION, weight: 9 },
|
||||||
{ entry: TrainerItemId.ENEMY_ATTACK_POISON_CHANCE, weight: 3 },
|
{ entry: TrainerItemId.ENEMY_ATTACK_POISON_CHANCE, weight: 3 },
|
||||||
@ -16,14 +16,14 @@ function initEnemyBuffTokenPool() {
|
|||||||
{ entry: TrainerItemId.ENEMY_ENDURE_CHANCE, weight: 4 },
|
{ entry: TrainerItemId.ENEMY_ENDURE_CHANCE, weight: 4 },
|
||||||
{ entry: TrainerItemId.ENEMY_FUSED_CHANCE, weight: 1 },
|
{ entry: TrainerItemId.ENEMY_FUSED_CHANCE, weight: 1 },
|
||||||
];
|
];
|
||||||
enemyBuffTokenPool[RewardTier.GREAT] = [
|
enemyBuffTokenPool[RarityTier.GREAT] = [
|
||||||
{ entry: TrainerItemId.ENEMY_DAMAGE_BOOSTER, weight: 5 },
|
{ entry: TrainerItemId.ENEMY_DAMAGE_BOOSTER, weight: 5 },
|
||||||
{ entry: TrainerItemId.ENEMY_DAMAGE_REDUCTION, weight: 5 },
|
{ entry: TrainerItemId.ENEMY_DAMAGE_REDUCTION, weight: 5 },
|
||||||
{ entry: TrainerItemId.ENEMY_STATUS_EFFECT_HEAL_CHANCE, weight: 5 },
|
{ entry: TrainerItemId.ENEMY_STATUS_EFFECT_HEAL_CHANCE, weight: 5 },
|
||||||
{ entry: TrainerItemId.ENEMY_ENDURE_CHANCE, weight: 5 },
|
{ entry: TrainerItemId.ENEMY_ENDURE_CHANCE, weight: 5 },
|
||||||
{ entry: TrainerItemId.ENEMY_FUSED_CHANCE, weight: 1 },
|
{ entry: TrainerItemId.ENEMY_FUSED_CHANCE, weight: 1 },
|
||||||
];
|
];
|
||||||
enemyBuffTokenPool[RewardTier.ULTRA] = [
|
enemyBuffTokenPool[RarityTier.ULTRA] = [
|
||||||
{ entry: TrainerItemId.ENEMY_DAMAGE_BOOSTER, weight: 10 },
|
{ entry: TrainerItemId.ENEMY_DAMAGE_BOOSTER, weight: 10 },
|
||||||
{ entry: TrainerItemId.ENEMY_DAMAGE_REDUCTION, weight: 10 },
|
{ entry: TrainerItemId.ENEMY_DAMAGE_REDUCTION, weight: 10 },
|
||||||
{ entry: TrainerItemId.ENEMY_HEAL, weight: 10 },
|
{ entry: TrainerItemId.ENEMY_HEAL, weight: 10 },
|
||||||
@ -31,8 +31,8 @@ function initEnemyBuffTokenPool() {
|
|||||||
{ entry: TrainerItemId.ENEMY_ENDURE_CHANCE, weight: 10 },
|
{ entry: TrainerItemId.ENEMY_ENDURE_CHANCE, weight: 10 },
|
||||||
{ entry: TrainerItemId.ENEMY_FUSED_CHANCE, weight: 5 },
|
{ entry: TrainerItemId.ENEMY_FUSED_CHANCE, weight: 5 },
|
||||||
];
|
];
|
||||||
enemyBuffTokenPool[RewardTier.ROGUE] = [];
|
enemyBuffTokenPool[RarityTier.ROGUE] = [];
|
||||||
enemyBuffTokenPool[RewardTier.MASTER] = [];
|
enemyBuffTokenPool[RarityTier.MASTER] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initTrainerItemPools() {
|
export function initTrainerItemPools() {
|
||||||
|
50
src/items/item-overrides.ts
Normal file
50
src/items/item-overrides.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import Overrides from "#app/overrides";
|
||||||
|
import type { Pokemon } from "#field/pokemon";
|
||||||
|
import type { HeldItemConfiguration } from "#items/held-item-data-types";
|
||||||
|
import { assignItemsFromConfiguration } from "#items/held-item-pool";
|
||||||
|
import type { TrainerItemConfiguration } from "#items/trainer-item-data-types";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses either `MODIFIER_OVERRIDE` in overrides.ts to set {@linkcode PersistentModifier}s for either:
|
||||||
|
* - The player
|
||||||
|
* - The enemy
|
||||||
|
* @param isPlayer {@linkcode boolean} for whether the player (`true`) or enemy (`false`) is being overridden
|
||||||
|
*/
|
||||||
|
export function overrideTrainerItems(isPlayer = true): void {
|
||||||
|
const trainerItemsOverride: TrainerItemConfiguration = isPlayer
|
||||||
|
? Overrides.STARTING_TRAINER_ITEMS_OVERRIDE
|
||||||
|
: Overrides.OPP_TRAINER_ITEMS_OVERRIDE;
|
||||||
|
if (!trainerItemsOverride || trainerItemsOverride.length === 0 || !globalScene) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's the opponent, clear all of their current modifiers to avoid stacking
|
||||||
|
if (!isPlayer) {
|
||||||
|
globalScene.clearEnemyItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
globalScene.assignTrainerItemsFromConfiguration(trainerItemsOverride, isPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses either `HELD_ITEMS_OVERRIDE` in overrides.ts to set {@linkcode PokemonHeldItemModifier}s for either:
|
||||||
|
* - The first member of the player's team when starting a new game
|
||||||
|
* - An enemy {@linkcode Pokemon} being spawned in
|
||||||
|
* @param pokemon {@linkcode Pokemon} whose held items are being overridden
|
||||||
|
* @param isPlayer {@linkcode boolean} for whether the {@linkcode pokemon} is the player's (`true`) or an enemy (`false`)
|
||||||
|
*/
|
||||||
|
export function overrideHeldItems(pokemon: Pokemon, isPlayer = true): void {
|
||||||
|
const heldItemsOverride: HeldItemConfiguration = isPlayer
|
||||||
|
? Overrides.STARTING_HELD_ITEMS_OVERRIDE
|
||||||
|
: Overrides.OPP_HELD_ITEMS_OVERRIDE;
|
||||||
|
if (!heldItemsOverride || heldItemsOverride.length === 0 || !globalScene) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isPlayer) {
|
||||||
|
pokemon.heldItemManager.clearItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
assignItemsFromConfiguration(heldItemsOverride, pokemon);
|
||||||
|
}
|
72
src/items/reward-defaults-tiers.ts
Normal file
72
src/items/reward-defaults-tiers.ts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { RewardId } from "#enums/reward-id";
|
||||||
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
|
|
||||||
|
export const rewardRarities = {
|
||||||
|
[RewardId.POKEBALL]: RarityTier.COMMON,
|
||||||
|
[RewardId.GREAT_BALL]: RarityTier.GREAT,
|
||||||
|
[RewardId.ULTRA_BALL]: RarityTier.ULTRA,
|
||||||
|
[RewardId.ROGUE_BALL]: RarityTier.ROGUE,
|
||||||
|
[RewardId.MASTER_BALL]: RarityTier.MASTER,
|
||||||
|
|
||||||
|
[RewardId.VOUCHER]: RarityTier.GREAT,
|
||||||
|
[RewardId.VOUCHER_PLUS]: RarityTier.ROGUE,
|
||||||
|
[RewardId.VOUCHER_PREMIUM]: RarityTier.MASTER,
|
||||||
|
|
||||||
|
[RewardId.NUGGET]: RarityTier.GREAT,
|
||||||
|
[RewardId.BIG_NUGGET]: RarityTier.ULTRA,
|
||||||
|
[RewardId.RELIC_GOLD]: RarityTier.ROGUE,
|
||||||
|
|
||||||
|
[RewardId.RARE_CANDY]: RarityTier.COMMON,
|
||||||
|
[RewardId.RARER_CANDY]: RarityTier.ULTRA,
|
||||||
|
|
||||||
|
[RewardId.EVOLUTION_ITEM]: RarityTier.GREAT,
|
||||||
|
[RewardId.RARE_EVOLUTION_ITEM]: RarityTier.ULTRA,
|
||||||
|
|
||||||
|
[RewardId.POTION]: RarityTier.COMMON,
|
||||||
|
[RewardId.SUPER_POTION]: RarityTier.COMMON,
|
||||||
|
[RewardId.HYPER_POTION]: RarityTier.GREAT,
|
||||||
|
[RewardId.MAX_POTION]: RarityTier.GREAT,
|
||||||
|
[RewardId.FULL_HEAL]: RarityTier.GREAT,
|
||||||
|
[RewardId.FULL_RESTORE]: RarityTier.GREAT,
|
||||||
|
|
||||||
|
[RewardId.REVIVE]: RarityTier.GREAT,
|
||||||
|
[RewardId.MAX_REVIVE]: RarityTier.GREAT,
|
||||||
|
[RewardId.SACRED_ASH]: RarityTier.GREAT,
|
||||||
|
|
||||||
|
[RewardId.ETHER]: RarityTier.COMMON,
|
||||||
|
[RewardId.MAX_ETHER]: RarityTier.COMMON,
|
||||||
|
|
||||||
|
[RewardId.ELIXIR]: RarityTier.GREAT,
|
||||||
|
[RewardId.MAX_ELIXIR]: RarityTier.GREAT,
|
||||||
|
|
||||||
|
[RewardId.PP_UP]: RarityTier.GREAT,
|
||||||
|
[RewardId.PP_MAX]: RarityTier.ULTRA,
|
||||||
|
|
||||||
|
[RewardId.TM_COMMON]: RarityTier.COMMON,
|
||||||
|
[RewardId.TM_GREAT]: RarityTier.GREAT,
|
||||||
|
[RewardId.TM_ULTRA]: RarityTier.ULTRA,
|
||||||
|
|
||||||
|
[RewardId.MINT]: RarityTier.ULTRA,
|
||||||
|
[RewardId.TERA_SHARD]: RarityTier.GREAT,
|
||||||
|
[RewardId.MEMORY_MUSHROOM]: RarityTier.GREAT,
|
||||||
|
[RewardId.DNA_SPLICERS]: RarityTier.MASTER,
|
||||||
|
|
||||||
|
[RewardId.SPECIES_STAT_BOOSTER]: RarityTier.GREAT,
|
||||||
|
[RewardId.RARE_SPECIES_STAT_BOOSTER]: RarityTier.ULTRA,
|
||||||
|
[RewardId.BASE_STAT_BOOSTER]: RarityTier.GREAT,
|
||||||
|
[RewardId.ATTACK_TYPE_BOOSTER]: RarityTier.ULTRA,
|
||||||
|
[RewardId.BERRY]: RarityTier.COMMON,
|
||||||
|
|
||||||
|
[RewardId.TEMP_STAT_STAGE_BOOSTER]: RarityTier.COMMON,
|
||||||
|
[RewardId.LURE]: RarityTier.COMMON,
|
||||||
|
[RewardId.SUPER_LURE]: RarityTier.GREAT,
|
||||||
|
[RewardId.MAX_LURE]: RarityTier.ULTRA,
|
||||||
|
|
||||||
|
[RewardId.FORM_CHANGE_ITEM]: RarityTier.ULTRA,
|
||||||
|
[RewardId.RARE_FORM_CHANGE_ITEM]: RarityTier.ROGUE,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getRewardTier(reward: RewardId): RarityTier {
|
||||||
|
const tier = rewardRarities[reward];
|
||||||
|
return tier ?? RarityTier.LUXURY;
|
||||||
|
}
|
340
src/items/reward-pool-utils.ts
Normal file
340
src/items/reward-pool-utils.ts
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import Overrides from "#app/overrides";
|
||||||
|
import { allRewards } from "#data/data-lists";
|
||||||
|
import { RewardPoolType } from "#enums/reward-pool-type";
|
||||||
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
|
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||||
|
import type { RewardFunc, RewardPool, RewardPoolWeights } from "#types/rewards";
|
||||||
|
import { isNullOrUndefined, pickWeightedIndex, randSeedInt } from "#utils/common";
|
||||||
|
import { getPartyLuckValue } from "#utils/party";
|
||||||
|
import { type Reward, RewardGenerator, RewardOption, type RewardOverride, TrainerItemReward } from "./reward";
|
||||||
|
import { rewardPool, rewardPoolWeights } from "./reward-pools";
|
||||||
|
import { getRewardDefaultTier } from "./reward-utils";
|
||||||
|
|
||||||
|
/*
|
||||||
|
This file still contains several functions to generate rewards from pools. The hierarchy of these functions is explained here.
|
||||||
|
|
||||||
|
At the top of the food chain is `generatePlayerRewardOptions`, which is responsible for creating item rewards for the player.
|
||||||
|
It can take a `CustomRewardSettings` to fix any number of rewards or tiers, then fills the remaining spots randomly.
|
||||||
|
Note that this function generates `RewardOption` instances, not yet `Reward`s.
|
||||||
|
Currently, there is only one reward pool, but in the future we will want to allow for custom pools.
|
||||||
|
|
||||||
|
The function `getNewRewardOption` is responsible for generating a single RewardOption from a given pool and set of weights.
|
||||||
|
Note that, in the previous system, this function could in principle generate rewards for enemies, which was used in some
|
||||||
|
cases to assign modifiers. This usage is now deprecated, as we have separate pools for held items and trainer items for enemies.
|
||||||
|
|
||||||
|
However, `getNewRewardOption` is not called directly by `generatePlayerRewardOptions`. Instead, it is filtered
|
||||||
|
by `getRewardOptionWithRetry`, which also checks existing rewards to minimize the chance of duplicates.
|
||||||
|
|
||||||
|
Note that the pool contains `WeightedReward` instances, which contain either a `Reward` or a `RewardGenerator`.
|
||||||
|
Once a pool entry is chosen, a specific `Reward` is generated accordingly and put in the returned `RewardOption`.
|
||||||
|
|
||||||
|
This will allow more customization in creating pools for challenges, MEs etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface CustomRewardSettings {
|
||||||
|
guaranteedRarityTiers?: RarityTier[];
|
||||||
|
guaranteedRewardOptions?: RewardOption[];
|
||||||
|
/** If specified, will override the next X items to be auto-generated from specific reward functions (these don't have to be pre-genned). */
|
||||||
|
guaranteedRewardFuncs?: RewardFunc[];
|
||||||
|
/**
|
||||||
|
* If set to `true`, will fill the remainder of shop items that were not overridden by the 3 options above, up to the `count` param value.
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* count = 4;
|
||||||
|
* customRewardSettings = { guaranteedRarityTiers: [RarityTier.GREAT], fillRemaining: true };
|
||||||
|
* ```
|
||||||
|
* The first item in the shop will be `GREAT` tier, and the remaining `3` items will be generated normally.
|
||||||
|
*
|
||||||
|
* If `fillRemaining: false` in the same scenario, only 1 `GREAT` tier item will appear in the shop (regardless of the value of `count`).
|
||||||
|
* @defaultValue `false`
|
||||||
|
*/
|
||||||
|
fillRemaining?: boolean;
|
||||||
|
/** If specified, can adjust the amount of money required for a shop reroll. If set to a negative value, the shop will not allow rerolls at all. */
|
||||||
|
rerollMultiplier?: number;
|
||||||
|
/**
|
||||||
|
* If `false`, will prevent set item tiers from upgrading via luck.
|
||||||
|
* @defaultValue `true`
|
||||||
|
*/
|
||||||
|
allowLuckUpgrades?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates weights for a {@linkcode RewardPool}. An array of weights is generated for each rarity tier. Weights can be 0.
|
||||||
|
* @param pool - The pool for which weights must be generated
|
||||||
|
* @param party - Party is required for generating the weights
|
||||||
|
* @param rerollCount - (Optional) Needed for weights of vouchers.
|
||||||
|
*/
|
||||||
|
export function generateRewardPoolWeights(pool: RewardPool, party: Pokemon[], rerollCount = 0) {
|
||||||
|
for (const tier of Object.keys(pool)) {
|
||||||
|
const poolWeights = pool[tier].map(w => {
|
||||||
|
if (w.reward instanceof TrainerItemReward) {
|
||||||
|
const id = w.reward.itemId;
|
||||||
|
if (globalScene.trainerItems.isMaxStack(id)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typeof w.weight === "number") {
|
||||||
|
return w.weight;
|
||||||
|
}
|
||||||
|
return w.weight(party, rerollCount);
|
||||||
|
});
|
||||||
|
rewardPoolWeights[tier] = poolWeights;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a random RarityTier to draw rewards from the pool. The probabilities are:
|
||||||
|
* 1/1024 (Master tier)
|
||||||
|
* 12/1024 (Rogue tier)
|
||||||
|
* 48/1024 (Ultra tier)
|
||||||
|
* 195/1024 (Great tier)
|
||||||
|
* 768/1024 (Common tier)
|
||||||
|
* return {@linkcode RarityTier}
|
||||||
|
*/
|
||||||
|
function randomBaseTier(): RarityTier {
|
||||||
|
const tierValue = randSeedInt(1024);
|
||||||
|
|
||||||
|
if (tierValue > 255) {
|
||||||
|
return RarityTier.COMMON;
|
||||||
|
}
|
||||||
|
if (tierValue > 60) {
|
||||||
|
return RarityTier.GREAT;
|
||||||
|
}
|
||||||
|
if (tierValue > 12) {
|
||||||
|
return RarityTier.ULTRA;
|
||||||
|
}
|
||||||
|
if (tierValue) {
|
||||||
|
return RarityTier.ROGUE;
|
||||||
|
}
|
||||||
|
return RarityTier.MASTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the upgrade count for a given rarity tier, based on the party luck. Will not update
|
||||||
|
* if the pool would have no entries at the new rarity.
|
||||||
|
* @param pool - RewardPool from which the reward will be generated
|
||||||
|
* @param baseTier - The initial tier to upgrade
|
||||||
|
* @param party - Party of the trainer using the item
|
||||||
|
* return {@linkcode RarityTier}
|
||||||
|
*/
|
||||||
|
function getRarityUpgradeCount(pool: RewardPool, baseTier: RarityTier, party: Pokemon[]): RarityTier {
|
||||||
|
let upgradeCount = 0;
|
||||||
|
if (baseTier < RarityTier.MASTER) {
|
||||||
|
const partyLuckValue = getPartyLuckValue(party);
|
||||||
|
const upgradeOdds = Math.floor(128 / ((partyLuckValue + 4) / 4));
|
||||||
|
while (pool.hasOwnProperty(baseTier + upgradeCount + 1) && pool[baseTier + upgradeCount + 1].length) {
|
||||||
|
if (randSeedInt(upgradeOdds) < 4) {
|
||||||
|
upgradeCount++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return upgradeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates reward options for a {@linkcode SelectRewardPhase}
|
||||||
|
* @param count - Determines the number of items to generate
|
||||||
|
* @param party - Party is required for generating proper reward pools
|
||||||
|
* @param rarityTiers - (Optional) If specified, rolls items in the specified tiers. Commonly used for tier-locking with Lock Capsule.
|
||||||
|
* @param customRewardSettings - (Optional) See {@linkcode CustomRewardSettings}
|
||||||
|
*/
|
||||||
|
export function generatePlayerRewardOptions(
|
||||||
|
count: number,
|
||||||
|
party: PlayerPokemon[],
|
||||||
|
rarityTiers?: RarityTier[],
|
||||||
|
customRewardSettings?: CustomRewardSettings,
|
||||||
|
): RewardOption[] {
|
||||||
|
const options: RewardOption[] = [];
|
||||||
|
const retryCount = Math.min(count * 5, 50);
|
||||||
|
// TODO: Change this to allow for custom reward pools
|
||||||
|
const pool = getRewardPoolForType(RewardPoolType.PLAYER);
|
||||||
|
const weights = getRewardWeightsForType(RewardPoolType.PLAYER);
|
||||||
|
if (!customRewardSettings) {
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
const tier = rarityTiers && rarityTiers.length > i ? rarityTiers[i] : undefined;
|
||||||
|
options.push(getRewardOptionWithRetry(pool, weights, options, retryCount, party, tier));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Guaranteed mod options first
|
||||||
|
if (customRewardSettings?.guaranteedRewardOptions && customRewardSettings.guaranteedRewardOptions.length > 0) {
|
||||||
|
options.push(...customRewardSettings.guaranteedRewardOptions!);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guaranteed mod functions second
|
||||||
|
if (customRewardSettings.guaranteedRewardFuncs && customRewardSettings.guaranteedRewardFuncs.length > 0) {
|
||||||
|
customRewardSettings.guaranteedRewardFuncs!.forEach((mod, _i) => {
|
||||||
|
const rewardId = Object.keys(allRewards).find(k => allRewards[k] === mod) as string;
|
||||||
|
const guaranteedMod: Reward = allRewards[rewardId]?.();
|
||||||
|
|
||||||
|
// Populates item id and tier
|
||||||
|
const guaranteedModTier = getRewardDefaultTier(guaranteedMod);
|
||||||
|
|
||||||
|
const modType = guaranteedMod instanceof RewardGenerator ? guaranteedMod.generateReward(party) : guaranteedMod;
|
||||||
|
if (modType) {
|
||||||
|
const option = new RewardOption(modType, 0, guaranteedModTier);
|
||||||
|
options.push(option);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guaranteed tiers third
|
||||||
|
if (customRewardSettings.guaranteedRarityTiers && customRewardSettings.guaranteedRarityTiers.length > 0) {
|
||||||
|
const allowLuckUpgrades = customRewardSettings.allowLuckUpgrades ?? true;
|
||||||
|
for (const tier of customRewardSettings.guaranteedRarityTiers) {
|
||||||
|
options.push(getRewardOptionWithRetry(pool, weights, options, retryCount, party, tier, allowLuckUpgrades));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill remaining
|
||||||
|
if (options.length < count && customRewardSettings.fillRemaining) {
|
||||||
|
while (options.length < count) {
|
||||||
|
options.push(getRewardOptionWithRetry(pool, weights, options, retryCount, party, undefined));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applies overrides for testing
|
||||||
|
overridePlayerRewardOptions(options, party);
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will generate a {@linkcode RewardOption} from the {@linkcode RewardPoolType.PLAYER} pool, attempting to retry duplicated items up to retryCount
|
||||||
|
* @param pool - {@linkcode RewardPool} to generate items from
|
||||||
|
* @param weights - {@linkcode RewardPoolWeights} to use when generating items
|
||||||
|
* @param existingOptions Currently generated options
|
||||||
|
* @param retryCount How many times to retry before allowing a dupe item
|
||||||
|
* @param party Current player party, used to calculate items in the pool
|
||||||
|
* @param tier If specified will generate item of tier
|
||||||
|
* @param allowLuckUpgrades `true` to allow items to upgrade tiers (the little animation that plays and is affected by luck)
|
||||||
|
*/
|
||||||
|
function getRewardOptionWithRetry(
|
||||||
|
pool: RewardPool,
|
||||||
|
weights: RewardPoolWeights,
|
||||||
|
existingOptions: RewardOption[],
|
||||||
|
retryCount: number,
|
||||||
|
party: PlayerPokemon[],
|
||||||
|
tier?: RarityTier,
|
||||||
|
allowLuckUpgrades?: boolean,
|
||||||
|
): RewardOption {
|
||||||
|
allowLuckUpgrades = allowLuckUpgrades ?? true;
|
||||||
|
let candidate = getNewRewardOption(pool, weights, party, tier, undefined, 0, allowLuckUpgrades);
|
||||||
|
let r = 0;
|
||||||
|
while (
|
||||||
|
existingOptions.length &&
|
||||||
|
++r < retryCount &&
|
||||||
|
//TODO: Improve this condition to refine what counts as a dupe
|
||||||
|
existingOptions.filter(o => o.type.name === candidate?.type.name || o.type.group === candidate?.type.group).length
|
||||||
|
) {
|
||||||
|
console.log("Retry count:", r);
|
||||||
|
console.log(candidate?.type.group);
|
||||||
|
console.log(candidate?.type.name);
|
||||||
|
console.log(existingOptions.filter(o => o.type.name === candidate?.type.name).length);
|
||||||
|
console.log(existingOptions.filter(o => o.type.group === candidate?.type.group).length);
|
||||||
|
candidate = getNewRewardOption(
|
||||||
|
pool,
|
||||||
|
weights,
|
||||||
|
party,
|
||||||
|
candidate?.type.tier ?? tier,
|
||||||
|
candidate?.upgradeCount,
|
||||||
|
0,
|
||||||
|
allowLuckUpgrades,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return candidate!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a Reward from the specified pool
|
||||||
|
* @param pool - {@linkcode RewardPool} to generate items from
|
||||||
|
* @param weights - {@linkcode RewardPoolWeights} to use when generating items
|
||||||
|
* @param party - party of the trainer using the item
|
||||||
|
* @param baseTier - If specified, will override the initial tier of an item (can still upgrade with luck)
|
||||||
|
* @param upgradeCount - If defined, means that this is a new Reward being generated to override another via luck upgrade. Used for recursive logic
|
||||||
|
* @param retryCount - Max allowed tries before the next tier down is checked for a valid Reward
|
||||||
|
* @param allowLuckUpgrades - Default true. If false, will not allow Reward to randomly upgrade to next tier
|
||||||
|
*/
|
||||||
|
function getNewRewardOption(
|
||||||
|
pool: RewardPool,
|
||||||
|
weights: RewardPoolWeights,
|
||||||
|
party: PlayerPokemon[],
|
||||||
|
baseTier?: RarityTier,
|
||||||
|
upgradeCount?: number,
|
||||||
|
retryCount = 0,
|
||||||
|
allowLuckUpgrades = true,
|
||||||
|
): RewardOption | null {
|
||||||
|
let tier = 0;
|
||||||
|
if (isNullOrUndefined(baseTier)) {
|
||||||
|
baseTier = randomBaseTier();
|
||||||
|
}
|
||||||
|
if (isNullOrUndefined(upgradeCount)) {
|
||||||
|
upgradeCount = allowLuckUpgrades ? getRarityUpgradeCount(pool, baseTier, party) : 0;
|
||||||
|
tier = baseTier + upgradeCount;
|
||||||
|
} else {
|
||||||
|
tier = baseTier;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tierWeights = weights[tier];
|
||||||
|
const index = pickWeightedIndex(tierWeights);
|
||||||
|
|
||||||
|
if (index === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let reward: Reward | RewardGenerator | null = pool[tier][index].reward;
|
||||||
|
if (reward instanceof RewardGenerator) {
|
||||||
|
reward = (reward as RewardGenerator).generateReward(party);
|
||||||
|
if (reward === null) {
|
||||||
|
console.log(RarityTier[tier], upgradeCount);
|
||||||
|
return getNewRewardOption(pool, weights, party, tier, upgradeCount, ++retryCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(reward);
|
||||||
|
|
||||||
|
return new RewardOption(reward as Reward, upgradeCount!, tier); // TODO: is this bang correct?
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the {@linkcode Reward} of the entries within {@linkcode options} with any
|
||||||
|
* {@linkcode RewardOverride} entries listed in {@linkcode Overrides.REWARD_OVERRIDE}
|
||||||
|
* up to the smallest amount of entries between {@linkcode options} and the override array.
|
||||||
|
* @param options Array of naturally rolled {@linkcode RewardOption}s
|
||||||
|
* @param party Array of the player's current party
|
||||||
|
*/
|
||||||
|
export function overridePlayerRewardOptions(options: RewardOption[], party: PlayerPokemon[]) {
|
||||||
|
const minLength = Math.min(options.length, Overrides.REWARD_OVERRIDE.length);
|
||||||
|
for (let i = 0; i < minLength; i++) {
|
||||||
|
const override: RewardOverride = Overrides.REWARD_OVERRIDE[i];
|
||||||
|
const rewardFunc = allRewards[override.name];
|
||||||
|
let reward: Reward | RewardGenerator | null = rewardFunc();
|
||||||
|
|
||||||
|
if (reward instanceof RewardGenerator) {
|
||||||
|
const pregenArgs = "type" in override && override.type !== null ? [override.type] : undefined;
|
||||||
|
reward = reward.generateReward(party, pregenArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reward) {
|
||||||
|
options[i].type = reward;
|
||||||
|
options[i].tier = getRewardDefaultTier(reward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRewardPoolForType(poolType: RewardPoolType): RewardPool {
|
||||||
|
switch (poolType) {
|
||||||
|
case RewardPoolType.PLAYER:
|
||||||
|
return rewardPool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRewardWeightsForType(poolType: RewardPoolType): RewardPoolWeights {
|
||||||
|
switch (poolType) {
|
||||||
|
case RewardPoolType.PLAYER:
|
||||||
|
return rewardPoolWeights;
|
||||||
|
}
|
||||||
|
}
|
9
src/items/reward-pools.ts
Normal file
9
src/items/reward-pools.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* Contains modifier pools for different contexts in the game.
|
||||||
|
* Can be safely imported without worrying about circular dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { RewardPool, RewardPoolWeights } from "#types/rewards";
|
||||||
|
|
||||||
|
export const rewardPool: RewardPool = {};
|
||||||
|
export const rewardPoolWeights: RewardPoolWeights = {};
|
115
src/items/reward-utils.ts
Normal file
115
src/items/reward-utils.ts
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
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 {
|
||||||
|
type HeldItemReward,
|
||||||
|
type PokemonMoveReward,
|
||||||
|
type RememberMoveReward,
|
||||||
|
type Reward,
|
||||||
|
RewardGenerator,
|
||||||
|
RewardOption,
|
||||||
|
type TmReward,
|
||||||
|
type TrainerItemReward,
|
||||||
|
} from "./reward";
|
||||||
|
import { getRewardTier } from "./reward-defaults-tiers";
|
||||||
|
import { getTrainerItemTier } from "./trainer-item-default-tiers";
|
||||||
|
|
||||||
|
export function isTmReward(reward: Reward): reward is TmReward {
|
||||||
|
return getRewardCategory(reward.id) === RewardCategoryId.TM;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isMoveReward(reward: Reward): reward is PokemonMoveReward {
|
||||||
|
const categoryId = getRewardCategory(reward.id);
|
||||||
|
return categoryId === RewardCategoryId.ETHER || categoryId === RewardCategoryId.PP_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isRememberMoveReward(reward: Reward): reward is RememberMoveReward {
|
||||||
|
return reward.id === RewardId.MEMORY_MUSHROOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a Reward from a given function
|
||||||
|
* @param rewardFunc
|
||||||
|
* @param pregenArgs Can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc.
|
||||||
|
*/
|
||||||
|
export function generateReward(rewardFunc: RewardFunc, pregenArgs?: any[]): Reward | null {
|
||||||
|
const reward = rewardFunc();
|
||||||
|
return reward instanceof RewardGenerator ? reward.generateReward(globalScene.getPlayerParty(), pregenArgs) : reward;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a Reward Option from a given function
|
||||||
|
* @param rewardFunc
|
||||||
|
* @param pregenArgs - can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc.
|
||||||
|
*/
|
||||||
|
export function generateRewardOption(rewardFunc: RewardFunc, pregenArgs?: any[]): RewardOption | null {
|
||||||
|
const reward = generateReward(rewardFunc, pregenArgs);
|
||||||
|
if (reward) {
|
||||||
|
const tier = getRewardDefaultTier(reward);
|
||||||
|
return new RewardOption(reward, 0, tier);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
if (reward.id === RewardId.TRAINER_ITEM) {
|
||||||
|
return getTrainerItemTier((reward as TrainerItemReward).itemId);
|
||||||
|
}
|
||||||
|
return getRewardTier(reward.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPlayerShopRewardOptionsForWave(waveIndex: number, baseCost: number): RewardOption[] {
|
||||||
|
if (!(waveIndex % 10)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
[
|
||||||
|
new RewardOption(allRewards.POTION(), 0, baseCost * 0.2),
|
||||||
|
new RewardOption(allRewards.ETHER(), 0, baseCost * 0.4),
|
||||||
|
new RewardOption(allRewards.REVIVE(), 0, baseCost * 2),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
new RewardOption(allRewards.SUPER_POTION(), 0, baseCost * 0.45),
|
||||||
|
new RewardOption(allRewards.FULL_HEAL(), 0, baseCost),
|
||||||
|
],
|
||||||
|
[new RewardOption(allRewards.ELIXIR(), 0, baseCost), new RewardOption(allRewards.MAX_ETHER(), 0, baseCost)],
|
||||||
|
[
|
||||||
|
new RewardOption(allRewards.HYPER_POTION(), 0, baseCost * 0.8),
|
||||||
|
new RewardOption(allRewards.MAX_REVIVE(), 0, baseCost * 2.75),
|
||||||
|
new RewardOption(allRewards.MEMORY_MUSHROOM(), 0, baseCost * 4),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
new RewardOption(allRewards.MAX_POTION(), 0, baseCost * 1.5),
|
||||||
|
new RewardOption(allRewards.MAX_ELIXIR(), 0, baseCost * 2.5),
|
||||||
|
],
|
||||||
|
[new RewardOption(allRewards.FULL_RESTORE(), 0, baseCost * 2.25)],
|
||||||
|
[new RewardOption(allRewards.SACRED_ASH(), 0, baseCost * 10)],
|
||||||
|
];
|
||||||
|
return options.slice(0, Math.ceil(Math.max(waveIndex + 10, 0) / 30)).flat();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isRewardId(id: RewardPoolId): id is RewardId {
|
||||||
|
return id > 0x2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isTrainerItemId(id: RewardPoolId): id is TrainerItemId {
|
||||||
|
return id > 0x1000 && id < 0x2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isHeldItemId(id: RewardPoolId): id is HeldItemId {
|
||||||
|
return id < 0x1000;
|
||||||
|
}
|
1852
src/items/reward.ts
Normal file
1852
src/items/reward.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
// TODO: move to `src/@types/`
|
// TODO: move to `src/@types/`
|
||||||
import type { RewardTier } from "#enums/reward-tier";
|
import type { RarityTier } from "#enums/reward-tier";
|
||||||
import type { TrainerItemId } from "#enums/trainer-item-id";
|
import type { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
|
|
||||||
export type TrainerItemData = {
|
export type TrainerItemData = {
|
||||||
@ -28,7 +28,7 @@ type TrainerItemPoolEntry = {
|
|||||||
export type TrainerItemPool = TrainerItemPoolEntry[];
|
export type TrainerItemPool = TrainerItemPoolEntry[];
|
||||||
|
|
||||||
export type TrainerItemTieredPool = {
|
export type TrainerItemTieredPool = {
|
||||||
[key in RewardTier]?: TrainerItemPool;
|
[key in RarityTier]?: TrainerItemPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function isTrainerItemPool(value: any): value is TrainerItemPool {
|
export function isTrainerItemPool(value: any): value is TrainerItemPool {
|
||||||
|
50
src/items/trainer-item-default-tiers.ts
Normal file
50
src/items/trainer-item-default-tiers.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
|
import { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
|
|
||||||
|
export const trainerItemRarities = {
|
||||||
|
[TrainerItemId.MAP]: RarityTier.COMMON,
|
||||||
|
[TrainerItemId.IV_SCANNER]: RarityTier.ULTRA,
|
||||||
|
[TrainerItemId.LOCK_CAPSULE]: RarityTier.ROGUE,
|
||||||
|
[TrainerItemId.MEGA_BRACELET]: RarityTier.ROGUE,
|
||||||
|
[TrainerItemId.DYNAMAX_BAND]: RarityTier.ROGUE,
|
||||||
|
[TrainerItemId.TERA_ORB]: RarityTier.ULTRA,
|
||||||
|
|
||||||
|
[TrainerItemId.GOLDEN_POKEBALL]: RarityTier.LUXURY,
|
||||||
|
|
||||||
|
[TrainerItemId.OVAL_CHARM]: RarityTier.LUXURY,
|
||||||
|
[TrainerItemId.EXP_SHARE]: RarityTier.ULTRA,
|
||||||
|
[TrainerItemId.EXP_BALANCE]: RarityTier.LUXURY,
|
||||||
|
|
||||||
|
[TrainerItemId.CANDY_JAR]: RarityTier.ULTRA,
|
||||||
|
[TrainerItemId.BERRY_POUCH]: RarityTier.ROGUE,
|
||||||
|
|
||||||
|
[TrainerItemId.HEALING_CHARM]: RarityTier.MASTER,
|
||||||
|
[TrainerItemId.EXP_CHARM]: RarityTier.ULTRA,
|
||||||
|
[TrainerItemId.SUPER_EXP_CHARM]: RarityTier.ROGUE,
|
||||||
|
[TrainerItemId.GOLDEN_EXP_CHARM]: RarityTier.LUXURY,
|
||||||
|
[TrainerItemId.AMULET_COIN]: RarityTier.ULTRA,
|
||||||
|
|
||||||
|
[TrainerItemId.ABILITY_CHARM]: RarityTier.ULTRA,
|
||||||
|
[TrainerItemId.SHINY_CHARM]: RarityTier.MASTER,
|
||||||
|
[TrainerItemId.CATCHING_CHARM]: RarityTier.ULTRA,
|
||||||
|
|
||||||
|
[TrainerItemId.BLACK_SLUDGE]: RarityTier.LUXURY,
|
||||||
|
[TrainerItemId.GOLDEN_BUG_NET]: RarityTier.LUXURY,
|
||||||
|
|
||||||
|
[TrainerItemId.LURE]: RarityTier.COMMON,
|
||||||
|
[TrainerItemId.SUPER_LURE]: RarityTier.GREAT,
|
||||||
|
[TrainerItemId.MAX_LURE]: RarityTier.ULTRA,
|
||||||
|
|
||||||
|
[TrainerItemId.X_ATTACK]: RarityTier.COMMON,
|
||||||
|
[TrainerItemId.X_DEFENSE]: RarityTier.COMMON,
|
||||||
|
[TrainerItemId.X_SP_ATK]: RarityTier.COMMON,
|
||||||
|
[TrainerItemId.X_SP_DEF]: RarityTier.COMMON,
|
||||||
|
[TrainerItemId.X_SPEED]: RarityTier.COMMON,
|
||||||
|
[TrainerItemId.X_ACCURACY]: RarityTier.COMMON,
|
||||||
|
[TrainerItemId.DIRE_HIT]: RarityTier.GREAT,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getTrainerItemTier(item: TrainerItemId): RarityTier {
|
||||||
|
const tier = trainerItemRarities[item];
|
||||||
|
return tier ?? RarityTier.LUXURY;
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { allTrainerItems } from "#data/data-lists";
|
import { allTrainerItems } from "#data/data-lists";
|
||||||
import { RewardTier } from "#enums/reward-tier";
|
import { RarityTier } from "#enums/reward-tier";
|
||||||
import type { TrainerItemId } from "#enums/trainer-item-id";
|
import type { TrainerItemId } from "#enums/trainer-item-id";
|
||||||
import type { TrainerItemPool, TrainerItemTieredPool } from "#items/trainer-item-data-types";
|
import type { TrainerItemPool, TrainerItemTieredPool } from "#items/trainer-item-data-types";
|
||||||
import type { TrainerItemManager } from "#items/trainer-item-manager";
|
import type { TrainerItemManager } from "#items/trainer-item-manager";
|
||||||
@ -29,13 +29,13 @@ export function getNewTrainerItemFromPool(pool: TrainerItemPool, manager: Traine
|
|||||||
return entry as TrainerItemId;
|
return entry as TrainerItemId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function assignEnemyBuffTokenForWave(tier: RewardTier) {
|
export function assignEnemyBuffTokenForWave(tier: RarityTier) {
|
||||||
let tierStackCount: number;
|
let tierStackCount: number;
|
||||||
switch (tier) {
|
switch (tier) {
|
||||||
case RewardTier.ULTRA:
|
case RarityTier.ULTRA:
|
||||||
tierStackCount = 5;
|
tierStackCount = 5;
|
||||||
break;
|
break;
|
||||||
case RewardTier.GREAT:
|
case RarityTier.GREAT:
|
||||||
tierStackCount = 3;
|
tierStackCount = 3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -297,9 +297,9 @@ export class DoubleBattleChanceBoosterTrainerItem extends LapsingTrainerItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TempStatToTrainerItemMap {
|
type TempStatToTrainerItemMap = {
|
||||||
[key: number]: TrainerItemId;
|
[key in TempBattleStat]: TrainerItemId;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const tempStatToTrainerItem: TempStatToTrainerItemMap = {
|
export const tempStatToTrainerItem: TempStatToTrainerItemMap = {
|
||||||
[Stat.ATK]: TrainerItemId.X_ATTACK,
|
[Stat.ATK]: TrainerItemId.X_ATTACK,
|
||||||
|
@ -15,9 +15,9 @@ import { getBiomeHasProps } from "#field/arena";
|
|||||||
import { initHeldItems } from "#items/all-held-items";
|
import { initHeldItems } from "#items/all-held-items";
|
||||||
import { initTrainerItems } from "#items/all-trainer-items";
|
import { initTrainerItems } from "#items/all-trainer-items";
|
||||||
import { initHeldItemPools } from "#items/init-held-item-pools";
|
import { initHeldItemPools } from "#items/init-held-item-pools";
|
||||||
|
import { initRewardPools } from "#items/init-reward-pools";
|
||||||
import { initTrainerItemPools } from "#items/init-trainer-item-pools";
|
import { initTrainerItemPools } from "#items/init-trainer-item-pools";
|
||||||
import { initModifierPools } from "#modifiers/init-modifier-pools";
|
import { initRewards } from "#items/reward";
|
||||||
import { initModifierTypes } from "#modifiers/modifier-type";
|
|
||||||
import { initMoves } from "#moves/move";
|
import { initMoves } from "#moves/move";
|
||||||
import { initMysteryEncounters } from "#mystery-encounters/mystery-encounters";
|
import { initMysteryEncounters } from "#mystery-encounters/mystery-encounters";
|
||||||
import { CacheBustedLoaderPlugin } from "#plugins/cache-busted-loader-plugin";
|
import { CacheBustedLoaderPlugin } from "#plugins/cache-busted-loader-plugin";
|
||||||
@ -370,8 +370,8 @@ export class LoadingScene extends SceneBase {
|
|||||||
|
|
||||||
this.loadLoadingScreen();
|
this.loadLoadingScreen();
|
||||||
|
|
||||||
initModifierTypes();
|
initRewards();
|
||||||
initModifierPools();
|
initRewardPools();
|
||||||
initHeldItemPools();
|
initHeldItemPools();
|
||||||
initTrainerItemPools();
|
initTrainerItemPools();
|
||||||
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
/*
|
|
||||||
* Contains modifier pools for different contexts in the game.
|
|
||||||
* Can be safely imported without worrying about circular dependencies.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type { ModifierPool } from "#types/modifier-types";
|
|
||||||
|
|
||||||
export const modifierPool: ModifierPool = {};
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user