From f91ca416365d431e004ba283dfe2b2b680568d25 Mon Sep 17 00:00:00 2001 From: f-raZ0R Date: Sat, 11 May 2024 20:28:31 -0400 Subject: [PATCH] they call it torment because that's what its like to implement this move --- src/data/battler-tags.ts | 21 ++++++++++++-------- src/field/pokemon.ts | 22 +++++++++++++++------ src/locales/en/battle.ts | 1 + src/phases.ts | 40 +++++++++++++++++++++++++------------- src/system/pokemon-data.ts | 1 + src/ui/fight-ui-handler.ts | 2 +- 6 files changed, 59 insertions(+), 28 deletions(-) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index dba5a7f3ba6..bcebb78a0d6 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -505,6 +505,7 @@ export class TormentedTag extends BattlerTag { canAdd(pokemon: Pokemon): boolean { if (pokemon.isMax()) return false; + else return true; } @@ -515,21 +516,25 @@ export class TormentedTag extends BattlerTag { onOverlap(pokemon: Pokemon): void { super.onOverlap(pokemon); - //TODO: This is not official game text. Grab what the game actually says if this happens. - pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nalready tormented!')); } - //Extremely janky hack to just test sure that this works in the first place. Athebyne please don't ship this. At the end of every turn, disables the last move you've used, for one turn. + onRemove(pokemon: Pokemon): void { + super.onRemove(pokemon); + pokemon.scene.queueMessage(getPokemonMessage(pokemon, 'is no longer\ntormented!')); + } + lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); if (ret) { const lastMove = pokemon.getLastXMoves(1)[0]; - if (!lastMove) + if (!lastMove || (lastMove.move === Moves.NONE)) return ret; - pokemon.summonData.disabledMove = lastMove.move; - pokemon.summonData.disabledTurns = 2; - - //pokemon.scene.queueMessage(disabledMove.getName(), `TORMENT TEST`); + if (lastMove.move === Moves.STRUGGLE) { + pokemon.summonData.unselectableMove = Moves.NONE; + } + else { + pokemon.summonData.unselectableMove = lastMove.move; + } return ret; } } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 8afff1b2724..f6bfaa90203 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1185,11 +1185,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.triggerPokemonFormChange(this, SpeciesFormChangeMoveLearnedTrigger); } - trySelectMove(moveIndex: integer, ignorePp?: boolean): boolean { + trySelectMove(moveIndex: integer, ignorePp?: boolean, skipSelection?: boolean): boolean { const move = this.getMoveset().length > moveIndex ? this.getMoveset()[moveIndex] : null; - return move?.isUsable(this, ignorePp); + return move?.isUsable(this, ignorePp) && (move?.isSelectable(this, ignorePp) || skipSelection); } showInfo(): void { @@ -2792,16 +2792,19 @@ export class EnemyPokemon extends Pokemon { } } - const movePool = this.getMoveset().filter(m => m.isUsable(this)); + const movePool = this.getMoveset().filter(m => m.isUsable(this)).filter(m => m.isSelectable(this)); if (movePool.length) { - if (movePool.length === 1) - return { move: movePool[0].moveId, targets: this.getNextTargets(movePool[0].moveId) }; const encoreTag = this.getTag(EncoreTag) as EncoreTag; if (encoreTag) { + if (this.summonData.disabledMove === encoreTag.moveId || this.summonData.unselectableMove === encoreTag.moveId) { + return { move: Moves.STRUGGLE, targets: this.getNextTargets(Moves.STRUGGLE) }; + } const encoreMove = movePool.find(m => m.moveId === encoreTag.moveId); if (encoreMove) return { move: encoreMove.moveId, targets: this.getNextTargets(encoreMove.moveId) }; - } + } + if (movePool.length === 1) + return { move: movePool[0].moveId, targets: this.getNextTargets(movePool[0].moveId) }; switch (this.aiType) { case AiType.RANDOM: const moveId = movePool[this.scene.randBattleSeedInt(movePool.length)].moveId; @@ -3138,6 +3141,7 @@ export class PokemonSummonData { public moveQueue: QueuedMove[] = []; public disabledMove: Moves = Moves.NONE; public disabledTurns: integer = 0; + public unselectableMove: Moves = Moves.NONE; public tags: BattlerTag[] = []; public abilitySuppressed: boolean = false; @@ -3221,6 +3225,12 @@ export class PokemonMove { return (ignorePp || this.ppUsed < this.getMovePp() || this.getMove().pp === -1) && !this.getMove().name.endsWith(' (N)'); } + isSelectable(pokemon: Pokemon, ignorePp?: boolean): boolean { + if ((this.moveId && pokemon.summonData?.disabledMove === this.moveId) || (this.moveId && pokemon.summonData?.unselectableMove === this.moveId)) + return false; + return (ignorePp || this.ppUsed < this.getMovePp() || this.getMove().pp === -1) && !this.getMove().name.endsWith(' (N)'); + } + getMove(): Move { return allMoves[this.moveId]; } diff --git a/src/locales/en/battle.ts b/src/locales/en/battle.ts index 7c948e6f09f..1bf42297394 100644 --- a/src/locales/en/battle.ts +++ b/src/locales/en/battle.ts @@ -35,6 +35,7 @@ export const battle: SimpleTranslationEntries = { "moveNotImplemented": "{{moveName}} is not yet implemented and cannot be selected.", "moveNoPP": "There's no PP left for\nthis move!", "moveDisabled": "{{moveName}} is disabled!", + "moveTormented": "{{pokemonName}} can't use the same move\n twice in a row due to the torment!", "noPokeballForce": "An unseen force\nprevents using Poké Balls.", "noPokeballTrainer": "You can't catch\nanother trainer's Pokémon!", "noPokeballMulti": "You can only throw a Poké Ball\nwhen there is one Pokémon remaining!", diff --git a/src/phases.ts b/src/phases.ts index 20c4dc73714..07687bc15fb 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -1664,11 +1664,11 @@ export class CommandPhase extends FieldPhase { if (moveQueue.length) { const queuedMove = moveQueue[0]; if (!queuedMove.move) - this.handleCommand(Command.FIGHT, -1, false); + this.handleCommand(Command.FIGHT, -1, false, false); else { const moveIndex = playerPokemon.getMoveset().findIndex(m => m.moveId === queuedMove.move); if (moveIndex > -1 && playerPokemon.getMoveset()[moveIndex].isUsable(playerPokemon, queuedMove.ignorePP)) { - this.handleCommand(Command.FIGHT, moveIndex, queuedMove.ignorePP, { targets: queuedMove.targets, multiple: queuedMove.targets.length > 1 }); + this.handleCommand(Command.FIGHT, moveIndex, queuedMove.ignorePP, true, { targets: queuedMove.targets, multiple: queuedMove.targets.length > 1 }); } else this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); } @@ -1680,14 +1680,20 @@ export class CommandPhase extends FieldPhase { const playerPokemon = this.scene.getPlayerField()[this.fieldIndex]; const enemyField = this.scene.getEnemyField(); let success: boolean; - + switch (command) { case Command.FIGHT: - let useStruggle = false; + let useStruggleA = false; + let useStruggleB = false; + let useStruggleC = false; + const encoreTag = playerPokemon.getTag(EncoreTag) as EncoreTag; if (cursor === -1 || - playerPokemon.trySelectMove(cursor, args[0] as boolean) || - (useStruggle = cursor > -1 && !playerPokemon.getMoveset().filter(m => m.isUsable(playerPokemon)).length)) { - const moveId = !useStruggle ? cursor > -1 ? playerPokemon.getMoveset()[cursor].moveId : Moves.NONE : Moves.STRUGGLE; + playerPokemon.trySelectMove(cursor, args[0] as boolean, args[1] as boolean) || + (useStruggleA = cursor > -1 && (!playerPokemon.getMoveset().filter(m => m.isSelectable(playerPokemon)).length) && !args[1]) || + (useStruggleB = cursor > -1 && (!playerPokemon.getMoveset().filter(m => m.isUsable(playerPokemon)).length)) || + (useStruggleC = cursor > -1 && encoreTag && encoreTag.moveId != Moves.NONE && (encoreTag.moveId === playerPokemon.summonData.unselectableMove || encoreTag.moveId === playerPokemon.summonData.disabledMove))) { + const moveId = !(useStruggleA || useStruggleB || useStruggleC) ? cursor > -1 ? playerPokemon.getMoveset()[cursor].moveId : Moves.NONE : Moves.STRUGGLE; + args.splice(1, 1); const turnCommand: TurnCommand = { command: Command.FIGHT, cursor: cursor, move: { move: moveId, targets: [], ignorePP: args[0] }, args: args }; const moveTargets: MoveTargetSet = args.length < 3 ? getMoveTargets(playerPokemon, moveId) : args[2]; if (!moveId) @@ -1706,13 +1712,14 @@ 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 + // Decides between a Tormented, Disabled, Not Implemented, or No PP translation message const errorMessage = - playerPokemon.summonData.disabledMove === move.moveId ? 'battle:moveDisabled' : + playerPokemon.summonData.unselectableMove === move.moveId ? 'battle:moveTormented' : playerPokemon.summonData.disabledMove === move.moveId ? 'battle:moveDisabled' : move.getName().endsWith(' (N)') ? 'battle:moveNotImplemented' : 'battle:moveNoPP'; const moveName = move.getName().replace(' (N)', ''); // Trims off the indicator + const pokemonName = playerPokemon.name; - this.scene.ui.showText(i18next.t(errorMessage, { moveName: moveName }), null, () => { + this.scene.ui.showText(i18next.t(errorMessage, { moveName: moveName, pokemonName: pokemonName }), null, () => { this.scene.ui.clearText(); this.scene.ui.setMode(Mode.FIGHT, this.fieldIndex); }, null, true); @@ -1837,10 +1844,17 @@ export class CommandPhase extends FieldPhase { const moveIndex = pokemon.getMoveset().findIndex(m => m.moveId === encoreTag.moveId); - if (moveIndex === -1 || !pokemon.getMoveset()[moveIndex].isUsable(pokemon)) - return false; + if (moveIndex === -1 || (!(pokemon.getMoveset()[moveIndex].ppUsed < pokemon.getMoveset()[moveIndex].getMovePp() || + pokemon.getMoveset()[moveIndex].getMove().pp === -1) && !pokemon.getMoveset()[moveIndex].getMove().name.endsWith(' (N)'))) { + return false; + } - this.handleCommand(Command.FIGHT, moveIndex, false); + + if (!pokemon.getMoveset()[moveIndex].isUsable(pokemon) || !pokemon.getMoveset()[moveIndex].isSelectable(pokemon)) { + this.handleCommand(Command.FIGHT, 0, true, false); + return true; + } + this.handleCommand(Command.FIGHT, moveIndex, false, false); return true; } diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index dfbb9be570b..92f5976479e 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -115,6 +115,7 @@ export default class PokemonData { this.summonData.moveQueue = source.summonData.moveQueue; this.summonData.disabledMove = source.summonData.disabledMove; this.summonData.disabledTurns = source.summonData.disabledTurns; + this.summonData.unselectableMove = source.summonData.unselectableMove; this.summonData.abilitySuppressed = source.summonData.abilitySuppressed; this.summonData.ability = source.summonData.ability; diff --git a/src/ui/fight-ui-handler.ts b/src/ui/fight-ui-handler.ts index 084337b4086..a5c32120083 100644 --- a/src/ui/fight-ui-handler.ts +++ b/src/ui/fight-ui-handler.ts @@ -100,7 +100,7 @@ export default class FightUiHandler extends UiHandler { if (button === Button.CANCEL || button === Button.ACTION) { if (button === Button.ACTION) { - if ((this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, cursor, false)) + if ((this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, cursor, false, false)) success = true; else ui.playError();