they call it torment because that's what its like to implement this move

pull/761/head
f-raZ0R 2024-05-11 20:28:31 -04:00
parent 8a71fe1e9f
commit f91ca41636
6 changed files with 59 additions and 28 deletions

View File

@ -505,6 +505,7 @@ export class TormentedTag extends BattlerTag {
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
if (pokemon.isMax()) if (pokemon.isMax())
return false; return false;
else
return true; return true;
} }
@ -515,21 +516,25 @@ export class TormentedTag extends BattlerTag {
onOverlap(pokemon: Pokemon): void { onOverlap(pokemon: Pokemon): void {
super.onOverlap(pokemon); 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 { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) { if (ret) {
const lastMove = pokemon.getLastXMoves(1)[0]; const lastMove = pokemon.getLastXMoves(1)[0];
if (!lastMove) if (!lastMove || (lastMove.move === Moves.NONE))
return ret; return ret;
pokemon.summonData.disabledMove = lastMove.move; if (lastMove.move === Moves.STRUGGLE) {
pokemon.summonData.disabledTurns = 2; pokemon.summonData.unselectableMove = Moves.NONE;
}
//pokemon.scene.queueMessage(disabledMove.getName(), `TORMENT TEST`); else {
pokemon.summonData.unselectableMove = lastMove.move;
}
return ret; return ret;
} }
} }

View File

@ -1185,11 +1185,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.scene.triggerPokemonFormChange(this, SpeciesFormChangeMoveLearnedTrigger); 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 const move = this.getMoveset().length > moveIndex
? this.getMoveset()[moveIndex] ? this.getMoveset()[moveIndex]
: null; : null;
return move?.isUsable(this, ignorePp); return move?.isUsable(this, ignorePp) && (move?.isSelectable(this, ignorePp) || skipSelection);
} }
showInfo(): void { 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) {
if (movePool.length === 1)
return { move: movePool[0].moveId, targets: this.getNextTargets(movePool[0].moveId) };
const encoreTag = this.getTag(EncoreTag) as EncoreTag; const encoreTag = this.getTag(EncoreTag) as EncoreTag;
if (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); const encoreMove = movePool.find(m => m.moveId === encoreTag.moveId);
if (encoreMove) if (encoreMove)
return { move: encoreMove.moveId, targets: this.getNextTargets(encoreMove.moveId) }; 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) { switch (this.aiType) {
case AiType.RANDOM: case AiType.RANDOM:
const moveId = movePool[this.scene.randBattleSeedInt(movePool.length)].moveId; const moveId = movePool[this.scene.randBattleSeedInt(movePool.length)].moveId;
@ -3138,6 +3141,7 @@ export class PokemonSummonData {
public moveQueue: QueuedMove[] = []; public moveQueue: QueuedMove[] = [];
public disabledMove: Moves = Moves.NONE; public disabledMove: Moves = Moves.NONE;
public disabledTurns: integer = 0; public disabledTurns: integer = 0;
public unselectableMove: Moves = Moves.NONE;
public tags: BattlerTag[] = []; public tags: BattlerTag[] = [];
public abilitySuppressed: boolean = false; 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)'); 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 { getMove(): Move {
return allMoves[this.moveId]; return allMoves[this.moveId];
} }

View File

