mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-21 00:52:47 +02:00
Added Crit Boost held items, King's Rock, Focus Band and Quick Claw
This commit is contained in:
parent
955592bdf6
commit
c323375590
@ -42,8 +42,6 @@ import type { AttackTypeBoosterModifierType, ModifierTypeOption } from "#app/mod
|
||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||
import type { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||
import {
|
||||
AttackTypeBoosterModifier,
|
||||
BypassSpeedChanceModifier,
|
||||
ContactHeldItemTransferChanceModifier,
|
||||
GigantamaxAccessModifier,
|
||||
MegaEvolutionAccessModifier,
|
||||
|
@ -92,11 +92,8 @@ import {
|
||||
PokemonHeldItemModifier,
|
||||
PokemonNatureWeightModifier,
|
||||
ShinyRateBoosterModifier,
|
||||
SurviveDamageModifier,
|
||||
TempStatStageBoosterModifier,
|
||||
TempCritBoosterModifier,
|
||||
StatBoosterModifier,
|
||||
CritBoosterModifier,
|
||||
PokemonBaseStatFlatModifier,
|
||||
PokemonBaseStatTotalModifier,
|
||||
PokemonIncrementingStatModifier,
|
||||
@ -257,6 +254,8 @@ import { timedEventManager } from "#app/global-event-manager";
|
||||
import { loadMoveAnimations } from "#app/sprites/pokemon-asset-loader";
|
||||
import { ResetStatusPhase } from "#app/phases/reset-status-phase";
|
||||
import { PokemonItemManager } from "./pokemon-held-item-manager";
|
||||
import { applyHeldItems } from "#app/items/all-held-items";
|
||||
import { ITEM_EFFECT } from "#app/items/held-item";
|
||||
|
||||
export enum LearnMoveSituation {
|
||||
MISC,
|
||||
@ -1446,7 +1445,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
getCritStage(source: Pokemon, move: Move): number {
|
||||
const critStage = new NumberHolder(0);
|
||||
applyMoveAttrs(HighCritAttr, source, this, move, critStage);
|
||||
globalScene.applyModifiers(CritBoosterModifier, source.isPlayer(), source, critStage);
|
||||
applyHeldItems(ITEM_EFFECT.CRIT_BOOST, { pokemon: source, critStage: critStage });
|
||||
globalScene.applyModifiers(TempCritBoosterModifier, source.isPlayer(), critStage);
|
||||
applyAbAttrs(BonusCritAbAttr, source, null, false, critStage);
|
||||
const critBoostTag = source.getTag(CritBoostTag);
|
||||
@ -1503,7 +1502,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
): number {
|
||||
const statValue = new NumberHolder(this.getStat(stat, false));
|
||||
if (!ignoreHeldItems) {
|
||||
globalScene.applyModifiers(StatBoosterModifier, this.isPlayer(), this, stat, statValue);
|
||||
applyHeldItems(ITEM_EFFECT.STAT_BOOST, { pokemon: this, stat: stat, statValue: statValue });
|
||||
}
|
||||
|
||||
// The Ruin abilities here are never ignored, but they reveal themselves on summon anyway
|
||||
@ -3995,7 +3994,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
surviveDamage.value = this.lapseTag(BattlerTagType.ENDURE_TOKEN);
|
||||
}
|
||||
if (!surviveDamage.value) {
|
||||
globalScene.applyModifiers(SurviveDamageModifier, this.isPlayer(), this, surviveDamage);
|
||||
applyHeldItems(ITEM_EFFECT.SURVIVE_CHANCE, { pokemon: this, surviveDamage: surviveDamage });
|
||||
}
|
||||
if (surviveDamage.value) {
|
||||
damage = this.hp - 1;
|
||||
|
@ -4,6 +4,7 @@ import { HeldItemId } from "#enums/held-item-id";
|
||||
import type { PokemonType } from "#enums/pokemon-type";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { Stat, type PermanentStat } from "#enums/stat";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
import { ITEM_EFFECT } from "./held-item";
|
||||
import {
|
||||
type ATTACK_TYPE_BOOST_PARAMS,
|
||||
@ -16,7 +17,10 @@ import {
|
||||
permanentStatToHeldItem,
|
||||
} from "./held-items/base-stat-booster";
|
||||
import { type BERRY_PARAMS, BerryHeldItem, berryTypeToHeldItem } from "./held-items/berry";
|
||||
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 EXP_BOOST_PARAMS, ExpBoosterHeldItem } from "./held-items/exp-booster";
|
||||
import { type FLINCH_CHANCE_PARAMS, FlinchChanceHeldItem } from "./held-items/flinch-chance";
|
||||
import { type HIT_HEAL_PARAMS, HitHealHeldItem } from "./held-items/hit-heal";
|
||||
import { InstantReviveHeldItem, type INSTANT_REVIVE_PARAMS } from "./held-items/instant-revive";
|
||||
import {
|
||||
@ -28,8 +32,9 @@ import {
|
||||
SpeciesStatBoostHeldItem,
|
||||
type STAT_BOOST_PARAMS,
|
||||
} from "./held-items/stat-booster";
|
||||
import type { TURN_END_HEAL_PARAMS } from "./held-items/turn-end-heal";
|
||||
import { TurnEndHealHeldItem } from "./held-items/turn-end-heal";
|
||||
import { type SURVIVE_CHANCE_PARAMS, SurviveChanceHeldItem } from "./held-items/survive-chance";
|
||||
import { type TURN_END_HEAL_PARAMS, TurnEndHealHeldItem } from "./held-items/turn-end-heal";
|
||||
import { type TURN_END_STATUS_PARAMS, TurnEndStatusHeldItem } from "./held-items/turn-end-status";
|
||||
|
||||
export const allHeldItems = {};
|
||||
|
||||
@ -55,6 +60,7 @@ export function initHeldItems() {
|
||||
allHeldItems[heldItemType] = new AttackTypeBoosterHeldItem(heldItemType, 99, pokemonType, 0.2);
|
||||
}
|
||||
|
||||
// Items that boost specific stats
|
||||
allHeldItems[HeldItemId.EVIOLITE] = new EvolutionStatBoostHeldItem(
|
||||
HeldItemId.EVIOLITE,
|
||||
1,
|
||||
@ -86,12 +92,27 @@ export function initHeldItems() {
|
||||
SpeciesId.CLAMPERL,
|
||||
]);
|
||||
|
||||
// Items that boost the crit rate
|
||||
allHeldItems[HeldItemId.SCOPE_LENS] = new CritBoostHeldItem(HeldItemId.SCOPE_LENS, 1, 1);
|
||||
allHeldItems[HeldItemId.LEEK] = new SpeciesCritBoostHeldItem(HeldItemId.LEEK, 1, 2, [
|
||||
SpeciesId.FARFETCHD,
|
||||
SpeciesId.GALAR_FARFETCHD,
|
||||
SpeciesId.SIRFETCHD,
|
||||
]);
|
||||
|
||||
allHeldItems[HeldItemId.LUCKY_EGG] = new ExpBoosterHeldItem(HeldItemId.LUCKY_EGG, 99, 40);
|
||||
allHeldItems[HeldItemId.GOLDEN_EGG] = new ExpBoosterHeldItem(HeldItemId.GOLDEN_EGG, 99, 100);
|
||||
|
||||
allHeldItems[HeldItemId.LEFTOVERS] = new TurnEndHealHeldItem(HeldItemId.LEFTOVERS, 4);
|
||||
allHeldItems[HeldItemId.SHELL_BELL] = new HitHealHeldItem(HeldItemId.SHELL_BELL, 4);
|
||||
|
||||
allHeldItems[HeldItemId.FOCUS_BAND] = new SurviveChanceHeldItem(HeldItemId.FOCUS_BAND, 5);
|
||||
allHeldItems[HeldItemId.QUICK_CLAW] = new BypassSpeedChanceHeldItem(HeldItemId.QUICK_CLAW, 3);
|
||||
allHeldItems[HeldItemId.KINGS_ROCK] = new FlinchChanceHeldItem(HeldItemId.KINGS_ROCK, 3, 10);
|
||||
|
||||
allHeldItems[HeldItemId.FLAME_ORB] = new TurnEndStatusHeldItem(HeldItemId.FLAME_ORB, 1, StatusEffect.BURN);
|
||||
allHeldItems[HeldItemId.TOXIC_ORB] = new TurnEndStatusHeldItem(HeldItemId.TOXIC_ORB, 1, StatusEffect.TOXIC);
|
||||
|
||||
// vitamins
|
||||
for (const [statKey, heldItemType] of Object.entries(permanentStatToHeldItem)) {
|
||||
const stat = Number(statKey) as PermanentStat;
|
||||
@ -109,6 +130,11 @@ type APPLY_HELD_ITEMS_PARAMS = {
|
||||
[ITEM_EFFECT.BASE_STAT_BOOSTER]: BASE_STAT_BOOSTER_PARAMS;
|
||||
[ITEM_EFFECT.INSTANT_REVIVE]: INSTANT_REVIVE_PARAMS;
|
||||
[ITEM_EFFECT.STAT_BOOST]: STAT_BOOST_PARAMS;
|
||||
[ITEM_EFFECT.CRIT_BOOST]: CRIT_BOOST_PARAMS;
|
||||
[ITEM_EFFECT.TURN_END_STATUS]: TURN_END_STATUS_PARAMS;
|
||||
[ITEM_EFFECT.SURVIVE_CHANCE]: SURVIVE_CHANCE_PARAMS;
|
||||
[ITEM_EFFECT.BYPASS_SPEED_CHANCE]: BYPASS_SPEED_CHANCE_PARAMS;
|
||||
[ITEM_EFFECT.FLINCH_CHANCE]: FLINCH_CHANCE_PARAMS;
|
||||
};
|
||||
|
||||
export function applyHeldItems<T extends ITEM_EFFECT>(effect: T, params: APPLY_HELD_ITEMS_PARAMS[T]) {
|
||||
|
@ -15,6 +15,11 @@ export const ITEM_EFFECT = {
|
||||
BASE_STAT_BOOSTER: 7,
|
||||
INSTANT_REVIVE: 8,
|
||||
STAT_BOOST: 9,
|
||||
CRIT_BOOST: 10,
|
||||
TURN_END_STATUS: 11,
|
||||
SURVIVE_CHANCE: 12,
|
||||
BYPASS_SPEED_CHANCE: 13,
|
||||
FLINCH_CHANCE: 14,
|
||||
} as const;
|
||||
|
||||
export type ITEM_EFFECT = (typeof ITEM_EFFECT)[keyof typeof ITEM_EFFECT];
|
||||
|
62
src/items/held-items/bypass-speed-chance.ts
Normal file
62
src/items/held-items/bypass-speed-chance.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import { HeldItem, ITEM_EFFECT } from "#app/items/held-item";
|
||||
import type { BooleanHolder } from "#app/utils/common";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import i18next from "i18next";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { Command } from "#app/ui/command-ui-handler";
|
||||
|
||||
export interface BYPASS_SPEED_CHANCE_PARAMS {
|
||||
/** The pokemon with the item */
|
||||
pokemon: Pokemon;
|
||||
doBypassSpeed: BooleanHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier used for held items, namely Toxic Orb and Flame Orb, that apply a
|
||||
* set {@linkcode StatusEffect} at the end of a turn.
|
||||
* @extends PokemonHeldItemModifier
|
||||
* @see {@linkcode apply}
|
||||
*/
|
||||
export class BypassSpeedChanceHeldItem extends HeldItem {
|
||||
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.BYPASS_SPEED_CHANCE];
|
||||
|
||||
/**
|
||||
* Checks if {@linkcode BypassSpeedChanceModifier} should be applied
|
||||
* @param pokemon the {@linkcode Pokemon} that holds the item
|
||||
* @param doBypassSpeed {@linkcode BooleanHolder} that is `true` if speed should be bypassed
|
||||
* @returns `true` if {@linkcode BypassSpeedChanceModifier} should be applied
|
||||
*/
|
||||
// override shouldApply(pokemon?: Pokemon, doBypassSpeed?: BooleanHolder): boolean {
|
||||
// return super.shouldApply(pokemon, doBypassSpeed) && !!doBypassSpeed;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Applies {@linkcode BypassSpeedChanceModifier}
|
||||
* @param pokemon the {@linkcode Pokemon} that holds the item
|
||||
* @param doBypassSpeed {@linkcode BooleanHolder} that is `true` if speed should be bypassed
|
||||
* @returns `true` if {@linkcode BypassSpeedChanceModifier} has been applied
|
||||
*/
|
||||
apply(params: BYPASS_SPEED_CHANCE_PARAMS): boolean {
|
||||
const pokemon = params.pokemon;
|
||||
const doBypassSpeed = params.doBypassSpeed;
|
||||
const stackCount = pokemon.heldItemManager.getStack(this.type);
|
||||
if (!doBypassSpeed.value && pokemon.randBattleSeedInt(10) < stackCount) {
|
||||
doBypassSpeed.value = true;
|
||||
const isCommandFight =
|
||||
globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()]?.command === Command.FIGHT;
|
||||
|
||||
if (isCommandFight) {
|
||||
globalScene.queueMessage(
|
||||
i18next.t("modifier:bypassSpeedChanceApply", {
|
||||
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||
itemName: this.name,
|
||||
}),
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
86
src/items/held-items/crit-booster.ts
Normal file
86
src/items/held-items/crit-booster.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import type { NumberHolder } from "#app/utils/common";
|
||||
import type { HeldItemId } from "#enums/held-item-id";
|
||||
import type { SpeciesId } from "#enums/species-id";
|
||||
import { HeldItem, ITEM_EFFECT } from "../held-item";
|
||||
|
||||
export interface CRIT_BOOST_PARAMS {
|
||||
/** The pokemon with the item */
|
||||
pokemon: Pokemon;
|
||||
critStage: NumberHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier used for held items that apply critical-hit stage boost(s).
|
||||
* using a multiplier.
|
||||
* @extends PokemonHeldItemModifier
|
||||
* @see {@linkcode apply}
|
||||
*/
|
||||
export class CritBoostHeldItem extends HeldItem {
|
||||
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.CRIT_BOOST];
|
||||
|
||||
/** The amount of stages by which the held item increases the current critical-hit stage value */
|
||||
protected stageIncrement: number;
|
||||
|
||||
constructor(type: HeldItemId, maxStackCount = 1, stageIncrement: number) {
|
||||
super(type, maxStackCount);
|
||||
|
||||
this.stageIncrement = stageIncrement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases the current critical-hit stage value by {@linkcode stageIncrement}.
|
||||
* @param _pokemon {@linkcode Pokemon} N/A
|
||||
* @param critStage {@linkcode NumberHolder} that holds the resulting critical-hit level
|
||||
* @returns always `true`
|
||||
*/
|
||||
apply(params: CRIT_BOOST_PARAMS): boolean {
|
||||
params.critStage.value += this.stageIncrement;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier used for held items that apply critical-hit stage boost(s)
|
||||
* if the holder is of a specific {@linkcode SpeciesId}.
|
||||
* @extends CritBoosterModifier
|
||||
* @see {@linkcode shouldApply}
|
||||
*/
|
||||
export class SpeciesCritBoostHeldItem extends CritBoostHeldItem {
|
||||
/** The species that the held item's critical-hit stage boost applies to */
|
||||
private species: SpeciesId[];
|
||||
|
||||
constructor(type: HeldItemId, maxStackCount = 1, stageIncrement: number, species: SpeciesId[]) {
|
||||
super(type, maxStackCount, stageIncrement);
|
||||
|
||||
this.species = species;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the holder's {@linkcode SpeciesId} (or its fused species) is listed
|
||||
* in {@linkcode species}.
|
||||
* @param pokemon {@linkcode Pokemon} that holds the held item
|
||||
* @param critStage {@linkcode NumberHolder} that holds the resulting critical-hit level
|
||||
* @returns `true` if the critical-hit level can be incremented, false otherwise
|
||||
*/
|
||||
// override shouldApply(pokemon: Pokemon, critStage: NumberHolder): boolean {
|
||||
// return (
|
||||
// super.shouldApply(pokemon, critStage) &&
|
||||
// (this.species.includes(pokemon.getSpeciesForm(true).speciesId) ||
|
||||
// (pokemon.isFusion() && this.species.includes(pokemon.getFusionSpeciesForm(true).speciesId)))
|
||||
// );
|
||||
// }
|
||||
|
||||
apply(params: CRIT_BOOST_PARAMS): boolean {
|
||||
const pokemon = params.pokemon;
|
||||
const fitsSpecies =
|
||||
this.species.includes(pokemon.getSpeciesForm(true).speciesId) ||
|
||||
(pokemon.isFusion() && this.species.includes(pokemon.getFusionSpeciesForm(true).speciesId));
|
||||
|
||||
if (fitsSpecies) {
|
||||
return super.apply(params);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import type { NumberHolder } from "#app/utils/common";
|
||||
import { HeldItemId } from "#enums/held-item-id";
|
||||
import i18next from "i18next";
|
||||
import type { HeldItemId } from "#enums/held-item-id";
|
||||
import { HeldItem, ITEM_EFFECT } from "../held-item";
|
||||
|
||||
export interface EXP_BOOST_PARAMS {
|
||||
@ -20,22 +19,6 @@ export class ExpBoosterHeldItem extends HeldItem {
|
||||
this.boostMultiplier = boostPercent * 0.01;
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
return this.type === HeldItemId.LUCKY_EGG
|
||||
? i18next.t("modifierType:ModifierType.LUCKY_EGG.name")
|
||||
: i18next.t("modifierType:ModifierType.GOLDEN_EGG.name");
|
||||
}
|
||||
|
||||
get description(): string {
|
||||
return this.type === HeldItemId.LUCKY_EGG
|
||||
? i18next.t("modifierType:ModifierType.LUCKY_EGG.description")
|
||||
: i18next.t("modifierType:ModifierType.GOLDEN_EGG.description");
|
||||
}
|
||||
|
||||
get icon(): string {
|
||||
return this.type === HeldItemId.LUCKY_EGG ? "lucky_egg" : "golden_egg";
|
||||
}
|
||||
|
||||
// TODO: What do we do with this? Need to look up all the shouldApply
|
||||
/**
|
||||
* Checks if {@linkcode PokemonExpBoosterModifier} should be applied
|
||||
|
57
src/items/held-items/flinch-chance.ts
Normal file
57
src/items/held-items/flinch-chance.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import { HeldItem, ITEM_EFFECT } from "#app/items/held-item";
|
||||
import type { BooleanHolder } from "#app/utils/common";
|
||||
import type { HeldItemId } from "#enums/held-item-id";
|
||||
|
||||
export interface FLINCH_CHANCE_PARAMS {
|
||||
/** The pokemon with the item */
|
||||
pokemon: Pokemon;
|
||||
flinched: BooleanHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier used for held items, namely Toxic Orb and Flame Orb, that apply a
|
||||
* set {@linkcode StatusEffect} at the end of a turn.
|
||||
* @extends PokemonHeldItemModifier
|
||||
* @see {@linkcode apply}
|
||||
*/
|
||||
export class FlinchChanceHeldItem extends HeldItem {
|
||||
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.FLINCH_CHANCE];
|
||||
private chance: number;
|
||||
|
||||
constructor(type: HeldItemId, maxStackCount = 1, chance: number) {
|
||||
super(type, maxStackCount);
|
||||
|
||||
this.chance = chance; // 10
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if {@linkcode FlinchChanceModifier} should be applied
|
||||
* @param pokemon the {@linkcode Pokemon} that holds the item
|
||||
* @param flinched {@linkcode BooleanHolder} that is `true` if the pokemon flinched
|
||||
* @returns `true` if {@linkcode FlinchChanceModifier} should be applied
|
||||
*/
|
||||
// override shouldApply(pokemon?: Pokemon, flinched?: BooleanHolder): boolean {
|
||||
// return super.shouldApply(pokemon, flinched) && !!flinched;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Applies {@linkcode FlinchChanceModifier} to randomly flinch targets hit.
|
||||
* @param pokemon - The {@linkcode Pokemon} that holds the item
|
||||
* @param flinched - A {@linkcode BooleanHolder} holding whether the pokemon has flinched
|
||||
* @returns `true` if {@linkcode FlinchChanceModifier} was applied successfully
|
||||
*/
|
||||
apply(params: FLINCH_CHANCE_PARAMS): boolean {
|
||||
const pokemon = params.pokemon;
|
||||
const flinched = params.flinched;
|
||||
const stackCount = pokemon.heldItemManager.getStack(this.type);
|
||||
// The check for pokemon.summonData is to ensure that a crash doesn't occur when a Pokemon with King's Rock procs a flinch
|
||||
// TODO: Since summonData is always defined now, we can probably remove this
|
||||
if (pokemon.summonData && !flinched.value && pokemon.randBattleSeedInt(100) < stackCount * this.chance) {
|
||||
flinched.value = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
57
src/items/held-items/survive-chance.ts
Normal file
57
src/items/held-items/survive-chance.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import { HeldItem, ITEM_EFFECT } from "#app/items/held-item";
|
||||
import type { BooleanHolder } from "#app/utils/common";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import i18next from "i18next";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
|
||||
export interface SURVIVE_CHANCE_PARAMS {
|
||||
/** The pokemon with the item */
|
||||
pokemon: Pokemon;
|
||||
surviveDamage: BooleanHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier used for held items, namely Toxic Orb and Flame Orb, that apply a
|
||||
* set {@linkcode StatusEffect} at the end of a turn.
|
||||
* @extends PokemonHeldItemModifier
|
||||
* @see {@linkcode apply}
|
||||
*/
|
||||
export class SurviveChanceHeldItem extends HeldItem {
|
||||
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.SURVIVE_CHANCE];
|
||||
|
||||
/**
|
||||
* Checks if the {@linkcode SurviveDamageModifier} should be applied
|
||||
* @param pokemon the {@linkcode Pokemon} that holds the item
|
||||
* @param surviveDamage {@linkcode BooleanHolder} that holds the survive damage
|
||||
* @returns `true` if the {@linkcode SurviveDamageModifier} should be applied
|
||||
*/
|
||||
// override shouldApply(pokemon?: Pokemon, surviveDamage?: BooleanHolder): boolean {
|
||||
// return super.shouldApply(pokemon, surviveDamage) && !!surviveDamage;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Applies {@linkcode SurviveDamageModifier}
|
||||
* @param pokemon the {@linkcode Pokemon} that holds the item
|
||||
* @param surviveDamage {@linkcode BooleanHolder} that holds the survive damage
|
||||
* @returns `true` if the survive damage has been applied
|
||||
*/
|
||||
apply(params: SURVIVE_CHANCE_PARAMS): boolean {
|
||||
const pokemon = params.pokemon;
|
||||
const surviveDamage = params.surviveDamage;
|
||||
const stackCount = pokemon.heldItemManager.getStack(this.type);
|
||||
if (!surviveDamage.value && pokemon.randBattleSeedInt(10) < stackCount) {
|
||||
surviveDamage.value = true;
|
||||
|
||||
globalScene.queueMessage(
|
||||
i18next.t("modifier:surviveDamageApply", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
typeName: this.name,
|
||||
}),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
40
src/items/held-items/turn-end-status.ts
Normal file
40
src/items/held-items/turn-end-status.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import { HeldItem, ITEM_EFFECT } from "#app/items/held-item";
|
||||
import type { StatusEffect } from "#enums/status-effect";
|
||||
import type { HeldItemId } from "#enums/held-item-id";
|
||||
|
||||
export interface TURN_END_STATUS_PARAMS {
|
||||
/** The pokemon with the item */
|
||||
pokemon: Pokemon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier used for held items, namely Toxic Orb and Flame Orb, that apply a
|
||||
* set {@linkcode StatusEffect} at the end of a turn.
|
||||
* @extends PokemonHeldItemModifier
|
||||
* @see {@linkcode apply}
|
||||
*/
|
||||
export class TurnEndStatusHeldItem extends HeldItem {
|
||||
public effects: ITEM_EFFECT[] = [ITEM_EFFECT.TURN_END_STATUS];
|
||||
/** The status effect to be applied by the held item */
|
||||
private effect: StatusEffect;
|
||||
|
||||
constructor(type: HeldItemId, maxStackCount = 1, effect: StatusEffect) {
|
||||
super(type, maxStackCount);
|
||||
|
||||
this.effect = effect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to inflicts the holder with the associated {@linkcode StatusEffect}.
|
||||
* @param pokemon {@linkcode Pokemon} that holds the held item
|
||||
* @returns `true` if the status effect was applied successfully
|
||||
*/
|
||||
apply(params: TURN_END_STATUS_PARAMS): boolean {
|
||||
return params.pokemon.trySetStatus(this.effect, true, undefined, undefined, this.name);
|
||||
}
|
||||
|
||||
getStatusEffect(): StatusEffect {
|
||||
return this.effect;
|
||||
}
|
||||
}
|
@ -13,7 +13,6 @@ import { LearnMovePhase, LearnMoveType } from "#app/phases/learn-move-phase";
|
||||
import { LevelUpPhase } from "#app/phases/level-up-phase";
|
||||
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
|
||||
import type { VoucherType } from "#app/system/voucher";
|
||||
import { Command } from "#app/ui/command-ui-handler";
|
||||
import { addTextObject, TextStyle } from "#app/ui/text";
|
||||
import { BooleanHolder, hslToHex, isNullOrUndefined, NumberHolder, toDmgValue } from "#app/utils/common";
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
@ -42,7 +41,6 @@ import {
|
||||
getModifierType,
|
||||
ModifierTypeGenerator,
|
||||
modifierTypes,
|
||||
PokemonHeldItemModifierType,
|
||||
} from "./modifier-type";
|
||||
import { Color, ShadowColor } from "#enums/color";
|
||||
import { FRIENDSHIP_GAIN_FROM_RARE_CANDY } from "#app/data/balance/starters";
|
||||
@ -1029,438 +1027,6 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier used for held items that apply critical-hit stage boost(s).
|
||||
* @extends PokemonHeldItemModifier
|
||||
* @see {@linkcode apply}
|
||||
*/
|
||||
export class CritBoosterModifier extends PokemonHeldItemModifier {
|
||||
/** The amount of stages by which the held item increases the current critical-hit stage value */
|
||||
protected stageIncrement: number;
|
||||
|
||||
constructor(type: ModifierType, pokemonId: number, stageIncrement: number, stackCount?: number) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
||||
this.stageIncrement = stageIncrement;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new CritBoosterModifier(this.type, this.pokemonId, this.stageIncrement, this.stackCount);
|
||||
}
|
||||
|
||||
getArgs(): any[] {
|
||||
return super.getArgs().concat(this.stageIncrement);
|
||||
}
|
||||
|
||||
matchType(modifier: Modifier): boolean {
|
||||
if (modifier instanceof CritBoosterModifier) {
|
||||
return (modifier as CritBoosterModifier).stageIncrement === this.stageIncrement;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases the current critical-hit stage value by {@linkcode stageIncrement}.
|
||||
* @param _pokemon {@linkcode Pokemon} N/A
|
||||
* @param critStage {@linkcode NumberHolder} that holds the resulting critical-hit level
|
||||
* @returns always `true`
|
||||
*/
|
||||
override apply(_pokemon: Pokemon, critStage: NumberHolder): boolean {
|
||||
critStage.value += this.stageIncrement;
|
||||
return true;
|
||||
}
|
||||
|
||||
getMaxHeldItemCount(_pokemon: Pokemon): number {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier used for held items that apply critical-hit stage boost(s)
|
||||
* if the holder is of a specific {@linkcode SpeciesId}.
|
||||
* @extends CritBoosterModifier
|
||||
* @see {@linkcode shouldApply}
|
||||
*/
|
||||
export class SpeciesCritBoosterModifier extends CritBoosterModifier {
|
||||
/** The species that the held item's critical-hit stage boost applies to */
|
||||
private species: SpeciesId[];
|
||||
|
||||
constructor(
|
||||
type: ModifierType,
|
||||
pokemonId: number,
|
||||
stageIncrement: number,
|
||||
species: SpeciesId[],
|
||||
stackCount?: number,
|
||||
) {
|
||||
super(type, pokemonId, stageIncrement, stackCount);
|
||||
|
||||
this.species = species;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new SpeciesCritBoosterModifier(
|
||||
this.type,
|
||||
this.pokemonId,
|
||||
this.stageIncrement,
|
||||
this.species,
|
||||
this.stackCount,
|
||||
);
|
||||
}
|
||||
|
||||
getArgs(): any[] {
|
||||
return [...super.getArgs(), this.species];
|
||||
}
|
||||
|
||||
matchType(modifier: Modifier): boolean {
|
||||
return modifier instanceof SpeciesCritBoosterModifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the holder's {@linkcode SpeciesId} (or its fused species) is listed
|
||||
* in {@linkcode species}.
|
||||
* @param pokemon {@linkcode Pokemon} that holds the held item
|
||||
* @param critStage {@linkcode NumberHolder} that holds the resulting critical-hit level
|
||||
* @returns `true` if the critical-hit level can be incremented, false otherwise
|
||||
*/
|
||||
override shouldApply(pokemon: Pokemon, critStage: NumberHolder): boolean {
|
||||
return (
|
||||
super.shouldApply(pokemon, critStage) &&
|
||||
(this.species.includes(pokemon.getSpeciesForm(true).speciesId) ||
|
||||
(pokemon.isFusion() && this.species.includes(pokemon.getFusionSpeciesForm(true).speciesId)))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies Specific Type item boosts (e.g., Magnet)
|
||||
*/
|
||||
export class AttackTypeBoosterModifier extends PokemonHeldItemModifier {
|
||||
public moveType: PokemonType;
|
||||
private boostMultiplier: number;
|
||||
|
||||
constructor(type: ModifierType, pokemonId: number, moveType: PokemonType, boostPercent: number, stackCount?: number) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
||||
this.moveType = moveType;
|
||||
this.boostMultiplier = boostPercent * 0.01;
|
||||
}
|
||||
|
||||
matchType(modifier: Modifier): boolean {
|
||||
if (modifier instanceof AttackTypeBoosterModifier) {
|
||||
const attackTypeBoosterModifier = modifier as AttackTypeBoosterModifier;
|
||||
return (
|
||||
attackTypeBoosterModifier.moveType === this.moveType &&
|
||||
attackTypeBoosterModifier.boostMultiplier === this.boostMultiplier
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new AttackTypeBoosterModifier(
|
||||
this.type,
|
||||
this.pokemonId,
|
||||
this.moveType,
|
||||
this.boostMultiplier * 100,
|
||||
this.stackCount,
|
||||
);
|
||||
}
|
||||
|
||||
getArgs(): any[] {
|
||||
return super.getArgs().concat([this.moveType, this.boostMultiplier * 100]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if {@linkcode AttackTypeBoosterModifier} should be applied
|
||||
* @param pokemon the {@linkcode Pokemon} that holds the held item
|
||||
* @param moveType the {@linkcode PokemonType} of the move being used
|
||||
* @param movePower the {@linkcode NumberHolder} that holds the power of the move
|
||||
* @returns `true` if boosts should be applied to the move.
|
||||
*/
|
||||
override shouldApply(pokemon?: Pokemon, moveType?: PokemonType, movePower?: NumberHolder): boolean {
|
||||
return (
|
||||
super.shouldApply(pokemon, moveType, movePower) &&
|
||||
typeof moveType === "number" &&
|
||||
movePower instanceof NumberHolder &&
|
||||
this.moveType === moveType
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies {@linkcode AttackTypeBoosterModifier}
|
||||
* @param pokemon {@linkcode Pokemon} that holds the held item
|
||||
* @param moveType {@linkcode PokemonType} of the move being used
|
||||
* @param movePower {@linkcode NumberHolder} that holds the power of the move
|
||||
* @returns `true` if boosts have been applied to the move.
|
||||
*/
|
||||
override apply(_pokemon: Pokemon, moveType: PokemonType, movePower: NumberHolder): boolean {
|
||||
if (moveType === this.moveType && movePower.value >= 1) {
|
||||
(movePower as NumberHolder).value = Math.floor(
|
||||
(movePower as NumberHolder).value * (1 + this.getStackCount() * this.boostMultiplier),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
getScoreMultiplier(): number {
|
||||
return 1.2;
|
||||
}
|
||||
|
||||
getMaxHeldItemCount(_pokemon: Pokemon): number {
|
||||
return 99;
|
||||
}
|
||||
}
|
||||
|
||||
export class SurviveDamageModifier extends PokemonHeldItemModifier {
|
||||
matchType(modifier: Modifier): boolean {
|
||||
return modifier instanceof SurviveDamageModifier;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new SurviveDamageModifier(this.type, this.pokemonId, this.stackCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the {@linkcode SurviveDamageModifier} should be applied
|
||||
* @param pokemon the {@linkcode Pokemon} that holds the item
|
||||
* @param surviveDamage {@linkcode BooleanHolder} that holds the survive damage
|
||||
* @returns `true` if the {@linkcode SurviveDamageModifier} should be applied
|
||||
*/
|
||||
override shouldApply(pokemon?: Pokemon, surviveDamage?: BooleanHolder): boolean {
|
||||
return super.shouldApply(pokemon, surviveDamage) && !!surviveDamage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies {@linkcode SurviveDamageModifier}
|
||||
* @param pokemon the {@linkcode Pokemon} that holds the item
|
||||
* @param surviveDamage {@linkcode BooleanHolder} that holds the survive damage
|
||||
* @returns `true` if the survive damage has been applied
|
||||
*/
|
||||
override apply(pokemon: Pokemon, surviveDamage: BooleanHolder): boolean {
|
||||
if (!surviveDamage.value && pokemon.randBattleSeedInt(10) < this.getStackCount()) {
|
||||
surviveDamage.value = true;
|
||||
|
||||
globalScene.queueMessage(
|
||||
i18next.t("modifier:surviveDamageApply", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
typeName: this.type.name,
|
||||
}),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
getMaxHeldItemCount(_pokemon: Pokemon): number {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
export class BypassSpeedChanceModifier extends PokemonHeldItemModifier {
|
||||
matchType(modifier: Modifier) {
|
||||
return modifier instanceof BypassSpeedChanceModifier;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new BypassSpeedChanceModifier(this.type, this.pokemonId, this.stackCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if {@linkcode BypassSpeedChanceModifier} should be applied
|
||||
* @param pokemon the {@linkcode Pokemon} that holds the item
|
||||
* @param doBypassSpeed {@linkcode BooleanHolder} that is `true` if speed should be bypassed
|
||||
* @returns `true` if {@linkcode BypassSpeedChanceModifier} should be applied
|
||||
*/
|
||||
override shouldApply(pokemon?: Pokemon, doBypassSpeed?: BooleanHolder): boolean {
|
||||
return super.shouldApply(pokemon, doBypassSpeed) && !!doBypassSpeed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies {@linkcode BypassSpeedChanceModifier}
|
||||
* @param pokemon the {@linkcode Pokemon} that holds the item
|
||||
* @param doBypassSpeed {@linkcode BooleanHolder} that is `true` if speed should be bypassed
|
||||
* @returns `true` if {@linkcode BypassSpeedChanceModifier} has been applied
|
||||
*/
|
||||
override apply(pokemon: Pokemon, doBypassSpeed: BooleanHolder): boolean {
|
||||
if (!doBypassSpeed.value && pokemon.randBattleSeedInt(10) < this.getStackCount()) {
|
||||
doBypassSpeed.value = true;
|
||||
const isCommandFight =
|
||||
globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()]?.command === Command.FIGHT;
|
||||
const hasQuickClaw = this.type instanceof PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW";
|
||||
|
||||
if (isCommandFight && hasQuickClaw) {
|
||||
globalScene.queueMessage(
|
||||
i18next.t("modifier:bypassSpeedChanceApply", {
|
||||
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||
itemName: i18next.t("modifierType:ModifierType.QUICK_CLAW.name"),
|
||||
}),
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
getMaxHeldItemCount(_pokemon: Pokemon): number {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for Pokemon held items like King's Rock
|
||||
* Because King's Rock can be stacked in PokeRogue, unlike mainline, it does not receive a boost from AbilityId.SERENE_GRACE
|
||||
*/
|
||||
export class FlinchChanceModifier extends PokemonHeldItemModifier {
|
||||
private chance: number;
|
||||
constructor(type: ModifierType, pokemonId: number, stackCount?: number) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
||||
this.chance = 10;
|
||||
}
|
||||
|
||||
matchType(modifier: Modifier) {
|
||||
return modifier instanceof FlinchChanceModifier;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new FlinchChanceModifier(this.type, this.pokemonId, this.stackCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if {@linkcode FlinchChanceModifier} should be applied
|
||||
* @param pokemon the {@linkcode Pokemon} that holds the item
|
||||
* @param flinched {@linkcode BooleanHolder} that is `true` if the pokemon flinched
|
||||
* @returns `true` if {@linkcode FlinchChanceModifier} should be applied
|
||||
*/
|
||||
override shouldApply(pokemon?: Pokemon, flinched?: BooleanHolder): boolean {
|
||||
return super.shouldApply(pokemon, flinched) && !!flinched;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies {@linkcode FlinchChanceModifier} to randomly flinch targets hit.
|
||||
* @param pokemon - The {@linkcode Pokemon} that holds the item
|
||||
* @param flinched - A {@linkcode BooleanHolder} holding whether the pokemon has flinched
|
||||
* @returns `true` if {@linkcode FlinchChanceModifier} was applied successfully
|
||||
*/
|
||||
override apply(pokemon: Pokemon, flinched: BooleanHolder): boolean {
|
||||
// The check for pokemon.summonData is to ensure that a crash doesn't occur when a Pokemon with King's Rock procs a flinch
|
||||
// TODO: Since summonData is always defined now, we can probably remove this
|
||||
if (pokemon.summonData && !flinched.value && pokemon.randBattleSeedInt(100) < this.getStackCount() * this.chance) {
|
||||
flinched.value = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
getMaxHeldItemCount(_pokemon: Pokemon): number {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
export class TurnHealModifier extends PokemonHeldItemModifier {
|
||||
matchType(modifier: Modifier) {
|
||||
return modifier instanceof TurnHealModifier;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new TurnHealModifier(this.type, this.pokemonId, this.stackCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies {@linkcode TurnHealModifier}
|
||||
* @param pokemon The {@linkcode Pokemon} that holds the item
|
||||
* @returns `true` if the {@linkcode Pokemon} was healed
|
||||
*/
|
||||
override apply(pokemon: Pokemon): boolean {
|
||||
if (!pokemon.isFullHp()) {
|
||||
globalScene.unshiftPhase(
|
||||
new PokemonHealPhase(
|
||||
pokemon.getBattlerIndex(),
|
||||
toDmgValue(pokemon.getMaxHp() / 16) * this.stackCount,
|
||||
i18next.t("modifier:turnHealApply", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
typeName: this.type.name,
|
||||
}),
|
||||
true,
|
||||
),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
getMaxHeldItemCount(_pokemon: Pokemon): number {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifier used for held items, namely Toxic Orb and Flame Orb, that apply a
|
||||
* set {@linkcode StatusEffect} at the end of a turn.
|
||||
* @extends PokemonHeldItemModifier
|
||||
* @see {@linkcode apply}
|
||||
*/
|
||||
export class TurnStatusEffectModifier extends PokemonHeldItemModifier {
|
||||
/** The status effect to be applied by the held item */
|
||||
private effect: StatusEffect;
|
||||
|
||||
constructor(type: ModifierType, pokemonId: number, stackCount?: number) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
||||
switch (type.id) {
|
||||
case "TOXIC_ORB":
|
||||
this.effect = StatusEffect.TOXIC;
|
||||
break;
|
||||
case "FLAME_ORB":
|
||||
this.effect = StatusEffect.BURN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if {@linkcode modifier} is an instance of this class,
|
||||
* intentionally ignoring potentially different {@linkcode effect}s
|
||||
* to prevent held item stockpiling since the item obtained first
|
||||
* would be the only item able to {@linkcode apply} successfully.
|
||||
* @override
|
||||
* @param modifier {@linkcode Modifier} being type tested
|
||||
* @return `true` if {@linkcode modifier} is an instance of
|
||||
* TurnStatusEffectModifier, false otherwise
|
||||
*/
|
||||
matchType(modifier: Modifier): boolean {
|
||||
return modifier instanceof TurnStatusEffectModifier;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new TurnStatusEffectModifier(this.type, this.pokemonId, this.stackCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to inflicts the holder with the associated {@linkcode StatusEffect}.
|
||||
* @param pokemon {@linkcode Pokemon} that holds the held item
|
||||
* @returns `true` if the status effect was applied successfully
|
||||
*/
|
||||
override apply(pokemon: Pokemon): boolean {
|
||||
return pokemon.trySetStatus(this.effect, true, undefined, undefined, this.type.name);
|
||||
}
|
||||
|
||||
getMaxHeldItemCount(_pokemon: Pokemon): number {
|
||||
return 1;
|
||||
}
|
||||
|
||||
getStatusEffect(): StatusEffect {
|
||||
return this.effect;
|
||||
}
|
||||
}
|
||||
|
||||
export class HitHealModifier extends PokemonHeldItemModifier {
|
||||
matchType(modifier: Modifier) {
|
||||
return modifier instanceof HitHealModifier;
|
||||
|
@ -57,8 +57,6 @@ import {
|
||||
DamageMoneyRewardModifier,
|
||||
EnemyAttackStatusEffectChanceModifier,
|
||||
EnemyEndureChanceModifier,
|
||||
FlinchChanceModifier,
|
||||
HitHealModifier,
|
||||
PokemonMultiHitModifier,
|
||||
} from "#app/modifier/modifier";
|
||||
import { PokemonPhase } from "#app/phases/pokemon-phase";
|
||||
@ -456,7 +454,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
|
||||
if (dealsDamage && !target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && !this.move.hitsSubstitute(user, target)) {
|
||||
const flinched = new BooleanHolder(false);
|
||||
globalScene.applyModifiers(FlinchChanceModifier, user.isPlayer(), user, flinched);
|
||||
applyHeldItems(ITEM_EFFECT.FLINCH_CHANCE, { pokemon: user, flinched: flinched });
|
||||
if (flinched.value) {
|
||||
target.addTag(BattlerTagType.FLINCHED, undefined, this.move.id, user.id);
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import {
|
||||
EnemyTurnHealModifier,
|
||||
EnemyStatusEffectHealChanceModifier,
|
||||
TurnStatusEffectModifier,
|
||||
TurnHeldItemTransferModifier,
|
||||
} from "#app/modifier/modifier";
|
||||
import i18next from "i18next";
|
||||
@ -55,7 +54,7 @@ export class TurnEndPhase extends FieldPhase {
|
||||
applyPostTurnAbAttrs(PostTurnAbAttr, pokemon);
|
||||
}
|
||||
|
||||
globalScene.applyModifiers(TurnStatusEffectModifier, pokemon.isPlayer(), pokemon);
|
||||
applyHeldItems(ITEM_EFFECT.TURN_END_STATUS, { pokemon: pokemon });
|
||||
globalScene.applyModifiers(TurnHeldItemTransferModifier, pokemon.isPlayer(), pokemon);
|
||||
|
||||
pokemon.tempSummonData.turnCount++;
|
||||
|
@ -5,7 +5,6 @@ import { AbilityId } from "#enums/ability-id";
|
||||
import { Stat } from "#app/enums/stat";
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import { PokemonMove } from "#app/field/pokemon";
|
||||
import { BypassSpeedChanceModifier } from "#app/modifier/modifier";
|
||||
import { Command } from "#app/ui/command-ui-handler";
|
||||
import { randSeedShuffle, BooleanHolder } from "#app/utils/common";
|
||||
import { AttemptCapturePhase } from "./attempt-capture-phase";
|
||||
@ -23,6 +22,8 @@ import { TrickRoomTag } from "#app/data/arena-tag";
|
||||
import { SwitchType } from "#enums/switch-type";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { TeraPhase } from "./tera-phase";
|
||||
import { ITEM_EFFECT } from "#app/items/held-item";
|
||||
import { applyHeldItems } from "#app/items/all-held-items";
|
||||
|
||||
export class TurnStartPhase extends FieldPhase {
|
||||
public readonly phaseName = "TurnStartPhase";
|
||||
@ -80,7 +81,7 @@ export class TurnStartPhase extends FieldPhase {
|
||||
applyAbAttrs(BypassSpeedChanceAbAttr, p, null, false, bypassSpeed);
|
||||
applyAbAttrs(PreventBypassSpeedChanceAbAttr, p, null, false, bypassSpeed, canCheckHeldItems);
|
||||
if (canCheckHeldItems.value) {
|
||||
globalScene.applyModifiers(BypassSpeedChanceModifier, p.isPlayer(), p, bypassSpeed);
|
||||
applyHeldItems(ITEM_EFFECT.BYPASS_SPEED_CHANCE, { pokemon: p, doBypassSpeed: bypassSpeed });
|
||||
}
|
||||
battlerBypassSpeed[p.getBattlerIndex()] = bypassSpeed;
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user