Compare commits

..

No commits in common. "c48ad4d5d4f3996be59a33362a8db4ab8dcc350e" and "d776df4b21d7d52fc5aceeb1c4dc31faa93a5e9b" have entirely different histories.

13 changed files with 80 additions and 80 deletions

View File

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

View File

@ -74,7 +74,6 @@ 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 {
@ -110,9 +109,13 @@ export class Ability implements Localizable {
} }
localize(): void { localize(): void {
const i18nKey = toCamelCase(AbilityId[this.id]); const i18nKey = 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`)}${this.nameAppend}` : ""; this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`) as string}${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,16 +1866,17 @@ interface PokemonPrevolutions {
export const pokemonPrevolutions: PokemonPrevolutions = {}; export const pokemonPrevolutions: PokemonPrevolutions = {};
export function initPokemonPrevolutions(): void { export function initPokemonPrevolutions(): void {
// TODO: Why do we have empty strings in our array? const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string);
const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ]; const prevolutionKeys = Object.keys(pokemonEvolutions);
for (const [pk, evolutions] of Object.entries(pokemonEvolutions)) { prevolutionKeys.forEach(pk => {
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 { toCamelCase, toTitleCase } from "#utils/strings"; import { 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,16 +162,10 @@ export abstract class Move implements Localizable {
} }
localize(): void { localize(): void {
const i18nKey = toCamelCase(MoveId[this.id]) 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;
if (this.id === MoveId.NONE) { this.name = this.id ? `${i18next.t(`move:${i18nKey}.name`)}${this.nameAppend}` : "";
this.name = ""; this.effect = this.id ? `${i18next.t(`move:${i18nKey}.effect`)}${this.nameAppend}` : "";
this.effect = ""
return;
}
this.name = `${i18next.t(`move:${i18nKey}.name`)}${this.nameAppend}`;
this.effect = `${i18next.t(`move:${i18nKey}.effect`)}${this.nameAppend}`;
} }
/** /**
@ -5997,8 +5991,8 @@ export class ProtectAttr extends AddBattlerTagAttr {
for (const turnMove of user.getLastXMoves(-1).slice()) { for (const turnMove of user.getLastXMoves(-1).slice()) {
if ( if (
// Quick & Wide guard increment the Protect counter without using it for fail chance // Quick & Wide guard increment the Protect counter without using it for fail chance
!(allMoves[turnMove.move].hasAttr("ProtectAttr") || !(allMoves[turnMove.move].hasAttr("ProtectAttr") ||
[MoveId.QUICK_GUARD, MoveId.WIDE_GUARD].includes(turnMove.move)) || [MoveId.QUICK_GUARD, MoveId.WIDE_GUARD].includes(turnMove.move)) ||
turnMove.result !== MoveResult.SUCCESS turnMove.result !== MoveResult.SUCCESS
) { ) {
break; break;

View File

@ -12,7 +12,6 @@ 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 {
@ -144,7 +143,11 @@ export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigge
super(); super();
this.move = move; this.move = move;
this.known = known; this.known = known;
const moveKey = toCamelCase(MoveId[this.move]); const moveKey = 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 = 0; public playerTerasUsed: number;
/** /**
* 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,11 +68,12 @@ export class Arena {
public readonly eventTarget: EventTarget = new EventTarget(); public readonly eventTarget: EventTarget = new EventTarget();
constructor(biome: BiomeId, playerFaints = 0) { constructor(biome: BiomeId, bgm: string, playerFaints = 0) {
this.biomeType = biome; this.biomeType = biome;
this.bgm = BiomeId[biome].toLowerCase(); this.bgm = bgm;
this.trainerPool = biomeTrainerPools[biome]; this.trainerPool = biomeTrainerPools[biome];
this.updatePoolsForTimeOfDay(); this.updatePoolsForTimeOfDay();
this.playerTerasUsed = 0;
this.playerFaints = playerFaints; this.playerFaints = playerFaints;
} }

View File

@ -447,9 +447,7 @@ export class LoadingScene extends SceneBase {
); );
if (!mobile) { if (!mobile) {
loadingGraphics.forEach(g => { loadingGraphics.map(g => g.setVisible(false));
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() as Phaser.GameObjects.Container[]; const modifierIcons = this.getAll().reverse();
for (const modifier of modifierIcons.slice(iconOverflowIndex)) { for (const modifier of modifierIcons.map(m => m as Phaser.GameObjects.Container).slice(iconOverflowIndex)) {
modifier.setVisible(ignoreLimit); modifier.setVisible(ignoreLimit);
} }
} }

View File

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

View File

@ -26,7 +26,6 @@ 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";
@ -707,7 +706,10 @@ 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 = toCamelCase(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:${localizationKey}.name`)); rules.push(i18next.t(`challenges:${localizationKey}.name`));
break; break;
} }

View File

@ -594,9 +594,13 @@ class SessionSlot extends Phaser.GameObjects.Container {
TextStyle.PARTY, TextStyle.PARTY,
{ fontSize: "54px", color: "#f8f8f8" }, { fontSize: "54px", color: "#f8f8f8" },
); );
text.setShadow(0, 0, undefined).setStroke("#424242", 14).setOrigin(1, 0); text.setShadow(0, 0, undefined);
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();
@ -641,7 +645,6 @@ 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.join(".")}.${t}` : `${topKey}:${t}`; return middleKey ? `${topKey}:${middleKey.map(m => m).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().slice(); const pokemonPrior = scene.getPlayerParty().map(pokemon => pokemon);
const bstsPrior = pokemonPrior.map(species => species.getSpeciesForm().getBaseStatTotal()); const bstsPrior = pokemonPrior.map(species => species.getSpeciesForm().getBaseStatTotal());
await runMysteryEncounterToEnd(game, 1); await runMysteryEncounterToEnd(game, 1);