mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-02-06 16:17:33 +00:00
[Bug] Starter select default attributes fixes (#3870)
* Test changes to starter ui stuff for edge case stuff to fix * Minor bug fixes * [starter-ui] cleanup outdated fix * use existing method to get the default form from the caught attributes * clear the existing StarterPreferences of potential invalid values * remember the last variant used even when disabling shiny form * fix variant and shiny checks for edge case with variant flags but no shiny flag * more fixes for invalid starter prefs and default settings --------- Co-authored-by: Opaque02 <66582645+Opaque02@users.noreply.github.com> Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com>
This commit is contained in:
parent
b2cd21bcb1
commit
e4da48f51a
@ -243,6 +243,8 @@ export class StarterPrefs {
|
|||||||
if (pStr !== StarterPrefers_private_latest) {
|
if (pStr !== StarterPrefers_private_latest) {
|
||||||
// something changed, store the update
|
// something changed, store the update
|
||||||
localStorage.setItem(`starterPrefs_${loggedInUser?.username}`, pStr);
|
localStorage.setItem(`starterPrefs_${loggedInUser?.username}`, pStr);
|
||||||
|
// update the latest prefs
|
||||||
|
StarterPrefers_private_latest = pStr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -915,7 +915,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.allSpecies.forEach((species, s) => {
|
this.allSpecies.forEach((species, s) => {
|
||||||
const icon = this.starterContainers[s].icon;
|
const icon = this.starterContainers[s].icon;
|
||||||
const dexEntry = this.scene.gameData.dexData[species.speciesId];
|
const dexEntry = this.scene.gameData.dexData[species.speciesId];
|
||||||
this.starterPreferences[species.speciesId] = this.starterPreferences[species.speciesId] ?? {};
|
|
||||||
|
// Initialize the StarterAttributes for this species
|
||||||
|
this.starterPreferences[species.speciesId] = this.initStarterPrefs(species);
|
||||||
|
|
||||||
if (dexEntry.caughtAttr) {
|
if (dexEntry.caughtAttr) {
|
||||||
icon.clearTint();
|
icon.clearTint();
|
||||||
@ -942,6 +944,93 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the starter attributes for the given PokemonSpecies, after sanitizing them.
|
||||||
|
* If somehow a preference is set for a form, variant, gender, ability or nature
|
||||||
|
* that wasn't actually unlocked or is invalid it will be cleared here
|
||||||
|
*
|
||||||
|
* @param species The species to get Starter Preferences for
|
||||||
|
* @returns StarterAttributes for the species
|
||||||
|
*/
|
||||||
|
initStarterPrefs(species: PokemonSpecies): StarterAttributes {
|
||||||
|
const starterAttributes = this.starterPreferences[species.speciesId];
|
||||||
|
const dexEntry = this.scene.gameData.dexData[species.speciesId];
|
||||||
|
const starterData = this.scene.gameData.starterData[species.speciesId];
|
||||||
|
|
||||||
|
// no preferences or Pokemon wasn't caught, return empty attribute
|
||||||
|
if (!starterAttributes || !dexEntry.caughtAttr) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const caughtAttr = dexEntry.caughtAttr;
|
||||||
|
|
||||||
|
const hasShiny = caughtAttr & DexAttr.SHINY;
|
||||||
|
const hasNonShiny = caughtAttr & DexAttr.NON_SHINY;
|
||||||
|
if (starterAttributes.shiny && !hasShiny) {
|
||||||
|
// shiny form wasn't unlocked, purging shiny and variant setting
|
||||||
|
delete starterAttributes.shiny;
|
||||||
|
delete starterAttributes.variant;
|
||||||
|
} else if (starterAttributes.shiny === false && !hasNonShiny) {
|
||||||
|
// non shiny form wasn't unlocked, purging shiny setting
|
||||||
|
delete starterAttributes.shiny;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (starterAttributes.variant !== undefined && !isNaN(starterAttributes.variant)) {
|
||||||
|
const unlockedVariants = [
|
||||||
|
hasNonShiny,
|
||||||
|
hasShiny && caughtAttr & DexAttr.DEFAULT_VARIANT,
|
||||||
|
hasShiny && caughtAttr & DexAttr.VARIANT_2,
|
||||||
|
hasShiny && caughtAttr & DexAttr.VARIANT_3
|
||||||
|
];
|
||||||
|
if (!unlockedVariants[starterAttributes.variant + 1]) { // add 1 as -1 = non-shiny
|
||||||
|
// requested variant wasn't unlocked, purging setting
|
||||||
|
delete starterAttributes.variant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (starterAttributes.female !== undefined) {
|
||||||
|
if (!(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)) {
|
||||||
|
// requested gender wasn't unlocked, purging setting
|
||||||
|
delete starterAttributes.female;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (starterAttributes.ability !== undefined) {
|
||||||
|
const speciesHasSingleAbility = species.ability2 === species.ability1;
|
||||||
|
const abilityAttr = starterData.abilityAttr;
|
||||||
|
const hasAbility1 = abilityAttr & AbilityAttr.ABILITY_1;
|
||||||
|
const hasAbility2 = abilityAttr & AbilityAttr.ABILITY_2;
|
||||||
|
const hasHiddenAbility = abilityAttr & AbilityAttr.ABILITY_HIDDEN;
|
||||||
|
// Due to a past bug it is possible that some Pokemon with a single ability have the ability2 flag
|
||||||
|
// In this case, we only count ability2 as valid if ability1 was not unlocked, otherwise we ignore it
|
||||||
|
const unlockedAbilities = [
|
||||||
|
hasAbility1,
|
||||||
|
speciesHasSingleAbility ? hasAbility2 && !hasAbility1 : hasAbility2,
|
||||||
|
hasHiddenAbility
|
||||||
|
];
|
||||||
|
if (!unlockedAbilities[starterAttributes.ability]) {
|
||||||
|
// requested ability wasn't unlocked, purging setting
|
||||||
|
delete starterAttributes.ability;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedForm = starterAttributes.form;
|
||||||
|
if (selectedForm !== undefined && (!species.forms[selectedForm]?.isStarterSelectable || !(caughtAttr & this.scene.gameData.getFormAttr(selectedForm)))) {
|
||||||
|
// requested form wasn't unlocked/isn't a starter form, purging setting
|
||||||
|
delete starterAttributes.form;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (starterAttributes.nature !== undefined) {
|
||||||
|
const unlockedNatures = this.scene.gameData.getNaturesForAttr(dexEntry.natureAttr);
|
||||||
|
if (unlockedNatures.indexOf(starterAttributes.nature as unknown as Nature) < 0) {
|
||||||
|
// requested nature wasn't unlocked, purging setting
|
||||||
|
delete starterAttributes.nature;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return starterAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the selections for all filters to their default starting value
|
* Set the selections for all filters to their default starting value
|
||||||
*/
|
*/
|
||||||
@ -1749,9 +1838,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
switch (button) {
|
switch (button) {
|
||||||
case Button.CYCLE_SHINY:
|
case Button.CYCLE_SHINY:
|
||||||
if (this.canCycleShiny) {
|
if (this.canCycleShiny) {
|
||||||
const newVariant = props.variant;
|
const newVariant = starterAttributes.variant ? starterAttributes.variant as Variant : props.variant;
|
||||||
starterAttributes.shiny = starterAttributes.shiny ? !starterAttributes.shiny : true;
|
starterAttributes.shiny = starterAttributes.shiny ? !starterAttributes.shiny : true;
|
||||||
this.setSpeciesDetails(this.lastSpecies, !props.shiny, undefined, undefined, props.shiny ? 0 : undefined, undefined, undefined);
|
this.setSpeciesDetails(this.lastSpecies, !props.shiny, undefined, undefined, props.shiny ? 0 : newVariant, undefined, undefined);
|
||||||
if (starterAttributes.shiny) {
|
if (starterAttributes.shiny) {
|
||||||
this.scene.playSound("se/sparkle");
|
this.scene.playSound("se/sparkle");
|
||||||
// Set the variant label to the shiny tint
|
// Set the variant label to the shiny tint
|
||||||
@ -1760,10 +1849,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.pokemonShinyIcon.setTint(tint);
|
this.pokemonShinyIcon.setTint(tint);
|
||||||
this.pokemonShinyIcon.setVisible(true);
|
this.pokemonShinyIcon.setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
// starterAttributes.variant = 0;
|
|
||||||
if (starterAttributes?.variant) {
|
|
||||||
delete starterAttributes.variant;
|
|
||||||
}
|
|
||||||
this.pokemonShinyIcon.setVisible(false);
|
this.pokemonShinyIcon.setVisible(false);
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
@ -2276,43 +2361,39 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
container.cost = this.scene.gameData.getSpeciesStarterValue(container.species.speciesId);
|
container.cost = this.scene.gameData.getSpeciesStarterValue(container.species.speciesId);
|
||||||
|
|
||||||
// First, ensure you have the caught attributes for the species else default to bigint 0
|
// First, ensure you have the caught attributes for the species else default to bigint 0
|
||||||
const isCaught = this.scene.gameData.dexData[container.species.speciesId]?.caughtAttr || BigInt(0);
|
const caughtAttr = this.scene.gameData.dexData[container.species.speciesId]?.caughtAttr || BigInt(0);
|
||||||
|
const starterData = this.scene.gameData.starterData[container.species.speciesId];
|
||||||
// Define the variables based on whether their respective variants have been caught
|
|
||||||
const isVariant3Caught = !!(isCaught & DexAttr.VARIANT_3);
|
|
||||||
const isVariant2Caught = !!(isCaught & DexAttr.VARIANT_2);
|
|
||||||
const isVariantCaught = !!(isCaught & DexAttr.SHINY);
|
|
||||||
const isUncaught = !isCaught && !isVariantCaught && !isVariant2Caught && !isVariant3Caught;
|
|
||||||
const isPassiveUnlocked = this.scene.gameData.starterData[container.species.speciesId].passiveAttr > 0;
|
|
||||||
const isPassiveUnlockable = this.isPassiveAvailable(container.species.speciesId) && !isPassiveUnlocked;
|
|
||||||
const isCostReduced = this.scene.gameData.starterData[container.species.speciesId].valueReduction > 0;
|
|
||||||
const isCostReductionUnlockable = this.isValueReductionAvailable(container.species.speciesId);
|
|
||||||
const isFavorite = this.starterPreferences[container.species.speciesId]?.favorite ?? false;
|
|
||||||
|
|
||||||
const isWin = this.scene.gameData.starterData[container.species.speciesId].classicWinCount > 0;
|
|
||||||
const isNotWin = this.scene.gameData.starterData[container.species.speciesId].classicWinCount === 0;
|
|
||||||
const isUndefined = this.scene.gameData.starterData[container.species.speciesId].classicWinCount === undefined;
|
|
||||||
const isHA = this.scene.gameData.starterData[container.species.speciesId].abilityAttr & AbilityAttr.ABILITY_HIDDEN;
|
|
||||||
const isEggPurchasable = this.isSameSpeciesEggAvailable(container.species.speciesId);
|
|
||||||
|
|
||||||
|
// Gen filter
|
||||||
const fitsGen = this.filterBar.getVals(DropDownColumn.GEN).includes(container.species.generation);
|
const fitsGen = this.filterBar.getVals(DropDownColumn.GEN).includes(container.species.generation);
|
||||||
|
|
||||||
|
// Type filter
|
||||||
const fitsType = this.filterBar.getVals(DropDownColumn.TYPES).some(type => container.species.isOfType((type as number) - 1));
|
const fitsType = this.filterBar.getVals(DropDownColumn.TYPES).some(type => container.species.isOfType((type as number) - 1));
|
||||||
|
|
||||||
|
// Caught / Shiny filter
|
||||||
|
const isNonShinyCaught = !!(caughtAttr & DexAttr.NON_SHINY);
|
||||||
|
const isShinyCaught = !!(caughtAttr & DexAttr.SHINY);
|
||||||
|
const isVariant1Caught = isShinyCaught && !!(caughtAttr & DexAttr.DEFAULT_VARIANT);
|
||||||
|
const isVariant2Caught = isShinyCaught && !!(caughtAttr & DexAttr.VARIANT_2);
|
||||||
|
const isVariant3Caught = isShinyCaught && !!(caughtAttr & DexAttr.VARIANT_3);
|
||||||
|
const isUncaught = !isNonShinyCaught && !isVariant1Caught && !isVariant2Caught && !isVariant3Caught;
|
||||||
const fitsCaught = this.filterBar.getVals(DropDownColumn.CAUGHT).some(caught => {
|
const fitsCaught = this.filterBar.getVals(DropDownColumn.CAUGHT).some(caught => {
|
||||||
if (caught === "SHINY3") {
|
if (caught === "SHINY3") {
|
||||||
return isVariant3Caught;
|
return isVariant3Caught;
|
||||||
} else if (caught === "SHINY2") {
|
} else if (caught === "SHINY2") {
|
||||||
return isVariant2Caught && !isVariant3Caught;
|
return isVariant2Caught && !isVariant3Caught;
|
||||||
} else if (caught === "SHINY") {
|
} else if (caught === "SHINY") {
|
||||||
return isVariantCaught && !isVariant2Caught && !isVariant3Caught;
|
return isVariant1Caught && !isVariant2Caught && !isVariant3Caught;
|
||||||
} else if (caught === "NORMAL") {
|
} else if (caught === "NORMAL") {
|
||||||
return isCaught && !isVariantCaught && !isVariant2Caught && !isVariant3Caught;
|
return isNonShinyCaught && !isVariant1Caught && !isVariant2Caught && !isVariant3Caught;
|
||||||
} else if (caught === "UNCAUGHT") {
|
} else if (caught === "UNCAUGHT") {
|
||||||
return isUncaught;
|
return isUncaught;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Passive Filter
|
||||||
|
const isPassiveUnlocked = starterData.passiveAttr > 0;
|
||||||
|
const isPassiveUnlockable = this.isPassiveAvailable(container.species.speciesId) && !isPassiveUnlocked;
|
||||||
const fitsPassive = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => {
|
const fitsPassive = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => {
|
||||||
if (unlocks.val === "PASSIVE" && unlocks.state === DropDownState.ON) {
|
if (unlocks.val === "PASSIVE" && unlocks.state === DropDownState.ON) {
|
||||||
return isPassiveUnlocked;
|
return isPassiveUnlocked;
|
||||||
@ -2325,6 +2406,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Cost Reduction Filter
|
||||||
|
const isCostReduced = starterData.valueReduction > 0;
|
||||||
|
const isCostReductionUnlockable = this.isValueReductionAvailable(container.species.speciesId);
|
||||||
const fitsCostReduction = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => {
|
const fitsCostReduction = this.filterBar.getVals(DropDownColumn.UNLOCKS).some(unlocks => {
|
||||||
if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.ON) {
|
if (unlocks.val === "COST_REDUCTION" && unlocks.state === DropDownState.ON) {
|
||||||
return isCostReduced;
|
return isCostReduced;
|
||||||
@ -2337,6 +2421,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Favorite Filter
|
||||||
|
const isFavorite = this.starterPreferences[container.species.speciesId]?.favorite ?? false;
|
||||||
const fitsFavorite = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
const fitsFavorite = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||||
if (misc.val === "FAVORITE" && misc.state === DropDownState.ON) {
|
if (misc.val === "FAVORITE" && misc.state === DropDownState.ON) {
|
||||||
return isFavorite;
|
return isFavorite;
|
||||||
@ -2349,28 +2435,34 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Ribbon / Classic Win Filter
|
||||||
|
const hasWon = starterData.classicWinCount > 0;
|
||||||
|
const hasNotWon = starterData.classicWinCount === 0;
|
||||||
|
const isUndefined = starterData.classicWinCount === undefined;
|
||||||
const fitsWin = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
const fitsWin = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||||
if (container.species.speciesId < 10) {
|
|
||||||
}
|
|
||||||
if (misc.val === "WIN" && misc.state === DropDownState.ON) {
|
if (misc.val === "WIN" && misc.state === DropDownState.ON) {
|
||||||
return isWin;
|
return hasWon;
|
||||||
} else if (misc.val === "WIN" && misc.state === DropDownState.EXCLUDE) {
|
} else if (misc.val === "WIN" && misc.state === DropDownState.EXCLUDE) {
|
||||||
return isNotWin || isUndefined;
|
return hasNotWon || isUndefined;
|
||||||
} else if (misc.val === "WIN" && misc.state === DropDownState.OFF) {
|
} else if (misc.val === "WIN" && misc.state === DropDownState.OFF) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// HA Filter
|
||||||
|
const hasHA = starterData.abilityAttr & AbilityAttr.ABILITY_HIDDEN;
|
||||||
const fitsHA = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
const fitsHA = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||||
if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.ON) {
|
if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.ON) {
|
||||||
return isHA;
|
return hasHA;
|
||||||
} else if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.EXCLUDE) {
|
} else if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.EXCLUDE) {
|
||||||
return !isHA;
|
return !hasHA;
|
||||||
} else if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.OFF) {
|
} else if (misc.val === "HIDDEN_ABILITY" && misc.state === DropDownState.OFF) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Egg Purchasable Filter
|
||||||
|
const isEggPurchasable = this.isSameSpeciesEggAvailable(container.species.speciesId);
|
||||||
const fitsEgg = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
const fitsEgg = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||||
if (misc.val === "EGG" && misc.state === DropDownState.ON) {
|
if (misc.val === "EGG" && misc.state === DropDownState.ON) {
|
||||||
return isEggPurchasable;
|
return isEggPurchasable;
|
||||||
@ -2381,6 +2473,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Pokerus Filter
|
||||||
const fitsPokerus = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
const fitsPokerus = this.filterBar.getVals(DropDownColumn.MISC).some(misc => {
|
||||||
if (misc.val === "POKERUS" && misc.state === DropDownState.ON) {
|
if (misc.val === "POKERUS" && misc.state === DropDownState.ON) {
|
||||||
return this.pokerusSpecies.includes(container.species);
|
return this.pokerusSpecies.includes(container.species);
|
||||||
@ -2579,56 +2672,13 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.natureCursor = species ? this.scene.gameData.getSpeciesDefaultNature(species) : 0;
|
this.natureCursor = species ? this.scene.gameData.getSpeciesDefaultNature(species) : 0;
|
||||||
|
|
||||||
const starterAttributes : StarterAttributes | null = species ? {...this.starterPreferences[species.speciesId]} : null;
|
const starterAttributes : StarterAttributes | null = species ? {...this.starterPreferences[species.speciesId]} : null;
|
||||||
// validate starterAttributes
|
|
||||||
if (starterAttributes) {
|
|
||||||
// this may cause changes so we created a copy of the attributes before
|
|
||||||
if (starterAttributes.variant && !isNaN(starterAttributes.variant)) {
|
|
||||||
if (![
|
|
||||||
this.speciesStarterDexEntry!.caughtAttr & DexAttr.NON_SHINY, // TODO: is that bang correct?
|
|
||||||
this.speciesStarterDexEntry!.caughtAttr & DexAttr.DEFAULT_VARIANT, // TODO: is that bang correct?
|
|
||||||
this.speciesStarterDexEntry!.caughtAttr & DexAttr.VARIANT_2, // TODO: is that bang correct?
|
|
||||||
this.speciesStarterDexEntry!.caughtAttr & DexAttr.VARIANT_3 // TODO: is that bang correct?
|
|
||||||
][starterAttributes.variant+1]) { // add 1 as -1 = non-shiny
|
|
||||||
// requested variant wasn't unlocked, purging setting
|
|
||||||
delete starterAttributes.variant;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof starterAttributes.female !== "boolean" || !(starterAttributes.female ?
|
|
||||||
this.speciesStarterDexEntry!.caughtAttr & DexAttr.FEMALE : // TODO: is this bang correct?
|
|
||||||
this.speciesStarterDexEntry!.caughtAttr & DexAttr.MALE // TODO: is this bang correct?
|
|
||||||
)) {
|
|
||||||
// requested gender wasn't unlocked, purging setting
|
|
||||||
delete starterAttributes.female;
|
|
||||||
}
|
|
||||||
|
|
||||||
const abilityAttr = this.scene.gameData.starterData[species!.speciesId].abilityAttr; // TODO: is this bang correct?
|
|
||||||
if (![
|
|
||||||
abilityAttr & AbilityAttr.ABILITY_1,
|
|
||||||
species!.ability2 ? (abilityAttr & AbilityAttr.ABILITY_2) : abilityAttr & AbilityAttr.ABILITY_HIDDEN, // TODO: is this bang correct?
|
|
||||||
species!.ability2 && abilityAttr & AbilityAttr.ABILITY_HIDDEN // TODO: is this bang correct?
|
|
||||||
][starterAttributes.ability!]) { // TODO: is this bang correct?
|
|
||||||
// requested ability wasn't unlocked, purging setting
|
|
||||||
delete starterAttributes.ability;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(species?.forms[starterAttributes.form!]?.isStarterSelectable && this.speciesStarterDexEntry!.caughtAttr & this.scene.gameData.getFormAttr(starterAttributes.form!))) { // TODO: are those bangs correct?
|
|
||||||
// requested form wasn't unlocked/isn't a starter form, purging setting
|
|
||||||
delete starterAttributes.form;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.scene.gameData.getNaturesForAttr(this.speciesStarterDexEntry?.natureAttr).indexOf(starterAttributes.nature as unknown as Nature) < 0) {
|
|
||||||
// requested nature wasn't unlocked, purging setting
|
|
||||||
delete starterAttributes.nature;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (starterAttributes?.nature) {
|
if (starterAttributes?.nature) {
|
||||||
// load default nature from stater save data, if set
|
// load default nature from stater save data, if set
|
||||||
this.natureCursor = starterAttributes.nature;
|
this.natureCursor = starterAttributes.nature;
|
||||||
}
|
}
|
||||||
if (starterAttributes?.ability && !isNaN(starterAttributes.ability)) {
|
if (starterAttributes?.ability && !isNaN(starterAttributes.ability)) {
|
||||||
// load default nature from stater save data, if set
|
// load default ability from stater save data, if set
|
||||||
this.abilityCursor = starterAttributes.ability;
|
this.abilityCursor = starterAttributes.ability;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2675,7 +2725,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.pokemonLuckText.setText(luck.toString());
|
this.pokemonLuckText.setText(luck.toString());
|
||||||
this.pokemonLuckText.setTint(getVariantTint(Math.min(luck - 1, 2) as Variant));
|
this.pokemonLuckText.setTint(getVariantTint(Math.min(luck - 1, 2) as Variant));
|
||||||
this.pokemonLuckLabelText.setVisible(this.pokemonLuckText.visible);
|
this.pokemonLuckLabelText.setVisible(this.pokemonLuckText.visible);
|
||||||
this.pokemonShinyIcon.setVisible(this.starterPreferences[species.speciesId]?.shiny ?? false);
|
|
||||||
|
|
||||||
//Growth translate
|
//Growth translate
|
||||||
let growthReadable = Utils.toReadableString(GrowthRate[species.growthRate]);
|
let growthReadable = Utils.toReadableString(GrowthRate[species.growthRate]);
|
||||||
@ -2699,12 +2748,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.pokemonHatchedIcon.setFrame(getEggTierForSpecies(species));
|
this.pokemonHatchedIcon.setFrame(getEggTierForSpecies(species));
|
||||||
}
|
}
|
||||||
this.pokemonHatchedCountText.setText(`${this.speciesStarterDexEntry.hatchedCount}`);
|
this.pokemonHatchedCountText.setText(`${this.speciesStarterDexEntry.hatchedCount}`);
|
||||||
|
|
||||||
const defaultDexAttr = this.getCurrentDexProps(species.speciesId);
|
const defaultDexAttr = this.getCurrentDexProps(species.speciesId);
|
||||||
const defaultProps = this.scene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
|
const defaultProps = this.scene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr);
|
||||||
const variant = defaultProps.variant;
|
const variant = defaultProps.variant;
|
||||||
const tint = getVariantTint(variant);
|
const tint = getVariantTint(variant);
|
||||||
this.pokemonShinyIcon.setFrame(getVariantIcon(variant));
|
this.pokemonShinyIcon.setFrame(getVariantIcon(variant));
|
||||||
this.pokemonShinyIcon.setTint(tint);
|
this.pokemonShinyIcon.setTint(tint);
|
||||||
|
this.pokemonShinyIcon.setVisible(defaultProps.shiny);
|
||||||
this.pokemonCaughtHatchedContainer.setVisible(true);
|
this.pokemonCaughtHatchedContainer.setVisible(true);
|
||||||
if (pokemonPrevolutions.hasOwnProperty(species.speciesId)) {
|
if (pokemonPrevolutions.hasOwnProperty(species.speciesId)) {
|
||||||
this.pokemonCaughtHatchedContainer.setY(16);
|
this.pokemonCaughtHatchedContainer.setY(16);
|
||||||
@ -2894,21 +2945,13 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
const dexEntry = this.scene.gameData.dexData[species.speciesId];
|
const dexEntry = this.scene.gameData.dexData[species.speciesId];
|
||||||
const abilityAttr = this.scene.gameData.starterData[species.speciesId].abilityAttr;
|
const abilityAttr = this.scene.gameData.starterData[species.speciesId].abilityAttr;
|
||||||
|
|
||||||
const isCaught = this.scene.gameData.dexData[species.speciesId]?.caughtAttr || BigInt(0);
|
const caughtAttr = this.scene.gameData.dexData[species.speciesId]?.caughtAttr || BigInt(0);
|
||||||
const isVariant3Caught = !!(isCaught & DexAttr.VARIANT_3);
|
|
||||||
const isVariant2Caught = !!(isCaught & DexAttr.VARIANT_2);
|
|
||||||
const isDefaultVariantCaught = !!(isCaught & DexAttr.DEFAULT_VARIANT);
|
|
||||||
const isVariantCaught = !!(isCaught & DexAttr.SHINY);
|
|
||||||
const isMaleCaught = !!(isCaught & DexAttr.MALE);
|
|
||||||
const isFemaleCaught = !!(isCaught & DexAttr.FEMALE);
|
|
||||||
|
|
||||||
const starterAttributes = this.starterPreferences[species.speciesId];
|
|
||||||
|
|
||||||
const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId));
|
|
||||||
const defaultAbilityIndex = this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species);
|
|
||||||
const defaultNature = this.scene.gameData.getSpeciesDefaultNature(species);
|
|
||||||
|
|
||||||
if (!dexEntry.caughtAttr) {
|
if (!dexEntry.caughtAttr) {
|
||||||
|
const props = this.scene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId));
|
||||||
|
const defaultAbilityIndex = this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species);
|
||||||
|
const defaultNature = this.scene.gameData.getSpeciesDefaultNature(species);
|
||||||
|
|
||||||
if (shiny === undefined || shiny !== props.shiny) {
|
if (shiny === undefined || shiny !== props.shiny) {
|
||||||
shiny = props.shiny;
|
shiny = props.shiny;
|
||||||
}
|
}
|
||||||
@ -2927,83 +2970,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
if (natureIndex === undefined || natureIndex !== defaultNature) {
|
if (natureIndex === undefined || natureIndex !== defaultNature) {
|
||||||
natureIndex = defaultNature;
|
natureIndex = defaultNature;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// compare current shiny, formIndex, female, variant, abilityIndex, natureIndex with the caught ones
|
|
||||||
// if the current ones are not caught, we need to find the next caught ones
|
|
||||||
if (shiny) {
|
|
||||||
if (!(isVariantCaught || isVariant2Caught || isVariant3Caught)) {
|
|
||||||
shiny = false;
|
|
||||||
starterAttributes.shiny = false;
|
|
||||||
variant = 0;
|
|
||||||
starterAttributes.variant = 0;
|
|
||||||
} else {
|
|
||||||
shiny = true;
|
|
||||||
starterAttributes.shiny = true;
|
|
||||||
if (variant === 0 && !isDefaultVariantCaught) {
|
|
||||||
if (isVariant2Caught) {
|
|
||||||
variant = 1;
|
|
||||||
starterAttributes.variant = 1;
|
|
||||||
} else if (isVariant3Caught) {
|
|
||||||
variant = 2;
|
|
||||||
starterAttributes.variant = 2;
|
|
||||||
} else {
|
|
||||||
variant = 0;
|
|
||||||
starterAttributes.variant = 0;
|
|
||||||
}
|
|
||||||
} else if (variant === 1 && !isVariant2Caught) {
|
|
||||||
if (isVariantCaught) {
|
|
||||||
variant = 0;
|
|
||||||
starterAttributes.variant = 0;
|
|
||||||
} else if (isVariant3Caught) {
|
|
||||||
variant = 2;
|
|
||||||
starterAttributes.variant = 2;
|
|
||||||
} else {
|
|
||||||
variant = 0;
|
|
||||||
starterAttributes.variant = 0;
|
|
||||||
}
|
|
||||||
} else if (variant === 2 && !isVariant3Caught) {
|
|
||||||
if (isVariantCaught) {
|
|
||||||
variant = 0;
|
|
||||||
starterAttributes.variant = 0;
|
|
||||||
} else if (isVariant2Caught) {
|
|
||||||
variant = 1;
|
|
||||||
starterAttributes.variant = 1;
|
|
||||||
} else {
|
|
||||||
variant = 0;
|
|
||||||
starterAttributes.variant = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (female) {
|
|
||||||
if (!isFemaleCaught) {
|
|
||||||
female = false;
|
|
||||||
starterAttributes.female = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!isMaleCaught) {
|
|
||||||
female = true;
|
|
||||||
starterAttributes.female = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (species.forms) {
|
|
||||||
const formCount = species.forms.length;
|
|
||||||
let newFormIndex = formIndex??0;
|
|
||||||
if (species.forms[newFormIndex]) {
|
|
||||||
const isValidForm = species.forms[newFormIndex].isStarterSelectable && dexEntry.caughtAttr & this.scene.gameData.getFormAttr(newFormIndex);
|
|
||||||
if (!isValidForm) {
|
|
||||||
do {
|
|
||||||
newFormIndex = (newFormIndex + 1) % formCount;
|
|
||||||
if (species.forms[newFormIndex].isStarterSelectable && dexEntry.caughtAttr & this.scene.gameData.getFormAttr(newFormIndex)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (newFormIndex !== props.formIndex);
|
|
||||||
formIndex = newFormIndex;
|
|
||||||
starterAttributes.form = formIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.shinyOverlay.setVisible(shiny ?? false); // TODO: is false the correct default?
|
this.shinyOverlay.setVisible(shiny ?? false); // TODO: is false the correct default?
|
||||||
@ -3045,8 +3011,19 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
currentFilteredContainer.checkIconId(female, formIndex, shiny, variant);
|
currentFilteredContainer.checkIconId(female, formIndex, shiny, variant);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.canCycleShiny = isVariantCaught || isVariant2Caught || isVariant3Caught;
|
const isNonShinyCaught = !!(caughtAttr & DexAttr.NON_SHINY);
|
||||||
|
const isShinyCaught = !!(caughtAttr & DexAttr.SHINY);
|
||||||
|
const isVariant1Caught = isShinyCaught && !!(caughtAttr & DexAttr.DEFAULT_VARIANT);
|
||||||
|
const isVariant2Caught = isShinyCaught && !!(caughtAttr & DexAttr.VARIANT_2);
|
||||||
|
const isVariant3Caught = isShinyCaught && !!(caughtAttr & DexAttr.VARIANT_3);
|
||||||
|
|
||||||
|
this.canCycleShiny = isNonShinyCaught && isShinyCaught;
|
||||||
|
this.canCycleVariant = !!shiny && [ isVariant1Caught, isVariant2Caught, isVariant3Caught].filter(v => v).length > 1;
|
||||||
|
|
||||||
|
const isMaleCaught = !!(caughtAttr & DexAttr.MALE);
|
||||||
|
const isFemaleCaught = !!(caughtAttr & DexAttr.FEMALE);
|
||||||
this.canCycleGender = isMaleCaught && isFemaleCaught;
|
this.canCycleGender = isMaleCaught && isFemaleCaught;
|
||||||
|
|
||||||
const hasAbility1 = abilityAttr & AbilityAttr.ABILITY_1;
|
const hasAbility1 = abilityAttr & AbilityAttr.ABILITY_1;
|
||||||
let hasAbility2 = abilityAttr & AbilityAttr.ABILITY_2;
|
let hasAbility2 = abilityAttr & AbilityAttr.ABILITY_2;
|
||||||
const hasHiddenAbility = abilityAttr & AbilityAttr.ABILITY_HIDDEN;
|
const hasHiddenAbility = abilityAttr & AbilityAttr.ABILITY_HIDDEN;
|
||||||
@ -3061,10 +3038,11 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.canCycleAbility = [ hasAbility1, hasAbility2, hasHiddenAbility ].filter(a => a).length > 1;
|
this.canCycleAbility = [ hasAbility1, hasAbility2, hasHiddenAbility ].filter(a => a).length > 1;
|
||||||
|
|
||||||
this.canCycleForm = species.forms.filter(f => f.isStarterSelectable || !pokemonFormChanges[species.speciesId]?.find(fc => fc.formKey))
|
this.canCycleForm = species.forms.filter(f => f.isStarterSelectable || !pokemonFormChanges[species.speciesId]?.find(fc => fc.formKey))
|
||||||
.map((_, f) => dexEntry.caughtAttr & this.scene.gameData.getFormAttr(f)).filter(f => f).length > 1;
|
.map((_, f) => dexEntry.caughtAttr & this.scene.gameData.getFormAttr(f)).filter(f => f).length > 1;
|
||||||
this.canCycleNature = this.scene.gameData.getNaturesForAttr(dexEntry.natureAttr).length > 1;
|
this.canCycleNature = this.scene.gameData.getNaturesForAttr(dexEntry.natureAttr).length > 1;
|
||||||
this.canCycleVariant = !!shiny && [ dexEntry.caughtAttr & DexAttr.DEFAULT_VARIANT, dexEntry.caughtAttr & DexAttr.VARIANT_2, dexEntry.caughtAttr & DexAttr.VARIANT_3].filter(v => v).length > 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dexEntry.caughtAttr && species.malePercent !== null) {
|
if (dexEntry.caughtAttr && species.malePercent !== null) {
|
||||||
@ -3442,39 +3420,55 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
return canStart;
|
return canStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this creates a temporary dex attr props that we use to check whether a pokemon is valid for a challenge.
|
/**
|
||||||
* when checking for certain challenges (i.e. mono type), we need to check for form changes AND evolutions
|
* Creates a temporary dex attr props that will be used to check whether a pokemon is valid for a challenge
|
||||||
* However, since some pokemon can evolve based on their intial gender/form, we need a way to look for that
|
* and to display the correct shiny, variant, and form based on the StarterPreferences
|
||||||
* This temporary dex attr will therefore ONLY look at gender and form, since there's no cases of shinies/variants
|
*
|
||||||
* having different evolutions to their non shiny/variant part, and so those can be ignored
|
* @param speciesId the id of the species to get props for
|
||||||
* Since the current form and gender is stored in the starter preferences, this is where we get the values from
|
* @returns the dex props
|
||||||
*/
|
*/
|
||||||
getCurrentDexProps(speciesId: number): bigint {
|
getCurrentDexProps(speciesId: number): bigint {
|
||||||
let props = 0n;
|
let props = 0n;
|
||||||
|
const caughtAttr = this.scene.gameData.dexData[speciesId].caughtAttr;
|
||||||
|
|
||||||
if (this.starterPreferences[speciesId]?.female) { // this checks the gender of the pokemon
|
/* this checks the gender of the pokemon; this works by checking a) that the starter preferences for the species exist, and if so, is it female. If so, it'll add DexAttr.FEMALE to our temp props
|
||||||
|
* It then checks b) if the caughtAttr for the pokemon is female and NOT male - this means that the ONLY gender we've gotten is female, and we need to add DexAttr.FEMALE to our temp props
|
||||||
|
* If neither of these pass, we add DexAttr.MALE to our temp props
|
||||||
|
*/
|
||||||
|
if (this.starterPreferences[speciesId]?.female || ((caughtAttr & DexAttr.FEMALE) > 0n && (caughtAttr & DexAttr.MALE) === 0n)) {
|
||||||
props += DexAttr.FEMALE;
|
props += DexAttr.FEMALE;
|
||||||
} else {
|
} else {
|
||||||
props += DexAttr.MALE;
|
props += DexAttr.MALE;
|
||||||
}
|
}
|
||||||
if (this.starterPreferences[speciesId]?.shiny) {
|
/* This part is very similar to above, but instead of for gender, it checks for shiny within starter preferences.
|
||||||
|
* If they're not there, it checks the caughtAttr for shiny only (i.e. SHINY === true && NON_SHINY === false)
|
||||||
|
*/
|
||||||
|
if (this.starterPreferences[speciesId]?.shiny || ((caughtAttr & DexAttr.SHINY) > 0n && (caughtAttr & DexAttr.NON_SHINY) === 0n)) {
|
||||||
props += DexAttr.SHINY;
|
props += DexAttr.SHINY;
|
||||||
if (this.starterPreferences[speciesId]?.variant) {
|
if (this.starterPreferences[speciesId]?.variant) {
|
||||||
props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.variant)) * DexAttr.DEFAULT_VARIANT;
|
props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.variant)) * DexAttr.DEFAULT_VARIANT;
|
||||||
} else {
|
} else {
|
||||||
props += DexAttr.DEFAULT_VARIANT;
|
/* This calculates the correct variant if there's no starter preferences for it.
|
||||||
|
* This gets the lowest tier variant that you've caught (in line with other mechanics) and adds it to the temp props
|
||||||
|
*/
|
||||||
|
if ((caughtAttr & DexAttr.DEFAULT_VARIANT) > 0) {
|
||||||
|
props += DexAttr.DEFAULT_VARIANT;
|
||||||
|
}
|
||||||
|
if ((caughtAttr & DexAttr.VARIANT_2) > 0) {
|
||||||
|
props += DexAttr.VARIANT_2;
|
||||||
|
} else if ((caughtAttr & DexAttr.VARIANT_3) > 0) {
|
||||||
|
props += DexAttr.VARIANT_3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
props += DexAttr.NON_SHINY;
|
props += DexAttr.NON_SHINY;
|
||||||
if (this.starterPreferences[speciesId]?.variant) {
|
|
||||||
delete this.starterPreferences[speciesId].variant;
|
|
||||||
}
|
|
||||||
props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant
|
props += DexAttr.DEFAULT_VARIANT; // we add the default variant here because non shiny versions are listed as default variant
|
||||||
}
|
}
|
||||||
if (this.starterPreferences[speciesId]?.form) { // this checks for the form of the pokemon
|
if (this.starterPreferences[speciesId]?.form) { // this checks for the form of the pokemon
|
||||||
props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.form)) * DexAttr.DEFAULT_FORM;
|
props += BigInt(Math.pow(2, this.starterPreferences[speciesId]?.form)) * DexAttr.DEFAULT_FORM;
|
||||||
} else {
|
} else {
|
||||||
props += DexAttr.DEFAULT_FORM;
|
// Get the first unlocked form
|
||||||
|
props += this.scene.gameData.getFormAttr(this.scene.gameData.getFormIndex(caughtAttr));
|
||||||
}
|
}
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user