@ -35,6 +35,7 @@ export const battle: SimpleTranslationEntries = {
"moveNotImplemented": "{{moveName}} is not yet implemented and cannot be selected.", "moveNotImplemented": "{{moveName}} is not yet implemented and cannot be selected.",
"moveNoPP": "There's no PP left for\nthis move!", "moveNoPP": "There's no PP left for\nthis move!",
"moveDisabled": "{{moveName}} is disabled!", "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.", "noPokeballForce": "An unseen force\nprevents using Poké Balls.",
"noPokeballTrainer": "You can't catch\nanother trainer's Pokémon!", "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!", "noPokeballMulti": "You can only throw a Poké Ball\nwhen there is one Pokémon remaining!",

View File

@ -1664,11 +1664,11 @@ export class CommandPhase extends FieldPhase {
if (moveQueue.length) { if (moveQueue.length) {
const queuedMove = moveQueue[0]; const queuedMove = moveQueue[0];
if (!queuedMove.move) if (!queuedMove.move)
this.handleCommand(Command.FIGHT, -1, false); this.handleCommand(Command.FIGHT, -1, false, false);
else { else {
const moveIndex = playerPokemon.getMoveset().findIndex(m => m.moveId === queuedMove.move); const moveIndex = playerPokemon.getMoveset().findIndex(m => m.moveId === queuedMove.move);
if (moveIndex > -1 && playerPokemon.getMoveset()[moveIndex].isUsable(playerPokemon, queuedMove.ignorePP)) { 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 } else
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex); 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 playerPokemon = this.scene.getPlayerField()[this.fieldIndex];
const enemyField = this.scene.getEnemyField(); const enemyField = this.scene.getEnemyField();
let success: boolean; let success: boolean;
switch (command) { switch (command) {
case Command.FIGHT: 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 || if (cursor === -1 ||
playerPokemon.trySelectMove(cursor, args[0] as boolean) || playerPokemon.trySelectMove(cursor, args[0] as boolean, args[1] as boolean) ||
(useStruggle = cursor > -1 && !playerPokemon.getMoveset().filter(m => m.isUsable(playerPokemon)).length)) { (useStruggleA = cursor > -1 && (!playerPokemon.getMoveset().filter(m => m.isSelectable(playerPokemon)).length) && !args[1]) ||
const moveId = !useStruggle ? cursor > -1 ? playerPokemon.getMoveset()[cursor].moveId : Moves.NONE : Moves.STRUGGLE; (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 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]; const moveTargets: MoveTargetSet = args.length < 3 ? getMoveTargets(playerPokemon, moveId) : args[2];
if (!moveId) if (!moveId)
@ -1706,13 +1712,14 @@ export class CommandPhase extends FieldPhase {
const move = playerPokemon.getMoveset()[cursor]; const move = playerPokemon.getMoveset()[cursor];
this.scene.ui.setMode(Mode.MESSAGE); 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 = 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'; move.getName().endsWith(' (N)') ? 'battle:moveNotImplemented' : 'battle:moveNoPP';
const moveName = move.getName().replace(' (N)', ''); // Trims off the indicator 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.clearText();
this.scene.ui.setMode(Mode.FIGHT, this.fieldIndex); this.scene.ui.setMode(Mode.FIGHT, this.fieldIndex);
}, null, true); }, null, true);
@ -1837,10 +1844,17 @@ export class CommandPhase extends FieldPhase {
const moveIndex = pokemon.getMoveset().findIndex(m => m.moveId === encoreTag.moveId); const moveIndex = pokemon.getMoveset().findIndex(m => m.moveId === encoreTag.moveId);
if (moveIndex === -1 || !pokemon.getMoveset()[moveIndex].isUsable(pokemon)) if (moveIndex === -1 || (!(pokemon.getMoveset()[moveIndex].ppUsed < pokemon.getMoveset()[moveIndex].getMovePp() ||
return false; 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; return true;
} }

View File

@ -115,6 +115,7 @@ export default class PokemonData {
this.summonData.moveQueue = source.summonData.moveQueue; this.summonData.moveQueue = source.summonData.moveQueue;
this.summonData.disabledMove = source.summonData.disabledMove; this.summonData.disabledMove = source.summonData.disabledMove;
this.summonData.disabledTurns = source.summonData.disabledTurns; this.summonData.disabledTurns = source.summonData.disabledTurns;
this.summonData.unselectableMove = source.summonData.unselectableMove;
this.summonData.abilitySuppressed = source.summonData.abilitySuppressed; this.summonData.abilitySuppressed = source.summonData.abilitySuppressed;
this.summonData.ability = source.summonData.ability; this.summonData.ability = source.summonData.ability;

View File

@ -100,7 +100,7 @@ export default class FightUiHandler extends UiHandler {
if (button === Button.CANCEL || button === Button.ACTION) { if (button === Button.CANCEL || button === Button.ACTION) {
if (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; success = true;
else else
ui.playError(); ui.playError();