Add session save data

This commit is contained in:
Flashfyre committed 2023-04-28 15:03:42 -04:00
1 parent fcd711673d
commit a2ecb4089d
12 files changed
+541 -105

No files matched your search

+17
View File
@@ -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
View File
@@ -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);
+43
View File
@@ -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;
}
}
+79
View File
@@ -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);
}
}