From 7c3b88820808f28b10ea3437a7028a76e7f87260 Mon Sep 17 00:00:00 2001 From: frutescens Date: Tue, 24 Sep 2024 14:10:55 -0700 Subject: [PATCH] documentation blah --- src/data/arena-tag.ts | 38 +++++++++++++++++++++++++++++++------- src/data/battler-tags.ts | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 1f935005ad5..432cfdc2b17 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -919,27 +919,47 @@ class SafeguardTag extends ArenaTag { } } +/** + * This arena tag facilitates the application of the move Imprison + * Imprison remains in effect as long as the source Pokemon is active and present on the field. + * Imprison will apply to any opposing Pokemon that switch onto the field as well. + */ class ImprisonTag extends ArenaTrapTag { private source: Pokemon; constructor(sourceId: integer, side: ArenaTagSide) { - console.log(side); super(ArenaTagType.IMPRISON, Moves.IMPRISON, sourceId, side, 1); } - onAdd(arena: Arena) { + /** + * This function applies the effects of Imprison to the opposing Pokemon already present on the field. + * @param arena + */ + override onAdd(arena: Arena) { this.source = arena.scene.getPokemonById(this.sourceId!)!; - const party = !this.source.isPlayer() ? arena.scene.getPlayerField() : arena.scene.getEnemyField(); - party?.forEach((p: PlayerPokemon | EnemyPokemon ) => { - p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId); - }); - arena.scene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", {pokemonNameWithAffix: getPokemonNameWithAffix(this.source)})); + if (this.source) { + const party = !this.source.isPlayer() ? arena.scene.getPlayerField() : arena.scene.getEnemyField(); + party?.forEach((p: PlayerPokemon | EnemyPokemon ) => { + p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId); + }); + arena.scene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", {pokemonNameWithAffix: getPokemonNameWithAffix(this.source)})); + } } + /** + * Checks if the source Pokemon is still active on the field + * @param _arena + * @returns `true` if the source of the tag is still active on the field | `false` if not + */ lapse(_arena: Arena): boolean { return this.source.isActive(true); } + /** + * This applies the effects of Imprison to any opposing Pokemon that switch into the field while the source Pokemon is still active + * @param pokemon the Pokemon Imprison is applied to + * @returns `true` + */ activateTrap(pokemon: Pokemon): boolean { if (this.source.isActive(true)) { pokemon.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId); @@ -947,6 +967,10 @@ class ImprisonTag extends ArenaTrapTag { return true; } + /** + * When the arena tag is removed, it also attempts to remove any related Battler Tags if they haven't already been removed from the affected Pokemon + * @param arena + */ onRemove(arena: Arena): void { const party = !this.source.isPlayer() ? arena.scene.getPlayerField() : arena.scene.getEnemyField(); party?.forEach((p: PlayerPokemon | EnemyPokemon) => { diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 1e98a5874bb..7ec1e966b53 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2455,18 +2455,30 @@ export class TormentTag extends MoveRestrictionBattlerTag { pokemon.scene.queueMessage(i18next.t("battlerTags:tormentOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500); } - override lapse(pokemon: Pokemon, tagType: BattlerTagLapseType): boolean { + /** + * Torment only ends when the affected Pokemon leaves the battle field + * @param pokemon the Pokemon under the effects of Torment + * @param _tagType + * @returns `true` if still present | `false` if not + */ + override lapse(pokemon: Pokemon, _tagType: BattlerTagLapseType): boolean { if (!pokemon.isActive(true)) { return false; } return true; } + /** + * This checks if the current move used is identical to the last used move with a MoveResult of SUCCESS/MISS + * @param move the move under investigation + * @returns `true` if there is valid consecutive usage | `false` if the moves are different from each other + */ isMoveRestricted(move: Moves): boolean { const lastMove = this.target.getLastXMoves(1)[0]; if ( !lastMove ) { return false; } + // This checks for moves like Rollout and Iceball, which are immune to the move restrictions of Torment const isLockedIntoMove = allMoves[lastMove.move].hasAttr(ConsecutiveUseDoublePowerAttr); const validLastMoveResult = (lastMove.result === MoveResult.SUCCESS) || (lastMove.result === MoveResult.MISS); if (lastMove.move === move && validLastMoveResult && lastMove.move !== Moves.STRUGGLE && !isLockedIntoMove) { @@ -2478,6 +2490,8 @@ export class TormentTag extends MoveRestrictionBattlerTag { override selectionDeniedText(_pokemon: Pokemon, move: Moves): string { return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name }); } + + //Torment does not interrupt the move if the move is performed consecutively in the same turn and right after Torment is applied } /** @@ -2495,6 +2509,11 @@ export class TauntTag extends MoveRestrictionBattlerTag { pokemon.scene.queueMessage(i18next.t("battlerTags:tauntOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500); } + /** + * Checks if a move is a status move and determines its restriction status on that basis + * @param move the move under investigation + * @returns `true` if the move is a status move | `false` if not + */ override isMoveRestricted(move: Moves): boolean { return allMoves[move].category === MoveCategory.STATUS; } @@ -2524,15 +2543,26 @@ export class ImprisonTag extends MoveRestrictionBattlerTag { this.source = pokemon.scene.getPokemonById(this.sourceId!)!; } + /** + * Checks if the source of Imprison is still active + * @param _pokemon + * @param _lapseType + * @returns `true` if the source is still active | `false` if not + */ override lapse(_pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean { return this.source.isActive(true); } + /** + * Checks if the source of the tag has the parameter move in its moveset and that the source is still active + * @param move the move under investigation + * @returns `true` if both conditions are met | `false` if either conditions are not met + */ override isMoveRestricted(move: Moves): boolean { const sourceMoveset = this.source.getMoveset().map(m => { return m!.moveId; }); - return sourceMoveset.includes(move); + return sourceMoveset.includes(move) && this.source.isActive(true); } override selectionDeniedText(_pokemon: Pokemon, move: Moves): string {