Add ""title"" screen and save data slots
This commit is contained in:
parent
bed98ad304
commit
879971ae2b
|
@ -3,7 +3,7 @@ import * as Utils from "./utils";
|
|||
|
||||
export interface UserInfo {
|
||||
username: string;
|
||||
hasGameSession: boolean;
|
||||
lastSessionSlot: integer;
|
||||
}
|
||||
|
||||
export let loggedInUser: UserInfo = null;
|
||||
|
@ -11,7 +11,14 @@ export let loggedInUser: UserInfo = null;
|
|||
export function updateUserInfo(): Promise<boolean> {
|
||||
return new Promise<boolean>(resolve => {
|
||||
if (bypassLogin) {
|
||||
loggedInUser = { username: 'Guest', hasGameSession: !!localStorage.getItem('sessionData') };
|
||||
let lastSessionSlot = -1;
|
||||
for (let s = 0; s < 2; s++) {
|
||||
if (localStorage.getItem(`sessionData${s ? s : ''}`)) {
|
||||
lastSessionSlot = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
loggedInUser = { username: 'Guest', lastSessionSlot: lastSessionSlot };
|
||||
return resolve(true);
|
||||
}
|
||||
Utils.apiFetch('account/info').then(response => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Phaser from 'phaser';
|
||||
import UI, { Mode } from './ui/ui';
|
||||
import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, CheckLoadPhase, TurnInitPhase, ReturnPhase, LevelCapPhase, ShowTrainerPhase, LoginPhase, ConsolidateDataPhase, MovePhase } from './phases';
|
||||
import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, TurnInitPhase, ReturnPhase, LevelCapPhase, ShowTrainerPhase, LoginPhase, ConsolidateDataPhase, MovePhase, TitlePhase } from './phases';
|
||||
import Pokemon, { PlayerPokemon, EnemyPokemon } from './field/pokemon';
|
||||
import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies, initSpecies } from './data/pokemon-species';
|
||||
import * as Utils from './utils';
|
||||
|
@ -104,6 +104,7 @@ export default class BattleScene extends Phaser.Scene {
|
|||
public enableVibration: boolean = false;
|
||||
|
||||
public gameData: GameData;
|
||||
public sessionSlotId: integer;
|
||||
|
||||
private phaseQueue: Phase[];
|
||||
private phaseQueuePrepend: Phase[];
|
||||
|
@ -614,7 +615,7 @@ export default class BattleScene extends Phaser.Scene {
|
|||
this.pushPhase(new LoginPhase(this));
|
||||
if (!bypassLogin)
|
||||
this.pushPhase(new ConsolidateDataPhase(this)); // TODO: Remove
|
||||
this.pushPhase(new CheckLoadPhase(this));
|
||||
this.pushPhase(new TitlePhase(this));
|
||||
|
||||
this.shiftPhase();
|
||||
});
|
||||
|
@ -1205,6 +1206,7 @@ export default class BattleScene extends Phaser.Scene {
|
|||
case Mode.BIOME_SELECT:
|
||||
case Mode.STARTER_SELECT:
|
||||
case Mode.CONFIRM:
|
||||
case Mode.OPTION_SELECT:
|
||||
this.ui.setOverlayMode(Mode.MENU);
|
||||
inputSuccess = true;
|
||||
break;
|
||||
|
|
|
@ -6,7 +6,7 @@ import Trainer from "./field/trainer";
|
|||
import { Species } from "./data/enums/species";
|
||||
import { Moves } from "./data/enums/moves";
|
||||
import { TrainerType } from "./data/enums/trainer-type";
|
||||
import { GameMode, GameModes } from "./game-mode";
|
||||
import { GameMode } from "./game-mode";
|
||||
import { BattleSpec } from "./enums/battle-spec";
|
||||
import { PlayerGender } from "./system/game-data";
|
||||
import { PokemonHeldItemModifier } from "./modifier/modifier";
|
||||
|
|
|
@ -5,6 +5,7 @@ import { version } from '../package.json';
|
|||
import UIPlugin from 'phaser3-rex-plugins/templates/ui/ui-plugin';
|
||||
import BBCodeTextPlugin from 'phaser3-rex-plugins/plugins/bbcodetext-plugin';
|
||||
import InputTextPlugin from 'phaser3-rex-plugins/plugins/inputtext-plugin.js';
|
||||
import BBCodeText from 'phaser3-rex-plugins/plugins/bbcodetext';
|
||||
|
||||
const config: Phaser.Types.Core.GameConfig = {
|
||||
type: Phaser.WEBGL,
|
||||
|
@ -62,6 +63,7 @@ Phaser.GameObjects.Sprite.prototype.setPositionRelative = setPositionRelative;
|
|||
Phaser.GameObjects.Image.prototype.setPositionRelative = setPositionRelative;
|
||||
Phaser.GameObjects.NineSlice.prototype.setPositionRelative = setPositionRelative;
|
||||
Phaser.GameObjects.Text.prototype.setPositionRelative = setPositionRelative;
|
||||
BBCodeText.prototype.setPositionRelative = setPositionRelative;
|
||||
Phaser.GameObjects.Rectangle.prototype.setPositionRelative = setPositionRelative;
|
||||
|
||||
document.fonts.load('16px emerald').then(() => document.fonts.load('10px pkmnems'));
|
||||
|
|
162
src/phases.ts
162
src/phases.ts
|
@ -35,7 +35,6 @@ import { Unlockables, getUnlockableName } from "./system/unlockables";
|
|||
import { getBiomeKey } from "./field/arena";
|
||||
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
|
||||
import { BattleSpec } from "./enums/battle-spec";
|
||||
import { GameModes } from "./game-mode";
|
||||
import { Species } from "./data/enums/species";
|
||||
import { HealAchv, LevelAchv, MoneyAchv, achvs } from "./system/achv";
|
||||
import { trainerConfigs } from "./data/trainer-config";
|
||||
|
@ -52,6 +51,7 @@ import ModifierSelectUiHandler, { SHOP_OPTIONS_ROW_LIMIT } from "./ui/modifier-s
|
|||
import { Setting } from "./system/settings";
|
||||
import { Tutorial, handleTutorial } from "./tutorial";
|
||||
import { TerrainType } from "./data/terrain";
|
||||
import { OptionSelectItem } from "./ui/abstact-option-select-ui-handler";
|
||||
|
||||
export class LoginPhase extends Phase {
|
||||
private showText: boolean;
|
||||
|
@ -122,6 +122,96 @@ export class LoginPhase extends Phase {
|
|||
}
|
||||
}
|
||||
|
||||
export class TitlePhase extends Phase {
|
||||
private loaded: boolean;
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene);
|
||||
|
||||
this.loaded = false;
|
||||
}
|
||||
|
||||
start(): void {
|
||||
super.start();
|
||||
|
||||
const options: OptionSelectItem[] = [];
|
||||
if (loggedInUser?.lastSessionSlot > -1) {
|
||||
options.push({
|
||||
label: 'Continue',
|
||||
handler: () => {
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
this.scene.gameData.loadSession(this.scene, loggedInUser.lastSessionSlot).then((success: boolean) => {
|
||||
if (success) {
|
||||
this.loaded = true;
|
||||
this.scene.ui.showText('Session loaded successfully.', null, () => this.end());
|
||||
} else
|
||||
this.end();
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
this.scene.ui.showText('Your session data could not be loaded.\nIt may be corrupted. Please reload the page.', null);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
options.push({
|
||||
label: 'New Game',
|
||||
handler: () => {
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
this.scene.ui.clearText();
|
||||
this.scene.sessionSlotId = 0;
|
||||
this.end();
|
||||
}
|
||||
},
|
||||
/*{
|
||||
label: 'Load',
|
||||
handler: () => {
|
||||
|
||||
}
|
||||
},*/
|
||||
/*{
|
||||
label: 'Daily Run',
|
||||
handler: () => {
|
||||
//this.scene.ui.setMode(Mode.MESSAGE);
|
||||
this.scene.ui.showText('This feature is not available yet.\nPlease check back soon!', null, () => this.scene.ui.clearText(), Utils.fixedInt(1000));
|
||||
},
|
||||
keepOpen: true
|
||||
}*/);
|
||||
this.scene.ui.setMode(Mode.OPTION_SELECT, {
|
||||
options: options
|
||||
});
|
||||
}
|
||||
|
||||
end(): void {
|
||||
if (!this.loaded) {
|
||||
this.scene.arena.preloadBgm();
|
||||
this.scene.pushPhase(new SelectStarterPhase(this.scene));
|
||||
} else
|
||||
this.scene.playBgm();
|
||||
|
||||
this.scene.pushPhase(new EncounterPhase(this.scene, this.loaded));
|
||||
|
||||
if (this.loaded) {
|
||||
const availablePartyMembers = this.scene.getParty().filter(p => !p.isFainted()).length;
|
||||
|
||||
this.scene.pushPhase(new SummonPhase(this.scene, 0));
|
||||
if (this.scene.currentBattle.double && availablePartyMembers > 1)
|
||||
this.scene.pushPhase(new SummonPhase(this.scene, 1));
|
||||
if (this.scene.currentBattle.waveIndex > 1 && this.scene.currentBattle.battleType !== BattleType.TRAINER) {
|
||||
this.scene.pushPhase(new CheckSwitchPhase(this.scene, 0, this.scene.currentBattle.double));
|
||||
if (this.scene.currentBattle.double && availablePartyMembers > 1)
|
||||
this.scene.pushPhase(new CheckSwitchPhase(this.scene, 1, this.scene.currentBattle.double));
|
||||
}
|
||||
}
|
||||
|
||||
for (let achv of Object.keys(this.scene.gameData.achvUnlocks)) {
|
||||
if (vouchers.hasOwnProperty(achv))
|
||||
this.scene.validateVoucher(vouchers[achv]);
|
||||
}
|
||||
|
||||
super.end();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove
|
||||
export class ConsolidateDataPhase extends Phase {
|
||||
start(): void {
|
||||
|
@ -169,74 +259,6 @@ export class ConsolidateDataPhase extends Phase {
|
|||
}
|
||||
}
|
||||
|
||||
export class CheckLoadPhase extends Phase {
|
||||
private loaded: boolean;
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene);
|
||||
|
||||
this.loaded = false;
|
||||
}
|
||||
|
||||
start(): void {
|
||||
super.start();
|
||||
|
||||
if (!loggedInUser?.hasGameSession)
|
||||
return this.end();
|
||||
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
this.scene.ui.showText('You currently have a session in progress.\nWould you like to continue where you left off?', null, () => {
|
||||
this.scene.ui.setMode(Mode.CONFIRM, () => {
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
this.scene.gameData.loadSession(this.scene).then((success: boolean) => {
|
||||
if (success) {
|
||||
this.loaded = true;
|
||||
this.scene.ui.showText('Session loaded successfully.', null, () => this.end());
|
||||
} else
|
||||
this.end();
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
this.scene.ui.showText('Your session data could not be loaded.\nIt may be corrupted. Please reload the page.', null);
|
||||
});
|
||||
}, () => {
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
this.scene.ui.clearText();
|
||||
this.end();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
end(): void {
|
||||
if (!this.loaded) {
|
||||
this.scene.arena.preloadBgm();
|
||||
this.scene.pushPhase(new SelectStarterPhase(this.scene));
|
||||
} else
|
||||
this.scene.playBgm();
|
||||
|
||||
this.scene.pushPhase(new EncounterPhase(this.scene, this.loaded));
|
||||
|
||||
if (this.loaded) {
|
||||
const availablePartyMembers = this.scene.getParty().filter(p => !p.isFainted()).length;
|
||||
|
||||
this.scene.pushPhase(new SummonPhase(this.scene, 0));
|
||||
if (this.scene.currentBattle.double && availablePartyMembers > 1)
|
||||
this.scene.pushPhase(new SummonPhase(this.scene, 1));
|
||||
if (this.scene.currentBattle.waveIndex > 1 && this.scene.currentBattle.battleType !== BattleType.TRAINER) {
|
||||
this.scene.pushPhase(new CheckSwitchPhase(this.scene, 0, this.scene.currentBattle.double));
|
||||
if (this.scene.currentBattle.double && availablePartyMembers > 1)
|
||||
this.scene.pushPhase(new CheckSwitchPhase(this.scene, 1, this.scene.currentBattle.double));
|
||||
}
|
||||
}
|
||||
|
||||
for (let achv of Object.keys(this.scene.gameData.achvUnlocks)) {
|
||||
if (vouchers.hasOwnProperty(achv))
|
||||
this.scene.validateVoucher(vouchers[achv]);
|
||||
}
|
||||
|
||||
super.end();
|
||||
}
|
||||
}
|
||||
|
||||
export class SelectGenderPhase extends Phase {
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene);
|
||||
|
@ -3024,7 +3046,7 @@ export class GameOverPhase extends BattlePhase {
|
|||
if (this.victory && !firstClear)
|
||||
this.scene.unshiftPhase(new GameOverModifierRewardPhase(this.scene, modifierTypes.VOUCHER_PREMIUM));
|
||||
this.scene.reset();
|
||||
this.scene.unshiftPhase(new CheckLoadPhase(this.scene));
|
||||
this.scene.unshiftPhase(new TitlePhase(this.scene));
|
||||
this.end();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -33,6 +33,7 @@ const saveKey = 'x0i2O7WRiANTqPmZ'; // Temporary; secure encryption is not yet n
|
|||
export enum GameDataType {
|
||||
SYSTEM,
|
||||
SESSION,
|
||||
DAILY_SESSION,
|
||||
SETTINGS,
|
||||
TUTORIALS
|
||||
}
|
||||
|
@ -474,7 +475,7 @@ export class GameData {
|
|||
} as SessionSaveData;
|
||||
|
||||
if (!bypassLogin) {
|
||||
Utils.apiPost(`savedata/update?datatype=${GameDataType.SESSION}`, JSON.stringify(sessionData))
|
||||
Utils.apiPost(`savedata/update?datatype=${GameDataType.SESSION}&slot=${scene.sessionSlotId}`, JSON.stringify(sessionData))
|
||||
.then(response => response.text())
|
||||
.then(error => {
|
||||
if (error) {
|
||||
|
@ -495,7 +496,7 @@ export class GameData {
|
|||
});
|
||||
}
|
||||
|
||||
loadSession(scene: BattleScene): Promise<boolean> {
|
||||
loadSession(scene: BattleScene, slotId: integer): Promise<boolean> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const handleSessionData = async (sessionDataStr: string) => {
|
||||
try {
|
||||
|
@ -580,7 +581,7 @@ export class GameData {
|
|||
};
|
||||
|
||||
if (!bypassLogin) {
|
||||
Utils.apiFetch(`savedata/get?datatype=${GameDataType.SESSION}`)
|
||||
Utils.apiFetch(`savedata/get?datatype=${GameDataType.SESSION}&slot=${slotId}`)
|
||||
.then(response => response.text())
|
||||
.then(async response => {
|
||||
if (!response.length || response[0] !== '{') {
|
||||
|
@ -591,7 +592,7 @@ export class GameData {
|
|||
await handleSessionData(response);
|
||||
});
|
||||
} else
|
||||
await handleSessionData(atob(localStorage.getItem('sessionData')));
|
||||
await handleSessionData(atob(localStorage.getItem(`sessionData${slotId ? slotId : ''}`)));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -40,8 +40,8 @@ export function addBBCodeTextObject(scene: Phaser.Scene, x: number, y: number, c
|
|||
scene.add.existing(ret);
|
||||
ret.setScale(0.1666666667);
|
||||
ret.setShadow(shadowSize, shadowSize, shadowColor);
|
||||
if (!(styleOptions as Phaser.Types.GameObjects.Text.TextStyle).lineSpacing)
|
||||
ret.setLineSpacing(5);
|
||||
if (!(styleOptions as BBCodeText.TextStyle).lineSpacing)
|
||||
ret.setLineSpacing(10);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ export enum Mode {
|
|||
BALL,
|
||||
TARGET_SELECT,
|
||||
MODIFIER_SELECT,
|
||||
//LOAD_SESSION,
|
||||
PARTY,
|
||||
SUMMARY,
|
||||
BIOME_SELECT,
|
||||
|
@ -59,6 +60,7 @@ export enum Mode {
|
|||
};
|
||||
|
||||
const transitionModes = [
|
||||
//Mode.LOAD_SESSION,
|
||||
Mode.PARTY,
|
||||
Mode.SUMMARY,
|
||||
Mode.STARTER_SELECT,
|
||||
|
@ -107,6 +109,7 @@ export default class UI extends Phaser.GameObjects.Container {
|
|||
new BallUiHandler(scene),
|
||||
new TargetSelectUiHandler(scene),
|
||||
new ModifierSelectUiHandler(scene),
|
||||
//LoadSessionUiHandler(scene),
|
||||
new PartyUiHandler(scene),
|
||||
new SummaryUiHandler(scene),
|
||||
new BiomeSelectUiHandler(scene),
|
||||
|
|
Loading…
Reference in New Issue