[Bug] Prevent an empty starterpreferences object from being saved (#6410)

* Prevent an empty starterpreferences object from being saved

* Fix ssui nullish coalescing

* Update src/utils/data.ts

Co-authored-by: Dean <69436131+emdeann@users.noreply.github.com>

---------

Co-authored-by: Dean <69436131+emdeann@users.noreply.github.com>
This commit is contained in:
Sirz Benjie 2025-08-26 01:48:55 -05:00 committed by GitHub
parent f0c24cd16e
commit c8a66b2e59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 6 deletions

View File

@ -1828,9 +1828,9 @@ export class StarterSelectUiHandler extends MessageUiHandler {
// The persistent starter data to apply e.g. candy upgrades
const persistentStarterData = globalScene.gameData.starterData[this.lastSpecies.speciesId];
// The sanitized starter preferences
let starterAttributes = this.starterPreferences[this.lastSpecies.speciesId];
let starterAttributes = this.starterPreferences[this.lastSpecies.speciesId] ?? {};
// The original starter preferences
const originalStarterAttributes = this.originalStarterPreferences[this.lastSpecies.speciesId];
const originalStarterAttributes = this.originalStarterPreferences[this.lastSpecies.speciesId] ?? {};
// this gets the correct pokemon cursor depending on whether you're in the starter screen or the party icons
if (!this.starterIconsCursorObj.visible) {
@ -3408,8 +3408,9 @@ export class StarterSelectUiHandler extends MessageUiHandler {
if (species) {
const defaultDexAttr = this.getCurrentDexProps(species.speciesId);
const defaultProps = globalScene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
// Bang is correct due to the `?` before variant
const variant = this.starterPreferences[species.speciesId]?.variant
? (this.starterPreferences[species.speciesId].variant as Variant)
? (this.starterPreferences[species.speciesId]!.variant as Variant)
: defaultProps.variant;
const tint = getVariantTint(variant);
this.pokemonShinyIcon.setFrame(getVariantIcon(variant)).setTint(tint);

View File

@ -64,7 +64,7 @@ const StarterPrefers_DEFAULT: string = "{}";
let StarterPrefers_private_latest: string = StarterPrefers_DEFAULT;
export interface StarterPreferences {
[key: number]: StarterAttributes;
[key: number]: StarterAttributes | undefined;
}
// called on starter selection show once
@ -74,10 +74,27 @@ export function loadStarterPreferences(): StarterPreferences {
localStorage.getItem(`starterPrefs_${loggedInUser?.username}`) || StarterPrefers_DEFAULT),
);
}
// called on starter selection clear, always
/**
* Check if an object has no properties of its own (its shape is `{}`)
* @param obj - Object to check
* @returns - Whether the object is bare
*/
export function isBareObject(obj: object): boolean {
for (const _ in obj) {
return false;
}
return true;
}
export function saveStarterPreferences(prefs: StarterPreferences): void {
const pStr: string = JSON.stringify(prefs);
// Fastest way to check if an object has any properties (does no allocation)
if (isBareObject(prefs)) {
console.warn("Refusing to save empty starter preferences");
return;
}
// no reason to store `{}` (for starters not customized)
const pStr: string = JSON.stringify(prefs, (_, value) => (isBareObject(value) ? undefined : value));
if (pStr !== StarterPrefers_private_latest) {
// something changed, store the update
localStorage.setItem(`starterPrefs_${loggedInUser?.username}`, pStr);