Add session save data
parent
fcd711673d
commit
a2ecb4089d
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2019",
|
||||
"target": "ES2020",
|
||||
"module": "ES2020",
|
||||
"moduleResolution": "node",
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true
|
||||
|
|
|
@ -27,6 +27,56 @@ import { TempBattleStat } from "./data/temp-battle-stat";
|
|||
import { ArenaTrapTag, TrickRoomTag } from "./data/arena-tag";
|
||||
import { PostWeatherLapseAbAttr, PreWeatherDamageAbAttr, ProtectStatAttr, SuppressWeatherEffectAbAttr, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreWeatherEffectAbAttrs } from "./data/ability";
|
||||
|
||||
export class CheckLoadPhase extends BattlePhase {
|
||||
private loaded: boolean;
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene);
|
||||
|
||||
this.loaded = false;
|
||||
}
|
||||
|
||||
start(): void {
|
||||
if (!this.scene.gameData.hasSession()) {
|
||||
this.end();
|
||||
return;
|
||||
}
|
||||
|
||||
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.arena.playBgm();
|
||||
|
||||
this.scene.pushPhase(new EncounterPhase(this.scene, this.loaded));
|
||||
this.scene.pushPhase(new SummonPhase(this.scene));
|
||||
|
||||
super.end();
|
||||
}
|
||||
}
|
||||
|
||||
export class SelectStarterPhase extends BattlePhase {
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene);
|
||||
|
@ -62,8 +112,12 @@ export class SelectStarterPhase extends BattlePhase {
|
|||
}
|
||||
|
||||
export class EncounterPhase extends BattlePhase {
|
||||
constructor(scene: BattleScene) {
|
||||
private loaded: boolean;
|
||||
|
||||
constructor(scene: BattleScene, loaded?: boolean) {
|
||||
super(scene);
|
||||
|
||||
this.loaded = !!loaded;
|
||||
}
|
||||
|
||||
start() {
|
||||
|
@ -73,7 +127,8 @@ export class EncounterPhase extends BattlePhase {
|
|||
|
||||
const battle = this.scene.currentBattle;
|
||||
const enemySpecies = this.scene.randomSpecies(battle.waveIndex, battle.enemyLevel, true);
|
||||
battle.enemyPokemon = new EnemyPokemon(this.scene, enemySpecies, battle.enemyLevel);
|
||||
if (!this.loaded)
|
||||
battle.enemyPokemon = new EnemyPokemon(this.scene, enemySpecies, battle.enemyLevel);
|
||||
const enemyPokemon = this.scene.getEnemyPokemon();
|
||||
enemyPokemon.resetSummonData();
|
||||
|
||||
|
@ -87,10 +142,16 @@ export class EncounterPhase extends BattlePhase {
|
|||
this.scene.field.moveBelow(enemyPokemon, this.scene.getPlayerPokemon());
|
||||
enemyPokemon.tint(0, 0.5);
|
||||
|
||||
regenerateModifierPoolThresholds(this.scene.getEnemyParty(), false);
|
||||
this.scene.generateEnemyModifiers();
|
||||
if (!this.loaded) {
|
||||
regenerateModifierPoolThresholds(this.scene.getEnemyParty(), false);
|
||||
this.scene.generateEnemyModifiers();
|
||||
}
|
||||
|
||||
this.scene.ui.setMode(Mode.MESSAGE).then(() => this.doEncounter());
|
||||
this.scene.ui.setMode(Mode.MESSAGE).then(() => {
|
||||
if (!this.loaded)
|
||||
this.scene.gameData.saveSession(this.scene);
|
||||
this.doEncounter();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -989,7 +1050,7 @@ abstract class MoveEffectPhase extends PokemonPhase {
|
|||
}
|
||||
return rand <= this.move.getMove().accuracy * accuracyMultiplier;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1500,6 +1561,8 @@ export class GameOverPhase extends BattlePhase {
|
|||
start() {
|
||||
super.start();
|
||||
|
||||
this.scene.gameData.clearSession();
|
||||
|
||||
this.scene.time.delayedCall(1000, () => {
|
||||
const fadeDuration = this.victory ? 10000 : 5000;
|
||||
this.scene.fadeOutBgm(fadeDuration, true);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Phaser from 'phaser';
|
||||
import { Biome } from './data/biome';
|
||||
import UI from './ui/ui';
|
||||
import { EncounterPhase, SummonPhase, CommandPhase, NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, SelectStarterPhase, MessagePhase } from './battle-phases';
|
||||
import { EncounterPhase, SummonPhase, CommandPhase, NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, SelectStarterPhase, MessagePhase, CheckLoadPhase } from './battle-phases';
|
||||
import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon';
|
||||
import PokemonSpecies, { allSpecies, getPokemonSpecies, initSpecies } from './data/pokemon-species';
|
||||
import * as Utils from './utils';
|
||||
|
@ -45,7 +45,7 @@ export enum Button {
|
|||
SLOW_DOWN
|
||||
}
|
||||
|
||||
interface PokeballCounts {
|
||||
export interface PokeballCounts {
|
||||
[pb: string]: integer;
|
||||
}
|
||||
|
||||
|
@ -474,16 +474,9 @@ export default class BattleScene extends Phaser.Scene {
|
|||
|
||||
this.currentBattle = null;
|
||||
this.waveCountText.setText(startingWave.toString());
|
||||
this.waveCountText.setVisible(false);
|
||||
|
||||
this.newArena(startingBiome);
|
||||
const biomeKey = this.arena.getBiomeKey();
|
||||
|
||||
this.arenaBg.setTexture(`${biomeKey}_bg`);
|
||||
this.arenaBgTransition.setTexture(`${biomeKey}_bg`);
|
||||
this.arenaPlayer.setTexture(`${biomeKey}_a`);
|
||||
this.arenaPlayerTransition.setTexture(`${biomeKey}_a`);
|
||||
this.arenaEnemy.setTexture(`${biomeKey}_b`);
|
||||
this.arenaNextEnemy.setTexture(`${biomeKey}_b`);
|
||||
this.newArena(startingBiome, true);
|
||||
|
||||
this.arenaBgTransition.setPosition(0, 0);
|
||||
this.arenaPlayer.setPosition(340, 20);
|
||||
|
@ -495,32 +488,46 @@ export default class BattleScene extends Phaser.Scene {
|
|||
this.trainer.setPosition(406, 132);
|
||||
}
|
||||
|
||||
newBattle(): Battle {
|
||||
if (this.currentBattle) {
|
||||
this.getEnemyPokemon().destroy();
|
||||
if (this.currentBattle.waveIndex % 10)
|
||||
this.pushPhase(new NextEncounterPhase(this));
|
||||
else {
|
||||
this.pushPhase(new SelectBiomePhase(this));
|
||||
this.pushPhase(new NewBiomeEncounterPhase(this));
|
||||
newBattle(waveIndex?: integer): Battle {
|
||||
if (!waveIndex) {
|
||||
if (this.currentBattle) {
|
||||
this.getEnemyPokemon().destroy();
|
||||
if (this.currentBattle.waveIndex % 10)
|
||||
this.pushPhase(new NextEncounterPhase(this));
|
||||
else {
|
||||
this.pushPhase(new SelectBiomePhase(this));
|
||||
this.pushPhase(new NewBiomeEncounterPhase(this));
|
||||
}
|
||||
} else {
|
||||
if (!this.quickStart)
|
||||
this.pushPhase(new CheckLoadPhase(this));
|
||||
else {
|
||||
this.arena.playBgm();
|
||||
this.pushPhase(new EncounterPhase(this));
|
||||
this.pushPhase(new SummonPhase(this));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!this.quickStart) {
|
||||
this.arena.preloadBgm();
|
||||
this.pushPhase(new SelectStarterPhase(this));
|
||||
} else
|
||||
this.arena.playBgm();
|
||||
this.pushPhase(new EncounterPhase(this));
|
||||
this.pushPhase(new SummonPhase(this));
|
||||
}
|
||||
|
||||
this.currentBattle = new Battle((this.currentBattle?.waveIndex || (startingWave - 1)) + 1);
|
||||
this.currentBattle = new Battle(waveIndex || ((this.currentBattle?.waveIndex || (startingWave - 1)) + 1));
|
||||
|
||||
return this.currentBattle;
|
||||
}
|
||||
|
||||
newArena(biome: Biome): Arena {
|
||||
newArena(biome: Biome, init?: boolean): Arena {
|
||||
this.arena = new Arena(this, biome, Biome[biome].toLowerCase());
|
||||
|
||||
if (init) {
|
||||
const biomeKey = this.arena.getBiomeKey();
|
||||
|
||||
this.arenaBg.setTexture(`${biomeKey}_bg`);
|
||||
this.arenaBgTransition.setTexture(`${biomeKey}_bg`);
|
||||
this.arenaPlayer.setTexture(`${biomeKey}_a`);
|
||||
this.arenaPlayerTransition.setTexture(`${biomeKey}_a`);
|
||||
this.arenaEnemy.setTexture(`${biomeKey}_b`);
|
||||
this.arenaNextEnemy.setTexture(`${biomeKey}_b`);
|
||||
}
|
||||
|
||||
return this.arena;
|
||||
}
|
||||
|
||||
|
@ -529,6 +536,7 @@ export default class BattleScene extends Phaser.Scene {
|
|||
this.waveCountText.setText(this.currentBattle.waveIndex.toString());
|
||||
this.waveCountText.setColor(!isBoss ? '#404040' : '#f89890');
|
||||
this.waveCountText.setShadowColor(!isBoss ? '#ded6b5' : '#984038');
|
||||
this.waveCountText.setVisible(true);
|
||||
}
|
||||
|
||||
updateWaveCountPosition(): void {
|
||||
|
@ -868,19 +876,19 @@ export default class BattleScene extends Phaser.Scene {
|
|||
return false;
|
||||
}
|
||||
|
||||
getModifiers(modifierType: { new(...args: any[]): Modifier }, player?: boolean): Modifier[] {
|
||||
getModifiers(modifierType: { new(...args: any[]): Modifier }, player?: boolean): PersistentModifier[] {
|
||||
if (player === undefined)
|
||||
player = true;
|
||||
return (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType);
|
||||
}
|
||||
|
||||
findModifiers(modifierFilter: ModifierPredicate, player?: boolean): Modifier[] {
|
||||
findModifiers(modifierFilter: ModifierPredicate, player?: boolean): PersistentModifier[] {
|
||||
if (player === undefined)
|
||||
player = true;
|
||||
return (player ? this.modifiers : this.enemyModifiers).filter(m => (modifierFilter as ModifierPredicate)(m));
|
||||
}
|
||||
|
||||
findModifier(modifierFilter: ModifierPredicate, player?: boolean): Modifier {
|
||||
findModifier(modifierFilter: ModifierPredicate, player?: boolean): PersistentModifier {
|
||||
if (player === undefined)
|
||||
player = true;
|
||||
return (player ? this.modifiers : this.enemyModifiers).find(m => (modifierFilter as ModifierPredicate)(m));
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { CommonAnim, CommonBattleAnim } from "./battle-anims";
|
||||
import { CommonAnimPhase, DamagePhase, MessagePhase, MovePhase, ObtainStatusEffectPhase, PokemonHealPhase } from "../battle-phases";
|
||||
import { CommonAnimPhase, DamagePhase, MovePhase, ObtainStatusEffectPhase, PokemonHealPhase } from "../battle-phases";
|
||||
import { getPokemonMessage } from "../messages";
|
||||
import Pokemon from "../pokemon";
|
||||
import { Stat } from "./pokemon-stat";
|
||||
import { StatusEffect } from "./status-effect";
|
||||
import * as Utils from "../utils";
|
||||
import { LapseBattlerTagAttr, Moves, allMoves } from "./move";
|
||||
import { Moves, allMoves } from "./move";
|
||||
import { Type } from "./type";
|
||||
|
||||
export enum BattlerTagType {
|
||||
|
@ -555,7 +555,7 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
|
|||
case BattlerTagType.NO_CRIT:
|
||||
return new BattlerTag(tagType, BattlerTagLapseType.AFTER_MOVE, turnCount, sourceMove);
|
||||
case BattlerTagType.IGNORE_ACCURACY:
|
||||
return new IgnoreAccuracyTag(turnCount, sourceMove);
|
||||
return new IgnoreAccuracyTag(sourceMove);
|
||||
case BattlerTagType.BYPASS_SLEEP:
|
||||
return new BattlerTag(BattlerTagType.BYPASS_SLEEP, BattlerTagLapseType.TURN_END, turnCount, sourceMove);
|
||||
case BattlerTagType.IGNORE_FLYING:
|
||||
|
|
|
@ -16,11 +16,14 @@ export class Status {
|
|||
public turnCount: integer;
|
||||
public cureTurn: integer;
|
||||
|
||||
constructor(effect: StatusEffect) {
|
||||
constructor(effect: StatusEffect, turnCount?: integer, cureTurn?: integer) {
|
||||
this.effect = effect;
|
||||
this.turnCount = 0;
|
||||
if (effect === StatusEffect.SLEEP)
|
||||
this.cureTurn = Utils.randInt(3, 1);
|
||||
this.turnCount = turnCount === undefined ? 0 : turnCount;
|
||||
if (cureTurn === undefined) {
|
||||
if (effect === StatusEffect.SLEEP)
|
||||
this.cureTurn = Utils.randInt(3, 1);
|
||||
} else
|
||||
this.cureTurn = cureTurn;
|
||||
}
|
||||
|
||||
incrementTurn(): void {
|
||||
|
|
|
@ -24,6 +24,7 @@ export enum ModifierTier {
|
|||
type NewModifierFunc = (type: ModifierType, args: any[]) => Modifier;
|
||||
|
||||
export class ModifierType {
|
||||
public id: string;
|
||||
public name: string;
|
||||
public description: string;
|
||||
public iconImage: string;
|
||||
|
@ -50,6 +51,30 @@ export class ModifierType {
|
|||
}
|
||||
}
|
||||
|
||||
type ModifierTypeGeneratorFunc = (party: Pokemon[], pregenArgs?: any[]) => ModifierType;
|
||||
|
||||
export class ModifierTypeGenerator extends ModifierType {
|
||||
private genTypeFunc: ModifierTypeGeneratorFunc;
|
||||
|
||||
constructor(genTypeFunc: ModifierTypeGeneratorFunc) {
|
||||
super(null, null, null, null);
|
||||
this.genTypeFunc = genTypeFunc;
|
||||
}
|
||||
|
||||
generateType(party: Pokemon[], pregenArgs?: any[]) {
|
||||
const ret = this.genTypeFunc(party, pregenArgs);
|
||||
if (ret) {
|
||||
ret.id = this.id;
|
||||
ret.setTier(this.tier);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
export interface GeneratedPersistentModifierType {
|
||||
getPregenArgs(): any[];
|
||||
}
|
||||
|
||||
class AddPokeballModifierType extends ModifierType {
|
||||
constructor(pokeballType: PokeballType, count: integer, iconImage?: string) {
|
||||
super(`${count}x ${getPokeballName(pokeballType)}`, `Receive ${getPokeballName(pokeballType)} x${count}`,
|
||||
|
@ -168,7 +193,7 @@ export class PokemonAllMovePpRestoreModifierType extends PokemonModifierType {
|
|||
}
|
||||
}
|
||||
|
||||
export class TempBattleStatBoosterModifierType extends ModifierType {
|
||||
export class TempBattleStatBoosterModifierType extends ModifierType implements GeneratedPersistentModifierType {
|
||||
public tempBattleStat: TempBattleStat;
|
||||
|
||||
constructor(tempBattleStat: TempBattleStat) {
|
||||
|
@ -179,6 +204,26 @@ export class TempBattleStatBoosterModifierType extends ModifierType {
|
|||
|
||||
this.tempBattleStat = tempBattleStat;
|
||||
}
|
||||
|
||||
getPregenArgs(): any[] {
|
||||
return [ this.tempBattleStat ];
|
||||
}
|
||||
}
|
||||
|
||||
export class BerryModifierType extends PokemonHeldItemModifierType implements GeneratedPersistentModifierType {
|
||||
private berryType: BerryType;
|
||||
|
||||
constructor(berryType: BerryType) {
|
||||
super(getBerryName(berryType), getBerryEffectDescription(berryType),
|
||||
(type, args) => new Modifiers.BerryModifier(type, (args[0] as Pokemon).id, berryType),
|
||||
null, 'berry');
|
||||
|
||||
this.berryType = berryType;
|
||||
}
|
||||
|
||||
getPregenArgs(): any[] {
|
||||
return [ this.berryType ];
|
||||
}
|
||||
}
|
||||
|
||||
function getAttackTypeBoosterItemName(type: Type) {
|
||||
|
@ -222,7 +267,7 @@ function getAttackTypeBoosterItemName(type: Type) {
|
|||
}
|
||||
}
|
||||
|
||||
export class AttackTypeBoosterModifierType extends PokemonHeldItemModifierType {
|
||||
export class AttackTypeBoosterModifierType extends PokemonHeldItemModifierType implements GeneratedPersistentModifierType {
|
||||
public moveType: Type;
|
||||
public boostPercent: integer;
|
||||
|
||||
|
@ -234,6 +279,10 @@ export class AttackTypeBoosterModifierType extends PokemonHeldItemModifierType {
|
|||
this.moveType = moveType;
|
||||
this.boostPercent = boostPercent;
|
||||
}
|
||||
|
||||
getPregenArgs(): any[] {
|
||||
return [ this.moveType ];
|
||||
}
|
||||
}
|
||||
|
||||
export class PokemonLevelIncrementModifierType extends PokemonModifierType {
|
||||
|
@ -266,7 +315,7 @@ function getBaseStatBoosterItemName(stat: Stat) {
|
|||
}
|
||||
}
|
||||
|
||||
export class PokemonBaseStatBoosterModifierType extends PokemonHeldItemModifierType {
|
||||
export class PokemonBaseStatBoosterModifierType extends PokemonHeldItemModifierType implements GeneratedPersistentModifierType {
|
||||
private stat: Stat;
|
||||
|
||||
constructor(name: string, stat: Stat, _iconImage?: string) {
|
||||
|
@ -274,6 +323,10 @@ export class PokemonBaseStatBoosterModifierType extends PokemonHeldItemModifierT
|
|||
|
||||
this.stat = stat;
|
||||
}
|
||||
|
||||
getPregenArgs(): any[] {
|
||||
return [ this.stat ];
|
||||
}
|
||||
}
|
||||
|
||||
class AllPokemonFullHpRestoreModifierType extends ModifierType {
|
||||
|
@ -343,7 +396,7 @@ function getEvolutionItemName(evolutionItem: EvolutionItem) {
|
|||
}
|
||||
}
|
||||
|
||||
export class EvolutionItemModifierType extends PokemonModifierType {
|
||||
export class EvolutionItemModifierType extends PokemonModifierType implements GeneratedPersistentModifierType {
|
||||
public evolutionItem: EvolutionItem;
|
||||
|
||||
constructor(evolutionItem: EvolutionItem) {
|
||||
|
@ -358,27 +411,18 @@ export class EvolutionItemModifierType extends PokemonModifierType {
|
|||
|
||||
this.evolutionItem = evolutionItem;
|
||||
}
|
||||
}
|
||||
|
||||
class ModifierTypeGenerator extends ModifierType {
|
||||
private genTypeFunc: Function;
|
||||
|
||||
constructor(genTypeFunc: Function) {
|
||||
super(null, null, null, null);
|
||||
this.genTypeFunc = genTypeFunc;
|
||||
}
|
||||
|
||||
generateType(party: Pokemon[]) {
|
||||
const ret = this.genTypeFunc(party);
|
||||
if (ret)
|
||||
ret.setTier(this.tier);
|
||||
return ret;
|
||||
getPregenArgs(): any[] {
|
||||
return [ this.evolutionItem ];
|
||||
}
|
||||
}
|
||||
|
||||
class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
||||
constructor() {
|
||||
super((party: Pokemon[]) => {
|
||||
super((party: Pokemon[], pregenArgs?: any[]) => {
|
||||
if (pregenArgs)
|
||||
return new AttackTypeBoosterModifierType(pregenArgs[0] as Type, 20);
|
||||
|
||||
const attackMoveTypes = party.map(p => p.moveset.map(m => m.getMove()).filter(m => m instanceof AttackMove).map(m => m.type)).flat();
|
||||
const attackMoveTypeWeights = new Map<Type, integer>();
|
||||
let totalWeight = 0;
|
||||
|
@ -417,7 +461,10 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
|||
|
||||
class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator {
|
||||
constructor() {
|
||||
super((party: Pokemon[]) => {
|
||||
super((party: Pokemon[], pregenArgs?: any[]) => {
|
||||
if (pregenArgs)
|
||||
return new EvolutionItemModifierType(pregenArgs[0] as EvolutionItem);
|
||||
|
||||
const evolutionItemPool = party.filter(p => pokemonEvolutions.hasOwnProperty(p.species.speciesId)).map(p => {
|
||||
const evolutions = pokemonEvolutions[p.species.speciesId]
|
||||
return evolutions.filter(e => e.item !== EvolutionItem.NONE && (!e.condition || e.condition.predicate(p)));
|
||||
|
@ -446,6 +493,7 @@ class WeightedModifierType {
|
|||
|
||||
constructor(modifierTypeFunc: ModifierTypeFunc, weight: integer | WeightedModifierTypeWeightFunc) {
|
||||
this.modifierType = modifierTypeFunc();
|
||||
this.modifierType.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifierTypeFunc);
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
|
@ -485,21 +533,29 @@ const modifierTypes = {
|
|||
ELIXIR: () => new PokemonAllMovePpRestoreModifierType('ELIXIR', 10),
|
||||
MAX_ELIXIR: () => new PokemonAllMovePpRestoreModifierType('MAX ELIXIR', -1),
|
||||
|
||||
TEMP_STAT_BOOSTER: () => new ModifierTypeGenerator((party: Pokemon[]) => {
|
||||
TEMP_STAT_BOOSTER: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
|
||||
if (pregenArgs)
|
||||
return new TempBattleStatBoosterModifierType(pregenArgs[0] as TempBattleStat);
|
||||
const randTempBattleStat = Utils.randInt(7) as TempBattleStat;
|
||||
return new TempBattleStatBoosterModifierType(randTempBattleStat);
|
||||
}),
|
||||
|
||||
BASE_STAT_BOOSTER: () => new ModifierTypeGenerator((party: Pokemon[]) => {
|
||||
BASE_STAT_BOOSTER: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
|
||||
if (pregenArgs) {
|
||||
const stat = pregenArgs[0] as Stat;
|
||||
return new PokemonBaseStatBoosterModifierType(getBaseStatBoosterItemName(stat), stat);
|
||||
}
|
||||
const randStat = Utils.randInt(6) as Stat;
|
||||
return new PokemonBaseStatBoosterModifierType(getBaseStatBoosterItemName(randStat), randStat);
|
||||
}),
|
||||
|
||||
ATTACK_TYPE_BOOSTER: () => new AttackTypeBoosterModifierTypeGenerator(),
|
||||
|
||||
BERRY: () => new ModifierTypeGenerator((party: Pokemon[]) => {
|
||||
BERRY: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
|
||||
if (pregenArgs)
|
||||
return new BerryModifierType(pregenArgs[0] as BerryType);
|
||||
const berryTypes = Utils.getEnumValues(BerryType);
|
||||
let randBerryType;
|
||||
let randBerryType: BerryType;
|
||||
let rand = Utils.randInt(10);
|
||||
if (rand < 2)
|
||||
randBerryType = BerryType.SITRUS;
|
||||
|
@ -507,9 +563,7 @@ const modifierTypes = {
|
|||
randBerryType = BerryType.LUM;
|
||||
else
|
||||
randBerryType = berryTypes[Utils.randInt(berryTypes.length - 2) + 2];
|
||||
return new PokemonHeldItemModifierType(getBerryName(randBerryType), getBerryEffectDescription(randBerryType),
|
||||
(type, args) => new Modifiers.BerryModifier(type, (args[0] as Pokemon).id, randBerryType),
|
||||
null, 'berry');
|
||||
return new BerryModifierType(randBerryType);
|
||||
}),
|
||||
|
||||
TM: () => new ModifierTypeGenerator((party: Pokemon[]) => {
|
||||
|
@ -575,11 +629,11 @@ const modifierPool = {
|
|||
return thresholdPartyMemberCount;
|
||||
}),
|
||||
new WeightedModifierType(modifierTypes.ETHER, (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.moveset.filter(m => m.getPpRatio() <= 0.2).length).length, 3);
|
||||
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length, 3);
|
||||
return thresholdPartyMemberCount * 3;
|
||||
}),
|
||||
new WeightedModifierType(modifierTypes.MAX_ETHER, (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.moveset.filter(m => m.getPpRatio() <= 0.2).length).length, 3);
|
||||
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length, 3);
|
||||
return thresholdPartyMemberCount;
|
||||
}),
|
||||
new WeightedModifierType(modifierTypes.TEMP_STAT_BOOSTER, 4),
|
||||
|
@ -611,11 +665,11 @@ const modifierPool = {
|
|||
return thresholdPartyMemberCount;
|
||||
}),
|
||||
new WeightedModifierType(modifierTypes.ELIXIR, (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.moveset.filter(m => m.getPpRatio() <= 0.2).length).length, 3);
|
||||
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length, 3);
|
||||
return thresholdPartyMemberCount * 3;
|
||||
}),
|
||||
new WeightedModifierType(modifierTypes.MAX_ELIXIR, (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.moveset.filter(m => m.getPpRatio() <= 0.2).length).length, 3);
|
||||
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length, 3);
|
||||
return thresholdPartyMemberCount;
|
||||
}),
|
||||
new WeightedModifierType(modifierTypes.MAP, (party: Pokemon[]) => {
|
||||
|
@ -714,6 +768,10 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], player?: bool
|
|||
}
|
||||
}
|
||||
|
||||
export function getModifierTypeFuncById(id: string): ModifierTypeFunc {
|
||||
return modifierTypes[id];
|
||||
}
|
||||
|
||||
export function getPlayerModifierTypeOptionsForWave(waveIndex: integer, count: integer, party: PlayerPokemon[]): ModifierTypeOption[] {
|
||||
if (waveIndex % 10 === 0)
|
||||
return modifierPool[ModifierTier.LUXURY].filter(m => !(m.weight instanceof Function) || m.weight(party)).map(m => new ModifierTypeOption(m.modifierType, false));
|
||||
|
|
|
@ -92,6 +92,10 @@ export abstract class PersistentModifier extends Modifier {
|
|||
|
||||
abstract clone(): PersistentModifier;
|
||||
|
||||
getArgs(): any[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
incrementStack(amount: integer, virtual: boolean): boolean {
|
||||
if (this.getStackCount() + amount <= this.getMaxStackCount()) {
|
||||
if (!virtual)
|
||||
|
@ -194,17 +198,21 @@ export class TempBattleStatBoosterModifier extends PersistentModifier {
|
|||
private tempBattleStat: TempBattleStat;
|
||||
private battlesLeft: integer;
|
||||
|
||||
constructor(type: ModifierTypes.TempBattleStatBoosterModifierType, tempBattleStat: TempBattleStat, stackCount?: integer) {
|
||||
constructor(type: ModifierTypes.TempBattleStatBoosterModifierType, tempBattleStat: TempBattleStat, battlesLeft?: integer, stackCount?: integer) {
|
||||
super(type, stackCount);
|
||||
|
||||
this.tempBattleStat = tempBattleStat;
|
||||
this.battlesLeft = 5;
|
||||
this.battlesLeft = battlesLeft || 5;
|
||||
}
|
||||
|
||||
clone(): TempBattleStatBoosterModifier {
|
||||
return new TempBattleStatBoosterModifier(this.type as ModifierTypes.TempBattleStatBoosterModifierType, this.tempBattleStat, this.stackCount);
|
||||
}
|
||||
|
||||
getArgs(): any[] {
|
||||
return [ this.tempBattleStat, this.battlesLeft ];
|
||||
}
|
||||
|
||||
apply(args: any[]): boolean {
|
||||
const tempBattleStat = args[0] as TempBattleStat;
|
||||
|
||||
|
@ -267,6 +275,10 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
|
|||
return this.matchType(modifier) && (modifier as PokemonHeldItemModifier).pokemonId === this.pokemonId;
|
||||
}
|
||||
|
||||
getArgs(): any[] {
|
||||
return [ this.pokemonId ];
|
||||
}
|
||||
|
||||
shouldApply(args: any[]): boolean {
|
||||
return super.shouldApply(args) && args.length && args[0] instanceof Pokemon && (this.pokemonId === -1 || (args[0] as Pokemon).id === this.pokemonId);
|
||||
}
|
||||
|
@ -332,6 +344,10 @@ export class PokemonBaseStatModifier extends PokemonHeldItemModifier {
|
|||
return new PokemonBaseStatModifier(this.type as ModifierTypes.PokemonBaseStatBoosterModifierType, this.pokemonId, this.stat, this.stackCount);
|
||||
}
|
||||
|
||||
getArgs(): any[] {
|
||||
return super.getArgs().concat(this.stat);
|
||||
}
|
||||
|
||||
shouldApply(args: any[]): boolean {
|
||||
return super.shouldApply(args) && args.length === 2 && args[1] instanceof Array<integer>;
|
||||
}
|
||||
|
@ -365,6 +381,10 @@ export class AttackTypeBoosterModifier extends PokemonHeldItemModifier {
|
|||
return new AttackTypeBoosterModifier(this.type, this.pokemonId, this.moveType, this.boostMultiplier * 100, this.stackCount);
|
||||
}
|
||||
|
||||
getArgs(): any[] {
|
||||
return super.getArgs().concat([ this.moveType, this.boostMultiplier * 100 ]);
|
||||
}
|
||||
|
||||
shouldApply(args: any[]): boolean {
|
||||
return super.shouldApply(args) && args.length === 2 && args[1] instanceof Utils.NumberHolder;
|
||||
}
|
||||
|
@ -543,6 +563,10 @@ export class BerryModifier extends PokemonHeldItemModifier {
|
|||
return new BerryModifier(this.type, this.pokemonId, this.berryType, this.stackCount);
|
||||
}
|
||||
|
||||
getArgs(): any[] {
|
||||
return super.getArgs().concat(this.berryType);
|
||||
}
|
||||
|
||||
shouldApply(args: any[]): boolean {
|
||||
return !this.consumed && super.shouldApply(args) && getBerryPredicate(this.berryType)(args[0] as Pokemon);
|
||||
}
|
||||
|
@ -818,6 +842,10 @@ export class HealingBoosterModifier extends PersistentModifier {
|
|||
return new HealingBoosterModifier(this.type, this.multiplier, this.stackCount);
|
||||
}
|
||||
|
||||
getArgs(): any[] {
|
||||
return [ this.multiplier ];
|
||||
}
|
||||
|
||||
apply(args: any[]): boolean {
|
||||
const healingMultiplier = args[0] as Utils.IntegerHolder;
|
||||
for (let s = 0; s < this.getStackCount(); s++)
|
||||
|
@ -853,6 +881,10 @@ export class ExpBoosterModifier extends PersistentModifier {
|
|||
return new ExpBoosterModifier(this.type, this.boostMultiplier * 100, this.stackCount);
|
||||
}
|
||||
|
||||
getArgs(): any[] {
|
||||
return [ this.boostMultiplier * 100 ];
|
||||
}
|
||||
|
||||
apply(args: any[]): boolean {
|
||||
(args[0] as Utils.NumberHolder).value = Math.floor((args[0] as Utils.NumberHolder).value * (1 + (this.getStackCount() * this.boostMultiplier)));
|
||||
|
||||
|
@ -880,6 +912,10 @@ export class PokemonExpBoosterModifier extends PokemonHeldItemModifier {
|
|||
return new PokemonExpBoosterModifier(this.type as ModifierTypes.PokemonExpBoosterModifierType, this.pokemonId, this.boostMultiplier * 100, this.stackCount);
|
||||
}
|
||||
|
||||
getArgs(): any[] {
|
||||
return super.getArgs().concat(this.boostMultiplier * 100);
|
||||
}
|
||||
|
||||
shouldApply(args: any[]): boolean {
|
||||
return super.shouldApply(args) && args.length === 2 && args[1] instanceof Utils.NumberHolder;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import { TempBattleStat } from './data/temp-battle-stat';
|
|||
import { WeakenMoveTypeTag } from './data/arena-tag';
|
||||
import { Biome } from './data/biome';
|
||||
import { Ability, TypeImmunityAbAttr, VariableMovePowerAbAttr, abilities, applyPreAttackAbAttrs, applyPreDefendAbAttrs } from './data/ability';
|
||||
import PokemonData from './system/pokemon-data';
|
||||
|
||||
export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
public id: integer;
|
||||
|
@ -54,7 +55,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
|
||||
private shinySparkle: Phaser.GameObjects.Sprite;
|
||||
|
||||
constructor(scene: BattleScene, x: number, y: number, species: PokemonSpecies, level: integer, abilityIndex?: integer, formIndex?: integer, gender?: Gender, shiny?: boolean, dataSource?: Pokemon) {
|
||||
constructor(scene: BattleScene, x: number, y: number, species: PokemonSpecies, level: integer, abilityIndex?: integer, formIndex?: integer, gender?: Gender, shiny?: boolean, dataSource?: Pokemon | PokemonData) {
|
||||
super(scene, x, y);
|
||||
|
||||
if (!species.isObtainable() && this.isPlayer())
|
||||
|
@ -666,7 +667,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
}
|
||||
|
||||
getMoveHistory(): TurnMove[] {
|
||||
return this.summonData.moveHistory;
|
||||
return this.battleSummonData.moveHistory;
|
||||
}
|
||||
|
||||
pushMoveHistory(turnMove: TurnMove) {
|
||||
|
@ -875,7 +876,7 @@ export class PlayerPokemon extends Pokemon {
|
|||
public metLevel: integer;
|
||||
public compatibleTms: Moves[];
|
||||
|
||||
constructor(scene: BattleScene, species: PokemonSpecies, level: integer, abilityIndex: integer, formIndex: integer, gender?: Gender, shiny?: boolean, dataSource?: Pokemon) {
|
||||
constructor(scene: BattleScene, species: PokemonSpecies, level: integer, abilityIndex: integer, formIndex: integer, gender?: Gender, shiny?: boolean, dataSource?: Pokemon | PokemonData) {
|
||||
super(scene, 106, 148, species, level, abilityIndex, formIndex, gender, shiny, dataSource);
|
||||
|
||||
this.metBiome = scene.arena?.biomeType || Biome.TOWN;
|
||||
|
@ -942,16 +943,19 @@ export class PlayerPokemon extends Pokemon {
|
|||
export class EnemyPokemon extends Pokemon {
|
||||
public aiType: AiType;
|
||||
|
||||
constructor(scene: BattleScene, species: PokemonSpecies, level: integer) {
|
||||
super(scene, -66, 84, species, level, undefined, scene.arena.getFormIndex(species));
|
||||
constructor(scene: BattleScene, species: PokemonSpecies, level: integer, dataSource?: PokemonData) {
|
||||
super(scene, -66, 84, species, level, dataSource?.abilityIndex, dataSource ? dataSource.formIndex : scene.arena.getFormIndex(species),
|
||||
dataSource?.gender, dataSource?.shiny, dataSource);
|
||||
|
||||
let prevolution: Species;
|
||||
let speciesId = species.speciesId;
|
||||
while ((prevolution = pokemonPrevolutions[speciesId])) {
|
||||
const evolution = pokemonEvolutions[prevolution].find(pe => pe.speciesId === speciesId);
|
||||
if (evolution.condition?.enforceFunc)
|
||||
evolution.condition.enforceFunc(this);
|
||||
speciesId = prevolution;
|
||||
if (!dataSource) {
|
||||
let prevolution: Species;
|
||||
let speciesId = species.speciesId;
|
||||
while ((prevolution = pokemonPrevolutions[speciesId])) {
|
||||
const evolution = pokemonEvolutions[prevolution].find(pe => pe.speciesId === speciesId);
|
||||
if (evolution.condition?.enforceFunc)
|
||||
evolution.condition.enforceFunc(this);
|
||||
speciesId = prevolution;
|
||||
}
|
||||
}
|
||||
|
||||
this.aiType = AiType.SMART_RANDOM;
|
||||
|
@ -1077,7 +1081,6 @@ export interface QueuedMove {
|
|||
|
||||
export class PokemonSummonData {
|
||||
public battleStats: integer[] = [ 0, 0, 0, 0, 0, 0, 0 ];
|
||||
public moveHistory: TurnMove[] = [];
|
||||
public moveQueue: QueuedMove[] = [];
|
||||
public tags: BattlerTag[] = [];
|
||||
public types: Type[];
|
||||
|
@ -1085,6 +1088,7 @@ export class PokemonSummonData {
|
|||
|
||||
export class PokemonBattleSummonData {
|
||||
public turnCount: integer = 1;
|
||||
public moveHistory: TurnMove[] = [];
|
||||
}
|
||||
|
||||
export class PokemonTurnData {
|
||||
|
|
|
@ -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 : [];
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue