Implement Pity System (#1752)

* Implement Pity System

* Add comments and optimised worst case slightly
This commit is contained in:
Xavion3 2024-06-04 05:43:52 +10:00 committed by GitHub
parent 145a79f8ef
commit ff0e4fbdf0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 41 additions and 2 deletions

View File

@ -497,11 +497,19 @@ export class EggHatchPhase extends Phase {
const ignoredSpecies = [ Species.PHIONE, Species.MANAPHY, Species.ETERNATUS ]; const ignoredSpecies = [ Species.PHIONE, Species.MANAPHY, Species.ETERNATUS ];
const speciesPool = Object.keys(speciesStarters) let speciesPool = Object.keys(speciesStarters)
.filter(s => speciesStarters[s] >= minStarterValue && speciesStarters[s] <= maxStarterValue) .filter(s => speciesStarters[s] >= minStarterValue && speciesStarters[s] <= maxStarterValue)
.map(s => parseInt(s) as Species) .map(s => parseInt(s) as Species)
.filter(s => !pokemonPrevolutions.hasOwnProperty(s) && getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1); .filter(s => !pokemonPrevolutions.hasOwnProperty(s) && getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1);
// If this is the 10th egg without unlocking something new, attempt to force it.
if (this.scene.gameData.unlockPity[this.egg.tier] >= 9) {
const lockedPool = speciesPool.filter(s => !this.scene.gameData.dexData[s].caughtAttr);
if (lockedPool.length) { // Skip this if everything is unlocked
speciesPool = lockedPool;
}
}
/** /**
* Pokemon that are cheaper in their tier get a weight boost. Regionals get a weight penalty * Pokemon that are cheaper in their tier get a weight boost. Regionals get a weight penalty
* 1 cost mons get 2x * 1 cost mons get 2x
@ -536,6 +544,12 @@ export class EggHatchPhase extends Phase {
} }
} }
if (!!this.scene.gameData.dexData[species].caughtAttr) {
this.scene.gameData.unlockPity[this.egg.tier] = Math.min(this.scene.gameData.unlockPity[this.egg.tier] + 1, 10);
} else {
this.scene.gameData.unlockPity[this.egg.tier] = 0;
}
const pokemonSpecies = getPokemonSpecies(species); const pokemonSpecies = getPokemonSpecies(species);
ret = this.scene.addPlayerPokemon(pokemonSpecies, 1, undefined, undefined, undefined, false); ret = this.scene.addPlayerPokemon(pokemonSpecies, 1, undefined, undefined, undefined, false);

View File

@ -100,6 +100,8 @@ interface SystemSaveData {
eggs: EggData[]; eggs: EggData[];
gameVersion: string; gameVersion: string;
timestamp: integer; timestamp: integer;
eggPity: integer[];
unlockPity: integer[];
} }
export interface SessionSaveData { export interface SessionSaveData {
@ -248,6 +250,8 @@ export class GameData {
public voucherUnlocks: VoucherUnlocks; public voucherUnlocks: VoucherUnlocks;
public voucherCounts: VoucherCounts; public voucherCounts: VoucherCounts;
public eggs: Egg[]; public eggs: Egg[];
public eggPity: integer[];
public unlockPity: integer[];
constructor(scene: BattleScene) { constructor(scene: BattleScene) {
this.scene = scene; this.scene = scene;
@ -272,6 +276,8 @@ export class GameData {
[VoucherType.GOLDEN]: 0 [VoucherType.GOLDEN]: 0
}; };
this.eggs = []; this.eggs = [];
this.eggPity = [0, 0, 0, 0];
this.unlockPity = [0, 0, 0, 0];
this.initDexData(); this.initDexData();
this.initStarterData(); this.initStarterData();
} }
@ -290,7 +296,9 @@ export class GameData {
voucherCounts: this.voucherCounts, voucherCounts: this.voucherCounts,
eggs: this.eggs.map(e => new EggData(e)), eggs: this.eggs.map(e => new EggData(e)),
gameVersion: this.scene.game.config.gameVersion, gameVersion: this.scene.game.config.gameVersion,
timestamp: new Date().getTime() timestamp: new Date().getTime(),
eggPity: this.eggPity.slice(0),
unlockPity: this.unlockPity.slice(0)
}; };
} }
@ -473,6 +481,9 @@ export class GameData {
? systemData.eggs.map(e => e.toEgg()) ? systemData.eggs.map(e => e.toEgg())
: []; : [];
this.eggPity = systemData.eggPity ? systemData.eggPity.slice(0) : [0, 0, 0, 0];
this.unlockPity = systemData.unlockPity ? systemData.unlockPity.slice(0) : [0, 0, 0, 0];
this.dexData = Object.assign(this.dexData, systemData.dexData); this.dexData = Object.assign(this.dexData, systemData.dexData);
this.consolidateDexData(this.dexData); this.consolidateDexData(this.dexData);
this.defaultDexData = null; this.defaultDexData = null;

View File

@ -378,6 +378,20 @@ export default class EggGachaUiHandler extends MessageUiHandler {
} else if (pullCount >= 10 && !tiers.filter(t => t >= EggTier.GREAT).length) { } else if (pullCount >= 10 && !tiers.filter(t => t >= EggTier.GREAT).length) {
tiers[Utils.randInt(tiers.length)] = EggTier.GREAT; tiers[Utils.randInt(tiers.length)] = EggTier.GREAT;
} }
for (let i = 0; i < pullCount; i++) {
this.scene.gameData.eggPity[EggTier.GREAT] += 1;
this.scene.gameData.eggPity[EggTier.ULTRA] += 1;
this.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 (this.scene.gameData.eggPity[EggTier.MASTER] >= 412 && tiers[i] === EggTier.COMMON) {
tiers[i] = EggTier.MASTER;
} else if (this.scene.gameData.eggPity[EggTier.ULTRA] >= 59 && tiers[i] === EggTier.COMMON) {
tiers[i] = EggTier.ULTRA;
} else if (this.scene.gameData.eggPity[EggTier.GREAT] >= 9 && tiers[i] === EggTier.COMMON) {
tiers[i] = EggTier.GREAT;
}
this.scene.gameData.eggPity[tiers[i]] = 0;
}
const timestamp = new Date().getTime(); const timestamp = new Date().getTime();