Fix crash when stealing an enemy item not in player pool

pull/78/head
Flashfyre 2024-04-10 14:31:29 -04:00
parent 8d751b22e2
commit 151b751300
3 changed files with 45 additions and 21 deletions

View File

@ -19,6 +19,7 @@ import { Stat } from "./pokemon-stat";
import { TerrainType } from "./terrain"; import { TerrainType } from "./terrain";
import { SpeciesFormChangeActiveTrigger } from "./pokemon-forms"; import { SpeciesFormChangeActiveTrigger } from "./pokemon-forms";
import { Species } from "./enums/species"; import { Species } from "./enums/species";
import { ModifierPoolType } from "#app/modifier/modifier-type";
export enum MoveCategory { export enum MoveCategory {
PHYSICAL, PHYSICAL,
@ -934,8 +935,9 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr {
return resolve(false); return resolve(false);
const heldItems = this.getTargetHeldItems(target).filter(i => i.getTransferrable(false)); const heldItems = this.getTargetHeldItems(target).filter(i => i.getTransferrable(false));
if (heldItems.length) { if (heldItems.length) {
const highestItemTier = heldItems.map(m => m.type.getOrInferTier()).reduce((highestTier, tier) => Math.max(tier, highestTier), 0); const poolType = target.isPlayer() ? ModifierPoolType.PLAYER : target.hasTrainer() ? ModifierPoolType.TRAINER : ModifierPoolType.WILD;
const tierHeldItems = heldItems.filter(m => m.type.getOrInferTier() === highestItemTier); const highestItemTier = heldItems.map(m => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier, highestTier), 0);
const tierHeldItems = heldItems.filter(m => m.type.getOrInferTier(poolType) === highestItemTier);
const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)]; const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)];
user.scene.tryTransferHeldItemModifier(stolenItem, user, false, false).then(success => { user.scene.tryTransferHeldItemModifier(stolenItem, user, false, false).then(success => {
if (success) if (success)
@ -980,8 +982,9 @@ export class RemoveHeldItemAttr extends MoveEffectAttr {
return resolve(false); return resolve(false);
const heldItems = this.getTargetHeldItems(target).filter(i => i.getTransferrable(false)); const heldItems = this.getTargetHeldItems(target).filter(i => i.getTransferrable(false));
if (heldItems.length) { if (heldItems.length) {
const highestItemTier = heldItems.map(m => m.type.getOrInferTier()).reduce((highestTier, tier) => Math.max(tier, highestTier), 0); const poolType = target.isPlayer() ? ModifierPoolType.PLAYER : target.hasTrainer() ? ModifierPoolType.TRAINER : ModifierPoolType.WILD;
const tierHeldItems = heldItems.filter(m => m.type.getOrInferTier() === highestItemTier); const highestItemTier = heldItems.map(m => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier, highestTier), 0);
const tierHeldItems = heldItems.filter(m => m.type.getOrInferTier(poolType) === highestItemTier);
const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)]; const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)];
user.scene.tryTransferHeldItemModifier(stolenItem, user, false, false).then(success => { user.scene.tryTransferHeldItemModifier(stolenItem, user, false, false).then(success => {
if (success) if (success)

View File

@ -63,16 +63,35 @@ export class ModifierType {
this.tier = tier; this.tier = tier;
} }
getOrInferTier(): ModifierTier { getOrInferTier(poolType: ModifierPoolType = ModifierPoolType.PLAYER): ModifierTier {
if (this.tier) if (this.tier)
return this.tier; return this.tier;
if (!this.id) if (!this.id)
return null; return null;
for (let tier of Utils.getEnumValues(ModifierTier)) { let poolTypes: ModifierPoolType[];
if (!modifierPool.hasOwnProperty(tier)) switch (poolType) {
continue; case ModifierPoolType.PLAYER:
if (modifierPool[tier].find(m => (m as WeightedModifierType).modifierType.id === (this.generatorId || this.id))) poolTypes = [ poolType, ModifierPoolType.TRAINER, ModifierPoolType.WILD ];
return (this.tier = tier); break;
case ModifierPoolType.WILD:
poolTypes = [ poolType, ModifierPoolType.PLAYER, ModifierPoolType.TRAINER ];
break;
case ModifierPoolType.TRAINER:
poolTypes = [ poolType, ModifierPoolType.PLAYER, ModifierPoolType.WILD ];
break;
default:
poolTypes = [ poolType ];
break;
}
// Try multiple pool types in case of stolen items
for (let type of poolTypes) {
const pool = getModifierPoolForType(type);
for (let tier of Utils.getEnumValues(ModifierTier)) {
if (!pool.hasOwnProperty(tier))
continue;
if (pool[tier].find(m => (m as WeightedModifierType).modifierType.id === (this.generatorId || this.id)))
return (this.tier = tier);
}
} }
return null; return null;
} }
@ -1179,9 +1198,7 @@ let enemyIgnoredPoolIndexes = {};
let enemyBuffModifierPoolThresholds = {}; let enemyBuffModifierPoolThresholds = {};
let enemyBuffIgnoredPoolIndexes = {}; let enemyBuffIgnoredPoolIndexes = {};
const tierWeights = [ 769 / 1024, 192 / 1024, 48 / 1024, 12 / 1024, 1 / 1024 ]; export function getModifierPoolForType(poolType: ModifierPoolType): ModifierPool {
export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: ModifierPoolType, rerollCount: integer = 0) {
let pool: ModifierPool; let pool: ModifierPool;
switch (poolType) { switch (poolType) {
case ModifierPoolType.PLAYER: case ModifierPoolType.PLAYER:
@ -1200,6 +1217,14 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod
pool = dailyStarterModifierPool; pool = dailyStarterModifierPool;
break; break;
} }
return pool;
}
const tierWeights = [ 769 / 1024, 192 / 1024, 48 / 1024, 12 / 1024, 1 / 1024 ];
export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: ModifierPoolType, rerollCount: integer = 0) {
const pool = getModifierPoolForType(poolType);
const ignoredIndexes = {}; const ignoredIndexes = {};
const modifierTableData = {}; const modifierTableData = {};
const thresholds = Object.fromEntries(new Map(Object.keys(pool).map(t => { const thresholds = Object.fromEntries(new Map(Object.keys(pool).map(t => {
@ -1360,27 +1385,22 @@ export function getDailyRunStarterModifiers(party: PlayerPokemon[]): Modifiers.P
function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier?: ModifierTier, upgradeCount?: integer, retryCount: integer = 0): ModifierTypeOption { function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier?: ModifierTier, upgradeCount?: integer, retryCount: integer = 0): ModifierTypeOption {
const player = !poolType; const player = !poolType;
let pool: ModifierPool; const pool = getModifierPoolForType(poolType);
let thresholds: object; let thresholds: object;
switch (poolType) { switch (poolType) {
case ModifierPoolType.PLAYER: case ModifierPoolType.PLAYER:
pool = modifierPool;
thresholds = modifierPoolThresholds; thresholds = modifierPoolThresholds;
break; break;
case ModifierPoolType.WILD: case ModifierPoolType.WILD:
pool = wildModifierPool;
thresholds = enemyModifierPoolThresholds; thresholds = enemyModifierPoolThresholds;
break; break;
case ModifierPoolType.TRAINER: case ModifierPoolType.TRAINER:
pool = trainerModifierPool;
thresholds = enemyModifierPoolThresholds; thresholds = enemyModifierPoolThresholds;
break; break;
case ModifierPoolType.ENEMY_BUFF: case ModifierPoolType.ENEMY_BUFF:
pool = enemyBuffModifierPool;
thresholds = enemyBuffModifierPoolThresholds; thresholds = enemyBuffModifierPoolThresholds;
break; break;
case ModifierPoolType.DAILY_STARTER: case ModifierPoolType.DAILY_STARTER:
pool = dailyStarterModifierPool;
thresholds = dailyStarterModifierPoolThresholds; thresholds = dailyStarterModifierPoolThresholds;
break; break;
} }

View File

@ -1738,12 +1738,13 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
return false; return false;
const withinParty = pokemon.isPlayer() === targetPokemon.isPlayer(); const withinParty = pokemon.isPlayer() === targetPokemon.isPlayer();
const poolType = pokemon.isPlayer() ? ModifierTypes.ModifierPoolType.PLAYER : pokemon.hasTrainer() ? ModifierTypes.ModifierPoolType.TRAINER : ModifierTypes.ModifierPoolType.WILD;
const transferredModifierTypes: ModifierTypes.ModifierType[] = []; const transferredModifierTypes: ModifierTypes.ModifierType[] = [];
const itemModifiers = pokemon.scene.findModifiers(m => m instanceof PokemonHeldItemModifier const itemModifiers = pokemon.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& (m as PokemonHeldItemModifier).pokemonId === targetPokemon.id && m.getTransferrable(withinParty), targetPokemon.isPlayer()) as PokemonHeldItemModifier[]; && (m as PokemonHeldItemModifier).pokemonId === targetPokemon.id && m.getTransferrable(withinParty), targetPokemon.isPlayer()) as PokemonHeldItemModifier[];
let highestItemTier = itemModifiers.map(m => m.type.getOrInferTier()).reduce((highestTier, tier) => Math.max(tier, highestTier), 0); let highestItemTier = itemModifiers.map(m => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier, highestTier), 0);
let tierItemModifiers = itemModifiers.filter(m => m.type.getOrInferTier() === highestItemTier); let tierItemModifiers = itemModifiers.filter(m => m.type.getOrInferTier(poolType) === highestItemTier);
let heldItemTransferPromises: Promise<void>[] = []; let heldItemTransferPromises: Promise<void>[] = [];