mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-08 00:19:29 +02:00
[Misc] Fix missing types in battler tags and remove DragonCheerTag (#6188)
* Fix missing types in battler tags * Fix issues with dragon cheer
This commit is contained in:
parent
1c59b67d7e
commit
e50ebaa815
@ -88,6 +88,15 @@ export type AbilityBattlerTagType =
|
|||||||
| BattlerTagType.SLOW_START
|
| BattlerTagType.SLOW_START
|
||||||
| BattlerTagType.TRUANT;
|
| BattlerTagType.TRUANT;
|
||||||
|
|
||||||
|
/** Subset of {@linkcode BattlerTagType}s that provide type boosts */
|
||||||
|
export type TypeBoostTagType = BattlerTagType.FIRE_BOOST | BattlerTagType.CHARGED;
|
||||||
|
|
||||||
|
/** Subset of {@linkcode BattlerTagType}s that boost the user's critical stage */
|
||||||
|
export type CritStageBoostTagType = BattlerTagType.CRIT_BOOST | BattlerTagType.DRAGON_CHEER;
|
||||||
|
|
||||||
|
/** Subset of {@linkcode BattlerTagType}s that remove one of the users' types */
|
||||||
|
export type RemovedTypeTagType = BattlerTagType.DOUBLE_SHOCKED | BattlerTagType.BURNED_UP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subset of {@linkcode BattlerTagType}s related to abilities that boost the highest stat.
|
* Subset of {@linkcode BattlerTagType}s related to abilities that boost the highest stat.
|
||||||
*/
|
*/
|
||||||
|
@ -34,15 +34,19 @@ import type { StatStageChangeCallback } from "#phases/stat-stage-change-phase";
|
|||||||
import i18next from "#plugins/i18n";
|
import i18next from "#plugins/i18n";
|
||||||
import type {
|
import type {
|
||||||
AbilityBattlerTagType,
|
AbilityBattlerTagType,
|
||||||
|
BattlerTagTypeData,
|
||||||
ContactSetStatusProtectedTagType,
|
ContactSetStatusProtectedTagType,
|
||||||
ContactStatStageChangeProtectedTagType,
|
ContactStatStageChangeProtectedTagType,
|
||||||
|
CritStageBoostTagType,
|
||||||
DamageProtectedTagType,
|
DamageProtectedTagType,
|
||||||
EndureTagType,
|
EndureTagType,
|
||||||
HighestStatBoostTagType,
|
HighestStatBoostTagType,
|
||||||
MoveRestrictionBattlerTagType,
|
MoveRestrictionBattlerTagType,
|
||||||
ProtectionBattlerTagType,
|
ProtectionBattlerTagType,
|
||||||
|
RemovedTypeTagType,
|
||||||
SemiInvulnerableTagType,
|
SemiInvulnerableTagType,
|
||||||
TrappingBattlerTagType,
|
TrappingBattlerTagType,
|
||||||
|
TypeBoostTagType,
|
||||||
} from "#types/battler-tags";
|
} from "#types/battler-tags";
|
||||||
import type { Mutable } from "#types/type-helpers";
|
import type { Mutable } from "#types/type-helpers";
|
||||||
import { BooleanHolder, coerceArray, getFrameMs, isNullOrUndefined, NumberHolder, toDmgValue } from "#utils/common";
|
import { BooleanHolder, coerceArray, getFrameMs, isNullOrUndefined, NumberHolder, toDmgValue } from "#utils/common";
|
||||||
@ -203,6 +207,19 @@ export class SerializableBattlerTag extends BattlerTag {
|
|||||||
private declare __SerializableBattlerTag: never;
|
private declare __SerializableBattlerTag: never;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for a generic serializable battler tag, i.e. one that does not have a
|
||||||
|
* dedicated subclass.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* Used to ensure type safety when serializing battler tags,
|
||||||
|
* allowing typescript to properly infer the type of the tag.
|
||||||
|
* @see BattlerTagTypeMap
|
||||||
|
*/
|
||||||
|
interface GenericSerializableBattlerTag<T extends BattlerTagType> extends SerializableBattlerTag {
|
||||||
|
tagType: T;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for tags that restrict the usage of moves. This effect is generally referred to as "disabling" a move
|
* Base class for tags that restrict the usage of moves. This effect is generally referred to as "disabling" a move
|
||||||
* in-game (not to be confused with {@linkcode MoveId.DISABLE}).
|
* in-game (not to be confused with {@linkcode MoveId.DISABLE}).
|
||||||
@ -560,6 +577,7 @@ export class BeakBlastChargingTag extends BattlerTag {
|
|||||||
* @see {@link https://bulbapedia.bulbagarden.net/wiki/Shell_Trap_(move) | Shell Trap}
|
* @see {@link https://bulbapedia.bulbagarden.net/wiki/Shell_Trap_(move) | Shell Trap}
|
||||||
*/
|
*/
|
||||||
export class ShellTrapTag extends BattlerTag {
|
export class ShellTrapTag extends BattlerTag {
|
||||||
|
public override readonly tagType = BattlerTagType.SHELL_TRAP;
|
||||||
public activated = false;
|
public activated = false;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -1144,6 +1162,7 @@ export class PowderTag extends BattlerTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class NightmareTag extends SerializableBattlerTag {
|
export class NightmareTag extends SerializableBattlerTag {
|
||||||
|
public override readonly tagType = BattlerTagType.NIGHTMARE;
|
||||||
constructor() {
|
constructor() {
|
||||||
super(BattlerTagType.NIGHTMARE, BattlerTagLapseType.TURN_END, 1, MoveId.NIGHTMARE);
|
super(BattlerTagType.NIGHTMARE, BattlerTagLapseType.TURN_END, 1, MoveId.NIGHTMARE);
|
||||||
}
|
}
|
||||||
@ -1197,6 +1216,7 @@ export class NightmareTag extends SerializableBattlerTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class FrenzyTag extends SerializableBattlerTag {
|
export class FrenzyTag extends SerializableBattlerTag {
|
||||||
|
public override readonly tagType = BattlerTagType.FRENZY;
|
||||||
constructor(turnCount: number, sourceMove: MoveId, sourceId: number) {
|
constructor(turnCount: number, sourceMove: MoveId, sourceId: number) {
|
||||||
super(BattlerTagType.FRENZY, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
|
super(BattlerTagType.FRENZY, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
|
||||||
}
|
}
|
||||||
@ -2199,7 +2219,7 @@ export class SemiInvulnerableTag extends SerializableBattlerTag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TypeImmuneTag extends SerializableBattlerTag {
|
export abstract class TypeImmuneTag extends SerializableBattlerTag {
|
||||||
#immuneType: PokemonType;
|
#immuneType: PokemonType;
|
||||||
public get immuneType(): PokemonType {
|
public get immuneType(): PokemonType {
|
||||||
return this.#immuneType;
|
return this.#immuneType;
|
||||||
@ -2218,6 +2238,7 @@ export class TypeImmuneTag extends SerializableBattlerTag {
|
|||||||
* @see {@link https://bulbapedia.bulbagarden.net/wiki/Telekinesis_(move) | MoveId.TELEKINESIS}
|
* @see {@link https://bulbapedia.bulbagarden.net/wiki/Telekinesis_(move) | MoveId.TELEKINESIS}
|
||||||
*/
|
*/
|
||||||
export class FloatingTag extends TypeImmuneTag {
|
export class FloatingTag extends TypeImmuneTag {
|
||||||
|
public override readonly tagType = BattlerTagType.FLOATING;
|
||||||
constructor(tagType: BattlerTagType, sourceMove: MoveId, turnCount: number) {
|
constructor(tagType: BattlerTagType, sourceMove: MoveId, turnCount: number) {
|
||||||
super(tagType, sourceMove, PokemonType.GROUND, turnCount);
|
super(tagType, sourceMove, PokemonType.GROUND, turnCount);
|
||||||
}
|
}
|
||||||
@ -2247,6 +2268,7 @@ export class FloatingTag extends TypeImmuneTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class TypeBoostTag extends SerializableBattlerTag {
|
export class TypeBoostTag extends SerializableBattlerTag {
|
||||||
|
public declare readonly tagType: TypeBoostTagType;
|
||||||
#boostedType: PokemonType;
|
#boostedType: PokemonType;
|
||||||
#boostValue: number;
|
#boostValue: number;
|
||||||
#oneUse: boolean;
|
#oneUse: boolean;
|
||||||
@ -2296,13 +2318,24 @@ export class TypeBoostTag extends SerializableBattlerTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class CritBoostTag extends SerializableBattlerTag {
|
export class CritBoostTag extends SerializableBattlerTag {
|
||||||
constructor(tagType: BattlerTagType, sourceMove: MoveId) {
|
public declare readonly tagType: CritStageBoostTagType;
|
||||||
|
/** The number of stages boosted by this tag */
|
||||||
|
public readonly critStages: number;
|
||||||
|
|
||||||
|
constructor(tagType: CritStageBoostTagType, sourceMove: MoveId) {
|
||||||
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove, undefined, true);
|
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove, undefined, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdd(pokemon: Pokemon): void {
|
onAdd(pokemon: Pokemon): void {
|
||||||
super.onAdd(pokemon);
|
super.onAdd(pokemon);
|
||||||
|
|
||||||
|
// Dragon cheer adds +2 crit stages if the pokemon is a Dragon type when the tag is added
|
||||||
|
if (this.tagType === BattlerTagType.DRAGON_CHEER && pokemon.getTypes(true).includes(PokemonType.DRAGON)) {
|
||||||
|
(this as Mutable<this>).critStages = 2;
|
||||||
|
} else {
|
||||||
|
(this as Mutable<this>).critStages = 1;
|
||||||
|
}
|
||||||
|
|
||||||
globalScene.phaseManager.queueMessage(
|
globalScene.phaseManager.queueMessage(
|
||||||
i18next.t("battlerTags:critBoostOnAdd", {
|
i18next.t("battlerTags:critBoostOnAdd", {
|
||||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||||
@ -2323,23 +2356,12 @@ export class CritBoostTag extends SerializableBattlerTag {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public override loadTag(source: BaseBattlerTag & Pick<CritBoostTag, "tagType" | "critStages">): void {
|
||||||
* Tag for the effects of Dragon Cheer, which boosts the critical hit ratio of the user's allies.
|
super.loadTag(source);
|
||||||
*/
|
// TODO: Remove the nullish coalescing once Zod Schemas come in
|
||||||
export class DragonCheerTag extends CritBoostTag {
|
// For now, this is kept for backwards compatibility with older save files
|
||||||
/** The types of the user's ally when the tag is added */
|
(this as Mutable<this>).critStages = source.critStages ?? 1;
|
||||||
public typesOnAdd: PokemonType[];
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super(BattlerTagType.CRIT_BOOST, MoveId.DRAGON_CHEER);
|
|
||||||
}
|
|
||||||
|
|
||||||
onAdd(pokemon: Pokemon): void {
|
|
||||||
super.onAdd(pokemon);
|
|
||||||
|
|
||||||
this.typesOnAdd = pokemon.getTypes(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2398,6 +2420,7 @@ export class SaltCuredTag extends SerializableBattlerTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class CursedTag extends SerializableBattlerTag {
|
export class CursedTag extends SerializableBattlerTag {
|
||||||
|
public override readonly tagType = BattlerTagType.CURSED;
|
||||||
constructor(sourceId: number) {
|
constructor(sourceId: number) {
|
||||||
super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, MoveId.CURSE, sourceId, true);
|
super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, MoveId.CURSE, sourceId, true);
|
||||||
}
|
}
|
||||||
@ -2444,7 +2467,8 @@ export class CursedTag extends SerializableBattlerTag {
|
|||||||
* Battler tag for attacks that remove a type post use.
|
* Battler tag for attacks that remove a type post use.
|
||||||
*/
|
*/
|
||||||
export class RemovedTypeTag extends SerializableBattlerTag {
|
export class RemovedTypeTag extends SerializableBattlerTag {
|
||||||
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: MoveId) {
|
public declare readonly tagType: RemovedTypeTagType;
|
||||||
|
constructor(tagType: RemovedTypeTagType, lapseType: BattlerTagLapseType, sourceMove: MoveId) {
|
||||||
super(tagType, lapseType, 1, sourceMove);
|
super(tagType, lapseType, 1, sourceMove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2454,7 +2478,8 @@ export class RemovedTypeTag extends SerializableBattlerTag {
|
|||||||
* @description `IGNORE_FLYING`: Persistent grounding effects (i.e. from Smack Down and Thousand Waves)
|
* @description `IGNORE_FLYING`: Persistent grounding effects (i.e. from Smack Down and Thousand Waves)
|
||||||
*/
|
*/
|
||||||
export class GroundedTag extends SerializableBattlerTag {
|
export class GroundedTag extends SerializableBattlerTag {
|
||||||
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: MoveId) {
|
public override readonly tagType = BattlerTagType.IGNORE_FLYING;
|
||||||
|
constructor(tagType: BattlerTagType.IGNORE_FLYING, lapseType: BattlerTagLapseType, sourceMove: MoveId) {
|
||||||
super(tagType, lapseType, 1, sourceMove);
|
super(tagType, lapseType, 1, sourceMove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3719,9 +3744,8 @@ export function getBattlerTag(
|
|||||||
case BattlerTagType.FIRE_BOOST:
|
case BattlerTagType.FIRE_BOOST:
|
||||||
return new TypeBoostTag(tagType, sourceMove, PokemonType.FIRE, 1.5, false);
|
return new TypeBoostTag(tagType, sourceMove, PokemonType.FIRE, 1.5, false);
|
||||||
case BattlerTagType.CRIT_BOOST:
|
case BattlerTagType.CRIT_BOOST:
|
||||||
return new CritBoostTag(tagType, sourceMove);
|
|
||||||
case BattlerTagType.DRAGON_CHEER:
|
case BattlerTagType.DRAGON_CHEER:
|
||||||
return new DragonCheerTag();
|
return new CritBoostTag(tagType, sourceMove);
|
||||||
case BattlerTagType.ALWAYS_CRIT:
|
case BattlerTagType.ALWAYS_CRIT:
|
||||||
case BattlerTagType.IGNORE_ACCURACY:
|
case BattlerTagType.IGNORE_ACCURACY:
|
||||||
return new SerializableBattlerTag(tagType, BattlerTagLapseType.TURN_END, 2, sourceMove);
|
return new SerializableBattlerTag(tagType, BattlerTagLapseType.TURN_END, 2, sourceMove);
|
||||||
@ -3813,7 +3837,7 @@ export function getBattlerTag(
|
|||||||
* @param source - An object containing the data necessary to reconstruct the BattlerTag.
|
* @param source - An object containing the data necessary to reconstruct the BattlerTag.
|
||||||
* @returns The valid battler tag
|
* @returns The valid battler tag
|
||||||
*/
|
*/
|
||||||
export function loadBattlerTag(source: SerializableBattlerTag): BattlerTag {
|
export function loadBattlerTag(source: BattlerTag | BattlerTagTypeData): BattlerTag {
|
||||||
// TODO: Remove this bang by fixing the signature of `getBattlerTag`
|
// TODO: Remove this bang by fixing the signature of `getBattlerTag`
|
||||||
// to allow undefined sourceIds and sourceMoves (with appropriate fallback for tags that require it)
|
// to allow undefined sourceIds and sourceMoves (with appropriate fallback for tags that require it)
|
||||||
const tag = getBattlerTag(source.tagType, source.turnCount, source.sourceMove!, source.sourceId!);
|
const tag = getBattlerTag(source.tagType, source.turnCount, source.sourceMove!, source.sourceId!);
|
||||||
@ -3854,7 +3878,7 @@ export type BattlerTagTypeMap = {
|
|||||||
[BattlerTagType.POWDER]: PowderTag;
|
[BattlerTagType.POWDER]: PowderTag;
|
||||||
[BattlerTagType.NIGHTMARE]: NightmareTag;
|
[BattlerTagType.NIGHTMARE]: NightmareTag;
|
||||||
[BattlerTagType.FRENZY]: FrenzyTag;
|
[BattlerTagType.FRENZY]: FrenzyTag;
|
||||||
[BattlerTagType.CHARGING]: SerializableBattlerTag;
|
[BattlerTagType.CHARGING]: GenericSerializableBattlerTag<BattlerTagType.CHARGING>;
|
||||||
[BattlerTagType.ENCORE]: EncoreTag;
|
[BattlerTagType.ENCORE]: EncoreTag;
|
||||||
[BattlerTagType.HELPING_HAND]: HelpingHandTag;
|
[BattlerTagType.HELPING_HAND]: HelpingHandTag;
|
||||||
[BattlerTagType.INGRAIN]: IngrainTag;
|
[BattlerTagType.INGRAIN]: IngrainTag;
|
||||||
@ -3894,11 +3918,11 @@ export type BattlerTagTypeMap = {
|
|||||||
[BattlerTagType.HIDDEN]: SemiInvulnerableTag;
|
[BattlerTagType.HIDDEN]: SemiInvulnerableTag;
|
||||||
[BattlerTagType.FIRE_BOOST]: TypeBoostTag;
|
[BattlerTagType.FIRE_BOOST]: TypeBoostTag;
|
||||||
[BattlerTagType.CRIT_BOOST]: CritBoostTag;
|
[BattlerTagType.CRIT_BOOST]: CritBoostTag;
|
||||||
[BattlerTagType.DRAGON_CHEER]: DragonCheerTag;
|
[BattlerTagType.DRAGON_CHEER]: CritBoostTag;
|
||||||
[BattlerTagType.ALWAYS_CRIT]: SerializableBattlerTag;
|
[BattlerTagType.ALWAYS_CRIT]: GenericSerializableBattlerTag<BattlerTagType.ALWAYS_CRIT>;
|
||||||
[BattlerTagType.IGNORE_ACCURACY]: SerializableBattlerTag;
|
[BattlerTagType.IGNORE_ACCURACY]: GenericSerializableBattlerTag<BattlerTagType.IGNORE_ACCURACY>;
|
||||||
[BattlerTagType.ALWAYS_GET_HIT]: SerializableBattlerTag;
|
[BattlerTagType.ALWAYS_GET_HIT]: GenericSerializableBattlerTag<BattlerTagType.ALWAYS_GET_HIT>;
|
||||||
[BattlerTagType.RECEIVE_DOUBLE_DAMAGE]: SerializableBattlerTag;
|
[BattlerTagType.RECEIVE_DOUBLE_DAMAGE]: GenericSerializableBattlerTag<BattlerTagType.RECEIVE_DOUBLE_DAMAGE>;
|
||||||
[BattlerTagType.BYPASS_SLEEP]: BattlerTag;
|
[BattlerTagType.BYPASS_SLEEP]: BattlerTag;
|
||||||
[BattlerTagType.IGNORE_FLYING]: GroundedTag;
|
[BattlerTagType.IGNORE_FLYING]: GroundedTag;
|
||||||
[BattlerTagType.ROOSTED]: RoostedTag;
|
[BattlerTagType.ROOSTED]: RoostedTag;
|
||||||
|
@ -25,7 +25,6 @@ import {
|
|||||||
AutotomizedTag,
|
AutotomizedTag,
|
||||||
BattlerTag,
|
BattlerTag,
|
||||||
CritBoostTag,
|
CritBoostTag,
|
||||||
DragonCheerTag,
|
|
||||||
EncoreTag,
|
EncoreTag,
|
||||||
ExposedTag,
|
ExposedTag,
|
||||||
GroundedTag,
|
GroundedTag,
|
||||||
@ -1390,8 +1389,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
const critBoostTag = source.getTag(CritBoostTag);
|
const critBoostTag = source.getTag(CritBoostTag);
|
||||||
if (critBoostTag) {
|
if (critBoostTag) {
|
||||||
// Dragon cheer only gives +1 crit stage to non-dragon types
|
// Dragon cheer only gives +1 crit stage to non-dragon types
|
||||||
critStage.value +=
|
critStage.value += critBoostTag.critStages;
|
||||||
critBoostTag instanceof DragonCheerTag && !critBoostTag.typesOnAdd.includes(PokemonType.DRAGON) ? 1 : 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`crit stage: +${critStage.value}`);
|
console.log(`crit stage: +${critStage.value}`);
|
||||||
|
Loading…
Reference in New Issue
Block a user