[Bug] Fix rare egg move and species rates for Manaphy eggs (#4125)

This commit is contained in:
PigeonBar 2024-09-10 10:15:07 -04:00 committed by GitHub
parent 4b8083211a
commit 5bf21a4f75
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 127 additions and 3 deletions

View File

@ -222,7 +222,7 @@ export class Egg {
let pokemonSpecies = getPokemonSpecies(this._species); let pokemonSpecies = getPokemonSpecies(this._species);
// Special condition to have Phione eggs also have a chance of generating Manaphy // Special condition to have Phione eggs also have a chance of generating Manaphy
if (this._species === Species.PHIONE) { if (this._species === Species.PHIONE && this._sourceType === EggSourceType.SAME_SPECIES_EGG) {
pokemonSpecies = getPokemonSpecies(Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE) ? Species.PHIONE : Species.MANAPHY); pokemonSpecies = getPokemonSpecies(Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE) ? Species.PHIONE : Species.MANAPHY);
} }
@ -326,7 +326,8 @@ export class Egg {
break; break;
} }
return Utils.randSeedInt(baseChance * Math.pow(2, 3 - this.tier)) ? Utils.randSeedInt(3) : 3; const tierMultiplier = this.isManaphyEgg() ? 2 : Math.pow(2, 3 - this.tier);
return Utils.randSeedInt(baseChance * tierMultiplier) ? Utils.randSeedInt(3) : 3;
} }
private getEggTierDefaultHatchWaves(eggTier?: EggTier): number { private getEggTierDefaultHatchWaves(eggTier?: EggTier): number {
@ -361,7 +362,12 @@ export class Egg {
* the species that was the legendary focus at the time * the species that was the legendary focus at the time
*/ */
if (this.isManaphyEgg()) { if (this.isManaphyEgg()) {
const rand = Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE); /**
* Adding a technicality to make unit tests easier: By making this check pass
* when Utils.randSeedInt(8) = 1, and by making the generatePlayerPokemon() species
* check pass when Utils.randSeedInt(8) = 0, we can tell them apart during tests.
*/
const rand = (Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE) !== 1);
return rand ? Species.PHIONE : Species.MANAPHY; return rand ? Species.PHIONE : Species.MANAPHY;
} else if (this.tier === EggTier.MASTER } else if (this.tier === EggTier.MASTER
&& this._sourceType === EggSourceType.GACHA_LEGENDARY) { && this._sourceType === EggSourceType.GACHA_LEGENDARY) {

View File

@ -0,0 +1,118 @@
import { Egg } from "#app/data/egg";
import { EggSourceType } from "#app/enums/egg-source-types";
import { EggTier } from "#app/enums/egg-type";
import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
describe("Manaphy Eggs", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
const EGG_HATCH_COUNT: integer = 48;
let rngSweepProgress: number = 0;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
game = new GameManager(phaserGame);
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
vi.restoreAllMocks();
});
beforeEach(async () => {
await game.importData("src/test/utils/saves/everything.prsv");
/**
* In our tests, we will perform an "RNG sweep" by letting rngSweepProgress
* increase uniformly from 0 to 1 in order to get a uniform sample of the
* possible RNG outcomes. This will let us quickly and consistently find
* the probability of each RNG outcome.
*/
vi.spyOn(Phaser.Math.RND, "realInRange").mockImplementation((min: number, max: number) => {
return rngSweepProgress * (max - min) + min;
});
});
it("should have correct Manaphy rates and Rare Egg Move rates, from the egg gacha", () => {
const scene = game.scene;
let manaphyCount = 0;
let phioneCount = 0;
let rareEggMoveCount = 0;
for (let i = 0; i < EGG_HATCH_COUNT; i++) {
rngSweepProgress = (2 * i + 1) / (2 * EGG_HATCH_COUNT);
const newEgg = new Egg({ scene, tier: EggTier.COMMON, sourceType: EggSourceType.GACHA_SHINY, id: 204 });
const newHatch = newEgg.generatePlayerPokemon(scene);
if (newHatch.species.speciesId === Species.MANAPHY) {
manaphyCount++;
} else if (newHatch.species.speciesId === Species.PHIONE) {
phioneCount++;
}
if (newEgg.eggMoveIndex === 3) {
rareEggMoveCount++;
}
}
expect(manaphyCount + phioneCount).toBe(EGG_HATCH_COUNT);
expect(manaphyCount).toBe(1/8 * EGG_HATCH_COUNT);
expect(rareEggMoveCount).toBe(1/12 * EGG_HATCH_COUNT);
});
it("should have correct Manaphy rates and Rare Egg Move rates, from Phione species eggs", () => {
const scene = game.scene;
let manaphyCount = 0;
let phioneCount = 0;
let rareEggMoveCount = 0;
for (let i = 0; i < EGG_HATCH_COUNT; i++) {
rngSweepProgress = (2 * i + 1) / (2 * EGG_HATCH_COUNT);
const newEgg = new Egg({ scene, species: Species.PHIONE, sourceType: EggSourceType.SAME_SPECIES_EGG });
const newHatch = newEgg.generatePlayerPokemon(scene);
if (newHatch.species.speciesId === Species.MANAPHY) {
manaphyCount++;
} else if (newHatch.species.speciesId === Species.PHIONE) {
phioneCount++;
}
if (newEgg.eggMoveIndex === 3) {
rareEggMoveCount++;
}
}
expect(manaphyCount + phioneCount).toBe(EGG_HATCH_COUNT);
expect(manaphyCount).toBe(1/8 * EGG_HATCH_COUNT);
expect(rareEggMoveCount).toBe(1/6 * EGG_HATCH_COUNT);
});
it("should have correct Manaphy rates and Rare Egg Move rates, from Manaphy species eggs", () => {
const scene = game.scene;
let manaphyCount = 0;
let phioneCount = 0;
let rareEggMoveCount = 0;
for (let i = 0; i < EGG_HATCH_COUNT; i++) {
rngSweepProgress = (2 * i + 1) / (2 * EGG_HATCH_COUNT);
const newEgg = new Egg({ scene, species: Species.MANAPHY, sourceType: EggSourceType.SAME_SPECIES_EGG });
const newHatch = newEgg.generatePlayerPokemon(scene);
if (newHatch.species.speciesId === Species.MANAPHY) {
manaphyCount++;
} else if (newHatch.species.speciesId === Species.PHIONE) {
phioneCount++;
}
if (newEgg.eggMoveIndex === 3) {
rareEggMoveCount++;
}
}
expect(phioneCount).toBe(0);
expect(manaphyCount).toBe(EGG_HATCH_COUNT);
expect(rareEggMoveCount).toBe(1/6 * EGG_HATCH_COUNT);
});
});