Shuckle Juice and Old Gateau

This commit is contained in:
Wlowscha 2025-06-09 10:12:17 +02:00
parent 76a3e612dd
commit 69b99887d9
No known key found for this signature in database
GPG Key ID: 3C8F1AD330565D04
5 changed files with 216 additions and 0 deletions

View File

@ -1,11 +1,14 @@
import { allHeldItems } from "#app/items/all-held-items";
import type { HeldItemId } from "#app/enums/held-item-id";
import type { FormChangeItem } from "#app/data/pokemon-forms";
import type { BASE_STAT_TOTAL_DATA } from "#app/items/held-items/base-stat-total";
import type { BASE_STAT_FLAT_DATA } from "#app/items/held-items/base-stat-flat";
interface HeldItemProperties {
stack: number;
disabled: boolean;
cooldown?: number;
data?: BASE_STAT_TOTAL_DATA | BASE_STAT_FLAT_DATA;
}
type HeldItemPropertyMap = {

View File

@ -3,6 +3,7 @@ import { HeldItemId } from "#enums/held-item-id";
import { getStatKey, type PermanentStat, Stat } from "#enums/stat";
import i18next from "i18next";
import { HeldItem, ITEM_EFFECT } from "../held-item";
import type { STAT_BOOST_PARAMS } from "./stat-booster";
export interface BASE_STAT_BOOSTER_PARAMS {
/** The pokemon with the item */
@ -78,4 +79,10 @@ export class BaseStatBoosterHeldItem extends HeldItem {
baseStats[this.stat] = Math.floor(baseStats[this.stat] * (1 + stackCount * 0.1));
return true;
}
getMaxStackCount(params: STAT_BOOST_PARAMS): number {
const pokemon = params.pokemon;
const stackCount = pokemon.heldItemManager.getStack(this.type);
return stackCount;
}
}

View File

@ -0,0 +1,64 @@
import type Pokemon from "#app/field/pokemon";
import type { HeldItemId } from "#enums/held-item-id";
import { HeldItem, ITEM_EFFECT } from "../held-item";
import type { Stat } from "#enums/stat";
export interface BASE_STAT_FLAT_PARAMS {
/** The pokemon with the item */
pokemon: Pokemon;
/** The amount of exp to gain */
baseStats: number[];
}
export interface BASE_STAT_FLAT_DATA {
statModifier: number;
}
/**
* Currently used by Old Gateau item
*/
export class BaseStatFlatHeldItem extends HeldItem {
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.BASE_STAT_FLAT];
private stats: Stat[];
public isTransferable = false;
constructor(type: HeldItemId, maxStackCount = 1, stats: Stat[]) {
super(type, maxStackCount);
this.stats = stats;
}
/**
* Checks if the {@linkcode PokemonBaseStatFlatModifier} should be applied to the {@linkcode Pokemon}.
* @param pokemon The {@linkcode Pokemon} that holds the item
* @param baseStats The base stats of the {@linkcode Pokemon}
* @returns `true` if the {@linkcode PokemonBaseStatFlatModifier} should be applied
*/
// override shouldApply(pokemon?: Pokemon, baseStats?: number[]): boolean {
// return super.shouldApply(pokemon, baseStats) && Array.isArray(baseStats);
// }
/**
* Applies the {@linkcode PokemonBaseStatFlatModifier}
* @param _pokemon The {@linkcode Pokemon} that holds the item
* @param baseStats The base stats of the {@linkcode Pokemon}
* @returns always `true`
*/
apply(params: BASE_STAT_FLAT_PARAMS): boolean {
const pokemon = params.pokemon;
const itemData = pokemon.heldItemManager.heldItems[this.type].data;
if (!itemData) {
return false;
}
const statModifier = itemData.statModifier;
const baseStats = params.baseStats;
// Modifies the passed in baseStats[] array by a flat value, only if the stat is specified in this.stats
baseStats.forEach((v, i) => {
if (this.stats.includes(i)) {
const newVal = Math.floor(v + statModifier);
baseStats[i] = Math.min(Math.max(newVal, 1), 999999);
}
});
return true;
}
}

View File

