Prevent `PartyHealPhase` from reviving pokemon in hardcore challenge

Add `SelectModifierPhase` on waves 10, 20, ...
if "No Auto Heal" challenge is active
This commit is contained in:
NightKev 2024-09-19 02:48:14 -07:00
parent f292087d6c
commit c7df07715d
2 changed files with 50 additions and 9 deletions

View File

@ -6,7 +6,7 @@ import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm, speciesStarte
import { Type } from "#app/data/type"; import { Type } from "#app/data/type";
import { TypeColor, TypeShadow } from "#app/enums/color"; import { TypeColor, TypeShadow } from "#app/enums/color";
import { Moves } from "#app/enums/moves"; import { Moves } from "#app/enums/moves";
import Pokemon, { EnemyPokemon, PokemonMove } from "#app/field/pokemon"; import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon";
import Trainer, { TrainerVariant } from "#app/field/trainer"; import Trainer, { TrainerVariant } from "#app/field/trainer";
import { GameMode } from "#app/game-mode"; import { GameMode } from "#app/game-mode";
import { ModifierTypeOption } from "#app/modifier/modifier-type"; import { ModifierTypeOption } from "#app/modifier/modifier-type";
@ -109,6 +109,11 @@ export enum ChallengeType {
* @see {@linkcode Challenge.applyMoveBlacklist} * @see {@linkcode Challenge.applyMoveBlacklist}
*/ */
MOVE_BLACKLIST, MOVE_BLACKLIST,
/**
* Checks if pokemon are allowed to be revived from fainting
* @see {@linkcode Challenge.applyRevivePrevention}
*/
PREVENT_REVIVE,
} }
/** /**
@ -484,6 +489,16 @@ export abstract class Challenge {
applyMoveBlacklist(move: PokemonMove, moveCanBeUsed: BooleanHolder): boolean { applyMoveBlacklist(move: PokemonMove, moveCanBeUsed: BooleanHolder): boolean {
return false; return false;
} }
/**
* An apply function for {@linkcode ChallengeType.PREVENT_REVIVE} challenges. Derived classes should alter this.
* @param pokemon The {@linkcode PlayerPokemon} being revived
* @param canBeRevived {@linkcode BooleanHolder} Whether the pokemon can be revived.
* @returns `true` if this function did anything.
*/
applyRevivePrevention(pokemon: PlayerPokemon, canBeRevived: BooleanHolder): boolean {
return false;
}
} }
type ChallengeCondition = (data: GameData) => boolean; type ChallengeCondition = (data: GameData) => boolean;
@ -883,6 +898,11 @@ export class HardcoreChallenge extends Challenge {
return true; return true;
} }
override applyRevivePrevention(pokemon: PlayerPokemon, canBeRevived: BooleanHolder): boolean {
canBeRevived.value = false;
return true;
}
static override loadChallenge(source: HardcoreChallenge | any): HardcoreChallenge { static override loadChallenge(source: HardcoreChallenge | any): HardcoreChallenge {
const newChallenge = new HardcoreChallenge(); const newChallenge = new HardcoreChallenge();
newChallenge.value = source.value; newChallenge.value = source.value;
@ -1094,6 +1114,15 @@ export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType
* @returns `true` if any challenge was successfully applied. * @returns `true` if any challenge was successfully applied.
*/ */
export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.MOVE_BLACKLIST, move: PokemonMove, moveCanBeUsed: BooleanHolder): boolean; export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.MOVE_BLACKLIST, move: PokemonMove, moveCanBeUsed: BooleanHolder): boolean;
/**
* Apply all challenges that modify if pokemon can be revived.
* @param gameMode The current {@linkcode GameMode}
* @param challengeType {@linkcode ChallengeType.PREVENT_REVIVE}
* @param pokemon The {@linkcode PlayerPokemon} being revived.
* @param canBeRevived {@linkcode BooleanHolder} Whether the pokemon can be revived.
* @returns `true` if any challenge was successfully applied.
*/
export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.PREVENT_REVIVE, pokemon: PlayerPokemon, canBeRevived: BooleanHolder): boolean;
export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType, ...args: any[]): boolean { export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType, ...args: any[]): boolean {
let ret = false; let ret = false;
gameMode.challenges.forEach(c => { gameMode.challenges.forEach(c => {
@ -1153,6 +1182,9 @@ export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType
case ChallengeType.MOVE_BLACKLIST: case ChallengeType.MOVE_BLACKLIST:
ret ||= c.applyMoveBlacklist(args[0], args[1]); ret ||= c.applyMoveBlacklist(args[0], args[1]);
break; break;
case ChallengeType.PREVENT_REVIVE:
ret ||= c.applyRevivePrevention(args[0], args[1]);
break;
} }
} }
}); });

View File

@ -1,6 +1,7 @@
import BattleScene from "#app/battle-scene"; import BattleScene from "#app/battle-scene";
import { applyChallenges, ChallengeType } from "#app/data/challenge"; import { applyChallenges, ChallengeType } from "#app/data/challenge";
import * as Utils from "#app/utils"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
import { BooleanHolder, fixedInt } from "#app/utils";
import { BattlePhase } from "./battle-phase"; import { BattlePhase } from "./battle-phase";
export class PartyHealPhase extends BattlePhase { export class PartyHealPhase extends BattlePhase {
@ -15,9 +16,10 @@ export class PartyHealPhase extends BattlePhase {
start() { start() {
super.start(); super.start();
const isHealPhaseActive = new Utils.BooleanHolder(true); const isHealPhaseActive = new BooleanHolder(true);
applyChallenges(this.scene.gameMode, ChallengeType.NO_HEAL_PHASE, isHealPhaseActive); applyChallenges(this.scene.gameMode, ChallengeType.NO_HEAL_PHASE, isHealPhaseActive);
if (!isHealPhaseActive.value) { if (!isHealPhaseActive.value) {
this.scene.unshiftPhase(new SelectModifierPhase(this.scene));
this.end(); this.end();
return; return;
} }
@ -26,17 +28,24 @@ export class PartyHealPhase extends BattlePhase {
if (bgmPlaying) { if (bgmPlaying) {
this.scene.fadeOutBgm(1000, false); this.scene.fadeOutBgm(1000, false);
} }
const canBeRevived = new BooleanHolder(true);
this.scene.ui.fadeOut(1000).then(() => { this.scene.ui.fadeOut(1000).then(() => {
for (const pokemon of this.scene.getParty()) { for (const pokemon of this.scene.getParty()) {
pokemon.hp = pokemon.getMaxHp(); applyChallenges(this.scene.gameMode, ChallengeType.PREVENT_REVIVE, pokemon, canBeRevived);
pokemon.resetStatus(); if (canBeRevived.value || !pokemon.isFainted()) {
for (const move of pokemon.moveset) { pokemon.hp = pokemon.getMaxHp();
move!.ppUsed = 0; // TODO: is this bang correct? pokemon.resetStatus();
for (const move of pokemon.moveset) {
if (move) {
move.ppUsed = 0;
}
}
pokemon.updateInfo(true);
} }
pokemon.updateInfo(true);
} }
const healSong = this.scene.playSoundWithoutBgm("heal"); const healSong = this.scene.playSoundWithoutBgm("heal");
this.scene.time.delayedCall(Utils.fixedInt(healSong.totalDuration * 1000), () => { this.scene.time.delayedCall(fixedInt(healSong.totalDuration * 1000), () => {
healSong.destroy(); healSong.destroy();
if (this.resumeBgm && bgmPlaying) { if (this.resumeBgm && bgmPlaying) {
this.scene.playBgm(); this.scene.playBgm();