mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-01 05:52:17 +02:00
Moving away from HeldItemAttr
This commit is contained in:
parent
054dfcf35a
commit
09e217b4cc
@ -121,7 +121,7 @@ import { MoveFlags } from "#enums/MoveFlags";
|
|||||||
import { MoveEffectTrigger } from "#enums/MoveEffectTrigger";
|
import { MoveEffectTrigger } from "#enums/MoveEffectTrigger";
|
||||||
import { MultiHitType } from "#enums/MultiHitType";
|
import { MultiHitType } from "#enums/MultiHitType";
|
||||||
import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSleepTalkMoves } from "./invalid-moves";
|
import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSleepTalkMoves } from "./invalid-moves";
|
||||||
import { applyHeldItemAttrs, AttackTypeBoosterHeldItemAttr } from "#app/modifier/held-items";
|
import { applyAttackTypeBoosterHeldItem } from "#app/modifier/held-items";
|
||||||
|
|
||||||
type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean;
|
type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean;
|
||||||
type UserMoveConditionFunc = (user: Pokemon, move: Move) => boolean;
|
type UserMoveConditionFunc = (user: Pokemon, move: Move) => boolean;
|
||||||
@ -838,7 +838,7 @@ export default class Move implements Localizable {
|
|||||||
|
|
||||||
if (!this.hasAttr(TypelessAttr)) {
|
if (!this.hasAttr(TypelessAttr)) {
|
||||||
globalScene.arena.applyTags(WeakenMoveTypeTag, simulated, this.type, power);
|
globalScene.arena.applyTags(WeakenMoveTypeTag, simulated, this.type, power);
|
||||||
applyHeldItemAttrs(AttackTypeBoosterHeldItemAttr, source, this.type, power)
|
applyAttackTypeBoosterHeldItem(source, this.type, power);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source.getTag(HelpingHandTag)) {
|
if (source.getTag(HelpingHandTag)) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
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 type { Localizable } from "#app/interfaces/locales";
|
import type { Localizable } from "#app/interfaces/locales";
|
||||||
import type { Constructor, NumberHolder } from "#app/utils";
|
import type { NumberHolder } from "#app/utils";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
@ -38,36 +38,37 @@ export class HeldItem implements Localizable {
|
|||||||
public isTransferable = true;
|
public isTransferable = true;
|
||||||
public isStealable = true;
|
public isStealable = true;
|
||||||
public isSuppressable = true;
|
public isSuppressable = true;
|
||||||
public attrs: HeldItemAttr[];
|
|
||||||
|
|
||||||
public name: string;
|
public name = "";
|
||||||
public description: string;
|
public description = "";
|
||||||
public icon: string;
|
public icon = "";
|
||||||
|
|
||||||
constructor(type: HeldItemType, maxStackCount = 1, name, description, icon) {
|
constructor(type: HeldItemType, maxStackCount = 1) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.maxStackCount = maxStackCount;
|
this.maxStackCount = maxStackCount;
|
||||||
|
|
||||||
this.isTransferable = true;
|
this.isTransferable = true;
|
||||||
this.isStealable = true;
|
this.isStealable = true;
|
||||||
this.isSuppressable = true;
|
this.isSuppressable = true;
|
||||||
|
|
||||||
this.name = name;
|
|
||||||
this.description = description;
|
|
||||||
this.icon = icon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: we might want to change things to make this work... otherwise it's pointless
|
localize(): void {
|
||||||
// to derive from Localizable.
|
this.name = this.getName();
|
||||||
localize(): void {}
|
this.description = this.getDescription();
|
||||||
|
this.icon = this.getIcon();
|
||||||
|
}
|
||||||
|
|
||||||
// get name(): string {
|
getName(): string {
|
||||||
// return i18next.t(`modifierType:AttackTypeBoosterItem.${AttackTypeBoosterItem[this.moveType]?.toLowerCase()}`);
|
return "";
|
||||||
// }
|
}
|
||||||
|
|
||||||
// getDescription(): string {
|
getDescription(): string {
|
||||||
// return
|
return "";
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
getIcon(): string {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
untransferable(): HeldItem {
|
untransferable(): HeldItem {
|
||||||
this.isTransferable = false;
|
this.isTransferable = false;
|
||||||
@ -84,31 +85,11 @@ export class HeldItem implements Localizable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr<T extends Constructor<HeldItemAttr>>(AttrType: T, ...args: ConstructorParameters<T>): HeldItem {
|
|
||||||
const attr = new AttrType(...args);
|
|
||||||
this.attrs.push(attr);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all ability attributes that match `attrType`
|
|
||||||
* @param attrType any attribute that extends {@linkcode AbAttr}
|
|
||||||
* @returns Array of attributes that match `attrType`, Empty Array if none match.
|
|
||||||
*/
|
|
||||||
getAttrs<T extends HeldItemAttr>(attrType: Constructor<T>): T[] {
|
|
||||||
return this.attrs.filter((a): a is T => a instanceof attrType);
|
|
||||||
}
|
|
||||||
|
|
||||||
hasAttr<T extends HeldItemAttr>(attrType: Constructor<T>): boolean {
|
|
||||||
return this.getAttrs(attrType).length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
getMaxStackCount(): number {
|
getMaxStackCount(): number {
|
||||||
return this.maxStackCount;
|
return this.maxStackCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
getIcon(stackCount: number, _forSummary?: boolean): Phaser.GameObjects.Container {
|
createIcon(stackCount: number, _forSummary?: boolean): Phaser.GameObjects.Container {
|
||||||
const container = globalScene.add.container(0, 0);
|
const container = globalScene.add.container(0, 0);
|
||||||
|
|
||||||
const item = globalScene.add.sprite(0, 12, "items");
|
const item = globalScene.add.sprite(0, 12, "items");
|
||||||
@ -144,87 +125,84 @@ export class HeldItem implements Localizable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class HeldItemAttr {
|
interface AttackTypeToHeldItemTypeMap {
|
||||||
public showItem: boolean;
|
[key: number]: HeldItemType;
|
||||||
|
|
||||||
constructor(showItem = false) {
|
|
||||||
this.showItem = showItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies ability effects without checking conditions
|
|
||||||
* @param pokemon - The pokemon to apply this ability to
|
|
||||||
* @param itemType - Whether or not the ability is a passive
|
|
||||||
* @param args - Extra args passed to the function. Handled by child classes.
|
|
||||||
* @see {@linkcode canApply}
|
|
||||||
*/
|
|
||||||
apply(..._args: any[]): void {}
|
|
||||||
|
|
||||||
getTriggerMessage(_pokemon: Pokemon, _itemType: HeldItemType, ..._args: any[]): string | null {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: May need to add back some condition logic... we'll deal with that later on
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AttackTypeBoosterHeldItemAttr extends HeldItemAttr {
|
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 class AttackTypeBoosterHeldItem extends HeldItem {
|
||||||
public moveType: PokemonType;
|
public moveType: PokemonType;
|
||||||
public powerBoost: number;
|
public powerBoost: number;
|
||||||
|
|
||||||
constructor(moveType: PokemonType, powerBoost: number) {
|
constructor(type: HeldItemType, maxStackCount = 1, moveType: PokemonType, powerBoost: number) {
|
||||||
super();
|
super(type, maxStackCount);
|
||||||
this.moveType = moveType;
|
this.moveType = moveType;
|
||||||
this.powerBoost = powerBoost;
|
this.powerBoost = powerBoost;
|
||||||
|
this.localize();
|
||||||
}
|
}
|
||||||
|
|
||||||
override apply(stackCount: number, args: any[]): void {
|
getName(): string {
|
||||||
const moveType = args[0];
|
return i18next.t(`modifierType:AttackTypeBoosterItem.${HeldItemType[this.type]?.toLowerCase()}`);
|
||||||
const movePower = args[1];
|
}
|
||||||
|
|
||||||
|
getDescription(): string {
|
||||||
|
return i18next.t("modifierType:ModifierType.AttackTypeBoosterModifierType.description", {
|
||||||
|
moveType: i18next.t(`pokemonInfo:Type.${PokemonType[this.moveType]}`),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getIcon(): string {
|
||||||
|
return `${HeldItemType[this.type]?.toLowerCase()}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(stackCount: number, moveType: PokemonType, movePower: NumberHolder): void {
|
||||||
if (moveType === this.moveType && movePower.value >= 1) {
|
if (moveType === this.moveType && movePower.value >= 1) {
|
||||||
(movePower as NumberHolder).value = Math.floor(
|
movePower.value = Math.floor(movePower.value * (1 + stackCount * this.powerBoost));
|
||||||
(movePower as NumberHolder).value * (1 + stackCount * this.powerBoost),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function applyHeldItemAttrs(attrType: Constructor<HeldItemAttr>, pokemon: Pokemon, ...args: any[]) {
|
export function applyAttackTypeBoosterHeldItem(pokemon: Pokemon, moveType: PokemonType, movePower: NumberHolder) {
|
||||||
if (pokemon) {
|
if (pokemon) {
|
||||||
for (const [item, stackCount] of pokemon.heldItemManager.getHeldItems()) {
|
for (const [item, stackCount] of pokemon.heldItemManager.getHeldItems()) {
|
||||||
if (allHeldItems[item].hasAttr(attrType)) {
|
if (allHeldItems[item] instanceof AttackTypeBoosterHeldItem) {
|
||||||
attrType.apply(stackCount, ...args);
|
allHeldItems[item].apply(stackCount, moveType, movePower);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const allHeldItems = [new HeldItem(HeldItemType.NONE, 0, "", "", "")];
|
type HeldItemMap = {
|
||||||
|
[key in HeldItemType]: HeldItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const allHeldItems = {} as HeldItemMap;
|
||||||
|
|
||||||
export function initHeldItems() {
|
export function initHeldItems() {
|
||||||
allHeldItems.push(
|
// SILK_SCARF, BLACK_BELT, etc...
|
||||||
new HeldItem(
|
for (const [typeKey, heldItemType] of Object.entries(attackTypeToHeldItemTypeMap)) {
|
||||||
HeldItemType.SILK_SCARF,
|
const pokemonType = Number(typeKey) as PokemonType;
|
||||||
99,
|
|
||||||
i18next.t("modifierType:AttackTypeBoosterItem.silk_scarf"),
|
|
||||||
i18next.t("modifierType:ModifierType.AttackTypeBoosterModifierType.description", {
|
|
||||||
moveType: i18next.t("pokemonInfo:Type.NORMAL"),
|
|
||||||
}),
|
|
||||||
"silk_scarf",
|
|
||||||
).attr(AttackTypeBoosterHeldItemAttr, PokemonType.NORMAL, 0.2),
|
|
||||||
new HeldItem(
|
|
||||||
HeldItemType.BLACK_BELT,
|
|
||||||
99,
|
|
||||||
i18next.t("modifierType:AttackTypeBoosterItem.black_belt"),
|
|
||||||
i18next.t("modifierType:ModifierType.AttackTypeBoosterModifierType.description", {
|
|
||||||
moveType: i18next.t("pokemonInfo:Type.FIGHTING"),
|
|
||||||
}),
|
|
||||||
"black_belt",
|
|
||||||
).attr(AttackTypeBoosterHeldItemAttr, PokemonType.FIGHTING, 0.2),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: I hate this. Can we just make it an interface?
|
allHeldItems[heldItemType] = new AttackTypeBoosterHeldItem(heldItemType, 99, pokemonType, 0.2);
|
||||||
export function getHeldItem(itemType: HeldItemType): HeldItem {
|
}
|
||||||
return allHeldItems.find(item => item.type === itemType)!; // TODO: is this bang correct?
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user