mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-10 17:39:31 +02:00
Merge branch 'beta' into pokerouge
This commit is contained in:
commit
aa240bfdf5
@ -1 +1 @@
|
||||
Subproject commit fa35780fed762017c89d1e9ece8a2779dff56c4d
|
||||
Subproject commit ab2716d5440c25f73986664aa3f3131821c3c392
|
@ -16,7 +16,7 @@ export type * from "#moves/move";
|
||||
* Map of move subclass names to their respective classes.
|
||||
* Does not include the ChargeMove subclasses. For that, use `ChargingMoveClassMap`.
|
||||
*
|
||||
* @privateremarks
|
||||
* @privateRemarks
|
||||
* The `never` field (`declare private _: never`) in some classes is necessary
|
||||
* to ensure typescript does not improperly narrow a failed `is` guard to `never`.
|
||||
*
|
||||
|
@ -242,8 +242,8 @@ export class BattleScene extends SceneBase {
|
||||
public battleStyle: BattleStyle = BattleStyle.SWITCH;
|
||||
/**
|
||||
* Defines whether or not to show type effectiveness hints
|
||||
* - true: No hints
|
||||
* - false: Show hints for moves
|
||||
* - true: Show hints for moves
|
||||
* - false: No hints
|
||||
*/
|
||||
public typeHints = false;
|
||||
|
||||
|
@ -1284,7 +1284,7 @@ export class PostDefendContactApplyTagChanceAbAttr extends PostDefendAbAttr {
|
||||
/**
|
||||
* Set stat stages when the user gets hit by a critical hit
|
||||
*
|
||||
* @privateremarks
|
||||
* @privateRemarks
|
||||
* It is the responsibility of the caller to ensure that this ability attribute is only applied
|
||||
* when the user has been hit by a critical hit; such an event is not checked here.
|
||||
*
|
||||
@ -2043,7 +2043,7 @@ export class AllyStatMultiplierAbAttr extends AbAttr {
|
||||
|
||||
/**
|
||||
* @param stat - The stat being modified
|
||||
* @param multipler - The multiplier to apply to the stat
|
||||
* @param multiplier - The multiplier to apply to the stat
|
||||
* @param ignorable - Whether the multiplier can be ignored by mold breaker-like moves and abilities
|
||||
*/
|
||||
constructor(stat: BattleStat, multiplier: number, ignorable = true) {
|
||||
@ -6444,23 +6444,23 @@ export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr {
|
||||
public override canApply({ pokemon, source, damage }: PostDamageAbAttrParams): boolean {
|
||||
const moveHistory = pokemon.getMoveHistory();
|
||||
// Will not activate when the Pokémon's HP is lowered by cutting its own HP
|
||||
const fordbiddenAttackingMoves = [MoveId.BELLY_DRUM, MoveId.SUBSTITUTE, MoveId.CURSE, MoveId.PAIN_SPLIT];
|
||||
const forbiddenAttackingMoves = [MoveId.BELLY_DRUM, MoveId.SUBSTITUTE, MoveId.CURSE, MoveId.PAIN_SPLIT];
|
||||
if (moveHistory.length > 0) {
|
||||
const lastMoveUsed = moveHistory[moveHistory.length - 1];
|
||||
if (fordbiddenAttackingMoves.includes(lastMoveUsed.move)) {
|
||||
if (forbiddenAttackingMoves.includes(lastMoveUsed.move)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Dragon Tail and Circle Throw switch out Pokémon before the Ability activates.
|
||||
const fordbiddenDefendingMoves = [MoveId.DRAGON_TAIL, MoveId.CIRCLE_THROW];
|
||||
const forbiddenDefendingMoves = [MoveId.DRAGON_TAIL, MoveId.CIRCLE_THROW];
|
||||
if (source) {
|
||||
const enemyMoveHistory = source.getMoveHistory();
|
||||
if (enemyMoveHistory.length > 0) {
|
||||
const enemyLastMoveUsed = enemyMoveHistory[enemyMoveHistory.length - 1];
|
||||
// Will not activate if the Pokémon's HP falls below half while it is in the air during Sky Drop.
|
||||
if (
|
||||
fordbiddenDefendingMoves.includes(enemyLastMoveUsed.move) ||
|
||||
forbiddenDefendingMoves.includes(enemyLastMoveUsed.move) ||
|
||||
(enemyLastMoveUsed.move === MoveId.SKY_DROP && enemyLastMoveUsed.result === MoveResult.OTHER)
|
||||
) {
|
||||
return false;
|
||||
|
@ -46,7 +46,7 @@ import {
|
||||
} from "#mystery-encounters/mystery-encounter-requirements";
|
||||
import { getRandomPartyMemberFunc, trainerConfigs } from "#trainers/trainer-config";
|
||||
import { TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#trainers/trainer-party-template";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { MoveInfoOverlay } from "#ui/move-info-overlay";
|
||||
import { isNullOrUndefined, randSeedInt, randSeedShuffle } from "#utils/common";
|
||||
import i18next from "i18next";
|
||||
|
@ -45,7 +45,7 @@ import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option";
|
||||
import { trainerConfigs } from "#trainers/trainer-config";
|
||||
import { TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#trainers/trainer-party-template";
|
||||
import type { OptionSelectConfig } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectConfig } from "#ui/abstract-option-select-ui-handler";
|
||||
import { randSeedInt, randSeedShuffle } from "#utils/common";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
import i18next from "i18next";
|
||||
|
@ -37,7 +37,7 @@ import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encou
|
||||
import { MoveRequirement } from "#mystery-encounters/mystery-encounter-requirements";
|
||||
import { DANCING_MOVES } from "#mystery-encounters/requirement-groups";
|
||||
import { PokemonData } from "#system/pokemon-data";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
import i18next from "i18next";
|
||||
|
||||
|
@ -33,7 +33,7 @@ import {
|
||||
MoneyRequirement,
|
||||
} from "#mystery-encounters/mystery-encounter-requirements";
|
||||
import i18next from "#plugins/i18n";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { randSeedItem } from "#utils/common";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import i18next from "i18next";
|
||||
|
||||
/** i18n namespace for the encounter */
|
||||
|
@ -42,7 +42,7 @@ import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encou
|
||||
import { PartySizeRequirement } from "#mystery-encounters/mystery-encounter-requirements";
|
||||
import { PokemonData } from "#system/pokemon-data";
|
||||
import { MusicPreference } from "#system/settings";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { isNullOrUndefined, NumberHolder, randInt, randSeedInt, randSeedItem, randSeedShuffle } from "#utils/common";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
import i18next from "i18next";
|
||||
|
@ -27,7 +27,7 @@ import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option";
|
||||
import { PokemonData } from "#system/pokemon-data";
|
||||
import type { HeldModifierConfig } from "#types/held-modifier-config";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { isNullOrUndefined, randSeedShuffle } from "#utils/common";
|
||||
import { getEnumValues } from "#utils/enums";
|
||||
import i18next from "i18next";
|
||||
|
@ -156,7 +156,7 @@ export class MysteryEncounterOption implements IMysteryEncounterOption {
|
||||
return true;
|
||||
}
|
||||
console.log(
|
||||
"Mystery Encounter Edge Case: Requirement not met due to primay pokemon overlapping with support pokemon. There's no valid primary pokemon left.",
|
||||
"Mystery Encounter Edge Case: Requirement not met due to primary pokemon overlapping with support pokemon. There's no valid primary pokemon left.",
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
@ -576,7 +576,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
||||
*/
|
||||
|
||||
/**
|
||||
* @statif Defines the type of encounter which is used as an identifier, should be tied to a unique MysteryEncounterType
|
||||
* @static Defines the type of encounter which is used as an identifier, should be tied to a unique MysteryEncounterType
|
||||
* NOTE: if new functions are added to {@linkcode MysteryEncounter} class
|
||||
* @param encounterType
|
||||
* @returns this
|
||||
@ -605,7 +605,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an option + phasefor the encounter.
|
||||
* Defines an option + phase for the encounter.
|
||||
* Use for easy/streamlined options.
|
||||
* There should be at least 2 options defined and no more than 4.
|
||||
* If complex use {@linkcode MysteryEncounterBuilder.withOption}
|
||||
@ -627,7 +627,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an option + phasefor the encounter.
|
||||
* Defines an option + phase for the encounter.
|
||||
* Use for easy/streamlined options.
|
||||
* There should be at least 2 options defined and no more than 4.
|
||||
* If complex use {@linkcode MysteryEncounterBuilder.withOption}
|
||||
|
@ -6,7 +6,7 @@ import { isNullOrUndefined } from "#utils/common";
|
||||
import i18next from "i18next";
|
||||
|
||||
/**
|
||||
* Will inject all relevant dialogue tokens that exist in the {@linkcode BattlegScene.currentBattle.mysteryEncounter.dialogueTokens}, into i18n text.
|
||||
* Will inject all relevant dialogue tokens that exist in the {@linkcode globalScene.currentBattle.mysteryEncounter.dialogueTokens}, into i18n text.
|
||||
* Also adds BBCodeText fragments for colored text, if applicable
|
||||
* @param keyOrString
|
||||
* @param primaryStyle Can define a text style to be applied to the entire string. Must be defined for BBCodeText styles to be applied correctly
|
||||
|
@ -46,7 +46,7 @@ import type { PokemonData } from "#system/pokemon-data";
|
||||
import type { TrainerConfig } from "#trainers/trainer-config";
|
||||
import { trainerConfigs } from "#trainers/trainer-config";
|
||||
import type { HeldModifierConfig } from "#types/held-modifier-config";
|
||||
import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import type { PartyOption, PokemonSelectFilter } from "#ui/party-ui-handler";
|
||||
import { PartyUiMode } from "#ui/party-ui-handler";
|
||||
import { coerceArray, isNullOrUndefined, randomString, randSeedInt, randSeedItem } from "#utils/common";
|
||||
|
@ -4045,7 +4045,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
* @param damage integer
|
||||
* @param ignoreSegments boolean, not currently used
|
||||
* @param preventEndure used to update damage if endure or sturdy
|
||||
* @param ignoreFaintPhas flag on whether to add FaintPhase if pokemon after applying damage faints
|
||||
* @param ignoreFaintPhase flag on whether to add FaintPhase if pokemon after applying damage faints
|
||||
* @returns integer representing damage dealt
|
||||
*/
|
||||
damage(damage: number, _ignoreSegments = false, preventEndure = false, ignoreFaintPhase = false): number {
|
||||
@ -5206,38 +5206,38 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
}
|
||||
|
||||
updateFusionPalette(ignoreOveride?: boolean): void {
|
||||
if (!this.getFusionSpeciesForm(ignoreOveride)) {
|
||||
updateFusionPalette(ignoreOverride?: boolean): void {
|
||||
if (!this.getFusionSpeciesForm(ignoreOverride)) {
|
||||
[this.getSprite(), this.getTintSprite()]
|
||||
.filter(s => !!s)
|
||||
.map(s => {
|
||||
s.pipelineData[`spriteColors${ignoreOveride && this.summonData.speciesForm ? "Base" : ""}`] = [];
|
||||
s.pipelineData[`fusionSpriteColors${ignoreOveride && this.summonData.speciesForm ? "Base" : ""}`] = [];
|
||||
s.pipelineData[`spriteColors${ignoreOverride && this.summonData.speciesForm ? "Base" : ""}`] = [];
|
||||
s.pipelineData[`fusionSpriteColors${ignoreOverride && this.summonData.speciesForm ? "Base" : ""}`] = [];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const speciesForm = this.getSpeciesForm(ignoreOveride);
|
||||
const fusionSpeciesForm = this.getFusionSpeciesForm(ignoreOveride);
|
||||
const speciesForm = this.getSpeciesForm(ignoreOverride);
|
||||
const fusionSpeciesForm = this.getFusionSpeciesForm(ignoreOverride);
|
||||
|
||||
const spriteKey = speciesForm.getSpriteKey(
|
||||
this.getGender(ignoreOveride) === Gender.FEMALE,
|
||||
this.getGender(ignoreOverride) === Gender.FEMALE,
|
||||
speciesForm.formIndex,
|
||||
this.shiny,
|
||||
this.variant,
|
||||
);
|
||||
const backSpriteKey = speciesForm
|
||||
.getSpriteKey(this.getGender(ignoreOveride) === Gender.FEMALE, speciesForm.formIndex, this.shiny, this.variant)
|
||||
.getSpriteKey(this.getGender(ignoreOverride) === Gender.FEMALE, speciesForm.formIndex, this.shiny, this.variant)
|
||||
.replace("pkmn__", "pkmn__back__");
|
||||
const fusionSpriteKey = fusionSpeciesForm.getSpriteKey(
|
||||
this.getFusionGender(ignoreOveride) === Gender.FEMALE,
|
||||
this.getFusionGender(ignoreOverride) === Gender.FEMALE,
|
||||
fusionSpeciesForm.formIndex,
|
||||
this.fusionShiny,
|
||||
this.fusionVariant,
|
||||
);
|
||||
const fusionBackSpriteKey = fusionSpeciesForm
|
||||
.getSpriteKey(
|
||||
this.getFusionGender(ignoreOveride) === Gender.FEMALE,
|
||||
this.getFusionGender(ignoreOverride) === Gender.FEMALE,
|
||||
fusionSpeciesForm.formIndex,
|
||||
this.fusionShiny,
|
||||
this.fusionVariant,
|
||||
@ -5522,8 +5522,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
[this.getSprite(), this.getTintSprite()]
|
||||
.filter(s => !!s)
|
||||
.map(s => {
|
||||
s.pipelineData[`spriteColors${ignoreOveride && this.summonData.speciesForm ? "Base" : ""}`] = spriteColors;
|
||||
s.pipelineData[`fusionSpriteColors${ignoreOveride && this.summonData.speciesForm ? "Base" : ""}`] =
|
||||
s.pipelineData[`spriteColors${ignoreOverride && this.summonData.speciesForm ? "Base" : ""}`] = spriteColors;
|
||||
s.pipelineData[`fusionSpriteColors${ignoreOverride && this.summonData.speciesForm ? "Base" : ""}`] =
|
||||
fusionSpriteColors;
|
||||
});
|
||||
|
||||
|
@ -105,7 +105,7 @@ import {
|
||||
TempExtraModifierModifier,
|
||||
TempStatStageBoosterModifier,
|
||||
TerastallizeAccessModifier,
|
||||
TerrastalizeModifier,
|
||||
TerastallizeModifier,
|
||||
TmModifier,
|
||||
TurnHealModifier,
|
||||
TurnHeldItemTransferModifier,
|
||||
@ -431,7 +431,7 @@ export class TerastallizeModifierType extends PokemonModifierType {
|
||||
super(
|
||||
"",
|
||||
`${PokemonType[teraType].toLowerCase()}_tera_shard`,
|
||||
(type, args) => new TerrastalizeModifier(type as TerastallizeModifierType, (args[0] as Pokemon).id, teraType),
|
||||
(type, args) => new TerastallizeModifier(type as TerastallizeModifierType, (args[0] as Pokemon).id, teraType),
|
||||
(pokemon: PlayerPokemon) => {
|
||||
if (
|
||||
[pokemon.species.speciesId, pokemon.fusionSpecies?.speciesId].filter(
|
||||
|
@ -2073,7 +2073,7 @@ export abstract class ConsumablePokemonModifier extends ConsumableModifier {
|
||||
}
|
||||
}
|
||||
|
||||
export class TerrastalizeModifier extends ConsumablePokemonModifier {
|
||||
export class TerastallizeModifier extends ConsumablePokemonModifier {
|
||||
public declare type: TerastallizeModifierType;
|
||||
public teraType: PokemonType;
|
||||
|
||||
@ -2084,9 +2084,9 @@ export class TerrastalizeModifier extends ConsumablePokemonModifier {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if {@linkcode TerrastalizeModifier} should be applied
|
||||
* Checks if {@linkcode TerastallizeModifier} should be applied
|
||||
* @param playerPokemon The {@linkcode PlayerPokemon} that consumes the item
|
||||
* @returns `true` if the {@linkcode TerrastalizeModifier} should be applied
|
||||
* @returns `true` if the {@linkcode TerastallizeModifier} should be applied
|
||||
*/
|
||||
override shouldApply(playerPokemon?: PlayerPokemon): boolean {
|
||||
return (
|
||||
@ -2098,7 +2098,7 @@ export class TerrastalizeModifier extends ConsumablePokemonModifier {
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies {@linkcode TerrastalizeModifier}
|
||||
* Applies {@linkcode TerastallizeModifier}
|
||||
* @param pokemon The {@linkcode PlayerPokemon} that consumes the item
|
||||
* @returns `true` if hp was restored
|
||||
*/
|
||||
@ -3875,7 +3875,7 @@ const ModifierClassMap = Object.freeze({
|
||||
ResetNegativeStatStageModifier,
|
||||
FieldEffectModifier,
|
||||
ConsumablePokemonModifier,
|
||||
TerrastalizeModifier,
|
||||
TerastallizeModifier,
|
||||
PokemonHpRestoreModifier,
|
||||
PokemonStatusHealModifier,
|
||||
ConsumablePokemonMoveModifier,
|
||||
|
@ -11,7 +11,7 @@ export abstract class Phase {
|
||||
/**
|
||||
* The string name of the phase, used to identify the phase type for {@linkcode is}
|
||||
*
|
||||
* @privateremarks
|
||||
* @privateRemarks
|
||||
*
|
||||
* When implementing a phase, you must set the `phaseName` property to the name of the phase.
|
||||
*/
|
||||
|
@ -112,7 +112,7 @@ export class CommandPhase extends FieldPhase {
|
||||
* Clear out all unusable moves in front of the currently acting pokemon's move queue.
|
||||
*/
|
||||
// TODO: Refactor move queue handling to ensure that this method is not necessary.
|
||||
private clearUnusuableMoves(): void {
|
||||
private clearUnusableMoves(): void {
|
||||
const playerPokemon = this.getPokemon();
|
||||
const moveQueue = playerPokemon.getMoveQueue();
|
||||
if (moveQueue.length === 0) {
|
||||
@ -143,7 +143,7 @@ export class CommandPhase extends FieldPhase {
|
||||
* @returns Whether a queued move was successfully set to be executed.
|
||||
*/
|
||||
private tryExecuteQueuedMove(): boolean {
|
||||
this.clearUnusuableMoves();
|
||||
this.clearUnusableMoves();
|
||||
const playerPokemon = globalScene.getPlayerField()[this.fieldIndex];
|
||||
const moveQueue = playerPokemon.getMoveQueue();
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { ChallengeType } from "#enums/challenge-type";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import { MapModifier, MoneyInterestModifier } from "#modifiers/modifier";
|
||||
import { BattlePhase } from "#phases/battle-phase";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { applyChallenges } from "#utils/challenge-utils";
|
||||
import { BooleanHolder, randSeedInt } from "#utils/common";
|
||||
|
||||
|
@ -16,7 +16,7 @@ import type { Modifier } from "#modifiers/modifier";
|
||||
import { getDailyRunStarterModifiers, regenerateModifierPoolThresholds } from "#modifiers/modifier-type";
|
||||
import type { SessionSaveData } from "#system/game-data";
|
||||
import { vouchers } from "#system/voucher";
|
||||
import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { SaveSlotUiMode } from "#ui/save-slot-select-ui-handler";
|
||||
import { isLocal, isLocalServerConnected, isNullOrUndefined } from "#utils/common";
|
||||
import i18next from "i18next";
|
||||
|
@ -144,7 +144,7 @@ export function setSettingGamepad(setting: SettingGamepad, value: number): boole
|
||||
handler: () => changeGamepadHandler(g),
|
||||
})),
|
||||
{
|
||||
label: i18next.t("settings:cancelContollerChoice"),
|
||||
label: i18next.t("settings:cancelControllerChoice"),
|
||||
handler: cancelHandler,
|
||||
},
|
||||
],
|
||||
|
@ -36,7 +36,7 @@ interface ArenaEffectInfo {
|
||||
/** The enum string representation of the effect */
|
||||
name: string;
|
||||
/** {@linkcode ArenaEffectType} type of effect */
|
||||
effecType: ArenaEffectType;
|
||||
effectType: ArenaEffectType;
|
||||
|
||||
/** The maximum duration set by the effect */
|
||||
maxDuration: number;
|
||||
@ -246,7 +246,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
|
||||
// Creates a proxy object to decide which text object needs to be updated
|
||||
let textObject: Phaser.GameObjects.Text;
|
||||
switch (fieldEffectInfo.effecType) {
|
||||
switch (fieldEffectInfo.effectType) {
|
||||
case ArenaEffectType.PLAYER:
|
||||
textObject = this.flyoutTextPlayer;
|
||||
break;
|
||||
@ -300,7 +300,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
|
||||
const existingTrapTagIndex = isArenaTrapTag
|
||||
? this.fieldEffectInfo.findIndex(
|
||||
e => tagAddedEvent.arenaTagType === e.tagType && arenaEffectType === e.effecType,
|
||||
e => tagAddedEvent.arenaTagType === e.tagType && arenaEffectType === e.effectType,
|
||||
)
|
||||
: -1;
|
||||
let name: string = getFieldEffectText(ArenaTagType[tagAddedEvent.arenaTagType]);
|
||||
@ -318,7 +318,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
|
||||
this.fieldEffectInfo.push({
|
||||
name,
|
||||
effecType: arenaEffectType,
|
||||
effectType: arenaEffectType,
|
||||
maxDuration: tagAddedEvent.duration,
|
||||
duration: tagAddedEvent.duration,
|
||||
tagType: tagAddedEvent.arenaTagType,
|
||||
@ -353,7 +353,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
? WeatherType[fieldEffectChangedEvent.newWeatherType]
|
||||
: TerrainType[fieldEffectChangedEvent.newTerrainType],
|
||||
),
|
||||
effecType:
|
||||
effectType:
|
||||
fieldEffectChangedEvent instanceof WeatherChangedEvent ? ArenaEffectType.WEATHER : ArenaEffectType.TERRAIN,
|
||||
maxDuration: fieldEffectChangedEvent.duration,
|
||||
duration: fieldEffectChangedEvent.duration,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Button } from "#enums/buttons";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import { AbstractOptionSelectUiHandler } from "#ui/abstact-option-select-ui-handler";
|
||||
import { AbstractOptionSelectUiHandler } from "#ui/abstract-option-select-ui-handler";
|
||||
|
||||
export class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler {
|
||||
modalContainer: Phaser.GameObjects.Container;
|
||||
|
@ -198,11 +198,11 @@ export class PlayerBattleInfo extends BattleInfo {
|
||||
this.lastLevelCapped = isLevelCapped;
|
||||
|
||||
if (this.lastExp !== pokemon.exp || this.lastLevel !== pokemon.level) {
|
||||
const durationMultipler = Math.max(
|
||||
const durationMultiplier = Math.max(
|
||||
Phaser.Tweens.Builders.GetEaseFunction("Cubic.easeIn")(1 - Math.min(pokemon.level - this.lastLevel, 10) / 10),
|
||||
0.1,
|
||||
);
|
||||
await this.updatePokemonExp(pokemon, false, durationMultipler);
|
||||
await this.updatePokemonExp(pokemon, false, durationMultiplier);
|
||||
} else if (isLevelCapped !== oldLevelCapped) {
|
||||
this.setLevel(pokemon.level);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ export class CommandUiHandler extends UiHandler {
|
||||
ui.add(this.commandsContainer);
|
||||
|
||||
this.teraButton = globalScene.add.sprite(-32, 15, "button_tera");
|
||||
this.teraButton.setName("terrastallize-button");
|
||||
this.teraButton.setName("terastallize-button");
|
||||
this.teraButton.setScale(1.3);
|
||||
this.teraButton.setFrame("fire");
|
||||
this.teraButton.setPipeline(globalScene.spritePipeline, {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { Button } from "#enums/buttons";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import type { OptionSelectConfig } from "#ui/abstact-option-select-ui-handler";
|
||||
import { AbstractOptionSelectUiHandler } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectConfig } from "#ui/abstract-option-select-ui-handler";
|
||||
import { AbstractOptionSelectUiHandler } from "#ui/abstract-option-select-ui-handler";
|
||||
import i18next from "i18next";
|
||||
|
||||
export class ConfirmUiHandler extends AbstractOptionSelectUiHandler {
|
||||
|
@ -2,7 +2,7 @@ import { pokerogueApi } from "#api/pokerogue-api";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { TextStyle } from "#enums/text-style";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import type { InputFieldConfig } from "#ui/form-modal-ui-handler";
|
||||
import { FormModalUiHandler } from "#ui/form-modal-ui-handler";
|
||||
import type { ModalConfig } from "#ui/modal-ui-handler";
|
||||
|
@ -7,7 +7,7 @@ import { Button } from "#enums/buttons";
|
||||
import { GameDataType } from "#enums/game-data-type";
|
||||
import { TextStyle } from "#enums/text-style";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { AdminMode, getAdminModeName } from "#ui/admin-ui-handler";
|
||||
import type { AwaitableUiHandler } from "#ui/awaitable-ui-handler";
|
||||
import { BgmBar } from "#ui/bgm-bar";
|
||||
|
@ -843,7 +843,7 @@ class ModifierOption extends Phaser.GameObjects.Container {
|
||||
/**
|
||||
* Start the tweens responsible for animating the option's appearance
|
||||
*
|
||||
* @privateremarks
|
||||
* @privateRemarks
|
||||
* This method is unusual. It "returns" (one via the actual return, one by via appending to the `promiseHolder`
|
||||
* parameter) two promises. The promise returned by the method resolves once the option's appearance animations have
|
||||
* completed, and is meant to allow callers to synchronize with the completion of the option's appearance animations.
|
||||
|
@ -46,7 +46,7 @@ import { getVariantIcon, getVariantTint } from "#sprites/variant";
|
||||
import type { StarterAttributes } from "#system/game-data";
|
||||
import { SettingKeyboard } from "#system/settings-keyboard";
|
||||
import type { DexEntry } from "#types/dex-data";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { BaseStatsOverlay } from "#ui/base-stats-overlay";
|
||||
import { MessageUiHandler } from "#ui/message-ui-handler";
|
||||
import { MoveInfoOverlay } from "#ui/move-info-overlay";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { allAbilities, allMoves, allSpecies } from "#data/data-lists";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import type { PlayerPokemon } from "#field/pokemon";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { FilterTextRow } from "#ui/filter-text";
|
||||
import type { InputFieldConfig } from "#ui/form-modal-ui-handler";
|
||||
import { FormModalUiHandler } from "#ui/form-modal-ui-handler";
|
||||
|
@ -33,7 +33,7 @@ import { getVariantIcon, getVariantTint } from "#sprites/variant";
|
||||
import type { DexAttrProps, StarterAttributes } from "#system/game-data";
|
||||
import { SettingKeyboard } from "#system/settings-keyboard";
|
||||
import type { DexEntry } from "#types/dex-data";
|
||||
import type { OptionSelectConfig } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectConfig } from "#ui/abstract-option-select-ui-handler";
|
||||
import { DropDown, DropDownLabel, DropDownOption, DropDownState, DropDownType, SortCriteria } from "#ui/dropdown";
|
||||
import { FilterBar } from "#ui/filter-bar";
|
||||
import { FilterText, FilterTextRow } from "#ui/filter-text";
|
||||
|
@ -702,11 +702,11 @@ export class RunInfoUiHandler extends UiHandler {
|
||||
rules.push(i18next.t("challenges:inverseBattle.shortName"));
|
||||
break;
|
||||
default: {
|
||||
const localisationKey = Challenges[this.runInfo.challenges[i].id]
|
||||
const localizationKey = Challenges[this.runInfo.challenges[i].id]
|
||||
.split("_")
|
||||
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
|
||||
.join("");
|
||||
rules.push(i18next.t(`challenges:${localisationKey}.name`));
|
||||
rules.push(i18next.t(`challenges:${localizationKey}.name`));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -401,7 +401,7 @@ class SessionSlot extends Phaser.GameObjects.Container {
|
||||
const gameModeLabel = addTextObject(
|
||||
8,
|
||||
5,
|
||||
`${GameMode.getModeName(data.gameMode) || i18next.t("gameMode:unkown")} - ${i18next.t("saveSlotSelectUiHandler:wave")} ${data.waveIndex}`,
|
||||
`${GameMode.getModeName(data.gameMode) || i18next.t("gameMode:unknown")} - ${i18next.t("saveSlotSelectUiHandler:wave")} ${data.waveIndex}`,
|
||||
TextStyle.WINDOW,
|
||||
);
|
||||
this.add(gameModeLabel);
|
||||
|
@ -8,7 +8,7 @@ import { UiHandler } from "#ui/ui-handler";
|
||||
import { addWindow } from "#ui/ui-theme";
|
||||
import i18next from "i18next";
|
||||
|
||||
type CancelFn = (succes?: boolean) => boolean;
|
||||
type CancelFn = (success?: boolean) => boolean;
|
||||
|
||||
/**
|
||||
* Abstract class for handling UI elements related to button bindings.
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import { AbstractOptionSelectUiHandler } from "#ui/abstact-option-select-ui-handler";
|
||||
import { AbstractOptionSelectUiHandler } from "#ui/abstract-option-select-ui-handler";
|
||||
|
||||
export class OptionSelectUiHandler extends AbstractOptionSelectUiHandler {
|
||||
constructor(mode: UiMode = UiMode.OPTION_SELECT) {
|
||||
|
@ -47,7 +47,7 @@ import { achvs } from "#system/achv";
|
||||
import type { DexAttrProps, StarterAttributes, StarterMoveset } from "#system/game-data";
|
||||
import { SettingKeyboard } from "#system/settings-keyboard";
|
||||
import type { DexEntry } from "#types/dex-data";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { DropDown, DropDownLabel, DropDownOption, DropDownState, DropDownType, SortCriteria } from "#ui/dropdown";
|
||||
import { FilterBar } from "#ui/filter-bar";
|
||||
import { MessageUiHandler } from "#ui/message-ui-handler";
|
||||
@ -901,7 +901,7 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
||||
this.pokemonEggMovesContainer.add(eggMoveContainer);
|
||||
}
|
||||
|
||||
this.teraIcon = globalScene.add.sprite(85, 63, "button_tera").setName("terrastallize-icon").setFrame("fire");
|
||||
this.teraIcon = globalScene.add.sprite(85, 63, "button_tera").setName("terastallize-icon").setFrame("fire");
|
||||
|
||||
// The font size should be set per language
|
||||
const instructionTextSize = textSettings.instructionTextSize;
|
||||
|
@ -879,7 +879,7 @@ export class SummaryUiHandler extends UiHandler {
|
||||
!isNullOrUndefined(this.pokemon)
|
||||
) {
|
||||
const teraIcon = globalScene.add.sprite(123, 26, "button_tera");
|
||||
teraIcon.setName("terrastallize-icon");
|
||||
teraIcon.setName("terastallize-icon");
|
||||
teraIcon.setFrame(PokemonType[this.pokemon.getTeraType()].toLowerCase());
|
||||
profileContainer.add(teraIcon);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import type { PlayerPokemon } from "#field/pokemon";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import type { InputFieldConfig } from "#ui/form-modal-ui-handler";
|
||||
import { FormModalUiHandler } from "#ui/form-modal-ui-handler";
|
||||
import type { ModalConfig } from "#ui/modal-ui-handler";
|
||||
@ -13,7 +13,7 @@ export class TestDialogueUiHandler extends FormModalUiHandler {
|
||||
setup() {
|
||||
super.setup();
|
||||
|
||||
const flattenKeys = (object?: any, topKey?: string, midleKey?: string[]): Array<any> => {
|
||||
const flattenKeys = (object?: any, topKey?: string, middleKey?: string[]): Array<any> => {
|
||||
return Object.keys(object ?? {})
|
||||
.map((t, i) => {
|
||||
const value = Object.values(object)[i];
|
||||
@ -23,7 +23,7 @@ export class TestDialogueUiHandler extends FormModalUiHandler {
|
||||
// If the value is an object, execute the same process
|
||||
// si el valor es un objeto ejecuta el mismo proceso
|
||||
|
||||
return flattenKeys(value, topKey ?? t, topKey ? (midleKey ? [...midleKey, t] : [t]) : undefined).filter(
|
||||
return flattenKeys(value, topKey ?? t, topKey ? (middleKey ? [...middleKey, t] : [t]) : undefined).filter(
|
||||
t => t.length > 0,
|
||||
);
|
||||
}
|
||||
@ -31,7 +31,7 @@ export class TestDialogueUiHandler extends FormModalUiHandler {
|
||||
// we check for null or undefined here as per above - the typeof is still an object but the value is null so we need to exit out of this and pass the null key
|
||||
|
||||
// Return in the format expected by i18next
|
||||
return midleKey ? `${topKey}:${midleKey.map(m => m).join(".")}.${t}` : `${topKey}:${t}`;
|
||||
return middleKey ? `${topKey}:${middleKey.map(m => m).join(".")}.${t}` : `${topKey}:${t}`;
|
||||
}
|
||||
})
|
||||
.filter(t => t);
|
||||
|
@ -1,10 +1,15 @@
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { allAbilities } from "#data/data-lists";
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { Button } from "#enums/buttons";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import { GameManager } from "#test/test-utils/game-manager";
|
||||
import type { PartyUiHandler } from "#ui/party-ui-handler";
|
||||
import i18next from "i18next";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
describe("Abilities - Arena Trap", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
@ -23,68 +28,64 @@ describe("Abilities - Arena Trap", () => {
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.moveset(MoveId.SPLASH)
|
||||
.ability(AbilityId.ARENA_TRAP)
|
||||
.enemyAbility(AbilityId.ARENA_TRAP)
|
||||
.enemySpecies(SpeciesId.RALTS)
|
||||
.enemyAbility(AbilityId.BALL_FETCH)
|
||||
.enemyMoveset(MoveId.TELEPORT);
|
||||
.enemyMoveset(MoveId.SPLASH);
|
||||
});
|
||||
|
||||
// TODO: Enable test when Issue #935 is addressed
|
||||
it.todo("should not allow grounded Pokémon to flee", async () => {
|
||||
// NB: Since switching moves bypass trapping, the only way fleeing can occur in PKR is from the player
|
||||
// TODO: Implement once forced flee helper exists
|
||||
it.todo("should interrupt player flee attempt and display message, unless user has Run Away");
|
||||
|
||||
// TODO: Figure out how to wrangle the UI into not timing out
|
||||
it.todo("should interrupt player switch attempt and display message", async () => {
|
||||
game.override.battleStyle("single");
|
||||
await game.classicMode.startBattle([SpeciesId.DUGTRIO, SpeciesId.GOTHITELLE]);
|
||||
|
||||
await game.classicMode.startBattle();
|
||||
const enemy = game.field.getEnemyPokemon();
|
||||
|
||||
const enemy = game.scene.getEnemyPokemon();
|
||||
game.doSwitchPokemon(1);
|
||||
game.onNextPrompt("CommandPhase", UiMode.PARTY, () => {
|
||||
// no switch out command should be queued due to arena trap
|
||||
expect(game.scene.currentBattle.turnCommands[0]).toBeNull();
|
||||
|
||||
game.move.select(MoveId.SPLASH);
|
||||
// back out and end the phase to avoid timeout
|
||||
console.log(game.scene.ui.getHandler().constructor.name);
|
||||
(game.scene.ui.getHandler() as PartyUiHandler).processInput(Button.CANCEL);
|
||||
});
|
||||
|
||||
await game.toNextTurn();
|
||||
await game.phaseInterceptor.to("CommandPhase");
|
||||
|
||||
expect(enemy).toBe(game.scene.getEnemyPokemon());
|
||||
expect(game.textInterceptor.logs).toContain(
|
||||
i18next.t("abilityTriggers:arenaTrap", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(enemy),
|
||||
abilityName: allAbilities[AbilityId.ARENA_TRAP].name,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("should guarantee double battle with any one LURE", async () => {
|
||||
game.override.startingModifier([{ name: "LURE" }]).startingWave(2);
|
||||
await game.classicMode.startBattle([SpeciesId.DUGTRIO]);
|
||||
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
expect(game.scene.getEnemyField().length).toBe(2);
|
||||
expect(game.scene.getEnemyField()).toHaveLength(2);
|
||||
});
|
||||
|
||||
/**
|
||||
* This checks if the Player Pokemon is able to switch out/run away after the Enemy Pokemon with {@linkcode AbilityId.ARENA_TRAP}
|
||||
* is forcefully moved out of the field from moves such as Roar {@linkcode MoveId.ROAR}
|
||||
*
|
||||
* Note: It should be able to switch out/run away
|
||||
*/
|
||||
it("should lift if pokemon with this ability leaves the field", async () => {
|
||||
game.override
|
||||
.battleStyle("double")
|
||||
.enemyMoveset(MoveId.SPLASH)
|
||||
.moveset([MoveId.ROAR, MoveId.SPLASH])
|
||||
.ability(AbilityId.BALL_FETCH);
|
||||
await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.SUDOWOODO, SpeciesId.LUNATONE]);
|
||||
game.override.battleStyle("single");
|
||||
await game.classicMode.startBattle([SpeciesId.MAGIKARP]);
|
||||
|
||||
const [enemy1, enemy2] = game.scene.getEnemyField();
|
||||
const [player1, player2] = game.scene.getPlayerField();
|
||||
const player = game.field.getPlayerPokemon();
|
||||
const enemy = game.field.getEnemyPokemon();
|
||||
|
||||
vi.spyOn(enemy1, "getAbility").mockReturnValue(allAbilities[AbilityId.ARENA_TRAP]);
|
||||
expect(player.isTrapped()).toBe(true);
|
||||
expect(enemy.isOnField()).toBe(true);
|
||||
|
||||
game.move.select(MoveId.ROAR);
|
||||
game.move.select(MoveId.SPLASH, 1);
|
||||
game.move.use(MoveId.ROAR);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
// This runs the fist command phase where the moves are selected
|
||||
await game.toNextTurn();
|
||||
// During the next command phase the player pokemons should not be trapped anymore
|
||||
game.move.select(MoveId.SPLASH);
|
||||
game.move.select(MoveId.SPLASH, 1);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(player1.isTrapped()).toBe(false);
|
||||
expect(player2.isTrapped()).toBe(false);
|
||||
expect(enemy1.isOnField()).toBe(false);
|
||||
expect(enemy2.isOnField()).toBe(true);
|
||||
expect(player.isTrapped()).toBe(false);
|
||||
expect(enemy.isOnField()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
@ -10,7 +10,7 @@ import { EncounterPhase } from "#phases/encounter-phase";
|
||||
import { SelectStarterPhase } from "#phases/select-starter-phase";
|
||||
import type { TitlePhase } from "#phases/title-phase";
|
||||
import { GameManager } from "#test/test-utils/game-manager";
|
||||
import type { OptionSelectItem } from "#ui/abstact-option-select-ui-handler";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import type { OptionSelectUiHandler } from "#ui/option-select-ui-handler";
|
||||
import type { SaveSlotSelectUiHandler } from "#ui/save-slot-select-ui-handler";
|
||||
import type { StarterSelectUiHandler } from "#ui/starter-select-ui-handler";
|
||||
|
Loading…
Reference in New Issue
Block a user