Add session save data
This commit is contained in:
1 parent
fcd711673d
commit
a2ecb4089d
12 files changed
+541
-105
No files matched your search
@@ -0,0 +1,17 @@
|
||||
import { Arena } from "../arena";
|
||||
import { ArenaTag } from "../data/arena-tag";
|
||||
import { Biome } from "../data/biome";
|
||||
import { Weather } from "../data/weather";
|
||||
|
||||
export default class ArenaData {
|
||||
public biome: Biome;
|
||||
public weather: Weather;
|
||||
public tags: ArenaTag[];
|
||||
|
||||
constructor(source: Arena | any) {
|
||||
const sourceArena = source instanceof Arena ? source as Arena : null;
|
||||
this.biome = sourceArena ? sourceArena.biomeType : source.biome;
|
||||
this.weather = sourceArena ? sourceArena.weather : source.weather ? new Weather(source.weather.weatherType, source.weather.turnsLeft) : undefined;
|
||||
this.tags = sourceArena ? sourceArena.tags : [];
|
||||
}
|
||||
}
|
||||
+137
-13
@@ -1,16 +1,34 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import BattleScene, { PokeballCounts } from "../battle-scene";
|
||||
import { Gender } from "../data/gender";
|
||||
import Pokemon from "../pokemon";
|
||||
import Pokemon, { EnemyPokemon, PlayerPokemon } from "../pokemon";
|
||||
import { pokemonPrevolutions } from "../data/pokemon-evolutions";
|
||||
import PokemonSpecies, { allSpecies, getPokemonSpecies } from "../data/pokemon-species";
|
||||
import { Species } from "../data/species";
|
||||
import * as Utils from "../utils";
|
||||
import PokemonData from "./pokemon-data";
|
||||
import { Weather } from "../data/weather";
|
||||
import PersistentModifierData from "./modifier-data";
|
||||
import { Biome } from "../data/biome";
|
||||
import { PokemonHeldItemModifier } from "../modifier/modifier";
|
||||
import { ArenaTag } from "../data/arena-tag";
|
||||
import ArenaData from "./arena-data";
|
||||
|
||||
interface SaveData {
|
||||
interface SystemSaveData {
|
||||
trainerId: integer;
|
||||
secretId: integer;
|
||||
dexData: DexData;
|
||||
timestamp: integer
|
||||
timestamp: integer;
|
||||
}
|
||||
|
||||
interface SessionSaveData {
|
||||
party: PokemonData[];
|
||||
enemyParty: PokemonData[];
|
||||
modifiers: PersistentModifierData[];
|
||||
enemyModifiers: PersistentModifierData[];
|
||||
arena: ArenaData;
|
||||
pokeballCounts: PokeballCounts;
|
||||
waveIndex: integer;
|
||||
timestamp: integer;
|
||||
}
|
||||
|
||||
export interface DexData {
|
||||
@@ -52,14 +70,14 @@ export class GameData {
|
||||
this.trainerId = Utils.randInt(65536);
|
||||
this.secretId = Utils.randInt(65536);
|
||||
this.initDexData();
|
||||
this.load();
|
||||
this.loadSystem();
|
||||
}
|
||||
|
||||
private save(): boolean {
|
||||
private saveSystem(): boolean {
|
||||
if (this.scene.quickStart)
|
||||
return false;
|
||||
|
||||
const data: SaveData = {
|
||||
const data: SystemSaveData = {
|
||||
trainerId: this.trainerId,
|
||||
secretId: this.secretId,
|
||||
dexData: this.dexData,
|
||||
@@ -71,12 +89,12 @@ export class GameData {
|
||||
return true;
|
||||
}
|
||||
|
||||
private load(): boolean {
|
||||
private loadSystem(): boolean {
|
||||
if (!localStorage.getItem('data'))
|
||||
return false;
|
||||
|
||||
const data = JSON.parse(atob(localStorage.getItem('data'))) as SaveData;
|
||||
console.log(data);
|
||||
const data = JSON.parse(atob(localStorage.getItem('data'))) as SystemSaveData;
|
||||
console.debug(data);
|
||||
|
||||
this.trainerId = data.trainerId;
|
||||
this.secretId = data.secretId;
|
||||
@@ -89,7 +107,113 @@ export class GameData {
|
||||
return true;
|
||||
}
|
||||
|
||||
private initDexData() {
|
||||
saveSession(scene: BattleScene): boolean {
|
||||
const sessionData = {
|
||||
party: scene.getParty().map(p => new PokemonData(p)),
|
||||
enemyParty: scene.getEnemyParty().map(p => new PokemonData(p)),
|
||||
modifiers: scene.findModifiers(m => true).map(m => new PersistentModifierData(m, true)),
|
||||
enemyModifiers: scene.findModifiers(m => true, false).map(m => new PersistentModifierData(m, false)),
|
||||
arena: new ArenaData(scene.arena),
|
||||
pokeballCounts: scene.pokeballCounts,
|
||||
waveIndex: scene.currentBattle.waveIndex,
|
||||
timestamp: new Date().getTime()
|
||||
} as SessionSaveData;
|
||||
|
||||
localStorage.setItem('sessionData', btoa(JSON.stringify(sessionData)));
|
||||
|
||||
console.debug('Session data saved');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
hasSession() {
|
||||
return !!localStorage.getItem('sessionData');
|
||||
}
|
||||
|
||||
loadSession(scene: BattleScene): Promise<boolean> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
if (!this.hasSession())
|
||||
return resolve(false);
|
||||
|
||||
try {
|
||||
const sessionData = JSON.parse(atob(localStorage.getItem('sessionData')), (k: string, v: any) => {
|
||||
if (k === 'party' || k === 'enemyParty') {
|
||||
const ret: PokemonData[] = [];
|
||||
for (let pd of v)
|
||||
ret.push(new PokemonData(pd));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (k === 'modifiers' || k === 'enemyModifiers') {
|
||||
const player = k === 'modifiers';
|
||||
const ret: PersistentModifierData[] = [];
|
||||
for (let md of v)
|
||||
ret.push(new PersistentModifierData(md, player));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (k === 'arena')
|
||||
return new ArenaData(v);
|
||||
|
||||
return v;
|
||||
}) as SessionSaveData;
|
||||
|
||||
console.debug(sessionData);
|
||||
|
||||
const loadPokemonAssets: Promise<void>[] = [];
|
||||
|
||||
const party = scene.getParty();
|
||||
party.splice(0, party.length);
|
||||
|
||||
for (let p of sessionData.party) {
|
||||
const pokemon = p.toPokemon(scene) as PlayerPokemon;
|
||||
pokemon.setVisible(false);
|
||||
loadPokemonAssets.push(pokemon.loadAssets());
|
||||
party.push(pokemon);
|
||||
}
|
||||
|
||||
const enemyPokemon = sessionData.enemyParty[0].toPokemon(scene) as EnemyPokemon;
|
||||
|
||||
Object.keys(scene.pokeballCounts).forEach((key: string) => {
|
||||
scene.pokeballCounts[key] = sessionData.pokeballCounts[key] || 0;
|
||||
});
|
||||
|
||||
scene.newArena(sessionData.arena.biome, true);
|
||||
scene.newBattle(sessionData.waveIndex).enemyPokemon = enemyPokemon;
|
||||
|
||||
loadPokemonAssets.push(enemyPokemon.loadAssets());
|
||||
|
||||
scene.arena.weather = sessionData.arena.weather;
|
||||
// TODO
|
||||
//scene.arena.tags = sessionData.arena.tags;
|
||||
|
||||
const modifiersModule = await import('../modifier/modifier');
|
||||
|
||||
for (let modifierData of sessionData.modifiers) {
|
||||
const modifier = modifierData.toModifier(scene, modifiersModule[modifierData.className]);
|
||||
if (modifier)
|
||||
scene.addModifier(modifier);
|
||||
}
|
||||
|
||||
for (let enemyModifierData of sessionData.enemyModifiers) {
|
||||
const modifier = enemyModifierData.toModifier(scene, modifiersModule[enemyModifierData.className]) as PokemonHeldItemModifier;
|
||||
if (modifier)
|
||||
scene.addEnemyModifier(modifier);
|
||||
}
|
||||
|
||||
Promise.all(loadPokemonAssets).then(() => resolve(true));
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
clearSession(): void {
|
||||
localStorage.removeItem('sessionData');
|
||||
}
|
||||
|
||||
private initDexData(): void {
|
||||
const data: DexData = {};
|
||||
|
||||
const initDexSubData = (dexData: DexData, count: integer): DexData[] => {
|
||||
@@ -148,7 +272,7 @@ export class GameData {
|
||||
const dexEntry = this.getPokemonDexEntry(pokemon);
|
||||
if (!dexEntry.seen) {
|
||||
dexEntry.seen = true;
|
||||
this.save();
|
||||
this.saveSystem();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +283,7 @@ export class GameData {
|
||||
const newCatch = !this.getDefaultDexEntry(pokemon.species);
|
||||
|
||||
dexEntry.caught = true;
|
||||
this.save();
|
||||
this.saveSystem();
|
||||
|
||||
if (newCatch && !pokemonPrevolutions.hasOwnProperty(pokemon.species.speciesId)) {
|
||||
this.scene.playSoundWithoutBgm('level_up_fanfare', 1500);
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import { PersistentModifier } from "../modifier/modifier";
|
||||
import { GeneratedPersistentModifierType, ModifierTypeGenerator, getModifierTypeFuncById } from "../modifier/modifier-type";
|
||||
|
||||
export default class ModifierData {
|
||||
private player: boolean;
|
||||
private typeId: string;
|
||||
private typePregenArgs: any[];
|
||||
private args: any[];
|
||||
private stackCount: integer;
|
||||
|
||||
public className: string;
|
||||
|
||||
constructor(source: PersistentModifier | any, player: boolean) {
|
||||
const sourceModifier = source instanceof PersistentModifier ? source as PersistentModifier : null;
|
||||
this.player = player;
|
||||
this.typeId = sourceModifier ? sourceModifier.type.id : source.typeId;
|
||||
if (sourceModifier) {
|
||||
if ('getPregenArgs' in source.type)
|
||||
this.typePregenArgs = (source.type as GeneratedPersistentModifierType).getPregenArgs();
|
||||
} else if (source.typePregenArgs)
|
||||
this.typePregenArgs = source.typePregenArgs;
|
||||
this.args = sourceModifier ? sourceModifier.getArgs() : source.args;
|
||||
this.stackCount = source.stackCount;
|
||||
this.className = sourceModifier ? sourceModifier.constructor.name : source.className;
|
||||
}
|
||||
|
||||
toModifier(scene: BattleScene, constructor: any): PersistentModifier {
|
||||
const typeFunc = getModifierTypeFuncById(this.typeId);
|
||||
if (!typeFunc)
|
||||
return null;
|
||||
|
||||
let type = typeFunc();
|
||||
type.id = this.typeId;
|
||||
|
||||
if (type instanceof ModifierTypeGenerator)
|
||||
type = (type as ModifierTypeGenerator).generateType(this.player ? scene.getParty() : scene.getEnemyParty(), this.typePregenArgs);
|
||||
|
||||
const ret = Reflect.construct(constructor, ([ type ] as any[]).concat(this.args).concat(this.stackCount)) as PersistentModifier
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import { Gender } from "../data/gender";
|
||||
import { PokeballType } from "../data/pokeball";
|
||||
import { getPokemonSpecies } from "../data/pokemon-species";
|
||||
import { Species } from "../data/species";
|
||||
import { Status } from "../data/status-effect";
|
||||
import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove, PokemonSummonData } from "../pokemon";
|
||||
|
||||
export default class PokemonData {
|
||||
public id: integer;
|
||||
public player: boolean;
|
||||
public species: Species;
|
||||
public formIndex: integer;
|
||||
public abilityIndex: integer;
|
||||
public shiny: boolean;
|
||||
public pokeball: PokeballType;
|
||||
public level: integer;
|
||||
public exp: integer;
|
||||
public levelExp: integer;
|
||||
public gender: Gender;
|
||||
public hp: integer;
|
||||
public stats: integer[];
|
||||
public ivs: integer[];
|
||||
public moveset: PokemonMove[];
|
||||
public status: Status;
|
||||
public winCount: integer;
|
||||
|
||||
public summonData: PokemonSummonData;
|
||||
|
||||
constructor(source: Pokemon | any) {
|
||||
const sourcePokemon = source instanceof Pokemon ? source as Pokemon : null;
|
||||
this.id = source.id;
|
||||
this.player = sourcePokemon ? sourcePokemon.isPlayer() : source.player;
|
||||
this.species = sourcePokemon ? sourcePokemon.species.speciesId : source.species;
|
||||
this.formIndex = source.formIndex;
|
||||
this.abilityIndex = source.abilityIndex;
|
||||
this.shiny = source.shiny;
|
||||
this.pokeball = source.pokeball;
|
||||
this.level = source.level;
|
||||
this.exp = source.exp;
|
||||
this.levelExp = source.levelExp;
|
||||
this.gender = source.gender;
|
||||
this.hp = source.hp;
|
||||
this.stats = source.stats;
|
||||
this.ivs = source.ivs;
|
||||
this.winCount = source.winCount;
|
||||
|
||||
if (sourcePokemon) {
|
||||
this.moveset = sourcePokemon.moveset;
|
||||
this.status = sourcePokemon.status;
|
||||
if (this.player)
|
||||
this.summonData = sourcePokemon.summonData;
|
||||
} else {
|
||||
this.moveset = source.moveset.map((m: any) => {
|
||||
const move = new PokemonMove(m.moveId, m.ppUsed, m.ppUp);
|
||||
move.disableTurns = m.disableTurns;
|
||||
return move;
|
||||
});
|
||||
this.status = source.status
|
||||
? new Status(source.status.effect, source.status.turnCount, source.status.cureTurn)
|
||||
: undefined;
|
||||
|
||||
this.summonData = new PokemonSummonData();
|
||||
if (source.summonData) {
|
||||
this.summonData.battleStats = source.summonData.battleStats;
|
||||
this.summonData.moveQueue = source.summonData.moveQueue;
|
||||
this.summonData.tags = []; // TODO
|
||||
this.summonData.types = source.summonData.types;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toPokemon(scene: BattleScene): Pokemon {
|
||||
const species = getPokemonSpecies(this.species);
|
||||
if (this.player)
|
||||
return new PlayerPokemon(scene, species, this.level, this.abilityIndex, this.formIndex, this.gender, this.shiny, this);
|
||||
return new EnemyPokemon(scene, species, this.level, this);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user