From 2b23ac814091af1f942e652aec850e3b9d6fd290 Mon Sep 17 00:00:00 2001 From: jatinkohli Date: Tue, 21 May 2024 01:05:42 -0700 Subject: [PATCH] Re-implement taunt as BattlerTag and add taunt immunities for oblivious and aroma veil abilities --- src/data/ability.ts | 4 ++++ src/data/battler-tags.ts | 28 +++++++++++++++++++++++++++ src/data/enums/battler-tag-type.ts | 1 + src/data/move.ts | 7 ++++--- src/field/pokemon.ts | 9 +++------ src/phases.ts | 31 ++++++++++-------------------- src/system/pokemon-data.ts | 3 --- 7 files changed, 50 insertions(+), 33 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index b4215b683cd..c8d4d6fb755 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -3009,6 +3009,7 @@ export function initAbilities() { .ignorable(), new Ability(Abilities.OBLIVIOUS, 3) .attr(BattlerTagImmunityAbAttr, BattlerTagType.INFATUATED) + .attr(BattlerTagImmunityAbAttr, BattlerTagType.TAUNT) .attr(IntimidateImmunityAbAttr) .ignorable() .partial(), @@ -3450,7 +3451,10 @@ export function initAbilities() { .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a bursting aura!')) .attr(MoveAbilityBypassAbAttr), new Ability(Abilities.AROMA_VEIL, 6) + .attr(BattlerTagImmunityAbAttr, BattlerTagType.INFATUATED) .attr(BattlerTagImmunityAbAttr, BattlerTagType.TORMENT) + .attr(BattlerTagImmunityAbAttr, BattlerTagType.TAUNT) + .attr(BattlerTagImmunityAbAttr, BattlerTagType.ENCORE) .ignorable() .partial(), new Ability(Abilities.FLOWER_VEIL, 6) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 1950d933cf8..aef8f5bf04d 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -514,6 +514,32 @@ export class TormentTag extends BattlerTag { } } +export class TauntTag extends BattlerTag { + public justTaunted: boolean = true; + + constructor() { + super(BattlerTagType.TAUNT, BattlerTagLapseType.TURN_END, 4, Moves.TAUNT); + } + + onAdd(pokemon: Pokemon) { + pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' fell for the taunt!')); + } + + onRemove(pokemon: Pokemon): void { + pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' shook off the taunt!')); + } + + lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType) { + const ret = super.lapse(pokemon, lapseType); + this.justTaunted = false; + return ret; + } + + getDescriptor(): string { + return 'taunt'; + } +} + export class HelpingHandTag extends BattlerTag { constructor(sourceId: integer) { super(BattlerTagType.HELPING_HAND, BattlerTagLapseType.TURN_END, 1, Moves.HELPING_HAND, sourceId); @@ -1341,6 +1367,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc return new EncoreTag(sourceId); case BattlerTagType.TORMENT: return new TormentTag(); + case BattlerTagType.TAUNT: + return new TauntTag(); case BattlerTagType.HELPING_HAND: return new HelpingHandTag(sourceId); case BattlerTagType.INGRAIN: diff --git a/src/data/enums/battler-tag-type.ts b/src/data/enums/battler-tag-type.ts index 5602a76dccb..f8ea45fa912 100644 --- a/src/data/enums/battler-tag-type.ts +++ b/src/data/enums/battler-tag-type.ts @@ -12,6 +12,7 @@ export enum BattlerTagType { CHARGING = "CHARGING", ENCORE = "ENCORE", TORMENT = "TORMENT", + TAUNT = "TAUNT", HELPING_HAND = "HELPING_HAND", INGRAIN = "INGRAIN", AQUA_RING = "AQUA_RING", diff --git a/src/data/move.ts b/src/data/move.ts index 8db1e0975f2..7fe850dbe8f 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -2,7 +2,7 @@ import { Moves } from "./enums/moves"; import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./battle-anims"; import { BattleEndPhase, MoveEffectPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase, ToggleDoublePositionPhase } from "../phases"; import { BattleStat, getBattleStatName } from "./battle-stat"; -import { EncoreTag, TormentTag } from "./battler-tags"; +import { EncoreTag, TauntTag, TormentTag } from "./battler-tags"; import { BattlerTagType } from "./enums/battler-tag-type"; import { getPokemonMessage } from "../messages"; import Pokemon, { AttackMoveResult, EnemyPokemon, HitResult, MoveResult, PlayerPokemon, PokemonMove, TurnMove } from "../field/pokemon"; @@ -3359,6 +3359,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr { case BattlerTagType.DROWSY: case BattlerTagType.NO_CRIT: case BattlerTagType.TORMENT: + case BattlerTagType.TAUNT: return -5; case BattlerTagType.SEEDED: case BattlerTagType.SALT_CURED: @@ -5493,8 +5494,8 @@ export function initMoves() { .attr(StatChangeAttr, BattleStat.SPDEF, 1, true) .attr(AddBattlerTagAttr, BattlerTagType.CHARGED, true, false), new StatusMove(Moves.TAUNT, Type.DARK, 100, 20, -1, 0, 3) - // .attr(TauntAttr) - .condition((user, target, move) => (!target.summonData.taunted)) + .attr(AddBattlerTagAttr, BattlerTagType.TAUNT) + .condition((user, target, move) => (target.findTag(t => t instanceof TauntTag) === undefined)) .partial(), new StatusMove(Moves.HELPING_HAND, Type.NORMAL, -1, 20, -1, 5, 3) .attr(AddBattlerTagAttr, BattlerTagType.HELPING_HAND) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index a4808c1da05..5ac98a8eee5 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -19,7 +19,7 @@ import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEv import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from '../data/tms'; import { DamagePhase, FaintPhase, LearnMovePhase, ObtainStatusEffectPhase, StatChangePhase, SwitchPhase, SwitchSummonPhase, ToggleDoublePositionPhase } from '../phases'; import { BattleStat } from '../data/battle-stat'; -import { BattlerTag, BattlerTagLapseType, EncoreTag, HelpingHandTag, HighestStatBoostTag, TypeBoostTag, getBattlerTag } from '../data/battler-tags'; +import { BattlerTag, BattlerTagLapseType, EncoreTag, HelpingHandTag, HighestStatBoostTag, TauntTag, TypeBoostTag, getBattlerTag } from '../data/battler-tags'; import { BattlerTagType } from "../data/enums/battler-tag-type"; import { Species } from '../data/enums/species'; import { WeatherType } from '../data/weather'; @@ -3389,9 +3389,6 @@ export class PokemonSummonData { public disabledTurns: integer = 0; public tormented = false; public prevMove: Moves = undefined; // for torment, carry over between battles while summoned - public justTaunted: boolean = false; - public taunted: boolean = false; - public tauntedTurns: integer = 0; public tags: BattlerTag[] = []; public abilitySuppressed: boolean = false; @@ -3474,8 +3471,8 @@ export class PokemonMove { isUsable(pokemon: Pokemon, ignorePp?: boolean): boolean { const isMoveDisabled = this.moveId && pokemon.summonData?.disabledMove === this.moveId; - // for taunt: check valid move, pokemon is taunted, - const isMoveDisabledTaunt = this.moveId && pokemon.summonData.taunted && this.getMove().category === MoveCategory.STATUS; + // for taunt: check valid move, pokemon is taunted, and move is status + const isMoveDisabledTaunt = this.moveId && (pokemon.findTag(t => t instanceof TauntTag) !== undefined) && this.getMove().category === MoveCategory.STATUS; // for torment: check valid move, pokemon is tormented, pokemon has moved this summon, and selected move is the same as previous move const isMoveDisabledTorment = this.moveId && pokemon.summonData.tormented && pokemon.summonData.prevMove === this.moveId; diff --git a/src/phases.ts b/src/phases.ts index 8c289df0bb0..421094c5b15 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -21,7 +21,7 @@ import { Biome } from "./data/enums/biome"; import { ModifierTier } from "./modifier/modifier-tier"; import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, PokemonPpRestoreModifierType, PokemonPpUpModifierType, RememberMoveModifierType, TmModifierType, getDailyRunStarterModifiers, getEnemyBuffModifierForWave, getModifierType, getPlayerModifierTypeOptions, getPlayerShopModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; -import { BattlerTagLapseType, EncoreTag, HideSpriteTag as HiddenTag, ProtectedTag, TrappedTag } from "./data/battler-tags"; +import { BattlerTagLapseType, EncoreTag, HideSpriteTag as HiddenTag, ProtectedTag, TauntTag, TrappedTag } from "./data/battler-tags"; import { BattlerTagType } from "./data/enums/battler-tag-type"; import { getPokemonMessage, getPokemonPrefix } from "./messages"; import { Starter } from "./ui/starter-select-ui-handler"; @@ -1743,7 +1743,7 @@ export class CommandPhase extends FieldPhase { else if (playerPokemon.summonData.tormented && playerPokemon.summonData.prevMove === move.moveId) { errorMessage = getPokemonMessage(playerPokemon, ' can\'t use the same move twice in a row due to the torment!'); canTranslate = false; - } else if (playerPokemon.summonData.taunted && move.getMove().category === MoveCategory.STATUS) { + } else if ((playerPokemon.findTag(t => t instanceof TauntTag) !== undefined) && move.getMove().category === MoveCategory.STATUS) { errorMessage = getPokemonMessage(playerPokemon, ' can\'t use ' + move.getName() + ' after the taunt!'); canTranslate = false; } else @@ -2111,16 +2111,7 @@ export class TurnEndPhase extends FieldPhase { pokemon.lapseTags(BattlerTagLapseType.TURN_END); // For torment, keep track of last used move. This remains between battles while the pokemon is still on the field. - pokemon.summonData.prevMove = pokemon.getLastXMoves(1)[0].move; - - if (pokemon.summonData.justTaunted) { - pokemon.summonData.justTaunted = false; - } - - if (pokemon.summonData.taunted && !--pokemon.summonData.tauntedTurns) { - this.scene.pushPhase(new MessagePhase(this.scene, getPokemonMessage(pokemon, " shook off the taunt!"))); - pokemon.summonData.taunted = false; - } + pokemon.summonData.prevMove = pokemon.getLastXMoves(1)[0] ? pokemon.getLastXMoves(1)[0].move : undefined; if (pokemon.summonData.disabledMove && !--pokemon.summonData.disabledTurns) { this.scene.pushPhase(new MessagePhase(this.scene, i18next.t('battle:notDisabled', { pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, moveName: allMoves[pokemon.summonData.disabledMove].name }))); @@ -2269,12 +2260,16 @@ export class MovePhase extends BattlePhase { console.log(Moves[this.move.moveId]); + const tauntTag = this.pokemon.findTag(t => t instanceof TauntTag); // undefined if pokemon is not taunted + + // decrement from taunt timer if target was taunted before moving + if (tauntTag && (tauntTag as TauntTag).justTaunted) + tauntTag.lapse(this.pokemon, BattlerTagLapseType.MOVE); + if (!this.canMove()) { if (this.move.moveId && this.pokemon.summonData.disabledMove === this.move.moveId) this.scene.queueMessage(`${this.move.getName()} is disabled!`); - else if (this.pokemon.summonData.taunted && this.move.getMove().category === MoveCategory.STATUS) { - if (this.pokemon.summonData.justTaunted) - this.pokemon.summonData.tauntedTurns--; + else if (tauntTag && this.move.getMove().category === MoveCategory.STATUS) { this.scene.queueMessage(getPokemonMessage(this.pokemon, ' can\'t use ' + this.move.getName() + ' after the taunt!')) } return this.end(); @@ -2729,12 +2724,6 @@ export class MoveEndPhase extends PokemonPhase { this.scene.arena.setIgnoreAbilities(false); - // if pokemon was taunted this turn and moved after the pokemon who taunted it, - // decrement taunt duration by 1 - if (pokemon.summonData.justTaunted) { - pokemon.summonData.tauntedTurns--; - } - this.end(); } } diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index bdd0e89bc75..a00bbd54c44 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -118,9 +118,6 @@ export default class PokemonData { this.summonData.abilitySuppressed = source.summonData.abilitySuppressed; this.summonData.tormented = source.summonData.tormented; this.summonData.prevMove = source.summonData.prevMove; - this.summonData.justTaunted = source.summonData.justTaunted; - this.summonData.taunted = source.summonData.taunted; - this.summonData.tauntedTurns = source.summonData.tauntedTurns; this.summonData.ability = source.summonData.ability; this.summonData.moveset = source.summonData.moveset?.map(m => PokemonMove.loadMove(m));