Compare commits

...

4 Commits

Author SHA1 Message Date
NightKev
c48ad4d5d4
Merge branch 'beta' into rest 2025-08-14 10:44:09 -07:00
Bertie690
f42237d415
[Refactor] Removed map(x => x) (#6256)
* Enforced a few usages of `toCamelCase`

* Removed `map(x => x)`

* Removed more maps and sufff

* Update test/mystery-encounter/encounters/weird-dream-encounter.test.ts

* Update game-data.ts types to work
2025-08-14 10:25:44 -07:00
fabske0
b44f0a4176
[Refactor] Remove bgm param from arena constructor (#6254) 2025-08-14 16:52:56 +00:00
Sirz Benjie
076ef81691
[Bug] [UI/UX] [Beta] Fix icons not showing in save slot selection (#6262)
Fix icons not showing in save slot selection
2025-08-13 20:49:46 -05:00
13 changed files with 80 additions and 80 deletions

View File

@ -104,6 +104,7 @@ import {
getLuckString, getLuckString,
getLuckTextTint, getLuckTextTint,
getPartyLuckValue, getPartyLuckValue,
type ModifierType,
PokemonHeldItemModifierType, PokemonHeldItemModifierType,
} from "#modifiers/modifier-type"; } from "#modifiers/modifier-type";
import { MysteryEncounter } from "#mystery-encounters/mystery-encounter"; import { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
@ -1203,7 +1204,9 @@ export class BattleScene extends SceneBase {
this.updateScoreText(); this.updateScoreText();
this.scoreText.setVisible(false); this.scoreText.setVisible(false);
[this.luckLabelText, this.luckText].map(t => t.setVisible(false)); [this.luckLabelText, this.luckText].forEach(t => {
t.setVisible(false);
});
this.newArena(Overrides.STARTING_BIOME_OVERRIDE || BiomeId.TOWN); this.newArena(Overrides.STARTING_BIOME_OVERRIDE || BiomeId.TOWN);
@ -1237,8 +1240,7 @@ export class BattleScene extends SceneBase {
Object.values(mp) Object.values(mp)
.flat() .flat()
.map(mt => mt.modifierType) .map(mt => mt.modifierType)
.filter(mt => "localize" in mt) .filter((mt): mt is ModifierType & Localizable => "localize" in mt && typeof mt.localize === "function"),
.map(lpb => lpb as unknown as Localizable),
), ),
]; ];
for (const item of localizable) { for (const item of localizable) {
@ -1513,8 +1515,8 @@ export class BattleScene extends SceneBase {
return this.currentBattle; return this.currentBattle;
} }
newArena(biome: BiomeId, playerFaints?: number): Arena { newArena(biome: BiomeId, playerFaints = 0): Arena {
this.arena = new Arena(biome, BiomeId[biome].toLowerCase(), playerFaints); this.arena = new Arena(biome, playerFaints);
this.eventTarget.dispatchEvent(new NewArenaEvent()); this.eventTarget.dispatchEvent(new NewArenaEvent());
this.arenaBg.pipelineData = { this.arenaBg.pipelineData = {
@ -2711,7 +2713,9 @@ export class BattleScene extends SceneBase {
} }
} }
this.party.map(p => p.updateInfo(instant)); this.party.forEach(p => {
p.updateInfo(instant);
});
} else { } else {
const args = [this]; const args = [this];
if (modifier.shouldApply(...args)) { if (modifier.shouldApply(...args)) {

View File

@ -74,6 +74,7 @@ import {
randSeedItem, randSeedItem,
toDmgValue, toDmgValue,
} from "#utils/common"; } from "#utils/common";
import { toCamelCase } from "#utils/strings";
import i18next from "i18next"; import i18next from "i18next";
export class Ability implements Localizable { export class Ability implements Localizable {
@ -109,13 +110,9 @@ export class Ability implements Localizable {
} }
localize(): void { localize(): void {
const i18nKey = AbilityId[this.id] const i18nKey = toCamelCase(AbilityId[this.id]);
.split("_")
.filter(f => f)
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
.join("") as string;
this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`) as string}${this.nameAppend}` : ""; this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`)}${this.nameAppend}` : "";
this.description = this.id ? (i18next.t(`ability:${i18nKey}.description`) as string) : ""; this.description = this.id ? (i18next.t(`ability:${i18nKey}.description`) as string) : "";
} }

View File

@ -1866,17 +1866,16 @@ interface PokemonPrevolutions {
export const pokemonPrevolutions: PokemonPrevolutions = {}; export const pokemonPrevolutions: PokemonPrevolutions = {};
export function initPokemonPrevolutions(): void { export function initPokemonPrevolutions(): void {
const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string); // TODO: Why do we have empty strings in our array?
const prevolutionKeys = Object.keys(pokemonEvolutions); const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ];
prevolutionKeys.forEach(pk => { for (const [pk, evolutions] of Object.entries(pokemonEvolutions)) {
const evolutions = pokemonEvolutions[pk];
for (const ev of evolutions) { for (const ev of evolutions) {
if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) { if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) {
continue; continue;
} }
pokemonPrevolutions[ev.speciesId] = Number.parseInt(pk) as SpeciesId; pokemonPrevolutions[ev.speciesId] = Number.parseInt(pk) as SpeciesId;
} }
}); }
} }

View File

@ -90,7 +90,7 @@ import type { ChargingMove, MoveAttrMap, MoveAttrString, MoveClassMap, MoveKindS
import type { TurnMove } from "#types/turn-move"; import type { TurnMove } from "#types/turn-move";
import { BooleanHolder, coerceArray, type Constructor, isNullOrUndefined, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common"; import { BooleanHolder, coerceArray, type Constructor, isNullOrUndefined, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common";
import { getEnumValues } from "#utils/enums"; import { getEnumValues } from "#utils/enums";
import { toTitleCase } from "#utils/strings"; import { toCamelCase, toTitleCase } from "#utils/strings";
import i18next from "i18next"; import i18next from "i18next";
import { applyChallenges } from "#utils/challenge-utils"; import { applyChallenges } from "#utils/challenge-utils";
@ -162,10 +162,16 @@ export abstract class Move implements Localizable {
} }
localize(): void { localize(): void {
const i18nKey = MoveId[this.id].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("") as unknown as string; const i18nKey = toCamelCase(MoveId[this.id])
this.name = this.id ? `${i18next.t(`move:${i18nKey}.name`)}${this.nameAppend}` : ""; if (this.id === MoveId.NONE) {
this.effect = this.id ? `${i18next.t(`move:${i18nKey}.effect`)}${this.nameAppend}` : ""; this.name = "";
this.effect = ""
return;
}
this.name = `${i18next.t(`move:${i18nKey}.name`)}${this.nameAppend}`;
this.effect = `${i18next.t(`move:${i18nKey}.effect`)}${this.nameAppend}`;
} }
/** /**

View File

@ -12,6 +12,7 @@ import { WeatherType } from "#enums/weather-type";
import type { Pokemon } from "#field/pokemon"; import type { Pokemon } from "#field/pokemon";
import type { PokemonFormChangeItemModifier } from "#modifiers/modifier"; import type { PokemonFormChangeItemModifier } from "#modifiers/modifier";
import { type Constructor, coerceArray } from "#utils/common"; import { type Constructor, coerceArray } from "#utils/common";
import { toCamelCase } from "#utils/strings";
import i18next from "i18next"; import i18next from "i18next";
export abstract class SpeciesFormChangeTrigger { export abstract class SpeciesFormChangeTrigger {
@ -143,11 +144,7 @@ export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigge
super(); super();
this.move = move; this.move = move;
this.known = known; this.known = known;
const moveKey = MoveId[this.move] const moveKey = toCamelCase(MoveId[this.move]);
.split("_")
.filter(f => f)
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
.join("") as unknown as string;
this.description = known this.description = known
? i18next.t("pokemonEvolutions:Forms.moveLearned", { ? i18next.t("pokemonEvolutions:Forms.moveLearned", {
move: i18next.t(`move:${moveKey}.name`), move: i18next.t(`move:${moveKey}.name`),

View File

@ -54,7 +54,7 @@ export class Arena {
public bgm: string; public bgm: string;
public ignoreAbilities: boolean; public ignoreAbilities: boolean;
public ignoringEffectSource: BattlerIndex | null; public ignoringEffectSource: BattlerIndex | null;
public playerTerasUsed: number; public playerTerasUsed = 0;
/** /**
* Saves the number of times a party pokemon faints during a arena encounter. * Saves the number of times a party pokemon faints during a arena encounter.
* {@linkcode globalScene.currentBattle.enemyFaints} is the corresponding faint counter for the enemy (this resets every wave). * {@linkcode globalScene.currentBattle.enemyFaints} is the corresponding faint counter for the enemy (this resets every wave).
@ -68,12 +68,11 @@ export class Arena {
public readonly eventTarget: EventTarget = new EventTarget(); public readonly eventTarget: EventTarget = new EventTarget();
constructor(biome: BiomeId, bgm: string, playerFaints = 0) { constructor(biome: BiomeId, playerFaints = 0) {
this.biomeType = biome; this.biomeType = biome;
this.bgm = bgm; this.bgm = BiomeId[biome].toLowerCase();
this.trainerPool = biomeTrainerPools[biome]; this.trainerPool = biomeTrainerPools[biome];
this.updatePoolsForTimeOfDay(); this.updatePoolsForTimeOfDay();
this.playerTerasUsed = 0;
this.playerFaints = playerFaints; this.playerFaints = playerFaints;
} }

View File

@ -447,7 +447,9 @@ export class LoadingScene extends SceneBase {
); );
if (!mobile) { if (!mobile) {
loadingGraphics.map(g => g.setVisible(false)); loadingGraphics.forEach(g => {
g.setVisible(false);
});
} }
const intro = this.add.video(0, 0); const intro = this.add.video(0, 0);

View File

@ -121,8 +121,8 @@ export class ModifierBar extends Phaser.GameObjects.Container {
} }
updateModifierOverflowVisibility(ignoreLimit: boolean) { updateModifierOverflowVisibility(ignoreLimit: boolean) {
const modifierIcons = this.getAll().reverse(); const modifierIcons = this.getAll().reverse() as Phaser.GameObjects.Container[];
for (const modifier of modifierIcons.map(m => m as Phaser.GameObjects.Container).slice(iconOverflowIndex)) { for (const modifier of modifierIcons.slice(iconOverflowIndex)) {
modifier.setVisible(ignoreLimit); modifier.setVisible(ignoreLimit);
} }
} }

View File

@ -207,10 +207,12 @@ export interface StarterData {
[key: number]: StarterDataEntry; [key: number]: StarterDataEntry;
} }
export interface TutorialFlags { // TODO: Rework into a bitmask
[key: string]: boolean; export type TutorialFlags = {
} [key in Tutorial]: boolean;
};
// TODO: Rework into a bitmask
export interface SeenDialogues { export interface SeenDialogues {
[key: string]: boolean; [key: string]: boolean;
} }
@ -823,52 +825,51 @@ export class GameData {
return true; // TODO: is `true` the correct return value? return true; // TODO: is `true` the correct return value?
} }
private loadGamepadSettings(): boolean { private loadGamepadSettings(): void {
Object.values(SettingGamepad) Object.values(SettingGamepad).forEach(setting => {
.map(setting => setting as SettingGamepad) setSettingGamepad(setting, settingGamepadDefaults[setting]);
.forEach(setting => setSettingGamepad(setting, settingGamepadDefaults[setting])); });
if (!localStorage.hasOwnProperty("settingsGamepad")) { if (!localStorage.hasOwnProperty("settingsGamepad")) {
return false; return;
} }
const settingsGamepad = JSON.parse(localStorage.getItem("settingsGamepad")!); // TODO: is this bang correct? const settingsGamepad = JSON.parse(localStorage.getItem("settingsGamepad")!); // TODO: is this bang correct?
for (const setting of Object.keys(settingsGamepad)) { for (const setting of Object.keys(settingsGamepad)) {
setSettingGamepad(setting as SettingGamepad, settingsGamepad[setting]); setSettingGamepad(setting as SettingGamepad, settingsGamepad[setting]);
} }
return true; // TODO: is `true` the correct return value?
} }
public saveTutorialFlag(tutorial: Tutorial, flag: boolean): boolean { /**
const key = getDataTypeKey(GameDataType.TUTORIALS); * Save the specified tutorial as having the specified completion status.
let tutorials: object = {}; * @param tutorial - The {@linkcode Tutorial} whose completion status is being saved
if (localStorage.hasOwnProperty(key)) { * @param status - The completion status to set
tutorials = JSON.parse(localStorage.getItem(key)!); // TODO: is this bang correct? */
} public saveTutorialFlag(tutorial: Tutorial, status: boolean): void {
// Grab the prior save data tutorial
const saveDataKey = getDataTypeKey(GameDataType.TUTORIALS);
const tutorials: TutorialFlags = localStorage.hasOwnProperty(saveDataKey)
? JSON.parse(localStorage.getItem(saveDataKey)!)
: {};
Object.keys(Tutorial) // TODO: We shouldn't be storing this like that
.map(t => t as Tutorial) for (const key of Object.values(Tutorial)) {
.forEach(t => {
const key = Tutorial[t];
if (key === tutorial) { if (key === tutorial) {
tutorials[key] = flag; tutorials[key] = status;
} else { } else {
tutorials[key] ??= false; tutorials[key] ??= false;
} }
}); }
localStorage.setItem(key, JSON.stringify(tutorials)); localStorage.setItem(saveDataKey, JSON.stringify(tutorials));
return true;
} }
public getTutorialFlags(): TutorialFlags { public getTutorialFlags(): TutorialFlags {
const key = getDataTypeKey(GameDataType.TUTORIALS); const key = getDataTypeKey(GameDataType.TUTORIALS);
const ret: TutorialFlags = {}; const ret: TutorialFlags = Object.values(Tutorial).reduce((acc, tutorial) => {
Object.values(Tutorial) acc[Tutorial[tutorial]] = false;
.map(tutorial => tutorial as Tutorial) return acc;
.forEach(tutorial => (ret[Tutorial[tutorial]] = false)); }, {} as TutorialFlags);
if (!localStorage.hasOwnProperty(key)) { if (!localStorage.hasOwnProperty(key)) {
return ret; return ret;

View File

@ -26,6 +26,7 @@ import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text";
import { UiHandler } from "#ui/ui-handler"; import { UiHandler } from "#ui/ui-handler";
import { addWindow } from "#ui/ui-theme"; import { addWindow } from "#ui/ui-theme";
import { formatFancyLargeNumber, formatLargeNumber, formatMoney, getPlayTimeString } from "#utils/common"; import { formatFancyLargeNumber, formatLargeNumber, formatMoney, getPlayTimeString } from "#utils/common";
import { toCamelCase } from "#utils/strings";
import i18next from "i18next"; import i18next from "i18next";
import RoundRectangle from "phaser3-rex-plugins/plugins/roundrectangle"; import RoundRectangle from "phaser3-rex-plugins/plugins/roundrectangle";
@ -706,10 +707,7 @@ export class RunInfoUiHandler extends UiHandler {
rules.push(i18next.t("challenges:inverseBattle.shortName")); rules.push(i18next.t("challenges:inverseBattle.shortName"));
break; break;
default: { default: {
const localizationKey = Challenges[this.runInfo.challenges[i].id] const localizationKey = toCamelCase(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:${localizationKey}.name`)); rules.push(i18next.t(`challenges:${localizationKey}.name`));
break; break;
} }

View File

@ -594,13 +594,9 @@ class SessionSlot extends Phaser.GameObjects.Container {
TextStyle.PARTY, TextStyle.PARTY,
{ fontSize: "54px", color: "#f8f8f8" }, { fontSize: "54px", color: "#f8f8f8" },
); );
text.setShadow(0, 0, undefined); text.setShadow(0, 0, undefined).setStroke("#424242", 14).setOrigin(1, 0);
text.setStroke("#424242", 14);
text.setOrigin(1, 0);
iconContainer.add(icon);
iconContainer.add(text);
iconContainer.add([icon, text]);
pokemonIconsContainer.add(iconContainer); pokemonIconsContainer.add(iconContainer);
pokemon.destroy(); pokemon.destroy();
@ -645,6 +641,7 @@ class SessionSlot extends Phaser.GameObjects.Container {
return; return;
} }
this.saveData = sessionData; this.saveData = sessionData;
this.setupWithData(sessionData);
resolve(true); resolve(true);
}) })
.catch(e => { .catch(e => {

View File

@ -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 // 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 in the format expected by i18next
return middleKey ? `${topKey}:${middleKey.map(m => m).join(".")}.${t}` : `${topKey}:${t}`; return middleKey ? `${topKey}:${middleKey.join(".")}.${t}` : `${topKey}:${t}`;
} }
}) })
.filter(t => t); .filter(t => t);

View File

@ -112,7 +112,7 @@ describe("Weird Dream - Mystery Encounter", () => {
it("should transform the new party into new species, 2 at +90/+110, the rest at +40/50 BST", async () => { it("should transform the new party into new species, 2 at +90/+110, the rest at +40/50 BST", async () => {
await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty);
const pokemonPrior = scene.getPlayerParty().map(pokemon => pokemon); const pokemonPrior = scene.getPlayerParty().slice();
const bstsPrior = pokemonPrior.map(species => species.getSpeciesForm().getBaseStatTotal()); const bstsPrior = pokemonPrior.map(species => species.getSpeciesForm().getBaseStatTotal());
await runMysteryEncounterToEnd(game, 1); await runMysteryEncounterToEnd(game, 1);