Added Mystical Rock

This commit is contained in:
Wlowscha 2025-06-07 23:48:35 +02:00
parent c323375590
commit bce7472e3d
No known key found for this signature in database
GPG Key ID: 3C8F1AD330565D04
5 changed files with 42 additions and 121 deletions

View File

@ -40,7 +40,8 @@ import { AbilityId } from "#enums/ability-id";
import { SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "#app/data/pokemon-forms"; import { SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "#app/data/pokemon-forms";
import { CommonAnimPhase } from "#app/phases/common-anim-phase"; import { CommonAnimPhase } from "#app/phases/common-anim-phase";
import { WeatherType } from "#enums/weather-type"; import { WeatherType } from "#enums/weather-type";
import { FieldEffectModifier } from "#app/modifier/modifier"; import { applyHeldItems } from "#app/items/all-held-items";
import { ITEM_EFFECT } from "#app/items/held-item";
export class Arena { export class Arena {
public biomeType: BiomeId; public biomeType: BiomeId;
@ -339,7 +340,7 @@ export class Arena {
if (!isNullOrUndefined(user)) { if (!isNullOrUndefined(user)) {
weatherDuration.value = 5; weatherDuration.value = 5;
globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, weatherDuration); applyHeldItems(ITEM_EFFECT.FIELD_EFFECT, { pokemon: user, fieldDuration: weatherDuration });
} }
this.weather = weather ? new Weather(weather, weatherDuration.value) : null; this.weather = weather ? new Weather(weather, weatherDuration.value) : null;
@ -420,7 +421,7 @@ export class Arena {
if (!isNullOrUndefined(user)) { if (!isNullOrUndefined(user)) {
terrainDuration.value = 5; terrainDuration.value = 5;
globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, terrainDuration); applyHeldItems(ITEM_EFFECT.FIELD_EFFECT, { pokemon: user, fieldDuration: terrainDuration });
} }
this.terrain = terrain ? new Terrain(terrain, terrainDuration.value) : null; this.terrain = terrain ? new Terrain(terrain, terrainDuration.value) : null;

View File

@ -20,6 +20,7 @@ import { type BERRY_PARAMS, BerryHeldItem, berryTypeToHeldItem } from "./held-it
import { type BYPASS_SPEED_CHANCE_PARAMS, BypassSpeedChanceHeldItem } from "./held-items/bypass-speed-chance"; import { type BYPASS_SPEED_CHANCE_PARAMS, BypassSpeedChanceHeldItem } from "./held-items/bypass-speed-chance";
import { type CRIT_BOOST_PARAMS, CritBoostHeldItem, SpeciesCritBoostHeldItem } from "./held-items/crit-booster"; import { type CRIT_BOOST_PARAMS, CritBoostHeldItem, SpeciesCritBoostHeldItem } from "./held-items/crit-booster";
import { type EXP_BOOST_PARAMS, ExpBoosterHeldItem } from "./held-items/exp-booster"; import { type EXP_BOOST_PARAMS, ExpBoosterHeldItem } from "./held-items/exp-booster";
import { type FIELD_EFFECT_PARAMS, FieldEffectHeldItem } from "./held-items/field-effect";
import { type FLINCH_CHANCE_PARAMS, FlinchChanceHeldItem } from "./held-items/flinch-chance"; import { type FLINCH_CHANCE_PARAMS, FlinchChanceHeldItem } from "./held-items/flinch-chance";
import { type HIT_HEAL_PARAMS, HitHealHeldItem } from "./held-items/hit-heal"; import { type HIT_HEAL_PARAMS, HitHealHeldItem } from "./held-items/hit-heal";
import { InstantReviveHeldItem, type INSTANT_REVIVE_PARAMS } from "./held-items/instant-revive"; import { InstantReviveHeldItem, type INSTANT_REVIVE_PARAMS } from "./held-items/instant-revive";
@ -109,6 +110,7 @@ export function initHeldItems() {
allHeldItems[HeldItemId.FOCUS_BAND] = new SurviveChanceHeldItem(HeldItemId.FOCUS_BAND, 5); allHeldItems[HeldItemId.FOCUS_BAND] = new SurviveChanceHeldItem(HeldItemId.FOCUS_BAND, 5);
allHeldItems[HeldItemId.QUICK_CLAW] = new BypassSpeedChanceHeldItem(HeldItemId.QUICK_CLAW, 3); allHeldItems[HeldItemId.QUICK_CLAW] = new BypassSpeedChanceHeldItem(HeldItemId.QUICK_CLAW, 3);
allHeldItems[HeldItemId.KINGS_ROCK] = new FlinchChanceHeldItem(HeldItemId.KINGS_ROCK, 3, 10); allHeldItems[HeldItemId.KINGS_ROCK] = new FlinchChanceHeldItem(HeldItemId.KINGS_ROCK, 3, 10);
allHeldItems[HeldItemId.MYSTICAL_ROCK] = new FieldEffectHeldItem(HeldItemId.MYSTICAL_ROCK, 2);
allHeldItems[HeldItemId.FLAME_ORB] = new TurnEndStatusHeldItem(HeldItemId.FLAME_ORB, 1, StatusEffect.BURN); allHeldItems[HeldItemId.FLAME_ORB] = new TurnEndStatusHeldItem(HeldItemId.FLAME_ORB, 1, StatusEffect.BURN);
allHeldItems[HeldItemId.TOXIC_ORB] = new TurnEndStatusHeldItem(HeldItemId.TOXIC_ORB, 1, StatusEffect.TOXIC); allHeldItems[HeldItemId.TOXIC_ORB] = new TurnEndStatusHeldItem(HeldItemId.TOXIC_ORB, 1, StatusEffect.TOXIC);
@ -135,6 +137,7 @@ type APPLY_HELD_ITEMS_PARAMS = {
[ITEM_EFFECT.SURVIVE_CHANCE]: SURVIVE_CHANCE_PARAMS; [ITEM_EFFECT.SURVIVE_CHANCE]: SURVIVE_CHANCE_PARAMS;
[ITEM_EFFECT.BYPASS_SPEED_CHANCE]: BYPASS_SPEED_CHANCE_PARAMS; [ITEM_EFFECT.BYPASS_SPEED_CHANCE]: BYPASS_SPEED_CHANCE_PARAMS;
[ITEM_EFFECT.FLINCH_CHANCE]: FLINCH_CHANCE_PARAMS; [ITEM_EFFECT.FLINCH_CHANCE]: FLINCH_CHANCE_PARAMS;
[ITEM_EFFECT.FIELD_EFFECT]: FIELD_EFFECT_PARAMS;
}; };
export function applyHeldItems<T extends ITEM_EFFECT>(effect: T, params: APPLY_HELD_ITEMS_PARAMS[T]) { export function applyHeldItems<T extends ITEM_EFFECT>(effect: T, params: APPLY_HELD_ITEMS_PARAMS[T]) {

View File

@ -20,6 +20,7 @@ export const ITEM_EFFECT = {
SURVIVE_CHANCE: 12, SURVIVE_CHANCE: 12,
BYPASS_SPEED_CHANCE: 13, BYPASS_SPEED_CHANCE: 13,
FLINCH_CHANCE: 14, FLINCH_CHANCE: 14,
FIELD_EFFECT: 15,
} as const; } as const;
export type ITEM_EFFECT = (typeof ITEM_EFFECT)[keyof typeof ITEM_EFFECT]; export type ITEM_EFFECT = (typeof ITEM_EFFECT)[keyof typeof ITEM_EFFECT];

View File

@ -0,0 +1,33 @@
import type Pokemon from "#app/field/pokemon";
import { HeldItem, ITEM_EFFECT } from "#app/items/held-item";
import type { NumberHolder } from "#app/utils/common";
export interface FIELD_EFFECT_PARAMS {
pokemon: Pokemon;
/** The pokemon with the item */
fieldDuration: NumberHolder;
}
/**
* Modifier used for held items, namely Mystical Rock, that extend the
* duration of weather and terrain effects.
* @extends PokemonHeldItemModifier
* @see {@linkcode apply}
*/
export class FieldEffectHeldItem extends HeldItem {
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.FIELD_EFFECT];
/**
* Provides two more turns per stack to any weather or terrain effect caused
* by the holder.
* @param pokemon {@linkcode Pokemon} that holds the held item
* @param fieldDuration {@linkcode NumberHolder} that stores the current field effect duration
* @returns `true` if the field effect extension was applied successfully
*/
apply(params: FIELD_EFFECT_PARAMS): boolean {
const pokemon = params.pokemon;
const stackCount = pokemon.heldItemManager.getStack(this.type);
params.fieldDuration.value += 2 * stackCount;
return true;
}
}

View File

@ -21,7 +21,7 @@ import type { MoveId } from "#enums/move-id";
import type { Nature } from "#enums/nature"; import type { Nature } from "#enums/nature";
import type { PokeballType } from "#enums/pokeball"; import type { PokeballType } from "#enums/pokeball";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { type PermanentStat, type TempBattleStat, BATTLE_STATS, Stat, TEMP_BATTLE_STATS } from "#enums/stat"; import { type PermanentStat, type TempBattleStat, Stat, TEMP_BATTLE_STATS } from "#enums/stat";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import type { PokemonType } from "#enums/pokemon-type"; import type { PokemonType } from "#enums/pokemon-type";
import i18next from "i18next"; import i18next from "i18next";
@ -1027,44 +1027,6 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier {
} }
} }
export class HitHealModifier extends PokemonHeldItemModifier {
matchType(modifier: Modifier) {
return modifier instanceof HitHealModifier;
}
clone() {
return new HitHealModifier(this.type, this.pokemonId, this.stackCount);
}
/**
* Applies {@linkcode HitHealModifier}
* @param pokemon The {@linkcode Pokemon} that holds the item
* @returns `true` if the {@linkcode Pokemon} was healed
*/
override apply(pokemon: Pokemon): boolean {
if (pokemon.turnData.totalDamageDealt && !pokemon.isFullHp()) {
// TODO: this shouldn't be undefined AFAIK
globalScene.unshiftPhase(
new PokemonHealPhase(
pokemon.getBattlerIndex(),
toDmgValue(pokemon.turnData.totalDamageDealt / 8) * this.stackCount,
i18next.t("modifier:hitHealApply", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
typeName: this.type.name,
}),
true,
),
);
}
return true;
}
getMaxHeldItemCount(_pokemon: Pokemon): number {
return 4;
}
}
export class LevelIncrementBoosterModifier extends PersistentModifier { export class LevelIncrementBoosterModifier extends PersistentModifier {
match(modifier: Modifier) { match(modifier: Modifier) {
return modifier instanceof LevelIncrementBoosterModifier; return modifier instanceof LevelIncrementBoosterModifier;
@ -1196,85 +1158,6 @@ export class PreserveBerryModifier extends PersistentModifier {
} }
} }
/**
* Modifier used for held items, namely White Herb, that restore adverse stat
* stages in battle.
* @extends PokemonHeldItemModifier
* @see {@linkcode apply}
*/
export class ResetNegativeStatStageModifier extends PokemonHeldItemModifier {
matchType(modifier: Modifier) {
return modifier instanceof ResetNegativeStatStageModifier;
}
clone() {
return new ResetNegativeStatStageModifier(this.type, this.pokemonId, this.stackCount);
}
/**
* Goes through the holder's stat stages and, if any are negative, resets that
* stat stage back to 0.
* @param pokemon {@linkcode Pokemon} that holds the item
* @returns `true` if any stat stages were reset, false otherwise
*/
override apply(pokemon: Pokemon): boolean {
let statRestored = false;
for (const s of BATTLE_STATS) {
if (pokemon.getStatStage(s) < 0) {
pokemon.setStatStage(s, 0);
statRestored = true;
}
}
if (statRestored) {
globalScene.queueMessage(
i18next.t("modifier:resetNegativeStatStageApply", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
typeName: this.type.name,
}),
);
}
return statRestored;
}
getMaxHeldItemCount(_pokemon: Pokemon): number {
return 2;
}
}
/**
* Modifier used for held items, namely Mystical Rock, that extend the
* duration of weather and terrain effects.
* @extends PokemonHeldItemModifier
* @see {@linkcode apply}
*/
export class FieldEffectModifier extends PokemonHeldItemModifier {
/**
* Provides two more turns per stack to any weather or terrain effect caused
* by the holder.
* @param pokemon {@linkcode Pokemon} that holds the held item
* @param fieldDuration {@linkcode NumberHolder} that stores the current field effect duration
* @returns `true` if the field effect extension was applied successfully
*/
override apply(_pokemon: Pokemon, fieldDuration: NumberHolder): boolean {
fieldDuration.value += 2 * this.stackCount;
return true;
}
override matchType(modifier: Modifier): boolean {
return modifier instanceof FieldEffectModifier;
}
override clone(): FieldEffectModifier {
return new FieldEffectModifier(this.type, this.pokemonId, this.stackCount);
}
override getMaxHeldItemCount(_pokemon?: Pokemon): number {
return 2;
}
}
export abstract class ConsumablePokemonModifier extends ConsumableModifier { export abstract class ConsumablePokemonModifier extends ConsumableModifier {
public pokemonId: number; public pokemonId: number;