mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-01 14:02:18 +02:00
More changes
This commit is contained in:
parent
8613dadad9
commit
560b6fd369
@ -1,18 +1,18 @@
|
||||
import { allHeldItems } from "#app/modifier/held-items";
|
||||
import type { HeldItemType } from "#app/modifier/held-items";
|
||||
import type { HeldItems } from "#app/modifier/held-items";
|
||||
|
||||
export class PokemonItemManager {
|
||||
private heldItems: [HeldItemType, number][];
|
||||
private heldItems: [HeldItems, number][];
|
||||
|
||||
constructor() {
|
||||
this.heldItems = [];
|
||||
}
|
||||
|
||||
getHeldItems(): [HeldItemType, number][] {
|
||||
getHeldItems(): [HeldItems, number][] {
|
||||
return this.heldItems;
|
||||
}
|
||||
|
||||
addHeldItem(itemType: HeldItemType, stack: number) {
|
||||
addHeldItem(itemType: HeldItems, stack: number) {
|
||||
const maxStack = allHeldItems[itemType].getMaxStackCount();
|
||||
|
||||
const existing = this.heldItems.find(([type]) => type === itemType);
|
||||
|
@ -21,6 +21,7 @@ import { initVouchers } from "#app/system/voucher";
|
||||
import { Biome } from "#enums/biome";
|
||||
import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters";
|
||||
import { timedEventManager } from "./global-event-manager";
|
||||
import { initHeldItems } from "./modifier/held-items";
|
||||
|
||||
export class LoadingScene extends SceneBase {
|
||||
public static readonly KEY = "loading";
|
||||
@ -375,6 +376,7 @@ export class LoadingScene extends SceneBase {
|
||||
initSpecies();
|
||||
initMoves();
|
||||
initAbilities();
|
||||
initHeldItems();
|
||||
initChallenges();
|
||||
initMysteryEncounters();
|
||||
}
|
||||
|
69
src/modifier/held-item-pool.ts
Normal file
69
src/modifier/held-item-pool.ts
Normal file
@ -0,0 +1,69 @@
|
||||
/**
|
||||
import { PlayerPokemon } from "#app/field/pokemon";
|
||||
import { randSeedInt } from "#app/utils/common";
|
||||
import { HeldItemCategories, HeldItems } from "./held-items";
|
||||
import { ModifierTier } from "./modifier-tier";
|
||||
|
||||
interface HeldItemPool {
|
||||
[tier: string]: [HeldItems | HeldItemCategories, number][];
|
||||
}
|
||||
|
||||
const dailyStarterHeldItemPool: HeldItemPool = {
|
||||
[ModifierTier.COMMON]: [
|
||||
[HeldItemCategories.BASE_STAT_BOOSTER, 1],
|
||||
[HeldItemCategories.BERRY, 3],
|
||||
],
|
||||
[ModifierTier.GREAT]: [
|
||||
[HeldItemCategories.ATTACK_TYPE_BOOSTER, 5],
|
||||
],
|
||||
[ModifierTier.ULTRA]: [
|
||||
[HeldItems.REVIVER_SEED, 4],
|
||||
[HeldItems.SOOTHE_BELL, 1],
|
||||
[HeldItems.SOUL_DEW, 1],
|
||||
[HeldItems.GOLDEN_PUNCH, 1],
|
||||
],
|
||||
[ModifierTier.ROGUE]: [
|
||||
[HeldItems.GRIP_CLAW, 5],
|
||||
[HeldItems.BATON, 2],
|
||||
[HeldItems.FOCUS_BAND, 5],
|
||||
[HeldItems.QUICK_CLAW, 3],
|
||||
[HeldItems.KINGS_ROCK, 3],
|
||||
],
|
||||
[ModifierTier.MASTER]: [
|
||||
[HeldItems.LEFTOVERS, 1],
|
||||
[HeldItems.SHELL_BELL, 1],
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
export function getDailyRunStarterModifiers(party: PlayerPokemon[]): HeldItems[] {
|
||||
const ret: HeldItems[] = [];
|
||||
for (const p of party) {
|
||||
for (let m = 0; m < 3; m++) {
|
||||
const tierValue = randSeedInt(64);
|
||||
|
||||
let tier: ModifierTier;
|
||||
if (tierValue > 25) {
|
||||
tier = ModifierTier.COMMON;
|
||||
} else if (tierValue > 12) {
|
||||
tier = ModifierTier.GREAT;
|
||||
} else if (tierValue > 4) {
|
||||
tier = ModifierTier.ULTRA;
|
||||
} else if (tierValue) {
|
||||
tier = ModifierTier.ROGUE;
|
||||
} else {
|
||||
tier = ModifierTier.MASTER;
|
||||
}
|
||||
|
||||
const modifier = getNewModifierTypeOption(party, ModifierPoolType.DAILY_STARTER, tier)?.type?.newModifier(
|
||||
p,
|
||||
);
|
||||
ret.push(modifier);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
*/
|
@ -5,35 +5,58 @@ import type { NumberHolder } from "#app/utils/common";
|
||||
import { PokemonType } from "#enums/pokemon-type";
|
||||
import i18next from "i18next";
|
||||
|
||||
export enum HeldItemType {
|
||||
NONE,
|
||||
export const HeldItems = {
|
||||
NONE: 0x0000,
|
||||
|
||||
SITRUS_BERRY = 1,
|
||||
LEPPA_BERRY,
|
||||
SITRUS_BERRY: 0x0101,
|
||||
LEPPA_BERRY: 0x0102,
|
||||
|
||||
SILK_SCARF = 101,
|
||||
BLACK_BELT,
|
||||
SHARP_BEAK,
|
||||
POISON_BARB,
|
||||
SOFT_SAND,
|
||||
HARD_STONE,
|
||||
SILVER_POWDER,
|
||||
SPELL_TAG,
|
||||
METAL_COAT,
|
||||
CHARCOAL,
|
||||
MYSTIC_WATER,
|
||||
MIRACLE_SEED,
|
||||
MAGNET,
|
||||
TWISTED_SPOON,
|
||||
NEVER_MELT_ICE,
|
||||
DRAGON_FANG,
|
||||
BLACK_GLASSES,
|
||||
FAIRY_FEATHER,
|
||||
}
|
||||
SILK_SCARF: 0x0201,
|
||||
BLACK_BELT: 0x0202,
|
||||
SHARP_BEAK: 0x0203,
|
||||
POISON_BARB: 0x0204,
|
||||
SOFT_SAND: 0x0205,
|
||||
HARD_STONE: 0x0206,
|
||||
SILVER_POWDER: 0x0207,
|
||||
SPELL_TAG: 0x0208,
|
||||
METAL_COAT: 0x0209,
|
||||
CHARCOAL: 0x020a,
|
||||
MYSTIC_WATER: 0x020b,
|
||||
MIRACLE_SEED: 0x020c,
|
||||
MAGNET: 0x020d,
|
||||
TWISTED_SPOON: 0x020e,
|
||||
NEVER_MELT_ICE: 0x020f,
|
||||
DRAGON_FANG: 0x0210,
|
||||
BLACK_GLASSES: 0x0211,
|
||||
FAIRY_FEATHER: 0x0212,
|
||||
|
||||
REVIVER_SEED: 0x0301,
|
||||
SOOTHE_BELL: 0x0302,
|
||||
SOUL_DEW: 0x0303,
|
||||
GOLDEN_PUNCH: 0x0304,
|
||||
GRIP_CLAW: 0x0305,
|
||||
BATON: 0x0306,
|
||||
FOCUS_BAND: 0x0307,
|
||||
QUICK_CLAW: 0x0308,
|
||||
KINGS_ROCK: 0x0309,
|
||||
LEFTOVERS: 0x030a,
|
||||
SHELL_BELL: 0x030b,
|
||||
};
|
||||
|
||||
export type HeldItems = (typeof HeldItems)[keyof typeof HeldItems];
|
||||
|
||||
export const HeldItemCategories = {
|
||||
NONE: 0x0000,
|
||||
BERRY: 0x0100,
|
||||
ATTACK_TYPE_BOOSTER: 0x0200,
|
||||
BASE_STAT_BOOSTER: 0x0400,
|
||||
};
|
||||
|
||||
export type HeldItemCategories = (typeof HeldItemCategories)[keyof typeof HeldItemCategories];
|
||||
|
||||
export class HeldItem implements Localizable {
|
||||
// public pokemonId: number;
|
||||
public type: HeldItemType;
|
||||
public type: HeldItems;
|
||||
public maxStackCount: number;
|
||||
public isTransferable = true;
|
||||
public isStealable = true;
|
||||
@ -43,7 +66,7 @@ export class HeldItem implements Localizable {
|
||||
public description = "";
|
||||
public icon = "";
|
||||
|
||||
constructor(type: HeldItemType, maxStackCount = 1) {
|
||||
constructor(type: HeldItems, maxStackCount = 1) {
|
||||
this.type = type;
|
||||
this.maxStackCount = maxStackCount;
|
||||
|
||||
@ -125,36 +148,36 @@ export class HeldItem implements Localizable {
|
||||
}
|
||||
}
|
||||
|
||||
interface AttackTypeToHeldItemTypeMap {
|
||||
[key: number]: HeldItemType;
|
||||
interface AttackTypeToHeldItemMap {
|
||||
[key: number]: HeldItems;
|
||||
}
|
||||
|
||||
export const attackTypeToHeldItemTypeMap: AttackTypeToHeldItemTypeMap = {
|
||||
[PokemonType.NORMAL]: HeldItemType.SILK_SCARF,
|
||||
[PokemonType.FIGHTING]: HeldItemType.BLACK_BELT,
|
||||
[PokemonType.FLYING]: HeldItemType.SHARP_BEAK,
|
||||
[PokemonType.POISON]: HeldItemType.POISON_BARB,
|
||||
[PokemonType.GROUND]: HeldItemType.SOFT_SAND,
|
||||
[PokemonType.ROCK]: HeldItemType.HARD_STONE,
|
||||
[PokemonType.BUG]: HeldItemType.SILVER_POWDER,
|
||||
[PokemonType.GHOST]: HeldItemType.SPELL_TAG,
|
||||
[PokemonType.STEEL]: HeldItemType.METAL_COAT,
|
||||
[PokemonType.FIRE]: HeldItemType.CHARCOAL,
|
||||
[PokemonType.WATER]: HeldItemType.MYSTIC_WATER,
|
||||
[PokemonType.GRASS]: HeldItemType.MIRACLE_SEED,
|
||||
[PokemonType.ELECTRIC]: HeldItemType.MAGNET,
|
||||
[PokemonType.PSYCHIC]: HeldItemType.TWISTED_SPOON,
|
||||
[PokemonType.ICE]: HeldItemType.NEVER_MELT_ICE,
|
||||
[PokemonType.DRAGON]: HeldItemType.DRAGON_FANG,
|
||||
[PokemonType.DARK]: HeldItemType.BLACK_GLASSES,
|
||||
[PokemonType.FAIRY]: HeldItemType.FAIRY_FEATHER,
|
||||
export const attackTypeToHeldItem: AttackTypeToHeldItemMap = {
|
||||
[PokemonType.NORMAL]: HeldItems.SILK_SCARF,
|
||||
[PokemonType.FIGHTING]: HeldItems.BLACK_BELT,
|
||||
[PokemonType.FLYING]: HeldItems.SHARP_BEAK,
|
||||
[PokemonType.POISON]: HeldItems.POISON_BARB,
|
||||
[PokemonType.GROUND]: HeldItems.SOFT_SAND,
|
||||
[PokemonType.ROCK]: HeldItems.HARD_STONE,
|
||||
[PokemonType.BUG]: HeldItems.SILVER_POWDER,
|
||||
[PokemonType.GHOST]: HeldItems.SPELL_TAG,
|
||||
[PokemonType.STEEL]: HeldItems.METAL_COAT,
|
||||
[PokemonType.FIRE]: HeldItems.CHARCOAL,
|
||||
[PokemonType.WATER]: HeldItems.MYSTIC_WATER,
|
||||
[PokemonType.GRASS]: HeldItems.MIRACLE_SEED,
|
||||
[PokemonType.ELECTRIC]: HeldItems.MAGNET,
|
||||
[PokemonType.PSYCHIC]: HeldItems.TWISTED_SPOON,
|
||||
[PokemonType.ICE]: HeldItems.NEVER_MELT_ICE,
|
||||
[PokemonType.DRAGON]: HeldItems.DRAGON_FANG,
|
||||
[PokemonType.DARK]: HeldItems.BLACK_GLASSES,
|
||||
[PokemonType.FAIRY]: HeldItems.FAIRY_FEATHER,
|
||||
};
|
||||
|
||||
export class AttackTypeBoosterHeldItem extends HeldItem {
|
||||
public moveType: PokemonType;
|
||||
public powerBoost: number;
|
||||
|
||||
constructor(type: HeldItemType, maxStackCount = 1, moveType: PokemonType, powerBoost: number) {
|
||||
constructor(type: HeldItems, maxStackCount = 1, moveType: PokemonType, powerBoost: number) {
|
||||
super(type, maxStackCount);
|
||||
this.moveType = moveType;
|
||||
this.powerBoost = powerBoost;
|
||||
@ -162,7 +185,7 @@ export class AttackTypeBoosterHeldItem extends HeldItem {
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return i18next.t(`modifierType:AttackTypeBoosterItem.${HeldItemType[this.type]?.toLowerCase()}`);
|
||||
return i18next.t(`modifierType:AttackTypeBoosterItem.${HeldItems[this.type]?.toLowerCase()}`);
|
||||
}
|
||||
|
||||
getDescription(): string {
|
||||
@ -172,7 +195,7 @@ export class AttackTypeBoosterHeldItem extends HeldItem {
|
||||
}
|
||||
|
||||
getIcon(): string {
|
||||
return `${HeldItemType[this.type]?.toLowerCase()}`;
|
||||
return `${HeldItems[this.type]?.toLowerCase()}`;
|
||||
}
|
||||
|
||||
apply(stackCount: number, moveType: PokemonType, movePower: NumberHolder): void {
|
||||
@ -192,17 +215,12 @@ export function applyAttackTypeBoosterHeldItem(pokemon: Pokemon, moveType: Pokem
|
||||
}
|
||||
}
|
||||
|
||||
type HeldItemMap = {
|
||||
[key in HeldItemType]: HeldItem;
|
||||
};
|
||||
|
||||
export const allHeldItems = {} as HeldItemMap;
|
||||
export const allHeldItems = {};
|
||||
|
||||
export function initHeldItems() {
|
||||
// SILK_SCARF, BLACK_BELT, etc...
|
||||
for (const [typeKey, heldItemType] of Object.entries(attackTypeToHeldItemTypeMap)) {
|
||||
for (const [typeKey, heldItemType] of Object.entries(attackTypeToHeldItem)) {
|
||||
const pokemonType = Number(typeKey) as PokemonType;
|
||||
|
||||
allHeldItems[heldItemType] = new AttackTypeBoosterHeldItem(heldItemType, 99, pokemonType, 0.2);
|
||||
}
|
||||
}
|
||||
|
@ -128,8 +128,8 @@ import { getStatKey, Stat, TEMP_BATTLE_STATS } from "#enums/stat";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
import i18next from "i18next";
|
||||
import { timedEventManager } from "#app/global-event-manager";
|
||||
import type { HeldItemType } from "./held-items";
|
||||
import { allHeldItems, attackTypeToHeldItemTypeMap } from "./held-items";
|
||||
import type { HeldItems } from "./held-items";
|
||||
import { allHeldItems, attackTypeToHeldItem } from "./held-items";
|
||||
|
||||
const outputModifierData = false;
|
||||
const useMaxWeightForOutput = false;
|
||||
@ -812,10 +812,10 @@ export class AttackTypeBoosterModifierType
|
||||
{
|
||||
public moveType: PokemonType;
|
||||
public boostPercent: number;
|
||||
public heldItemId: HeldItemType;
|
||||
public heldItemId: HeldItems;
|
||||
|
||||
constructor(moveType: PokemonType, boostPercent: number) {
|
||||
const heldItemId = attackTypeToHeldItemTypeMap[moveType];
|
||||
const heldItemId = attackTypeToHeldItem[moveType];
|
||||
super(
|
||||
"",
|
||||
allHeldItems[heldItemId].getIcon(),
|
||||
|
120
src/modifier/reward-generator.ts
Normal file
120
src/modifier/reward-generator.ts
Normal file
@ -0,0 +1,120 @@
|
||||
import { AttackMove } from "#app/data/moves/move";
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import { PokemonType } from "#enums/pokemon-type";
|
||||
import { attackTypeToHeldItem } from "./held-items";
|
||||
import { HeldItemReward, type Reward } from "./reward";
|
||||
|
||||
function getRandomWeightedSelection<T>(weights: Map<T, number>): T | null {
|
||||
const totalWeight = Array.from(weights.values()).reduce((sum, weight) => sum + weight, 0);
|
||||
|
||||
if (totalWeight === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const randInt = Math.floor(Math.random() * totalWeight);
|
||||
|
||||
let accumulatedWeight = 0;
|
||||
for (const [item, weight] of weights.entries()) {
|
||||
accumulatedWeight += weight;
|
||||
if (randInt < accumulatedWeight) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export class RewardGenerator<T extends number> {
|
||||
options: T[];
|
||||
tempWeights: Map<T, number>;
|
||||
|
||||
constructor(options: T[]) {
|
||||
this.options = options;
|
||||
this.tempWeights = new Map(this.options.map(option => [option, 1]));
|
||||
}
|
||||
|
||||
generate(party: Pokemon[], overrideWeightFunction?: Function) {
|
||||
const weights = overrideWeightFunction ? overrideWeightFunction(party) : this.weightFunction(party);
|
||||
|
||||
for (const [option, tempWeight] of this.tempWeights.entries()) {
|
||||
if (tempWeight === 0 && weights.has(option)) {
|
||||
weights.set(option, 0);
|
||||
}
|
||||
}
|
||||
|
||||
const value: T | null = getRandomWeightedSelection(weights);
|
||||
|
||||
if (value) {
|
||||
this.tempWeights.set(value, 0);
|
||||
return this.generateReward(value);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
weightFunction(_party: Pokemon[]): Map<T, number> {
|
||||
const defaultWeightMap = new Map<T, number>();
|
||||
|
||||
this.options.forEach(option => {
|
||||
defaultWeightMap.set(option, 1);
|
||||
});
|
||||
|
||||
return defaultWeightMap;
|
||||
}
|
||||
|
||||
generateReward(_value: T): Reward | null {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export class AttackTypeBoosterHeldItemRewardGenerator extends RewardGenerator<PokemonType> {
|
||||
constructor() {
|
||||
//TODO: we can also construct this, but then have to handle options being null
|
||||
const options = [
|
||||
PokemonType.NORMAL,
|
||||
PokemonType.FIGHTING,
|
||||
PokemonType.FLYING,
|
||||
PokemonType.POISON,
|
||||
PokemonType.GROUND,
|
||||
PokemonType.ROCK,
|
||||
PokemonType.BUG,
|
||||
PokemonType.GHOST,
|
||||
PokemonType.STEEL,
|
||||
PokemonType.FIRE,
|
||||
PokemonType.WATER,
|
||||
PokemonType.GRASS,
|
||||
PokemonType.ELECTRIC,
|
||||
PokemonType.PSYCHIC,
|
||||
PokemonType.ICE,
|
||||
PokemonType.DRAGON,
|
||||
PokemonType.DARK,
|
||||
PokemonType.FAIRY,
|
||||
];
|
||||
super(options);
|
||||
}
|
||||
|
||||
weightFunction(party: Pokemon[]): Map<PokemonType, number> {
|
||||
const attackMoveTypes = party.flatMap(p =>
|
||||
p
|
||||
.getMoveset()
|
||||
.map(m => m.getMove())
|
||||
.filter(m => m instanceof AttackMove)
|
||||
.map(m => m.type),
|
||||
);
|
||||
|
||||
const attackMoveTypeWeights = new Map<PokemonType, number>();
|
||||
|
||||
for (const type of attackMoveTypes) {
|
||||
const currentWeight = attackMoveTypeWeights.get(type) ?? 0;
|
||||
if (currentWeight < 3) {
|
||||
attackMoveTypeWeights.set(type, currentWeight + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return attackMoveTypeWeights;
|
||||
}
|
||||
|
||||
generateReward(value: PokemonType) {
|
||||
return new HeldItemReward(attackTypeToHeldItem[value]);
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import type { PokeballType } from "#enums/pokeball";
|
||||
import i18next from "i18next";
|
||||
import { allHeldItems, type HeldItem } from "./held-items";
|
||||
import { allHeldItems, type HeldItems } from "./held-items";
|
||||
import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball";
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
|
||||
@ -77,8 +77,9 @@ export class PartySelectReward extends Reward {
|
||||
}
|
||||
|
||||
export class HeldItemReward extends PartySelectReward {
|
||||
private itemId;
|
||||
constructor(itemId: HeldItem) {
|
||||
private itemId: HeldItems;
|
||||
|
||||
constructor(itemId: HeldItems) {
|
||||
super();
|
||||
this.itemId = itemId;
|
||||
}
|
||||
@ -103,38 +104,14 @@ export class HeldItemReward extends PartySelectReward {
|
||||
|
||||
|
||||
|
||||
export class RewardGenerator {
|
||||
options: number[];
|
||||
optionWeights: number[];
|
||||
|
||||
constructor(options: number[]) {
|
||||
this.options = options;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class PokeballRewardGenerator extends RewardGenerator{
|
||||
|
||||
constructor(
|
||||
options: PokeballType[],
|
||||
condition?: (party: Pokemon[], option: number) => boolean,
|
||||
getOptionWeight?: (party: Pokemon[], option: number) => number,
|
||||
) {
|
||||
super(options);
|
||||
|
||||
this.isAvailable = isAvailable;
|
||||
this.getOptionWeight = getOptionWeight;
|
||||
}
|
||||
|
||||
isAvailable(): boolean {
|
||||
|
||||
}
|
||||
|
||||
optionWeights() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -162,12 +139,6 @@ export class RewardManager {
|
||||
this.rewardPool = rewardPool;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
* */
|
||||
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user