mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-30 13:33:01 +02:00
Fixing (most) berry usage
This commit is contained in:
parent
29af976c49
commit
215ce632ef
@ -57,7 +57,6 @@ import {
|
|||||||
getModifierPoolForType,
|
getModifierPoolForType,
|
||||||
getPartyLuckValue,
|
getPartyLuckValue,
|
||||||
ModifierPoolType,
|
ModifierPoolType,
|
||||||
PokemonHeldItemModifierType,
|
|
||||||
} from "#app/modifier/modifier-type";
|
} from "#app/modifier/modifier-type";
|
||||||
import AbilityBar from "#app/ui/ability-bar";
|
import AbilityBar from "#app/ui/ability-bar";
|
||||||
import {
|
import {
|
||||||
|
@ -88,8 +88,9 @@ import type { BattlerIndex } from "#app/battle";
|
|||||||
import type Move from "#app/data/moves/move";
|
import type Move from "#app/data/moves/move";
|
||||||
import type { ArenaTrapTag, SuppressAbilitiesTag } from "#app/data/arena-tag";
|
import type { ArenaTrapTag, SuppressAbilitiesTag } from "#app/data/arena-tag";
|
||||||
import { noAbilityTypeOverrideMoves } from "../moves/invalid-moves";
|
import { noAbilityTypeOverrideMoves } from "../moves/invalid-moves";
|
||||||
import { HeldItemId } from "#enums/held-item-id";
|
import { HeldItemCategoryId, HeldItemId, isItemInCategory } from "#enums/held-item-id";
|
||||||
import { allHeldItems } from "#app/items/all-held-items";
|
import { allHeldItems } from "#app/items/all-held-items";
|
||||||
|
import { berryTypeToHeldItem } from "#app/items/held-items/berry";
|
||||||
|
|
||||||
export class BlockRecoilDamageAttr extends AbAttr {
|
export class BlockRecoilDamageAttr extends AbAttr {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -5432,10 +5433,14 @@ export class PostTurnRestoreBerryAbAttr extends PostTurnAbAttr {
|
|||||||
override canApplyPostTurn(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _args: any[]): boolean {
|
override canApplyPostTurn(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _args: any[]): boolean {
|
||||||
// Ensure we have at least 1 recoverable berry (at least 1 berry in berriesEaten is not capped)
|
// Ensure we have at least 1 recoverable berry (at least 1 berry in berriesEaten is not capped)
|
||||||
const cappedBerries = new Set(
|
const cappedBerries = new Set(
|
||||||
globalScene
|
pokemon
|
||||||
.getModifiers(BerryModifier, pokemon.isPlayer())
|
.getHeldItems()
|
||||||
.filter(bm => bm.pokemonId === pokemon.id && bm.getCountUnderMax() < 1)
|
.filter(
|
||||||
.map(bm => bm.berryType),
|
bm =>
|
||||||
|
isItemInCategory(bm, HeldItemCategoryId.BERRY) &&
|
||||||
|
pokemon.heldItemManager.getStack(bm) < allHeldItems[bm].maxStackCount,
|
||||||
|
)
|
||||||
|
.map(bm => allHeldItems[bm].berryType),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.berriesUnderCap = pokemon.battleData.berriesEaten.filter(bt => !cappedBerries.has(bt));
|
this.berriesUnderCap = pokemon.battleData.berriesEaten.filter(bt => !cappedBerries.has(bt));
|
||||||
@ -5465,30 +5470,15 @@ export class PostTurnRestoreBerryAbAttr extends PostTurnAbAttr {
|
|||||||
const randomIdx = randSeedInt(this.berriesUnderCap.length);
|
const randomIdx = randSeedInt(this.berriesUnderCap.length);
|
||||||
const chosenBerryType = this.berriesUnderCap[randomIdx];
|
const chosenBerryType = this.berriesUnderCap[randomIdx];
|
||||||
pokemon.battleData.berriesEaten.splice(randomIdx, 1); // Remove berry from memory
|
pokemon.battleData.berriesEaten.splice(randomIdx, 1); // Remove berry from memory
|
||||||
const chosenBerry = new BerryModifierType(chosenBerryType);
|
const chosenBerry = berryTypeToHeldItem[chosenBerryType];
|
||||||
|
|
||||||
// Add the randomly chosen berry or update the existing one
|
pokemon.heldItemManager.add(chosenBerry);
|
||||||
const berryModifier = globalScene.findModifier(
|
|
||||||
m => m instanceof BerryModifier && m.berryType === chosenBerryType && m.pokemonId === pokemon.id,
|
|
||||||
pokemon.isPlayer(),
|
|
||||||
) as BerryModifier | undefined;
|
|
||||||
|
|
||||||
if (berryModifier) {
|
|
||||||
berryModifier.stackCount++;
|
|
||||||
} else {
|
|
||||||
const newBerry = new BerryModifier(chosenBerry, pokemon.id, chosenBerryType, 1);
|
|
||||||
if (pokemon.isPlayer()) {
|
|
||||||
globalScene.addModifier(newBerry);
|
|
||||||
} else {
|
|
||||||
globalScene.addEnemyModifier(newBerry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
globalScene.updateModifiers(pokemon.isPlayer());
|
globalScene.updateModifiers(pokemon.isPlayer());
|
||||||
globalScene.phaseManager.queueMessage(
|
globalScene.phaseManager.queueMessage(
|
||||||
i18next.t("abilityTriggers:postTurnLootCreateEatenBerry", {
|
i18next.t("abilityTriggers:postTurnLootCreateEatenBerry", {
|
||||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||||
berryName: chosenBerry.name,
|
berryName: allHeldItems[chosenBerry].name,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
@ -5537,8 +5527,7 @@ export class RepeatBerryNextTurnAbAttr extends PostTurnAbAttr {
|
|||||||
// This doesn't count as "eating" a berry (for unnerve/stuff cheeks/unburden) as no item is consumed.
|
// This doesn't count as "eating" a berry (for unnerve/stuff cheeks/unburden) as no item is consumed.
|
||||||
for (const berryType of pokemon.summonData.berriesEatenLast) {
|
for (const berryType of pokemon.summonData.berriesEatenLast) {
|
||||||
getBerryEffectFunc(berryType)(pokemon);
|
getBerryEffectFunc(berryType)(pokemon);
|
||||||
const bMod = new BerryModifier(new BerryModifierType(berryType), pokemon.id, berryType, 1);
|
globalScene.eventTarget.dispatchEvent(new BerryUsedEvent(pokemon, berryType)); // trigger message
|
||||||
globalScene.eventTarget.dispatchEvent(new BerryUsedEvent(bMod)); // trigger message
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// uncomment to make cheek pouch work with cud chew
|
// uncomment to make cheek pouch work with cud chew
|
||||||
|
@ -87,7 +87,7 @@ export const HeldItemId = {
|
|||||||
MACHO_BRACE: 0x0909,
|
MACHO_BRACE: 0x0909,
|
||||||
|
|
||||||
// Evo trackers
|
// Evo trackers
|
||||||
GIMMIGHOUL_EVO_TRACKER: 0x0a01,
|
GIMMIGHOUL_EVO_TRACKER: 0x0A01,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type HeldItemId = (typeof HeldItemId)[keyof typeof HeldItemId];
|
export type HeldItemId = (typeof HeldItemId)[keyof typeof HeldItemId];
|
||||||
@ -103,3 +103,27 @@ export const HeldItemNames: Record<HeldItemValue, HeldItemName> = Object.entries
|
|||||||
},
|
},
|
||||||
{} as Record<HeldItemValue, HeldItemName>
|
{} as Record<HeldItemValue, HeldItemName>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
export const HeldItemCategoryId = {
|
||||||
|
NONE: 0x0000,
|
||||||
|
BERRY: 0x0100,
|
||||||
|
CONSUMABLE: 0x0200,
|
||||||
|
TYPE_ATTACK_BOOSTER: 0x0300,
|
||||||
|
STAT_BOOSTER: 0x0400,
|
||||||
|
CRIT_BOOSTER: 0x0500,
|
||||||
|
GAIN_INCREASE: 0x0600,
|
||||||
|
UNIQUE: 0x0700,
|
||||||
|
BASE_STAT_BOOST: 0x0900,
|
||||||
|
EVO_TRACKER: 0x0A00,
|
||||||
|
};
|
||||||
|
|
||||||
|
export type HeldItemCategoryId = (typeof HeldItemCategoryId)[keyof typeof HeldItemCategoryId];
|
||||||
|
|
||||||
|
function getHeldItemCategory(itemId: HeldItemId): HeldItemCategoryId {
|
||||||
|
return itemId & 0xFF00;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isItemInCategory(itemId: HeldItemId, category: HeldItemCategoryId): boolean {
|
||||||
|
return getHeldItemCategory(itemId) === category;
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
|
import type Pokemon from "#app/field/pokemon";
|
||||||
|
import type { BerryType } from "#enums/berry-type";
|
||||||
import type Move from "../data/moves/move";
|
import type Move from "../data/moves/move";
|
||||||
import type { BerryModifier } from "../modifier/modifier";
|
|
||||||
|
|
||||||
/** Alias for all {@linkcode BattleScene} events */
|
/** Alias for all {@linkcode BattleScene} events */
|
||||||
export enum BattleSceneEventType {
|
export enum BattleSceneEventType {
|
||||||
@ -81,12 +82,13 @@ export class MoveUsedEvent extends Event {
|
|||||||
* @extends Event
|
* @extends Event
|
||||||
*/
|
*/
|
||||||
export class BerryUsedEvent extends Event {
|
export class BerryUsedEvent extends Event {
|
||||||
/** The {@linkcode BerryModifier} being used */
|
/** The {@linkcode BerryType} being used */
|
||||||
public berryModifier: BerryModifier;
|
public pokemon: Pokemon;
|
||||||
constructor(berry: BerryModifier) {
|
public berryType: BerryType;
|
||||||
|
constructor(pokemon: Pokemon, berryType: BerryType) {
|
||||||
super(BattleSceneEventType.BERRY_USED);
|
super(BattleSceneEventType.BERRY_USED);
|
||||||
|
this.pokemon = pokemon;
|
||||||
this.berryModifier = berry;
|
this.berryType = berryType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,11 +153,7 @@ export function initHeldItems() {
|
|||||||
.unstealable()
|
.unstealable()
|
||||||
.untransferable()
|
.untransferable()
|
||||||
.unsuppressable();
|
.unsuppressable();
|
||||||
allHeldItems[HeldItemId.OLD_GATEAU] = new BaseStatFlatHeldItem(HeldItemId.OLD_GATEAU, 1, [
|
allHeldItems[HeldItemId.OLD_GATEAU] = new BaseStatFlatHeldItem(HeldItemId.OLD_GATEAU, 1)
|
||||||
Stat.HP,
|
|
||||||
Stat.ATK,
|
|
||||||
Stat.DEF,
|
|
||||||
])
|
|
||||||
.unstealable()
|
.unstealable()
|
||||||
.untransferable()
|
.untransferable()
|
||||||
.unsuppressable();
|
.unsuppressable();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { getBerryEffectDescription, getBerryEffectFunc, getBerryName } from "#app/data/berry";
|
import { getBerryEffectDescription, getBerryEffectFunc, getBerryName } from "#app/data/berry";
|
||||||
|
import { BerryUsedEvent } from "#app/events/battle-scene";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { ConsumableHeldItem, ITEM_EFFECT } from "#app/items/held-item";
|
import { ConsumableHeldItem, ITEM_EFFECT } from "#app/items/held-item";
|
||||||
@ -26,10 +27,8 @@ export const berryTypeToHeldItem: BerryTypeToHeldItemMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export interface BERRY_PARAMS {
|
export interface BERRY_PARAMS {
|
||||||
/** The pokemon with the item */
|
/** The pokemon with the berry */
|
||||||
pokemon: Pokemon;
|
pokemon: Pokemon;
|
||||||
/** Whether the move was used by a player pokemon */
|
|
||||||
isPlayer: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Maybe split up into subclasses?
|
// TODO: Maybe split up into subclasses?
|
||||||
@ -72,7 +71,6 @@ export class BerryHeldItem extends ConsumableHeldItem {
|
|||||||
*/
|
*/
|
||||||
apply(params: BERRY_PARAMS): boolean {
|
apply(params: BERRY_PARAMS): boolean {
|
||||||
const pokemon = params.pokemon;
|
const pokemon = params.pokemon;
|
||||||
const isPlayer = params.isPlayer;
|
|
||||||
|
|
||||||
const preserve = new BooleanHolder(false);
|
const preserve = new BooleanHolder(false);
|
||||||
globalScene.applyModifiers(PreserveBerryModifier, pokemon.isPlayer(), pokemon, preserve);
|
globalScene.applyModifiers(PreserveBerryModifier, pokemon.isPlayer(), pokemon, preserve);
|
||||||
@ -80,20 +78,15 @@ export class BerryHeldItem extends ConsumableHeldItem {
|
|||||||
|
|
||||||
// munch the berry and trigger unburden-like effects
|
// munch the berry and trigger unburden-like effects
|
||||||
getBerryEffectFunc(this.berryType)(pokemon);
|
getBerryEffectFunc(this.berryType)(pokemon);
|
||||||
this.consume(pokemon, isPlayer, consumed);
|
this.consume(pokemon, pokemon.isPlayer(), consumed);
|
||||||
|
|
||||||
// TODO: Update this method to work with held items
|
// TODO: Update this method to work with held items
|
||||||
// Update berry eaten trackers for Belch, Harvest, Cud Chew, etc.
|
// Update berry eaten trackers for Belch, Harvest, Cud Chew, etc.
|
||||||
// Don't recover it if we proc berry pouch (no item duplication)
|
// Don't recover it if we proc berry pouch (no item duplication)
|
||||||
pokemon.recordEatenBerry(this.berryType, consumed);
|
pokemon.recordEatenBerry(this.berryType, consumed);
|
||||||
|
|
||||||
|
globalScene.eventTarget.dispatchEvent(new BerryUsedEvent(pokemon, this.berryType));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMaxHeldItemCount(_pokemon: Pokemon): number {
|
|
||||||
if ([BerryType.LUM, BerryType.LEPPA, BerryType.SITRUS, BerryType.ENIGMA].includes(this.berryType)) {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,15 @@ import {
|
|||||||
RepeatBerryNextTurnAbAttr,
|
RepeatBerryNextTurnAbAttr,
|
||||||
} from "#app/data/abilities/ability";
|
} from "#app/data/abilities/ability";
|
||||||
import { CommonAnim } from "#app/data/battle-anims";
|
import { CommonAnim } from "#app/data/battle-anims";
|
||||||
import { BerryUsedEvent } from "#app/events/battle-scene";
|
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { BerryModifier } from "#app/modifier/modifier";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { BooleanHolder } from "#app/utils/common";
|
import { BooleanHolder } from "#app/utils/common";
|
||||||
import { FieldPhase } from "./field-phase";
|
import { FieldPhase } from "./field-phase";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
|
import { allHeldItems, applyHeldItems } from "#app/items/all-held-items";
|
||||||
|
import { ITEM_EFFECT } from "#app/items/held-item";
|
||||||
|
import { HeldItemCategoryId, isItemInCategory } from "#enums/held-item-id";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The phase after attacks where the pokemon eat berries.
|
* The phase after attacks where the pokemon eat berries.
|
||||||
@ -36,10 +37,10 @@ export class BerryPhase extends FieldPhase {
|
|||||||
* @param pokemon - The {@linkcode Pokemon} to check
|
* @param pokemon - The {@linkcode Pokemon} to check
|
||||||
*/
|
*/
|
||||||
eatBerries(pokemon: Pokemon): void {
|
eatBerries(pokemon: Pokemon): void {
|
||||||
const hasUsableBerry = !!globalScene.findModifier(
|
const hasUsableBerry = pokemon.getHeldItems().some(m => {
|
||||||
m => m instanceof BerryModifier && m.shouldApply(pokemon),
|
//TODO: This is bugged, must fix the .shouldApply() function
|
||||||
pokemon.isPlayer(),
|
isItemInCategory(m, HeldItemCategoryId.BERRY) && allHeldItems[m].shouldApply(pokemon);
|
||||||
);
|
});
|
||||||
|
|
||||||
if (!hasUsableBerry) {
|
if (!hasUsableBerry) {
|
||||||
return;
|
return;
|
||||||
@ -64,14 +65,7 @@ export class BerryPhase extends FieldPhase {
|
|||||||
CommonAnim.USE_ITEM,
|
CommonAnim.USE_ITEM,
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const berryModifier of globalScene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon)) {
|
applyHeldItems(ITEM_EFFECT.BERRY, { pokemon: pokemon });
|
||||||
// No need to track berries being eaten; already done inside applyModifiers
|
|
||||||
if (berryModifier.consumed) {
|
|
||||||
berryModifier.consumed = false;
|
|
||||||
pokemon.loseHeldItem(berryModifier);
|
|
||||||
}
|
|
||||||
globalScene.eventTarget.dispatchEvent(new BerryUsedEvent(berryModifier));
|
|
||||||
}
|
|
||||||
globalScene.updateModifiers(pokemon.isPlayer());
|
globalScene.updateModifiers(pokemon.isPlayer());
|
||||||
|
|
||||||
// AbilityId.CHEEK_POUCH only works once per round of nom noms
|
// AbilityId.CHEEK_POUCH only works once per round of nom noms
|
||||||
|
@ -177,8 +177,8 @@ export default class BattleFlyout extends Phaser.GameObjects.Container {
|
|||||||
const berryUsedEvent = event as BerryUsedEvent;
|
const berryUsedEvent = event as BerryUsedEvent;
|
||||||
if (
|
if (
|
||||||
!berryUsedEvent ||
|
!berryUsedEvent ||
|
||||||
berryUsedEvent.berryModifier.pokemonId !== this.pokemon?.id ||
|
berryUsedEvent.pokemon.id !== this.pokemon?.id ||
|
||||||
berryUsedEvent.berryModifier.berryType !== BerryType.LEPPA
|
berryUsedEvent.berryType !== BerryType.LEPPA
|
||||||
) {
|
) {
|
||||||
// We only care about Leppa berries
|
// We only care about Leppa berries
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user