mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-30 21:42:20 +02:00
Partial implementation of item steal items
This commit is contained in:
parent
2024281580
commit
1cb956e872
@ -28,6 +28,11 @@ import { type FLINCH_CHANCE_PARAMS, FlinchChanceHeldItem } from "./held-items/fl
|
||||
import { type FRIENDSHIP_BOOST_PARAMS, FriendshipBoosterHeldItem } from "./held-items/friendship-booster";
|
||||
import { type HIT_HEAL_PARAMS, HitHealHeldItem } from "./held-items/hit-heal";
|
||||
import { InstantReviveHeldItem, type INSTANT_REVIVE_PARAMS } from "./held-items/instant-revive";
|
||||
import {
|
||||
ContactItemStealChanceHeldItem,
|
||||
type ITEM_STEAL_PARAMS,
|
||||
TurnEndItemStealHeldItem,
|
||||
} from "./held-items/item-steal";
|
||||
import { type MULTI_HIT_PARAMS, MultiHitHeldItem } from "./held-items/multi-hit";
|
||||
import { type NATURE_WEIGHT_BOOST_PARAMS, NatureWeightBoosterHeldItem } from "./held-items/nature-weight-booster";
|
||||
import {
|
||||
@ -123,6 +128,8 @@ export function initHeldItems() {
|
||||
allHeldItems[HeldItemId.MULTI_LENS] = new MultiHitHeldItem(HeldItemId.MULTI_LENS, 2);
|
||||
allHeldItems[HeldItemId.GOLDEN_PUNCH] = new DamageMoneyRewardHeldItem(HeldItemId.GOLDEN_PUNCH, 5);
|
||||
allHeldItems[HeldItemId.BATON] = new BatonHeldItem(HeldItemId.BATON, 1);
|
||||
allHeldItems[HeldItemId.GRIP_CLAW] = new ContactItemStealChanceHeldItem(HeldItemId.GRIP_CLAW, 5, 10);
|
||||
allHeldItems[HeldItemId.MINI_BLACK_HOLE] = new TurnEndItemStealHeldItem(HeldItemId.MINI_BLACK_HOLE, 1);
|
||||
|
||||
allHeldItems[HeldItemId.FLAME_ORB] = new TurnEndStatusHeldItem(HeldItemId.FLAME_ORB, 1, StatusEffect.BURN);
|
||||
allHeldItems[HeldItemId.TOXIC_ORB] = new TurnEndStatusHeldItem(HeldItemId.TOXIC_ORB, 1, StatusEffect.TOXIC);
|
||||
@ -156,6 +163,8 @@ type APPLY_HELD_ITEMS_PARAMS = {
|
||||
[ITEM_EFFECT.MULTI_HIT]: MULTI_HIT_PARAMS;
|
||||
[ITEM_EFFECT.DAMAGE_MONEY_REWARD]: DAMAGE_MONEY_REWARD_PARAMS;
|
||||
[ITEM_EFFECT.BATON]: BATON_PARAMS;
|
||||
[ITEM_EFFECT.CONTACT_ITEM_STEAL_CHANCE]: ITEM_STEAL_PARAMS;
|
||||
[ITEM_EFFECT.TURN_END_ITEM_STEAL]: ITEM_STEAL_PARAMS;
|
||||
};
|
||||
|
||||
export function applyHeldItems<T extends ITEM_EFFECT>(effect: T, params: APPLY_HELD_ITEMS_PARAMS[T]) {
|
||||
|
@ -27,6 +27,10 @@ export const ITEM_EFFECT = {
|
||||
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,
|
||||
} as const;
|
||||
|
||||
export type ITEM_EFFECT = (typeof ITEM_EFFECT)[keyof typeof ITEM_EFFECT];
|
||||
@ -48,28 +52,16 @@ export class HeldItem {
|
||||
this.isSuppressable = true;
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
get name(): string {
|
||||
return i18next.t(`modifierType:ModifierType.${HeldItemNames[this.type]}.name`) + " (new)";
|
||||
}
|
||||
|
||||
getDescription(): string {
|
||||
get description(): string {
|
||||
return i18next.t(`modifierType:ModifierType.${HeldItemNames[this.type]}.description`);
|
||||
}
|
||||
|
||||
getIcon(): string {
|
||||
return `${HeldItemNames[this.type]?.toLowerCase()}`;
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
return "";
|
||||
}
|
||||
|
||||
get description(): string {
|
||||
return "";
|
||||
}
|
||||
|
||||
get iconName(): string {
|
||||
return "";
|
||||
return `${HeldItemNames[this.type]?.toLowerCase()}`;
|
||||
}
|
||||
|
||||
// TODO: Aren't these fine as just properties to set in the subclass definition?
|
||||
|
155
src/items/held-items/item-steal.ts
Normal file
155
src/items/held-items/item-steal.ts
Normal file
@ -0,0 +1,155 @@
|
||||
import Pokemon from "#app/field/pokemon";
|
||||
import { randSeedFloat } from "#app/utils/common";
|
||||
import type { HeldItemId } from "#enums/held-item-id";
|
||||
import i18next from "i18next";
|
||||
import { HeldItem, ITEM_EFFECT } from "../held-item";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { allHeldItems } from "../all-held-items";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
|
||||
export interface ITEM_STEAL_PARAMS {
|
||||
/** The pokemon with the item */
|
||||
pokemon: Pokemon;
|
||||
/** The pokemon to steal from (optional) */
|
||||
target?: Pokemon;
|
||||
}
|
||||
|
||||
// constructor(type: HeldItemId, maxStackCount = 1, boostPercent: number) {
|
||||
|
||||
/**
|
||||
* Abstract class for held items that steal other Pokemon's items.
|
||||
* @see {@linkcode TurnHeldItemTransferModifier}
|
||||
* @see {@linkcode ContactHeldItemTransferChanceModifier}
|
||||
*/
|
||||
export abstract class ItemTransferHeldItem extends HeldItem {
|
||||
/**
|
||||
* Steals an item, chosen randomly, from a set of target Pokemon.
|
||||
* @param pokemon The {@linkcode Pokemon} holding this item
|
||||
* @param target The {@linkcode Pokemon} to steal from (optional)
|
||||
* @param _args N/A
|
||||
* @returns `true` if an item was stolen; false otherwise.
|
||||
*/
|
||||
apply(params: ITEM_STEAL_PARAMS): boolean {
|
||||
const opponents = this.getTargets(params);
|
||||
|
||||
if (!opponents.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const pokemon = params.pokemon;
|
||||
//TODO: Simplify this logic here
|
||||
const targetPokemon = opponents[pokemon.randBattleSeedInt(opponents.length)];
|
||||
|
||||
const transferredItemCount = this.getTransferredItemCount(params);
|
||||
if (!transferredItemCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Change this logic to use held items
|
||||
const transferredModifierTypes: HeldItemId[] = [];
|
||||
const heldItems = targetPokemon.heldItemManager.getHeldItemKeys();
|
||||
|
||||
for (let i = 0; i < transferredItemCount; i++) {
|
||||
if (!heldItems.length) {
|
||||
break;
|
||||
}
|
||||
const randItemIndex = pokemon.randBattleSeedInt(heldItems.length);
|
||||
const randItem = heldItems[randItemIndex];
|
||||
// TODO: Fix this after updating the various methods in battle-scene.ts
|
||||
if (globalScene.tryTransferHeldItemModifier(randItem, pokemon, false)) {
|
||||
transferredModifierTypes.push(randItem);
|
||||
heldItems.splice(randItemIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (const mt of transferredModifierTypes) {
|
||||
globalScene.phaseManager.queueMessage(this.getTransferMessage(params, mt));
|
||||
}
|
||||
|
||||
return !!transferredModifierTypes.length;
|
||||
}
|
||||
|
||||
abstract getTargets(params: ITEM_STEAL_PARAMS): Pokemon[];
|
||||
|
||||
abstract getTransferredItemCount(params: ITEM_STEAL_PARAMS): number;
|
||||
|
||||
abstract getTransferMessage(params: ITEM_STEAL_PARAMS, itemId: HeldItemId): string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier for held items that steal items from the enemy at the end of
|
||||
* each turn.
|
||||
* @see {@linkcode modifierTypes[MINI_BLACK_HOLE]}
|
||||
*/
|
||||
export class TurnEndItemStealHeldItem extends ItemTransferHeldItem {
|
||||
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.TURN_END_ITEM_STEAL];
|
||||
isTransferable = true;
|
||||
|
||||
/**
|
||||
* Determines the targets to transfer items from when this applies.
|
||||
* @param pokemon the {@linkcode Pokemon} holding this item
|
||||
* @param _args N/A
|
||||
* @returns the opponents of the source {@linkcode Pokemon}
|
||||
*/
|
||||
getTargets(params: ITEM_STEAL_PARAMS): Pokemon[] {
|
||||
return params.pokemon instanceof Pokemon ? params.pokemon.getOpponents() : [];
|
||||
}
|
||||
|
||||
getTransferredItemCount(_params: ITEM_STEAL_PARAMS): number {
|
||||
return 1;
|
||||
}
|
||||
|
||||
getTransferMessage(params: ITEM_STEAL_PARAMS, itemId: HeldItemId): string {
|
||||
return i18next.t("modifier:turnHeldItemTransferApply", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(params.target),
|
||||
itemName: allHeldItems[itemId].name,
|
||||
pokemonName: params.pokemon.getNameToRender(),
|
||||
typeName: this.name,
|
||||
});
|
||||
}
|
||||
|
||||
setTransferrableFalse(): void {
|
||||
this.isTransferable = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier for held items that add a chance to steal items from the target of a
|
||||
* successful attack.
|
||||
* @see {@linkcode modifierTypes[GRIP_CLAW]}
|
||||
* @see {@linkcode HeldItemTransferModifier}
|
||||
*/
|
||||
export class ContactItemStealChanceHeldItem extends ItemTransferHeldItem {
|
||||
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.CONTACT_ITEM_STEAL_CHANCE];
|
||||
public readonly chance: number;
|
||||
|
||||
constructor(type: HeldItemId, maxStackCount = 1, chancePercent: number) {
|
||||
super(type, maxStackCount);
|
||||
|
||||
this.chance = chancePercent / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the target to steal items from when this applies.
|
||||
* @param _holderPokemon The {@linkcode Pokemon} holding this item
|
||||
* @param targetPokemon The {@linkcode Pokemon} the holder is targeting with an attack
|
||||
* @returns The target {@linkcode Pokemon} as array for further use in `apply` implementations
|
||||
*/
|
||||
getTargets(params: ITEM_STEAL_PARAMS): Pokemon[] {
|
||||
return params.target ? [params.target] : [];
|
||||
}
|
||||
|
||||
getTransferredItemCount(params: ITEM_STEAL_PARAMS): number {
|
||||
const stackCount = params.pokemon.heldItemManager.getStack(this.type);
|
||||
return randSeedFloat() <= this.chance * stackCount ? 1 : 0;
|
||||
}
|
||||
|
||||
getTransferMessage(params: ITEM_STEAL_PARAMS, itemId: HeldItemId): string {
|
||||
return i18next.t("modifier:contactHeldItemTransferApply", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(params.target),
|
||||
itemName: allHeldItems[itemId].name,
|
||||
pokemonName: params.pokemon.getNameToRender(),
|
||||
typeName: this.name,
|
||||
});
|
||||
}
|
||||
}
|
@ -4,7 +4,8 @@ import { getLevelTotalExp } from "#app/data/exp";
|
||||
import { MAX_PER_TYPE_POKEBALLS } from "#app/data/pokeball";
|
||||
import { type FormChangeItem, SpeciesFormChangeItemTrigger } from "#app/data/pokemon-forms";
|
||||
import { getStatusEffectHealText } from "#app/data/status-effect";
|
||||
import Pokemon, { type PlayerPokemon } from "#app/field/pokemon";
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import type { PlayerPokemon } from "#app/field/pokemon";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import Overrides from "#app/overrides";
|
||||
import { LearnMoveType } from "#app/phases/learn-move-phase";
|
||||
@ -2005,166 +2006,6 @@ export class BoostBugSpawnModifier extends PersistentModifier {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract class for held items that steal other Pokemon's items.
|
||||
* @see {@linkcode TurnHeldItemTransferModifier}
|
||||
* @see {@linkcode ContactHeldItemTransferChanceModifier}
|
||||
*/
|
||||
export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
|
||||
/**
|
||||
* Determines the targets to transfer items from when this applies.
|
||||
* @param pokemon the {@linkcode Pokemon} holding this item
|
||||
* @param _args N/A
|
||||
* @returns the opponents of the source {@linkcode Pokemon}
|
||||
*/
|
||||
getTargets(pokemon?: Pokemon, ..._args: unknown[]): Pokemon[] {
|
||||
return pokemon instanceof Pokemon ? pokemon.getOpponents() : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Steals an item, chosen randomly, from a set of target Pokemon.
|
||||
* @param pokemon The {@linkcode Pokemon} holding this item
|
||||
* @param target The {@linkcode Pokemon} to steal from (optional)
|
||||
* @param _args N/A
|
||||
* @returns `true` if an item was stolen; false otherwise.
|
||||
*/
|
||||
override apply(pokemon: Pokemon, target?: Pokemon, ..._args: unknown[]): boolean {
|
||||
const opponents = this.getTargets(pokemon, target);
|
||||
|
||||
if (!opponents.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const targetPokemon = opponents[pokemon.randBattleSeedInt(opponents.length)];
|
||||
|
||||
const transferredItemCount = this.getTransferredItemCount();
|
||||
if (!transferredItemCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const transferredModifierTypes: ModifierType[] = [];
|
||||
const itemModifiers = globalScene.findModifiers(
|
||||
m => m instanceof PokemonHeldItemModifier && m.pokemonId === targetPokemon.id && m.isTransferable,
|
||||
targetPokemon.isPlayer(),
|
||||
) as PokemonHeldItemModifier[];
|
||||
|
||||
for (let i = 0; i < transferredItemCount; i++) {
|
||||
if (!itemModifiers.length) {
|
||||
break;
|
||||
}
|
||||
const randItemIndex = pokemon.randBattleSeedInt(itemModifiers.length);
|
||||
const randItem = itemModifiers[randItemIndex];
|
||||
if (globalScene.tryTransferHeldItemModifier(randItem, pokemon, false)) {
|
||||
transferredModifierTypes.push(randItem.type);
|
||||
itemModifiers.splice(randItemIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (const mt of transferredModifierTypes) {
|
||||
globalScene.phaseManager.queueMessage(this.getTransferMessage(pokemon, targetPokemon, mt));
|
||||
}
|
||||
|
||||
return !!transferredModifierTypes.length;
|
||||
}
|
||||
|
||||
abstract getTransferredItemCount(): number;
|
||||
|
||||
abstract getTransferMessage(pokemon: Pokemon, targetPokemon: Pokemon, item: ModifierType): string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier for held items that steal items from the enemy at the end of
|
||||
* each turn.
|
||||
* @see {@linkcode modifierTypes[MINI_BLACK_HOLE]}
|
||||
*/
|
||||
export class TurnHeldItemTransferModifier extends HeldItemTransferModifier {
|
||||
isTransferable = true;
|
||||
|
||||
matchType(modifier: Modifier): boolean {
|
||||
return modifier instanceof TurnHeldItemTransferModifier;
|
||||
}
|
||||
|
||||
clone(): TurnHeldItemTransferModifier {
|
||||
return new TurnHeldItemTransferModifier(this.type, this.pokemonId, this.stackCount);
|
||||
}
|
||||
|
||||
getTransferredItemCount(): number {
|
||||
return this.getStackCount();
|
||||
}
|
||||
|
||||
getTransferMessage(pokemon: Pokemon, targetPokemon: Pokemon, item: ModifierType): string {
|
||||
return i18next.t("modifier:turnHeldItemTransferApply", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(targetPokemon),
|
||||
itemName: item.name,
|
||||
pokemonName: pokemon.getNameToRender(),
|
||||
typeName: this.type.name,
|
||||
});
|
||||
}
|
||||
|
||||
getMaxHeldItemCount(_pokemon: Pokemon): number {
|
||||
return 1;
|
||||
}
|
||||
|
||||
setTransferrableFalse(): void {
|
||||
this.isTransferable = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier for held items that add a chance to steal items from the target of a
|
||||
* successful attack.
|
||||
* @see {@linkcode modifierTypes[GRIP_CLAW]}
|
||||
* @see {@linkcode HeldItemTransferModifier}
|
||||
*/
|
||||
export class ContactHeldItemTransferChanceModifier extends HeldItemTransferModifier {
|
||||
public readonly chance: number;
|
||||
|
||||
constructor(type: ModifierType, pokemonId: number, chancePercent: number, stackCount?: number) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
||||
this.chance = chancePercent / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the target to steal items from when this applies.
|
||||
* @param _holderPokemon The {@linkcode Pokemon} holding this item
|
||||
* @param targetPokemon The {@linkcode Pokemon} the holder is targeting with an attack
|
||||
* @returns The target {@linkcode Pokemon} as array for further use in `apply` implementations
|
||||
*/
|
||||
override getTargets(_holderPokemon: Pokemon, targetPokemon: Pokemon): Pokemon[] {
|
||||
return targetPokemon ? [targetPokemon] : [];
|
||||
}
|
||||
|
||||
matchType(modifier: Modifier): boolean {
|
||||
return modifier instanceof ContactHeldItemTransferChanceModifier;
|
||||
}
|
||||
|
||||
clone(): ContactHeldItemTransferChanceModifier {
|
||||
return new ContactHeldItemTransferChanceModifier(this.type, this.pokemonId, this.chance * 100, this.stackCount);
|
||||
}
|
||||
|
||||
getArgs(): any[] {
|
||||
return super.getArgs().concat(this.chance * 100);
|
||||
}
|
||||
|
||||
getTransferredItemCount(): number {
|
||||
return randSeedFloat() <= this.chance * this.getStackCount() ? 1 : 0;
|
||||
}
|
||||
|
||||
getTransferMessage(pokemon: Pokemon, targetPokemon: Pokemon, item: ModifierType): string {
|
||||
return i18next.t("modifier:contactHeldItemTransferApply", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(targetPokemon),
|
||||
itemName: item.name,
|
||||
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||
typeName: this.type.name,
|
||||
});
|
||||
}
|
||||
|
||||
getMaxHeldItemCount(_pokemon: Pokemon): number {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
export class IvScannerModifier extends PersistentModifier {
|
||||
constructor(type: ModifierType, _stackCount?: number) {
|
||||
super(type);
|
||||
|
Loading…
Reference in New Issue
Block a user