From 61c963cce62eba8f8446d19c8b430274320091cd Mon Sep 17 00:00:00 2001 From: jatinkohli Date: Mon, 20 May 2024 01:29:45 -0700 Subject: [PATCH] Begin implementing torment --- src/data/move.ts | 20 +++++++++++++++++++- src/field/pokemon.ts | 7 ++++++- src/phases.ts | 26 +++++++++++++++++++++----- src/system/pokemon-data.ts | 2 ++ 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 6849a0fe7ce..06d69949437 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -3021,6 +3021,22 @@ export class DisableMoveAttr extends MoveEffectAttr { } } +export class TormentAttr extends MoveEffectAttr { + constructor() { + super(false); + } + + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]) { + const ret = this.canApply(user, target, move, args); + + if (ret) { + target.summonData.justTormented = true; + user.scene.queueMessage(getPokemonMessage(target, ' was subjected to torment!')); + } + return ret; + } +} + export class FrenzyAttr extends MoveEffectAttr { constructor() { super(true, MoveEffectTrigger.HIT); @@ -5141,7 +5157,9 @@ export function initMoves() { .attr(WeatherChangeAttr, WeatherType.HAIL) .target(MoveTarget.BOTH_SIDES), new StatusMove(Moves.TORMENT, Type.DARK, 100, 15, -1, 0, 3) - .unimplemented(), + .attr(TormentAttr) + .condition((user, target, move) => (!target.summonData.justTormented && !target.summonData.tormented)) + .partial(), new StatusMove(Moves.FLATTER, Type.DARK, 100, 15, -1, 0, 3) .attr(StatChangeAttr, BattleStat.SPATK, 1) .attr(ConfuseAttr), diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 0a5e0a6a991..673958ba3ea 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -3321,6 +3321,8 @@ export class PokemonSummonData { public disabledTurns: integer = 0; public tags: BattlerTag[] = []; public abilitySuppressed: boolean = false; + public justTormented: boolean = false; + public tormented: boolean = false; public speciesForm: PokemonSpeciesForm; public fusionSpeciesForm: PokemonSpeciesForm; @@ -3398,7 +3400,10 @@ export class PokemonMove { } isUsable(pokemon: Pokemon, ignorePp?: boolean): boolean { - if (this.moveId && pokemon.summonData?.disabledMove === this.moveId) + const isMoveDisabled = this.moveId && pokemon.summonData?.disabledMove === this.moveId; + // 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.getLastXMoves(1)[0] && pokemon.getLastXMoves(1)[0].move === this.moveId; + if (isMoveDisabled || isMoveDisabledTorment) return false; return (ignorePp || this.ppUsed < this.getMovePp() || this.getMove().pp === -1) && !this.getMove().name.endsWith(' (N)'); } diff --git a/src/phases.ts b/src/phases.ts index f70fe9e857a..ed9cb87e24c 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -1732,13 +1732,23 @@ export class CommandPhase extends FieldPhase { const move = playerPokemon.getMoveset()[cursor]; this.scene.ui.setMode(Mode.MESSAGE); - // Decides between a Disabled, Not Implemented, or No PP translation message - const errorMessage = - playerPokemon.summonData.disabledMove === move.moveId ? 'battle:moveDisabled' : - move.getName().endsWith(' (N)') ? 'battle:moveNotImplemented' : 'battle:moveNoPP'; + // Decides between a Disabled, Not Implemented, Tormented, or No PP translation message + var errorMessage; + var canTranslate = true; + if (playerPokemon.summonData.disabledMove === move.moveId) + errorMessage = 'battle:moveDisabled'; + else if (move.getName().endsWith(' (N)')) + errorMessage = 'battle:moveNotImplemented'; + else if (playerPokemon.summonData.tormented && playerPokemon.getLastXMoves(1)[0] && playerPokemon.getLastXMoves(1)[0].move === move.moveId) { + errorMessage = getPokemonMessage(playerPokemon, ' can\'t use the same move twice in a row due to the torment!'); + canTranslate = false; + } else + errorMessage = 'battle:moveNoPP'; + const moveName = move.getName().replace(' (N)', ''); // Trims off the indicator - this.scene.ui.showText(i18next.t(errorMessage, { moveName: moveName }), null, () => { + errorMessage = canTranslate ? i18next.t(errorMessage, { moveName: moveName }) : errorMessage; + this.scene.ui.showText(errorMessage, null, () => { this.scene.ui.clearText(); this.scene.ui.setMode(Mode.FIGHT, this.fieldIndex); }, null, true); @@ -2092,6 +2102,12 @@ export class TurnEndPhase extends FieldPhase { const handlePokemon = (pokemon: Pokemon) => { pokemon.lapseTags(BattlerTagLapseType.TURN_END); + + // transition from just tormented (tormented status does not apply on same turn it's given) and tormented + if (pokemon.summonData.justTormented && !pokemon.summonData.tormented) { + pokemon.summonData.justTormented = false; + pokemon.summonData.tormented = true; + } 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 }))); diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index dfbb9be570b..e557d22e0f1 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -116,6 +116,8 @@ export default class PokemonData { this.summonData.disabledMove = source.summonData.disabledMove; this.summonData.disabledTurns = source.summonData.disabledTurns; this.summonData.abilitySuppressed = source.summonData.abilitySuppressed; + this.summonData.justTormented = source.summonData.justTormented; + this.summonData.tormented = source.summonData.tormented; this.summonData.ability = source.summonData.ability; this.summonData.moveset = source.summonData.moveset?.map(m => PokemonMove.loadMove(m));