Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Challenge] Add Trick room challenge #4343

Open
wants to merge 11 commits into
base: beta
Choose a base branch
from
3,987 changes: 2,004 additions & 1,983 deletions public/images/items.json

Large diffs are not rendered by default.

Binary file modified public/images/items.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
71 changes: 71 additions & 0 deletions src/data/challenge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Moves } from "#app/enums/moves";
import { TypeColor, TypeShadow } from "#app/enums/color";
import { pokemonEvolutions } from "./pokemon-evolutions";
import { pokemonFormChanges } from "./pokemon-forms";
import { Stat } from "#enums/stat";

/** A constant for the default max cost of the starting party before a run */
const DEFAULT_PARTY_MAX_COST = 10;
Expand Down Expand Up @@ -59,6 +60,11 @@ export enum ChallengeType {
* @see {@linkcode Challenge.applyTypeEffectiveness}
*/
TYPE_EFFECTIVENESS,
/**
* Challenge that enables Trick Room in a run
* @see {@link https://bulbapedia.bulbagarden.net/wiki/Trick_Room_(move)}
*/
TRICK_ROOM,
/**
* Modifies what level the AI pokemon are. UNIMPLEMENTED.
*/
Expand Down Expand Up @@ -340,6 +346,15 @@ export abstract class Challenge {
return false;
}

/**
* An apply function for TRICK_ROOM challenges. Derived classes should alter this.
* @param isTrickRoom {@link Utils.BooleanHolder} Whether the battle is under the effect of Trick Room.
* @returns `true` if this function did anything.
*/
applyTrickRoom(isTrickRoom: Utils.BooleanHolder): boolean {
KimJeongSun marked this conversation as resolved.
Show resolved Hide resolved
return false;
}

/**
* An apply function for AI_LEVEL challenges. Derived classes should alter this.
* @param level {@link Utils.IntegerHolder} The generated level.
Expand Down Expand Up @@ -707,6 +722,48 @@ export class InverseBattleChallenge extends Challenge {
}
}

/**
* Challenge that enables Trick Room in a run
*/
export class TrickRoomChallenge extends Challenge {
constructor() {
super(Challenges.TRICK_ROOM, 1);
}

static loadChallenge(source: TrickRoomChallenge | any): TrickRoomChallenge {
const newChallenge = new TrickRoomChallenge();
newChallenge.value = source.value;
newChallenge.severity = source.severity;
return newChallenge;
}

override getDifficulty(): number {
return 0;
}

/**
* @override
* this challenge inverts the Speed IV of the pokemon.
* @param pokemon {@link Pokemon} The pokemon to modify.
* @returns `true` if any challenge was successfully applied.
*/
override applyStarterModify(pokemon: Pokemon): boolean {
pokemon.ivs[Stat.SPD] = 31 - pokemon.ivs[Stat.SPD];
return true;
}

/**
* @override
* this challenge inverts whether the battle is under the effect of Trick Room.
* @param isTrickRoom {@link Utils.BooleanHolder} Whether the battle is under the effect of Trick Room.
* @returns `true` if any challenge was successfully applied.
*/
override applyTrickRoom(isTrickRoom: Utils.BooleanHolder): boolean {
isTrickRoom.value = !isTrickRoom.value;
return true;
}
}

/**
* Lowers the amount of starter points available.
*/
Expand Down Expand Up @@ -834,6 +891,14 @@ export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType
* @returns True if any challenge was successfully applied.
*/
export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.TYPE_EFFECTIVENESS, effectiveness: Utils.NumberHolder): boolean;
/**
* Apply all challenges that modify Trick Room.
* @param gameMode The current {@linkcode GameMode}
* @param challengeType {@linkcode ChallengeType.TRICK_ROOM}
* @param isTrickRoom {@linkcode Utils.BooleanHolder} Whether the battle is under the effect of Trick Room.
* @returns `true` if any challenge was successfully applied.
*/
export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType.TRICK_ROOM, isTrickRoom: Utils.BooleanHolder): boolean;
/**
* Apply all challenges that modify what level AI are.
* @param gameMode {@link GameMode} The current gameMode
Expand Down Expand Up @@ -918,6 +983,9 @@ export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType
case ChallengeType.TYPE_EFFECTIVENESS:
ret ||= c.applyTypeEffectiveness(args[0]);
break;
case ChallengeType.TRICK_ROOM:
ret ||= c.applyTrickRoom(args[0]);
break;
case ChallengeType.AI_LEVEL:
ret ||= c.applyLevelChange(args[0], args[1], args[2], args[3]);
break;
Expand Down Expand Up @@ -961,6 +1029,8 @@ export function copyChallenge(source: Challenge | any): Challenge {
return FreshStartChallenge.loadChallenge(source);
case Challenges.INVERSE_BATTLE:
return InverseBattleChallenge.loadChallenge(source);
case Challenges.TRICK_ROOM:
return TrickRoomChallenge.loadChallenge(source);
}
throw new Error("Unknown challenge copied");
}
Expand All @@ -973,5 +1043,6 @@ export function initChallenges() {
new SingleTypeChallenge(),
new FreshStartChallenge(),
new InverseBattleChallenge(),
new TrickRoomChallenge(),
);
}
1 change: 1 addition & 0 deletions src/enums/challenges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export enum Challenges {
LOWER_STARTER_POINTS,
FRESH_START,
INVERSE_BATTLE,
TRICK_ROOM,
}
4 changes: 4 additions & 0 deletions src/locales/en/achv.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,10 @@
"name": "Mirror rorriM",
"description": "Complete the Inverse Battle challenge.\n.egnellahc elttaB esrevnI eht etelpmoC"
},
"TRICK_ROOM": {
"name": "You're Too Fast!",
"description": "Complete the Trick Room challenge."
},
"BREEDERS_IN_SPACE": {
"name": "Breeders in Space!",
"description": "Beat the Expert Pokémon Breeder in the Space Biome."
Expand Down
7 changes: 7 additions & 0 deletions src/locales/en/challenges.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,12 @@
"desc": "Type matchups are reversed and no type is immune to any other type.\nDisables other challenges' achievements.",
"value.0": "Off",
"value.1": "On"
},
"trickRoom": {
"name": "Trick Room",
"shortName": "Trick Room",
"desc": "All battles are under the effect of Trick Room, where slower Pokémon move sooner and faster Pokémon move later.\nDisables other challenges' achievements.",
"value.0": "Off",
"value.1": "On"
}
}
2 changes: 2 additions & 0 deletions src/phases/turn-start-phase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { TurnEndPhase } from "./turn-end-phase";
import { WeatherEffectPhase } from "./weather-effect-phase";
import { BattlerIndex } from "#app/battle";
import { TrickRoomTag } from "#app/data/arena-tag";
import { applyChallenges, ChallengeType } from "#app/data/challenge";

export class TurnStartPhase extends FieldPhase {
constructor(scene: BattleScene) {
Expand Down Expand Up @@ -52,6 +53,7 @@ export class TurnStartPhase extends FieldPhase {
// Next, a check for Trick Room is applied. If Trick Room is present, the order is reversed.
const speedReversed = new Utils.BooleanHolder(false);
this.scene.arena.applyTags(TrickRoomTag, speedReversed);
applyChallenges(this.scene.gameMode, ChallengeType.TRICK_ROOM, speedReversed);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think optimize this you should instead do that check before orderedTargets.sort is ran and adjust the sort function instead. Cause afaik the reverse() + a sort before takes quite some resources

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

how about this?


    // Next, a check for Trick Room is applied to determine sort order.
    const speedReversed = new Utils.BooleanHolder(false);
    this.scene.arena.applyTags(TrickRoomTag, speedReversed);
    applyChallenges(this.scene.gameMode, ChallengeType.TRICK_ROOM, speedReversed);

    // Adjust the sort function based on whether Trick Room is active.
    orderedTargets.sort((a: Pokemon, b: Pokemon) => {
      const aSpeed = a?.getEffectiveStat(Stat.SPD) || 0;
      const bSpeed = b?.getEffectiveStat(Stat.SPD) || 0;

      return speedReversed.value ? aSpeed - bSpeed : bSpeed - aSpeed;
    });


if (speedReversed.value) {
orderedTargets = orderedTargets.reverse();
Expand Down
Loading
Loading