[Bug] Fixes bug with frenzy moves keeping the confusion counter despite disruption (#3041)

* Adds frenzyMissFunc trigger on NO_EFFECT hit result

* Refactors FrenzyAttr to properly lapse tags each turn and remove tags on disrupt

* Makes comment on CONFUSED tag clearer

* Changes all integer usages to number in battler-tags

* Update getBattlerTag function to use number instead of integer
This commit is contained in:
schmidtc1 2024-07-24 14:07:51 -04:00 committed by GitHub
parent a526403534
commit 54feaa0b32
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 55 deletions

View File

@ -32,11 +32,11 @@ export enum BattlerTagLapseType {
export class BattlerTag {
public tagType: BattlerTagType;
public lapseType: BattlerTagLapseType[];
public turnCount: integer;
public turnCount: number;
public sourceMove: Moves;
public sourceId?: integer;
public sourceId?: number;
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType | BattlerTagLapseType[], turnCount: integer, sourceMove: Moves, sourceId?: integer) {
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType | BattlerTagLapseType[], turnCount: number, sourceMove: Moves, sourceId?: number) {
this.tagType = tagType;
this.lapseType = typeof lapseType === "number" ? [ lapseType ] : lapseType;
this.turnCount = turnCount;
@ -119,7 +119,7 @@ export class RechargingTag extends BattlerTag {
}
export class TrappedTag extends BattlerTag {
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: integer, sourceMove: Moves, sourceId: integer) {
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: number, sourceMove: Moves, sourceId: number) {
super(tagType, lapseType, turnCount, sourceMove, sourceId);
}
@ -222,7 +222,7 @@ export class InterruptedTag extends BattlerTag {
* BattlerTag that represents the {@link https://bulbapedia.bulbagarden.net/wiki/Confusion_(status_condition) Confusion} status condition
*/
export class ConfusedTag extends BattlerTag {
constructor(turnCount: integer, sourceMove: Moves) {
constructor(turnCount: number, sourceMove: Moves) {
super(BattlerTagType.CONFUSED, BattlerTagLapseType.MOVE, turnCount, sourceMove);
}
@ -282,7 +282,7 @@ export class ConfusedTag extends BattlerTag {
* @see {@linkcode apply}
*/
export class DestinyBondTag extends BattlerTag {
constructor(sourceMove: Moves, sourceId: integer) {
constructor(sourceMove: Moves, sourceId: number) {
super(BattlerTagType.DESTINY_BOND, BattlerTagLapseType.PRE_MOVE, 1, sourceMove, sourceId);
}
@ -325,7 +325,7 @@ export class DestinyBondTag extends BattlerTag {
}
export class InfatuatedTag extends BattlerTag {
constructor(sourceMove: integer, sourceId: integer) {
constructor(sourceMove: number, sourceId: number) {
super(BattlerTagType.INFATUATED, BattlerTagLapseType.MOVE, 1, sourceMove, sourceId);
}
@ -387,9 +387,9 @@ export class InfatuatedTag extends BattlerTag {
}
export class SeedTag extends BattlerTag {
private sourceIndex: integer;
private sourceIndex: number;
constructor(sourceId: integer) {
constructor(sourceId: number) {
super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId);
}
@ -484,19 +484,21 @@ export class NightmareTag extends BattlerTag {
}
export class FrenzyTag extends BattlerTag {
constructor(sourceMove: Moves, sourceId: integer) {
super(BattlerTagType.FRENZY, BattlerTagLapseType.CUSTOM, 1, sourceMove, sourceId);
constructor(turnCount: number, sourceMove: Moves, sourceId: number) {
super(BattlerTagType.FRENZY, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
}
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
pokemon.addTag(BattlerTagType.CONFUSED, pokemon.randSeedIntRange(2, 4));
if (this.turnCount < 2) { // Only add CONFUSED tag if a disruption occurs on the final confusion-inducing turn of FRENZY
pokemon.addTag(BattlerTagType.CONFUSED, pokemon.randSeedIntRange(2, 4));
}
}
}
export class ChargingTag extends BattlerTag {
constructor(sourceMove: Moves, sourceId: integer) {
constructor(sourceMove: Moves, sourceId: number) {
super(BattlerTagType.CHARGING, BattlerTagLapseType.CUSTOM, 1, sourceMove, sourceId);
}
}
@ -504,7 +506,7 @@ export class ChargingTag extends BattlerTag {
export class EncoreTag extends BattlerTag {
public moveId: Moves;
constructor(sourceId: integer) {
constructor(sourceId: number) {
super(BattlerTagType.ENCORE, BattlerTagLapseType.AFTER_MOVE, 3, Moves.ENCORE, sourceId);
}
@ -577,7 +579,7 @@ export class EncoreTag extends BattlerTag {
}
export class HelpingHandTag extends BattlerTag {
constructor(sourceId: integer) {
constructor(sourceId: number) {
super(BattlerTagType.HELPING_HAND, BattlerTagLapseType.TURN_END, 1, Moves.HELPING_HAND, sourceId);
}
@ -596,7 +598,7 @@ export class HelpingHandTag extends BattlerTag {
* @extends TrappedTag
*/
export class IngrainTag extends TrappedTag {
constructor(sourceId: integer) {
constructor(sourceId: number) {
super(BattlerTagType.INGRAIN, BattlerTagLapseType.TURN_END, 1, Moves.INGRAIN, sourceId);
}
@ -754,7 +756,7 @@ export class DrowsyTag extends BattlerTag {
export abstract class DamagingTrapTag extends TrappedTag {
private commonAnim: CommonAnim;
constructor(tagType: BattlerTagType, commonAnim: CommonAnim, turnCount: integer, sourceMove: Moves, sourceId: integer) {
constructor(tagType: BattlerTagType, commonAnim: CommonAnim, turnCount: number, sourceMove: Moves, sourceId: number) {
super(tagType, BattlerTagLapseType.TURN_END, turnCount, sourceMove, sourceId);
this.commonAnim = commonAnim;
@ -798,7 +800,7 @@ export abstract class DamagingTrapTag extends TrappedTag {
}
export class BindTag extends DamagingTrapTag {
constructor(turnCount: integer, sourceId: integer) {
constructor(turnCount: number, sourceId: number) {
super(BattlerTagType.BIND, CommonAnim.BIND, turnCount, Moves.BIND, sourceId);
}
@ -812,7 +814,7 @@ export class BindTag extends DamagingTrapTag {
}
export class WrapTag extends DamagingTrapTag {
constructor(turnCount: integer, sourceId: integer) {
constructor(turnCount: number, sourceId: number) {
super(BattlerTagType.WRAP, CommonAnim.WRAP, turnCount, Moves.WRAP, sourceId);
}
@ -825,7 +827,7 @@ export class WrapTag extends DamagingTrapTag {
}
export abstract class VortexTrapTag extends DamagingTrapTag {
constructor(tagType: BattlerTagType, commonAnim: CommonAnim, turnCount: integer, sourceMove: Moves, sourceId: integer) {
constructor(tagType: BattlerTagType, commonAnim: CommonAnim, turnCount: number, sourceMove: Moves, sourceId: number) {
super(tagType, commonAnim, turnCount, sourceMove, sourceId);
}
@ -835,19 +837,19 @@ export abstract class VortexTrapTag extends DamagingTrapTag {
}
export class FireSpinTag extends VortexTrapTag {
constructor(turnCount: integer, sourceId: integer) {
constructor(turnCount: number, sourceId: number) {
super(BattlerTagType.FIRE_SPIN, CommonAnim.FIRE_SPIN, turnCount, Moves.FIRE_SPIN, sourceId);
}
}
export class WhirlpoolTag extends VortexTrapTag {
constructor(turnCount: integer, sourceId: integer) {
constructor(turnCount: number, sourceId: number) {
super(BattlerTagType.WHIRLPOOL, CommonAnim.WHIRLPOOL, turnCount, Moves.WHIRLPOOL, sourceId);
}
}
export class ClampTag extends DamagingTrapTag {
constructor(turnCount: integer, sourceId: integer) {
constructor(turnCount: number, sourceId: number) {
super(BattlerTagType.CLAMP, CommonAnim.CLAMP, turnCount, Moves.CLAMP, sourceId);
}
@ -860,7 +862,7 @@ export class ClampTag extends DamagingTrapTag {
}
export class SandTombTag extends DamagingTrapTag {
constructor(turnCount: integer, sourceId: integer) {
constructor(turnCount: number, sourceId: number) {
super(BattlerTagType.SAND_TOMB, CommonAnim.SAND_TOMB, turnCount, Moves.SAND_TOMB, sourceId);
}
@ -873,7 +875,7 @@ export class SandTombTag extends DamagingTrapTag {
}
export class MagmaStormTag extends DamagingTrapTag {
constructor(turnCount: integer, sourceId: integer) {
constructor(turnCount: number, sourceId: number) {
super(BattlerTagType.MAGMA_STORM, CommonAnim.MAGMA_STORM, turnCount, Moves.MAGMA_STORM, sourceId);
}
@ -883,7 +885,7 @@ export class MagmaStormTag extends DamagingTrapTag {
}
export class SnapTrapTag extends DamagingTrapTag {
constructor(turnCount: integer, sourceId: integer) {
constructor(turnCount: number, sourceId: number) {
super(BattlerTagType.SNAP_TRAP, CommonAnim.SNAP_TRAP, turnCount, Moves.SNAP_TRAP, sourceId);
}
@ -893,7 +895,7 @@ export class SnapTrapTag extends DamagingTrapTag {
}
export class ThunderCageTag extends DamagingTrapTag {
constructor(turnCount: integer, sourceId: integer) {
constructor(turnCount: number, sourceId: number) {
super(BattlerTagType.THUNDER_CAGE, CommonAnim.THUNDER_CAGE, turnCount, Moves.THUNDER_CAGE, sourceId);
}
@ -906,7 +908,7 @@ export class ThunderCageTag extends DamagingTrapTag {
}
export class InfestationTag extends DamagingTrapTag {
constructor(turnCount: integer, sourceId: integer) {
constructor(turnCount: number, sourceId: number) {
super(BattlerTagType.INFESTATION, CommonAnim.INFESTATION, turnCount, Moves.INFESTATION, sourceId);
}
@ -948,9 +950,9 @@ export class ProtectedTag extends BattlerTag {
}
export class ContactDamageProtectedTag extends ProtectedTag {
private damageRatio: integer;
private damageRatio: number;
constructor(sourceMove: Moves, damageRatio: integer) {
constructor(sourceMove: Moves, damageRatio: number) {
super(sourceMove, BattlerTagType.SPIKY_SHIELD);
this.damageRatio = damageRatio;
@ -984,9 +986,9 @@ export class ContactDamageProtectedTag extends ProtectedTag {
export class ContactStatChangeProtectedTag extends ProtectedTag {
private stat: BattleStat;
private levels: integer;
private levels: number;
constructor(sourceMove: Moves, tagType: BattlerTagType, stat: BattleStat, levels: integer) {
constructor(sourceMove: Moves, tagType: BattlerTagType, stat: BattleStat, levels: number) {
super(sourceMove, tagType);
this.stat = stat;
@ -1095,7 +1097,7 @@ export class SturdyTag extends BattlerTag {
}
export class PerishSongTag extends BattlerTag {
constructor(turnCount: integer) {
constructor(turnCount: number) {
super(BattlerTagType.PERISH_SONG, BattlerTagLapseType.TURN_END, turnCount, Moves.PERISH_SONG);
}
@ -1151,7 +1153,7 @@ export class CenterOfAttentionTag extends BattlerTag {
export class AbilityBattlerTag extends BattlerTag {
public ability: Abilities;
constructor(tagType: BattlerTagType, ability: Abilities, lapseType: BattlerTagLapseType, turnCount: integer) {
constructor(tagType: BattlerTagType, ability: Abilities, lapseType: BattlerTagLapseType, turnCount: number) {
super(tagType, lapseType, turnCount, undefined);
this.ability = ability;
@ -1239,7 +1241,7 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
const stats = [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
let highestStat: Stat;
stats.map(s => pokemon.getBattleStat(s)).reduce((highestValue: integer, value: integer, i: integer) => {
stats.map(s => pokemon.getBattleStat(s)).reduce((highestValue: number, value: number, i: number) => {
if (value > highestValue) {
highestStat = stats[i];
return value;
@ -1305,7 +1307,7 @@ export class TerrainHighestStatBoostTag extends HighestStatBoostTag implements T
}
export class SemiInvulnerableTag extends BattlerTag {
constructor(tagType: BattlerTagType, turnCount: integer, sourceMove: Moves) {
constructor(tagType: BattlerTagType, turnCount: number, sourceMove: Moves) {
super(tagType, BattlerTagLapseType.MOVE_EFFECT, turnCount, sourceMove);
}
@ -1437,9 +1439,9 @@ export class ReceiveDoubleDamageTag extends BattlerTag {
}
export class SaltCuredTag extends BattlerTag {
private sourceIndex: integer;
private sourceIndex: number;
constructor(sourceId: integer) {
constructor(sourceId: number) {
super(BattlerTagType.SALT_CURED, BattlerTagLapseType.TURN_END, 1, Moves.SALT_CURE, sourceId);
}
@ -1486,9 +1488,9 @@ export class SaltCuredTag extends BattlerTag {
}
export class CursedTag extends BattlerTag {
private sourceIndex: integer;
private sourceIndex: number;
constructor(sourceId: integer) {
constructor(sourceId: number) {
super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId);
}
@ -1587,6 +1589,7 @@ export class IceFaceTag extends BattlerTag {
}
}
/**
* Battler tag enabling the Stockpile mechanic. This tag handles:
* - Stack tracking, including max limit enforcement (which is replicated in Stockpile for redundancy).
@ -1675,7 +1678,7 @@ export class StockpilingTag extends BattlerTag {
}
}
export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourceMove: Moves, sourceId: integer): BattlerTag {
export function getBattlerTag(tagType: BattlerTagType, turnCount: number, sourceMove: Moves, sourceId: number): BattlerTag {
switch (tagType) {
case BattlerTagType.RECHARGING:
return new RechargingTag(sourceMove);
@ -1692,7 +1695,7 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
case BattlerTagType.NIGHTMARE:
return new NightmareTag();
case BattlerTagType.FRENZY:
return new FrenzyTag(sourceMove, sourceId);
return new FrenzyTag(turnCount, sourceMove, sourceId);
case BattlerTagType.CHARGING:
return new ChargingTag(sourceMove, sourceId);
case BattlerTagType.ENCORE:

View File

@ -4060,19 +4060,16 @@ export class FrenzyAttr extends MoveEffectAttr {
return false;
}
if (!user.getMoveQueue().length) {
if (!user.getTag(BattlerTagType.FRENZY)) {
const turnCount = user.randSeedIntRange(1, 2);
new Array(turnCount).fill(null).map(() => user.getMoveQueue().push({ move: move.id, targets: [ target.getBattlerIndex() ], ignorePP: true }));
user.addTag(BattlerTagType.FRENZY, 1, move.id, user.id);
} else {
applyMoveAttrs(AddBattlerTagAttr, user, target, move, args);
user.lapseTag(BattlerTagType.FRENZY);
}
return true;
if (!user.getTag(BattlerTagType.FRENZY) && !user.getMoveQueue().length) {
const turnCount = user.randSeedIntRange(1, 2);
new Array(turnCount).fill(null).map(() => user.getMoveQueue().push({ move: move.id, targets: [ target.getBattlerIndex() ], ignorePP: true }));
user.addTag(BattlerTagType.FRENZY, turnCount, move.id, user.id);
} else {
applyMoveAttrs(AddBattlerTagAttr, user, target, move, args);
user.lapseTag(BattlerTagType.FRENZY); // if FRENZY is already in effect (moveQueue.length > 0), lapse the tag
}
return false;
return true;
}
}
@ -4080,7 +4077,7 @@ export const frenzyMissFunc: UserMoveConditionFunc = (user: Pokemon, move: Move)
while (user.getMoveQueue().length && user.getMoveQueue()[0].move === move.id) {
user.getMoveQueue().shift();
}
user.lapseTag(BattlerTagType.FRENZY);
user.removeTag(BattlerTagType.FRENZY); // FRENZY tag should be disrupted on miss/no effect
return true;
};
@ -5980,6 +5977,7 @@ export function initMoves() {
new AttackMove(Moves.THRASH, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 1)
.attr(FrenzyAttr)
.attr(MissEffectAttr, frenzyMissFunc)
.attr(NoEffectAttr, frenzyMissFunc)
.target(MoveTarget.RANDOM_NEAR_ENEMY),
new AttackMove(Moves.DOUBLE_EDGE, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 1)
.attr(RecoilAttr, false, 0.33)
@ -6098,6 +6096,7 @@ export function initMoves() {
new AttackMove(Moves.PETAL_DANCE, Type.GRASS, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 1)
.attr(FrenzyAttr)
.attr(MissEffectAttr, frenzyMissFunc)
.attr(NoEffectAttr, frenzyMissFunc)
.makesContact()
.danceMove()
.target(MoveTarget.RANDOM_NEAR_ENEMY),
@ -6431,6 +6430,7 @@ export function initMoves() {
new AttackMove(Moves.OUTRAGE, Type.DRAGON, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 2)
.attr(FrenzyAttr)
.attr(MissEffectAttr, frenzyMissFunc)
.attr(NoEffectAttr, frenzyMissFunc)
.target(MoveTarget.RANDOM_NEAR_ENEMY),
new StatusMove(Moves.SANDSTORM, Type.ROCK, -1, 10, -1, 0, 2)
.attr(WeatherChangeAttr, WeatherType.SANDSTORM)
@ -8281,6 +8281,7 @@ export function initMoves() {
.makesContact(false)
.attr(FrenzyAttr)
.attr(MissEffectAttr, frenzyMissFunc)
.attr(NoEffectAttr, frenzyMissFunc)
.target(MoveTarget.RANDOM_NEAR_ENEMY),
new AttackMove(Moves.WAVE_CRASH, Type.WATER, MoveCategory.PHYSICAL, 120, 100, 10, -1, 0, 8)
.attr(RecoilAttr, false, 0.33)

View File

@ -2287,7 +2287,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const tags = this.summonData.tags;
const tag = tags.find(t => t.tagType === tagType);
if (tag) {
tag.turnCount = 0;
tag.onRemove(this);
tags.splice(tags.indexOf(tag), 1);
}