Add egg gacha system and various minor changes
Add egg gacha system; remove certain mythical Pokemon from the wild pool as egg exclusive; add egg vouchers with UI; rework Shiny Charm odds; fix trainer Pokemon shiny odds not properly ignoring Shiny Charm modifier
This commit is contained in:
1 parent
50d4858caa
commit
aa94e044ab
71 files changed
+4303
-2241
No files matched your search
+12
-1
@@ -31,6 +31,14 @@ export class Achv {
|
||||
this.conditionFunc = conditionFunc;
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
getIconImage(): string {
|
||||
return this.iconImage;
|
||||
}
|
||||
|
||||
setSecret(hasParent?: boolean): this {
|
||||
this.secret = true;
|
||||
this.hasParent = !!hasParent;
|
||||
@@ -118,10 +126,13 @@ export const achvs = {
|
||||
MEGA_EVOLVE: new Achv('Megamorph', 'Mega evolve a Pokémon', 'mega_bracelet', 50),
|
||||
SPLICE: new Achv('Infinite Fusion', 'Splice two Pokémon together with DNA Splicers', 'dna_splicers', 10),
|
||||
MINI_BLACK_HOLE: new ModifierAchv('A Hole Lot of Items', 'Acquire a Mini Black Hole', 'mini_black_hole', 25, modifier => modifier instanceof TurnHeldItemTransferModifier).setSecret(),
|
||||
CATCH_LEGENDARY: new Achv('Legendary', 'Catch a legendary Pokémon', 'mb', 50).setSecret(),
|
||||
CATCH_MYTHICAL: new Achv('Mythical', 'Catch a mythical Pokémon', 'strange_ball', 50).setSecret(),
|
||||
CATCH_LEGENDARY: new Achv('Legendary', 'Catch a legendary Pokémon', 'mb', 75).setSecret(),
|
||||
SEE_SHINY: new Achv('Shiny', 'Find a shiny Pokémon in the wild', 'pb_gold', 75),
|
||||
SHINY_PARTY: new Achv('That\'s Dedication', 'Have a full party of shiny Pokémon', 'shiny_charm', 100).setSecret(true),
|
||||
HATCH_MYTHICAL: new Achv('Mythical Egg', 'Hatch a mythical Pokémon from an egg', 'pair_of_tickets', 75).setSecret(),
|
||||
HATCH_LEGENDARY: new Achv('Legendary Egg', 'Hatch a legendary Pokémon from an egg', 'mystic_ticket', 100).setSecret(),
|
||||
HATCH_SHINY: new Achv('Shiny Egg', 'Hatch a shiny Pokémon from an egg', 'golden_mystic_ticket', 100).setSecret(),
|
||||
HIDDEN_ABILITY: new Achv('Hidden Potential', 'Catch a Pokémon with a hidden ability', 'ability_charm', 75),
|
||||
PERFECT_IVS: new Achv('Certificate of Authenticity', 'Get perfect IVs on a Pokémon', 'blunder_policy', 100),
|
||||
CLASSIC_VICTORY: new Achv('Undefeated', 'Beat the game in classic mode', 'relic_crown', 150)
|
||||
|
||||
@@ -3,16 +3,18 @@ import { Egg, GachaType } from "../data/egg";
|
||||
export default class EggData {
|
||||
public id: integer;
|
||||
public gachaType: GachaType;
|
||||
public hatchWaves: integer;
|
||||
public timestamp: integer;
|
||||
|
||||
constructor(source: Egg | any) {
|
||||
const sourceEgg = source instanceof Egg ? source as Egg : null;
|
||||
this.id = sourceEgg ? sourceEgg.id : source.id;
|
||||
this.gachaType = sourceEgg ? sourceEgg.gachaType : source.gachaType;
|
||||
this.hatchWaves = sourceEgg ? sourceEgg.hatchWaves : source.hatchWaves;
|
||||
this.timestamp = sourceEgg ? sourceEgg.timestamp : source.timestamp;
|
||||
}
|
||||
|
||||
toEgg(): Egg {
|
||||
return new Egg(this.id, this.gachaType, this.timestamp);
|
||||
return new Egg(this.id, this.gachaType, this.hatchWaves, this.timestamp);
|
||||
}
|
||||
}
|
||||
+59
-1
@@ -16,6 +16,7 @@ import { Setting, setSetting, settingDefaults } from "./settings";
|
||||
import { achvs } from "./achv";
|
||||
import EggData from "./egg-data";
|
||||
import { Egg } from "../data/egg";
|
||||
import { VoucherType, vouchers } from "./voucher";
|
||||
|
||||
interface SystemSaveData {
|
||||
trainerId: integer;
|
||||
@@ -23,6 +24,8 @@ interface SystemSaveData {
|
||||
dexData: DexData;
|
||||
unlocks: Unlocks;
|
||||
achvUnlocks: AchvUnlocks;
|
||||
voucherUnlocks: VoucherUnlocks;
|
||||
voucherCounts: VoucherCounts;
|
||||
eggs: EggData[];
|
||||
gameVersion: string;
|
||||
timestamp: integer;
|
||||
@@ -54,6 +57,14 @@ interface AchvUnlocks {
|
||||
[key: string]: integer
|
||||
}
|
||||
|
||||
interface VoucherUnlocks {
|
||||
[key: string]: integer
|
||||
}
|
||||
|
||||
export interface VoucherCounts {
|
||||
[type: string]: integer;
|
||||
}
|
||||
|
||||
export interface DexData {
|
||||
[key: integer]: DexEntry
|
||||
}
|
||||
@@ -96,6 +107,8 @@ export class GameData {
|
||||
|
||||
public achvUnlocks: AchvUnlocks;
|
||||
|
||||
public voucherUnlocks: VoucherUnlocks;
|
||||
public voucherCounts: VoucherCounts;
|
||||
public eggs: Egg[];
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
@@ -109,6 +122,12 @@ export class GameData {
|
||||
[Unlockables.SPLICED_ENDLESS_MODE]: false
|
||||
};
|
||||
this.achvUnlocks = {};
|
||||
this.voucherUnlocks = {};
|
||||
this.voucherCounts = {
|
||||
[VoucherType.REGULAR]: 0,
|
||||
[VoucherType.PLUS]: 0,
|
||||
[VoucherType.PREMIUM]: 0
|
||||
};
|
||||
this.eggs = [];
|
||||
this.initDexData();
|
||||
this.loadSystem();
|
||||
@@ -124,6 +143,8 @@ export class GameData {
|
||||
dexData: this.dexData,
|
||||
unlocks: this.unlocks,
|
||||
achvUnlocks: this.achvUnlocks,
|
||||
voucherUnlocks: this.voucherUnlocks,
|
||||
voucherCounts: this.voucherCounts,
|
||||
eggs: this.eggs.map(e => new EggData(e)),
|
||||
gameVersion: this.scene.game.config.gameVersion,
|
||||
timestamp: new Date().getTime()
|
||||
@@ -141,7 +162,16 @@ export class GameData {
|
||||
if (!localStorage.hasOwnProperty('data'))
|
||||
return false;
|
||||
|
||||
const data = JSON.parse(atob(localStorage.getItem('data')), (k: string, v: any) => k.endsWith('Attr') ? BigInt(v) : v) as SystemSaveData;
|
||||
const data = JSON.parse(atob(localStorage.getItem('data')), (k: string, v: any) => {
|
||||
if (k === 'eggs') {
|
||||
const ret: EggData[] = [];
|
||||
for (let e of v)
|
||||
ret.push(new EggData(e));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return k.endsWith('Attr') ? BigInt(v) : v;
|
||||
}) as SystemSaveData;
|
||||
|
||||
console.debug(data);
|
||||
|
||||
@@ -168,6 +198,20 @@ export class GameData {
|
||||
}
|
||||
}
|
||||
|
||||
if (data.voucherUnlocks) {
|
||||
for (let v of Object.keys(data.voucherUnlocks)) {
|
||||
if (vouchers.hasOwnProperty(v))
|
||||
this.voucherUnlocks[v] = data.voucherUnlocks[v];
|
||||
}
|
||||
}
|
||||
|
||||
if (data.voucherCounts) {
|
||||
Utils.getEnumKeys(VoucherType).forEach(key => {
|
||||
const index = VoucherType[key];
|
||||
this.voucherCounts[index] = data.voucherCounts[index] || 0;
|
||||
});
|
||||
}
|
||||
|
||||
this.eggs = data.eggs
|
||||
? data.eggs.map(e => e.toEgg())
|
||||
: [];
|
||||
@@ -423,6 +467,20 @@ export class GameData {
|
||||
});
|
||||
}
|
||||
|
||||
updateSpeciesDexIvs(speciesId: Species, ivs: integer[]): void {
|
||||
let dexEntry: DexEntry;
|
||||
do {
|
||||
dexEntry = this.scene.gameData.dexData[speciesId];
|
||||
const dexIvs = dexEntry.ivs;
|
||||
for (let i = 0; i < dexIvs.length; i++) {
|
||||
if (dexIvs[i] < ivs[i])
|
||||
dexIvs[i] = ivs[i];
|
||||
}
|
||||
if (dexIvs.filter(iv => iv === 31).length === 6)
|
||||
this.scene.validateAchv(achvs.PERFECT_IVS);
|
||||
} while (pokemonPrevolutions.hasOwnProperty(speciesId) && (speciesId = pokemonPrevolutions[speciesId]));
|
||||
}
|
||||
|
||||
getSpeciesDefaultDexAttr(species: PokemonSpecies): bigint {
|
||||
let ret = 0n;
|
||||
const dexEntry = this.dexData[species.speciesId];
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import { TrainerType, trainerConfigs } from "../data/trainer-type";
|
||||
import { ModifierTier } from "../modifier/modifier-type";
|
||||
import { Achv, achvs } from "./achv";
|
||||
|
||||
export enum VoucherType {
|
||||
REGULAR,
|
||||
PLUS,
|
||||
PREMIUM
|
||||
}
|
||||
|
||||
export class Voucher {
|
||||
public id: string;
|
||||
public voucherType: VoucherType;
|
||||
public description: string;
|
||||
|
||||
private conditionFunc: (scene: BattleScene, args: any[]) => boolean;
|
||||
|
||||
constructor(voucherType: VoucherType, description: string, conditionFunc?: (scene: BattleScene, args: any[]) => boolean) {
|
||||
this.description = description;
|
||||
this.voucherType = voucherType;
|
||||
this.conditionFunc = conditionFunc;
|
||||
}
|
||||
|
||||
validate(scene: BattleScene, args: any[]): boolean {
|
||||
return !this.conditionFunc || this.conditionFunc(scene, args);
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return getVoucherTypeName(this.voucherType);
|
||||
}
|
||||
|
||||
getIconImage(): string {
|
||||
return getVoucherTypeIcon(this.voucherType);
|
||||
}
|
||||
|
||||
getTier(): ModifierTier {
|
||||
switch (this.voucherType) {
|
||||
case VoucherType.REGULAR:
|
||||
return ModifierTier.GREAT;
|
||||
case VoucherType.PLUS:
|
||||
return ModifierTier.ULTRA;
|
||||
case VoucherType.PREMIUM:
|
||||
return ModifierTier.MASTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getVoucherTypeName(voucherType: VoucherType): string {
|
||||
switch (voucherType) {
|
||||
case VoucherType.REGULAR:
|
||||
return 'Egg Voucher';
|
||||
case VoucherType.PLUS:
|
||||
return 'Egg Voucher Plus';
|
||||
case VoucherType.PREMIUM:
|
||||
return 'Egg Voucher Premium';
|
||||
}
|
||||
}
|
||||
|
||||
export function getVoucherTypeIcon(voucherType: VoucherType): string {
|
||||
switch (voucherType) {
|
||||
case VoucherType.REGULAR:
|
||||
return 'coupon';
|
||||
case VoucherType.PLUS:
|
||||
return 'pair_of_tickets';
|
||||
case VoucherType.PREMIUM:
|
||||
return 'mystic_ticket';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export interface Vouchers {
|
||||
[key: string]: Voucher
|
||||
}
|
||||
|
||||
export const vouchers: Vouchers = {};
|
||||
|
||||
const voucherAchvs: Achv[] = [ achvs.CLASSIC_VICTORY ];
|
||||
|
||||
{
|
||||
(function() {
|
||||
const bossTrainerTypes = Object.keys(trainerConfigs)
|
||||
.filter(tt => trainerConfigs[tt].isBoss && trainerConfigs[tt].getDerivedType() !== TrainerType.RIVAL);
|
||||
|
||||
for (let trainerType of bossTrainerTypes) {
|
||||
const voucherType = trainerConfigs[trainerType].moneyMultiplier < 10
|
||||
? VoucherType.REGULAR
|
||||
: VoucherType.PLUS;
|
||||
const key = TrainerType[trainerType];
|
||||
vouchers[key] = new Voucher(voucherType, `Defeat ${trainerConfigs[trainerType].name}`);
|
||||
}
|
||||
|
||||
for (let achv of voucherAchvs) {
|
||||
const voucherType = achv.score >= 150
|
||||
? VoucherType.PREMIUM
|
||||
: achv.score >= 100
|
||||
? VoucherType.PLUS
|
||||
: VoucherType.REGULAR;
|
||||
vouchers[achv.id] = new Voucher(voucherType, achv.description);
|
||||
}
|
||||
|
||||
const voucherKeys = Object.keys(vouchers);
|
||||
for (let k of voucherKeys)
|
||||
vouchers[k].id = k;
|
||||
})();
|
||||
}
|
||||
Reference in new issue
Block a user