@ -0,0 +1,81 @@
import type Pokemon from "#app/field/pokemon";
import i18next from "i18next";
import { HeldItem, ITEM_EFFECT } from "../held-item";
export interface BASE_STAT_TOTAL_PARAMS {
/** The pokemon with the item */
pokemon: Pokemon;
/** The amount of exp to gain */
baseStats: number[];
}
export interface BASE_STAT_TOTAL_DATA {
statModifier: number;
}
/**
* Currently used by Shuckle Juice item
*/
export class BaseStatTotalHeldItem extends HeldItem {
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.BASE_STAT_TOTAL];
public isTransferable = false;
get name(): string {
return i18next.t("modifierType:ModifierType.MYSTERY_ENCOUNTER_SHUCKLE_JUICE") + " (new)";
}
// TODO: where is this description shown?
get description(): string {
return i18next.t("modifierType:ModifierType.PokemonBaseStatTotalModifierType.description", {
increaseDecrease: i18next.t(
this.statModifier >= 0
? "modifierType:ModifierType.PokemonBaseStatTotalModifierType.extra.increase"
: "modifierType:ModifierType.PokemonBaseStatTotalModifierType.extra.decrease",
),
blessCurse: i18next.t(
this.statModifier >= 0
? "modifierType:ModifierType.PokemonBaseStatTotalModifierType.extra.blessed"
: "modifierType:ModifierType.PokemonBaseStatTotalModifierType.extra.cursed",
),
statValue: this.statModifier,
});
}
get icon(): string {
return "berry_juice";
}
/**
* Checks if {@linkcode PokemonBaseStatTotalModifier} should be applied to the specified {@linkcode Pokemon}.
* @param pokemon the {@linkcode Pokemon} to be modified
* @param baseStats the base stats of the {@linkcode Pokemon}
* @returns `true` if the {@linkcode Pokemon} should be modified
*/
// override shouldApply(pokemon?: Pokemon, baseStats?: number[]): boolean {
// return super.shouldApply(pokemon, baseStats) && Array.isArray(baseStats);
// }
/**
* Applies the {@linkcode PokemonBaseStatTotalModifier}
* @param _pokemon the {@linkcode Pokemon} to be modified
* @param baseStats the base stats of the {@linkcode Pokemon}
* @returns always `true`
*/
apply(params: BASE_STAT_TOTAL_PARAMS): boolean {
const pokemon = params.pokemon;
const itemData = pokemon.heldItemManager.heldItems[this.type].data;
if (!itemData) {
return false;
}
const statModifier = itemData.statModifier;
const baseStats = params.baseStats;
// Modifies the passed in baseStats[] array
baseStats.forEach((v, i) => {
// HP is affected by half as much as other stats
const newVal = i === 0 ? Math.floor(v + statModifier / 2) : Math.floor(v + statModifier);
baseStats[i] = Math.min(Math.max(newVal, 1), 999999);
});
return true;
}
}

View File

@ -0,0 +1,61 @@
import type Pokemon from "#app/field/pokemon";
import { HeldItem, ITEM_EFFECT } from "../held-item";
import { Stat } from "#enums/stat";
import type { NumberHolder } from "#app/utils/common";
export interface INCREMENTING_STAT_PARAMS {
/** The pokemon with the item */
pokemon: Pokemon;
stat: Stat;
statHolder: NumberHolder;
}
/**
* Currently used by Macho Brace item
*/
export class IncrementingStatHeldItem extends HeldItem {
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.INCREMENTING_STAT];
public isTransferable = false;
/**
* Checks if the {@linkcode PokemonIncrementingStatModifier} should be applied to the {@linkcode Pokemon}.
* @param pokemon The {@linkcode Pokemon} that holds the item
* @param stat The affected {@linkcode Stat}
* @param statHolder The {@linkcode NumberHolder} that holds the stat
* @returns `true` if the {@linkcode PokemonBaseStatFlatModifier} should be applied
*/
// override shouldApply(pokemon?: Pokemon, stat?: Stat, statHolder?: NumberHolder): boolean {
// return super.shouldApply(pokemon, stat, statHolder) && !!statHolder;
// }
/**
* Applies the {@linkcode PokemonIncrementingStatModifier}
* @param _pokemon The {@linkcode Pokemon} that holds the item
* @param stat The affected {@linkcode Stat}
* @param statHolder The {@linkcode NumberHolder} that holds the stat
* @returns always `true`
*/
apply(params: INCREMENTING_STAT_PARAMS): boolean {
const pokemon = params.pokemon;
const stackCount = pokemon.heldItemManager.getStack(this.type);
const statHolder = params.statHolder;
// Modifies the passed in stat number holder by +2 per stack for HP, +1 per stack for other stats
// If the Macho Brace is at max stacks (50), adds additional 10% to total HP and 5% to other stats
const isHp = params.stat === Stat.HP;
if (isHp) {
statHolder.value += 2 * stackCount;
if (stackCount === this.maxStackCount) {
statHolder.value = Math.floor(statHolder.value * 1.1);
}
} else {
statHolder.value += stackCount;
if (stackCount === this.maxStackCount) {
statHolder.value = Math.floor(statHolder.value * 1.05);
}
}
return true;
}
}