diff --git a/src/data/balance/rates.ts b/src/data/balance/rates.ts index 778740e2106..c5eaf40e608 100644 --- a/src/data/balance/rates.ts +++ b/src/data/balance/rates.ts @@ -12,6 +12,28 @@ export const BASE_SHINY_CHANCE = 64; export const BASE_HIDDEN_ABILITY_CHANCE = 256; // #region Egg properties + +// Threshold x at which a gacha egg is determined to be a certain tier +// Specifically, the tier is determined by the highest threshold a random value between 0-255 meets or exceeds +// Legendary Up Gacha raises these thresholds by 1, thereby giving Legendary eggs 2/256 chance +export const GACHA_DEFAULT_COMMON_EGG_THRESHOLD = 52; // Default 204/256 chance, 203/256 chance in Legendary Up Gacha +export const GACHA_DEFAULT_RARE_EGG_THRESHOLD = 8; // Default 44/256 chance +export const GACHA_DEFAULT_EPIC_EGG_THRESHOLD = 1; // Default 7/256 chance, leaving Legendary as 1/256 chance +export const GACHA_LEGENDARY_UP_THRESHOLD_OFFSET = 1; // The offset to threshold for Legendary Up gacha eggs. +x/256 Legendary Egg chance, -x/256 Common Egg chance + +// The number of eggs without finding a certain tier egg it takes for egg pity to kick in and that tier to be forced +// These numbers are roughly the 80% mark. That is, 80% of the time you'll get an egg before this gets triggered. +export const EGG_PITY_LEGENDARY_THRESHOLD = 412; +export const EGG_PITY_EPIC_THRESHOLD = 59; +export const EGG_PITY_RARE_THRESHOLD = 9; + +// Waves to hatch an egg of a given tier +export const HATCH_WAVES_COMMON_EGG = 10; +export const HATCH_WAVES_RARE_EGG = 25; +export const HATCH_WAVES_EPIC_EGG = 50; +export const HATCH_WAVES_LEGENDARY_EGG = 100; +export const HATCH_WAVES_MANAPHY_EGG = 50; + // Rates for specific random properties in 1/x export const GACHA_DEFAULT_SHINY_RATE = 128; export const GACHA_SHINY_UP_SHINY_RATE = 64; @@ -24,3 +46,8 @@ export const GACHA_EGG_HA_RATE = 192; export const GACHA_DEFAULT_RARE_EGGMOVE_RATE = 6; export const SAME_SPECIES_EGG_RARE_EGGMOVE_RATE = 3; export const GACHA_MOVE_UP_RARE_EGGMOVE_RATE = 3; + +// #region Variant properties +// The chance x/10 of a shiny being a variant, then of being specifically an epic variant +export const SHINY_VARIANT_CHANCE = 4; +export const SHINY_EPIC_CHANCE = 1; diff --git a/src/data/egg.ts b/src/data/egg.ts index eacadf7a08c..c83554f2a19 100644 --- a/src/data/egg.ts +++ b/src/data/egg.ts @@ -10,7 +10,7 @@ import i18next from "i18next"; import { EggTier } from "#enums/egg-type"; import { Species } from "#enums/species"; import { EggSourceType } from "#enums/egg-source-types"; -import { MANAPHY_EGG_MANAPHY_RATE, SAME_SPECIES_EGG_HA_RATE, GACHA_EGG_HA_RATE, GACHA_DEFAULT_RARE_EGGMOVE_RATE, SAME_SPECIES_EGG_RARE_EGGMOVE_RATE, GACHA_MOVE_UP_RARE_EGGMOVE_RATE, GACHA_DEFAULT_SHINY_RATE, GACHA_SHINY_UP_SHINY_RATE, SAME_SPECIES_EGG_SHINY_RATE } from "#app/data/balance/rates"; +import { MANAPHY_EGG_MANAPHY_RATE, SAME_SPECIES_EGG_HA_RATE, GACHA_EGG_HA_RATE, GACHA_DEFAULT_RARE_EGGMOVE_RATE, SAME_SPECIES_EGG_RARE_EGGMOVE_RATE, GACHA_MOVE_UP_RARE_EGGMOVE_RATE, GACHA_DEFAULT_SHINY_RATE, GACHA_SHINY_UP_SHINY_RATE, SAME_SPECIES_EGG_SHINY_RATE, EGG_PITY_LEGENDARY_THRESHOLD, EGG_PITY_EPIC_THRESHOLD, EGG_PITY_RARE_THRESHOLD, SHINY_VARIANT_CHANCE, SHINY_EPIC_CHANCE, GACHA_DEFAULT_COMMON_EGG_THRESHOLD, GACHA_DEFAULT_RARE_EGG_THRESHOLD, GACHA_DEFAULT_EPIC_EGG_THRESHOLD, GACHA_LEGENDARY_UP_THRESHOLD_OFFSET, HATCH_WAVES_MANAPHY_EGG, HATCH_WAVES_COMMON_EGG, HATCH_WAVES_RARE_EGG, HATCH_WAVES_EPIC_EGG, HATCH_WAVES_LEGENDARY_EGG } from "#app/data/balance/rates"; export const EGG_SEED = 1073741824; @@ -330,24 +330,24 @@ export class Egg { private getEggTierDefaultHatchWaves(eggTier?: EggTier): number { if (this._species === Species.PHIONE || this._species === Species.MANAPHY) { - return 50; + return HATCH_WAVES_MANAPHY_EGG; } switch (eggTier ?? this._tier) { case EggTier.COMMON: - return 10; + return HATCH_WAVES_COMMON_EGG; case EggTier.GREAT: - return 25; + return HATCH_WAVES_RARE_EGG; case EggTier.ULTRA: - return 50; + return HATCH_WAVES_EPIC_EGG; } - return 100; + return HATCH_WAVES_LEGENDARY_EGG; } private rollEggTier(): EggTier { - const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? 1 : 0; + const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0; const tierValue = Utils.randInt(256); - return tierValue >= 52 + tierValueOffset ? EggTier.COMMON : tierValue >= 8 + tierValueOffset ? EggTier.GREAT : tierValue >= 1 + tierValueOffset ? EggTier.ULTRA : EggTier.MASTER; + return tierValue >= GACHA_DEFAULT_COMMON_EGG_THRESHOLD + tierValueOffset ? EggTier.COMMON : tierValue >= GACHA_DEFAULT_RARE_EGG_THRESHOLD + tierValueOffset ? EggTier.GREAT : tierValue >= GACHA_DEFAULT_EPIC_EGG_THRESHOLD + tierValueOffset ? EggTier.ULTRA : EggTier.MASTER; } private rollSpecies(scene: BattleScene): Species | null { @@ -487,9 +487,9 @@ export class Egg { } const rand = Utils.randSeedInt(10); - if (rand >= 4) { + if (rand >= SHINY_VARIANT_CHANCE) { return VariantTier.STANDARD; // 6/10 - } else if (rand >= 1) { + } else if (rand >= SHINY_EPIC_CHANCE) { return VariantTier.RARE; // 3/10 } else { return VariantTier.EPIC; // 1/10 @@ -497,16 +497,16 @@ export class Egg { } private checkForPityTierOverrides(scene: BattleScene): void { - const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? 1 : 0; + const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0; scene.gameData.eggPity[EggTier.GREAT] += 1; scene.gameData.eggPity[EggTier.ULTRA] += 1; scene.gameData.eggPity[EggTier.MASTER] += 1 + tierValueOffset; // These numbers are roughly the 80% mark. That is, 80% of the time you'll get an egg before this gets triggered. - if (scene.gameData.eggPity[EggTier.MASTER] >= 412 && this._tier === EggTier.COMMON) { + if (scene.gameData.eggPity[EggTier.MASTER] >= EGG_PITY_LEGENDARY_THRESHOLD && this._tier === EggTier.COMMON) { this._tier = EggTier.MASTER; - } else if (scene.gameData.eggPity[EggTier.ULTRA] >= 59 && this._tier === EggTier.COMMON) { + } else if (scene.gameData.eggPity[EggTier.ULTRA] >= EGG_PITY_EPIC_THRESHOLD && this._tier === EggTier.COMMON) { this._tier = EggTier.ULTRA; - } else if (scene.gameData.eggPity[EggTier.GREAT] >= 9 && this._tier === EggTier.COMMON) { + } else if (scene.gameData.eggPity[EggTier.GREAT] >= EGG_PITY_RARE_THRESHOLD && this._tier === EggTier.COMMON) { this._tier = EggTier.GREAT; } scene.gameData.eggPity[this._tier] = 0; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index b7a50a602f3..66af69da79f 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -64,7 +64,7 @@ import { PokemonAnimType } from "#enums/pokemon-anim-type"; import { PLAYER_PARTY_MAX_SIZE } from "#app/constants"; import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data"; import { SwitchType } from "#enums/switch-type"; -import { BASE_HIDDEN_ABILITY_CHANCE, BASE_SHINY_CHANCE } from "#app/data/balance/rates"; +import { BASE_HIDDEN_ABILITY_CHANCE, BASE_SHINY_CHANCE, SHINY_EPIC_CHANCE, SHINY_VARIANT_CHANCE } from "#app/data/balance/rates"; export enum FieldPosition { CENTER, @@ -1922,9 +1922,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.executeWithSeedOffset(() => { rand.value = Utils.randSeedInt(10); }, this.id, this.scene.waveSeed); - if (rand.value >= 4) { + if (rand.value >= SHINY_VARIANT_CHANCE) { return 0; // 6/10 - } else if (rand.value >= 1) { + } else if (rand.value >= SHINY_EPIC_CHANCE) { return 1; // 3/10 } else { return 2; // 1/10