Updated No Free heal challenge to implement two other modes and applied minor adjustments on challenge.ts file

Signed-off-by: Matilde Simões <matilde.simoes@tecnico.ulisboa.pt>
    Co-authored-by: Fuad Ali <fuad.ali@tecnico.ulisboa.pt>
This commit is contained in:
Matilde Simões 2025-07-02 20:20:41 +01:00
parent 68e1ee84f9
commit c4c4fdfd21
3 changed files with 73 additions and 26 deletions

View File

@ -1,4 +1,4 @@
import { BooleanHolder, type NumberHolder, randSeedItem } from "#app/utils/common";
import { BooleanHolder, type NumberHolder, randSeedItem, isNullOrUndefined } from "#app/utils/common";
import { deepCopy } from "#app/utils/data";
import i18next from "i18next";
import type { DexAttrProps, GameData } from "#app/system/game-data";
@ -357,13 +357,22 @@ export abstract class Challenge {
return false;
}
/**
* An apply function for NO_SHOP_PHASE. Derived classes should alter this.
* @param _applyShopPhase {@link BooleanHolder} Whether it should apply the shop phase.
* @returns {@link boolean} if this function did anything.
*/
applyNoShopPhase(_applyShopPhase: BooleanHolder): boolean {
return false;
}
/**
* An apply function for PREVENT_REVIVE. Derived classes should alter this.
* @param _canBeRevived {@link BooleanHolder} Whether it should revive the fainted Pokemon.
* @returns {@link boolean} if this function did anything.
*/
applyRevivePrevention(_canBeRevived: BooleanHolder): boolean {
return true;
return false;
}
/**
@ -974,13 +983,24 @@ export class LowerStarterPointsChallenge extends Challenge {
*/
export class NoFreeHealsChallenge extends Challenge {
constructor() {
super(Challenges.NO_AUTO_HEAL, 1);
super(Challenges.NO_AUTO_HEAL, 3);
}
applyNoHealPhase(applyHealPhase: BooleanHolder): boolean {
if (this.value !== 1) {
applyHealPhase.value = false;
return true;
}
return false;
}
applyNoShopPhase(applyShopPhase: BooleanHolder): boolean {
if (this.value !== 2) {
applyShopPhase.value = false;
return true;
}
return false;
}
static loadChallenge(source: NoFreeHealsChallenge | any): NoFreeHealsChallenge {
const newChallenge = new NoFreeHealsChallenge();
@ -1001,6 +1021,8 @@ export class HardcoreChallenge extends Challenge {
"modifierType:ModifierType.REVIVER_SEED",
];
private moveBlacklist = [MoveId.REVIVAL_BLESSING];
constructor() {
super(Challenges.HARDCORE, 2);
}
@ -1018,10 +1040,12 @@ export class HardcoreChallenge extends Challenge {
}
applyMoveBlacklist(move: PokemonMove, moveCanBeUsed: BooleanHolder): boolean {
const moveBlacklist = [MoveId.REVIVAL_BLESSING];
moveCanBeUsed.value = !moveBlacklist.includes(move.moveId);
if (this.moveBlacklist.includes(move.moveId)) {
moveCanBeUsed.value = false;
return true;
}
return false;
}
applyRevivePrevention(canBeRevived: BooleanHolder): boolean {
canBeRevived.value = false;
@ -1033,16 +1057,18 @@ export class HardcoreChallenge extends Challenge {
canStay.value = false;
} else {
canStay.value = true;
}
return true;
}
return false;
}
override applyShouldFuse(pokemon: Pokemon, pokemonToFuse: Pokemon, canFuse: BooleanHolder): boolean {
if (pokemon!.isFainted() || pokemonToFuse.isFainted()) {
canFuse.value = false;
}
return true;
}
return false;
}
static override loadChallenge(source: HardcoreChallenge | any): HardcoreChallenge {
const newChallenge = new HardcoreChallenge();
@ -1068,15 +1094,18 @@ export class LimitedCatchChallenge extends Challenge {
}
override applyAddPokemonToParty(waveIndex: number, canAddToParty: BooleanHolder): boolean {
if (waveIndex % 10 !== 1) {
const lastMystery = globalScene.lastMysteryEncounter?.encounterType;
if (lastMystery === undefined && !(waveIndex % 10 === 1)) {
if (
isNullOrUndefined(lastMystery) ||
!(waveIndex % 10 === 2 && !this.mysteryEncounterBlacklist.includes(lastMystery!))
) {
canAddToParty.value = false;
}
if (!(waveIndex % 10 === 1) && !(!this.mysteryEncounterBlacklist.includes(lastMystery!) && waveIndex % 10 === 2)) {
canAddToParty.value = false;
}
return true;
}
return false;
}
}
static override loadChallenge(source: LimitedCatchChallenge | any): LimitedCatchChallenge {
const newChallenge = new LimitedCatchChallenge();
@ -1244,6 +1273,14 @@ export function applyChallenges(challengeType: ChallengeType.FLIP_STAT, pokemon:
* @returns True if any challenge was successfully applied.
*/
export function applyChallenges(challengeType: ChallengeType.NO_HEAL_PHASE, applyHealPhase: BooleanHolder): boolean;
/**
* Apply all challenges that modify whether the shop will appear.
* @param challengeType {@link ChallengeType} ChallengeType.NO_SHOP_PHASE
* @param applyShopPhase {@link BooleanHolder} Whether it should apply the shop phase.
* @returns True if any challenge was successfully applied.
*/
export function applyChallenges(challengeType: ChallengeType.NO_SHOP_PHASE, applyShopPhase: BooleanHolder): boolean;
/**
* Apply all challenges that modify whether a shop item should be blacklisted.
* @param challengeType {@link ChallengeType} ChallengeType.SHOP_ITEM_BLACKLIST
@ -1372,6 +1409,9 @@ export function applyChallenges(challengeType: ChallengeType, ...args: any[]): b
case ChallengeType.NO_HEAL_PHASE:
ret ||= c.applyNoHealPhase(args[0]);
break;
case ChallengeType.NO_SHOP_PHASE:
ret ||= c.applyNoShopPhase(args[0]);
break;
case ChallengeType.SHOP_ITEM_BLACKLIST:
ret ||= c.applyShopItemBlacklist(args[0], args[1]);
break;

View File

@ -70,6 +70,10 @@ export enum ChallengeType {
* Challenge that modifies if the player should auto heal every 10th wave
*/
NO_HEAL_PHASE,
/**
* Challenge that modifies if the shop should appear
*/
NO_SHOP_PHASE,
/**
* Modifies if the shop item is blacklisted
* @see {@linkcode Challenge.applyShopItemBlacklist}

View File

@ -214,7 +214,10 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
const removeHealShop = globalScene.gameMode.hasNoShop;
const baseShopCost = new NumberHolder(globalScene.getWaveMoneyAmount(1));
globalScene.applyModifier(HealShopCostModifier, true, baseShopCost);
const shopTypeOptions = removeHealShop
const isShopActive = new BooleanHolder(true);
applyChallenges(ChallengeType.NO_SHOP_PHASE, isShopActive);
const shopTypeOptions =
removeHealShop || !isShopActive.value
? []
: getPlayerShopModifierTypeOptionsForWave(globalScene.currentBattle.waveIndex, baseShopCost.value).filter(
shopItem => {