diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index af97a4e65..89cfa8fac 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -75,6 +75,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public friendship: integer; public metLevel: integer; public metBiome: Biome | -1; + public luck: integer; public pauseEvolutions: boolean; public pokerus: boolean; @@ -142,6 +143,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.status = dataSource.status; this.friendship = dataSource.friendship !== undefined ? dataSource.friendship : this.species.baseFriendship; this.metLevel = dataSource.metLevel || 5; + this.luck = dataSource.luck; this.metBiome = dataSource.metBiome; this.pauseEvolutions = dataSource.pauseEvolutions; this.pokerus = !!dataSource.pokerus; @@ -189,6 +191,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.generateFusionSpecies(); } } + + this.luck = this.isShiny() ? this.variant + this.fusionVariant : 0; } this.generateName(); diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 54484a1e0..a4b369d40 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -1518,7 +1518,7 @@ export class ModifierTypeOption { } export function getPartyLuckValue(party: Pokemon[]): integer { - return Phaser.Math.Clamp(party.map(p => p.isFainted() || !p.isShiny() ? 0 : !p.isFusion() || !p.shiny || !p.fusionShiny ? p.variant + 1 : (p.variant + 1) + (p.fusionVariant + 1)) + return Phaser.Math.Clamp(party.map(p => p.isFainted() ? 0 : p.luck) .reduce((total: integer, value: integer) => total += value, 0), 0, 14); } diff --git a/src/phases.ts b/src/phases.ts index 535a6c2b2..640f47592 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -497,6 +497,7 @@ export class SelectStarterPhase extends Phase { starterPokemon.tryPopulateMoveset(starter.moveset); if (starter.passive) starterPokemon.passive = true; + starterPokemon.luck = this.scene.gameData.getDexAttrLuck(this.scene.gameData.dexData[starter.species.speciesId].caughtAttr); if (starter.pokerus) starterPokemon.pokerus = true; if (this.scene.gameMode.isSplicedOnly) diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 23c3f24af..e11c2dcc5 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -1189,6 +1189,10 @@ export class GameData { return Math.pow(2, this.getSpeciesDefaultNature(species)); } + getDexAttrLuck(dexAttr: bigint): integer { + return dexAttr & DexAttr.SHINY ? dexAttr & DexAttr.VARIANT_3 ? 3 : dexAttr & DexAttr.VARIANT_2 ? 2 : 1 : 0; + } + getNaturesForAttr(natureAttr: integer): Nature[] { let ret: Nature[] = []; for (let n = 0; n < 25; n++) { diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 8ad14d5ca..2fc4cac2b 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -36,6 +36,7 @@ export default class PokemonData { public friendship: integer; public metLevel: integer; public metBiome: Biome | -1; + public luck: integer; public pauseEvolutions: boolean; public pokerus: boolean; @@ -75,6 +76,7 @@ export default class PokemonData { this.friendship = source.friendship !== undefined ? source.friendship : getPokemonSpecies(this.species).baseFriendship; this.metLevel = source.metLevel || 5; this.metBiome = source.metBiome !== undefined ? source.metBiome : -1; + this.luck = source.luck !== undefined ? source.luck : (source.shiny ? (source.variant + 1) : 0) + (source.fusionShiny ? source.fusionVariant + 1 : 0); if (!forHistory) this.pauseEvolutions = !!source.pauseEvolutions; this.pokerus = !!source.pokerus; diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 369dcf44f..2fd67ac04 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -97,6 +97,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { private pokemonGrowthRateText: Phaser.GameObjects.Text; private type1Icon: Phaser.GameObjects.Sprite; private type2Icon: Phaser.GameObjects.Sprite; + private pokemonLuckLabelText: Phaser.GameObjects.Text; + private pokemonLuckText: Phaser.GameObjects.Text; private pokemonGenderText: Phaser.GameObjects.Text; private pokemonUncaughtText: Phaser.GameObjects.Text; private pokemonAbilityLabelText: Phaser.GameObjects.Text; @@ -418,6 +420,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.type2Icon.setOrigin(0, 0); this.starterSelectContainer.add(this.type2Icon); + this.pokemonLuckLabelText = addTextObject(this.scene, 8, 89, 'Luck:', TextStyle.WINDOW_ALT, { fontSize: '56px' }); + this.pokemonLuckLabelText.setOrigin(0, 0); + this.starterSelectContainer.add(this.pokemonLuckLabelText); + + this.pokemonLuckText = addTextObject(this.scene, 8 + this.pokemonLuckLabelText.displayWidth + 2, 89, '0', TextStyle.WINDOW, { fontSize: '56px' }); + this.pokemonLuckText.setOrigin(0, 0); + this.starterSelectContainer.add(this.pokemonLuckText); + this.pokemonCandyIcon = this.scene.add.sprite(1, 12, 'items', 'candy'); this.pokemonCandyIcon.setScale(0.5); this.pokemonCandyIcon.setOrigin(0, 0); @@ -1249,6 +1259,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (this.speciesStarterDexEntry?.caughtAttr) { const colorScheme = starterColors[species.speciesId]; + const luck = this.scene.gameData.getDexAttrLuck(this.speciesStarterDexEntry.caughtAttr); + this.pokemonLuckText.setVisible(!!luck); + this.pokemonLuckText.setText(luck.toString()); + this.pokemonLuckText.setTint(getVariantTint(Math.min(luck - 1, 2) as Variant)); + this.pokemonLuckLabelText.setVisible(this.pokemonLuckText.visible); + this.pokemonGrowthRateText.setText(Utils.toReadableString(GrowthRate[species.growthRate])); this.pokemonGrowthRateText.setColor(getGrowthRateColor(species.growthRate)); this.pokemonGrowthRateText.setShadowColor(getGrowthRateColor(species.growthRate, true)); @@ -1310,6 +1326,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonGrowthRateLabelText.setVisible(false); this.type1Icon.setVisible(false); this.type2Icon.setVisible(false); + this.pokemonLuckLabelText.setVisible(false); + this.pokemonLuckText.setVisible(false); this.pokemonUncaughtText.setVisible(true); this.pokemonAbilityLabelText.setVisible(false); this.pokemonPassiveLabelText.setVisible(false); @@ -1334,6 +1352,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonGrowthRateLabelText.setVisible(false); this.type1Icon.setVisible(false); this.type2Icon.setVisible(false); + this.pokemonLuckLabelText.setVisible(false); + this.pokemonLuckText.setVisible(false); this.pokemonUncaughtText.setVisible(!!species); this.pokemonAbilityLabelText.setVisible(false); this.pokemonPassiveLabelText.setVisible(false); diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index e6f3d2233..c06b16df4 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -16,7 +16,7 @@ import { getBiomeName } from "../data/biomes"; import { Nature, getNatureStatMultiplier } from "../data/nature"; import { loggedInUser } from "../account"; import { PlayerGender } from "../system/game-data"; -import { getVariantTint } from "#app/data/variant"; +import { Variant, getVariantTint } from "#app/data/variant"; enum Page { PROFILE, @@ -604,6 +604,17 @@ export default class SummaryUiHandler extends UiHandler { if (this.pokemon.isTerastallized()) profileContainer.add(getTypeIcon(types.length, this.pokemon.getTeraType(), true)); + if (this.pokemon.luck) { + const luckLabelText = addTextObject(this.scene, 141, 28, 'Luck:', TextStyle.SUMMARY_ALT); + luckLabelText.setOrigin(0, 0); + profileContainer.add(luckLabelText); + + const luckText = addTextObject(this.scene, 141 + luckLabelText.displayWidth + 2, 28, this.pokemon.luck.toString(), TextStyle.SUMMARY); + luckText.setOrigin(0, 0); + luckText.setTint(getVariantTint((Math.min(this.pokemon.luck - 1, 2)) as Variant)); + profileContainer.add(luckText); + } + const ability = this.pokemon.getAbility(true); const abilityNameText = addTextObject(this.scene, 7, 66, ability.name, TextStyle.SUMMARY_ALT);