Add egg moves logic
parent
7f77507d2b
commit
649717a3cd
|
@ -0,0 +1,43 @@
|
|||
import { Moves } from "./enums/moves";
|
||||
import { Species } from "./enums/species";
|
||||
import { allMoves } from "./move";
|
||||
import * as Utils from "../utils";
|
||||
|
||||
|
||||
export const speciesEggMoves = {
|
||||
};
|
||||
|
||||
function parseEggMoves(content: string): void {
|
||||
let output = '';
|
||||
|
||||
const speciesNames = Utils.getEnumKeys(Species);
|
||||
const speciesValues = Utils.getEnumValues(Species);
|
||||
const lines = content.split(/\n/g);
|
||||
|
||||
lines.forEach((line, l) => {
|
||||
const cols = line.split(',').slice(0, 5);
|
||||
const moveNames = allMoves.map(m => m.name.replace(/ \([A-Z]\)$/, '').toLowerCase());
|
||||
const enumSpeciesName = cols[0].toUpperCase().replace(/[ -]/g, '_');
|
||||
const species = speciesValues[speciesNames.findIndex(s => s === enumSpeciesName)];
|
||||
|
||||
let eggMoves: Moves[] = [];
|
||||
|
||||
for (let m = 0; m < 4; m++) {
|
||||
const moveName = cols[m + 1].trim();
|
||||
const moveIndex = moveName !== 'N/A' ? moveNames.findIndex(mn => mn === moveName.toLowerCase()) : -1;
|
||||
eggMoves.push(moveIndex > -1 ? moveIndex as Moves : Moves.NONE);
|
||||
}
|
||||
|
||||
if (eggMoves.find(m => m !== Moves.NONE))
|
||||
output += `[Species.${Species[species]}]: [ ${eggMoves.map(m => `Moves.${Moves[m]}`).join(', ')} ],\n`;
|
||||
});
|
||||
|
||||
console.log(output);
|
||||
}
|
||||
|
||||
const eggMovesStr = ``;
|
||||
if (eggMovesStr) {
|
||||
setTimeout(() => {
|
||||
parseEggMoves(eggMovesStr);
|
||||
}, 1000);
|
||||
}
|
|
@ -7,7 +7,8 @@ import { Type } from './type';
|
|||
import { LevelMoves, pokemonFormLevelMoves, pokemonFormLevelMoves as pokemonSpeciesFormLevelMoves, pokemonSpeciesLevelMoves } from './pokemon-level-moves';
|
||||
import { uncatchableSpecies } from './biomes';
|
||||
import * as Utils from '../utils';
|
||||
import { StarterMoveset } from '../system/game-data';
|
||||
import { StarterEggMoveData, StarterMoveset } from '../system/game-data';
|
||||
import { speciesEggMoves } from './egg-moves';
|
||||
|
||||
export enum Region {
|
||||
NORMAL,
|
||||
|
@ -98,6 +99,13 @@ export abstract class PokemonSpeciesForm {
|
|||
this.genderDiffs = genderDiffs;
|
||||
}
|
||||
|
||||
getRootSpeciesId(): Species {
|
||||
let ret = this.speciesId;
|
||||
while (pokemonPrevolutions.hasOwnProperty(ret))
|
||||
ret = pokemonPrevolutions[ret];
|
||||
return ret;
|
||||
}
|
||||
|
||||
isOfType(type: integer): boolean {
|
||||
return this.type1 === type || (this.type2 !== null && this.type2 === type);
|
||||
}
|
||||
|
@ -261,8 +269,14 @@ export abstract class PokemonSpeciesForm {
|
|||
return ret;
|
||||
}
|
||||
|
||||
validateStarterMoveset(moveset: StarterMoveset): boolean {
|
||||
validateStarterMoveset(moveset: StarterMoveset, eggMoves: integer): boolean {
|
||||
const rootSpeciesId = this.getRootSpeciesId();
|
||||
for (let moveId of moveset) {
|
||||
if (speciesEggMoves.hasOwnProperty(rootSpeciesId)) {
|
||||
const eggMoveIndex = speciesEggMoves[rootSpeciesId].findIndex(m => m === moveId);
|
||||
if (eggMoveIndex > -1 && eggMoves & Math.pow(2, eggMoveIndex))
|
||||
continue;
|
||||
}
|
||||
if (pokemonFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) {
|
||||
if (!pokemonFormLevelMoves[this.speciesId][this.formIndex].find(lm => lm[0] <= 5 && lm[1] === moveId))
|
||||
return false;
|
||||
|
|
|
@ -15,6 +15,7 @@ import { Gender, getGenderColor, getGenderSymbol } from "./data/gender";
|
|||
import { achvs } from "./system/achv";
|
||||
import { addWindow } from "./ui/window";
|
||||
import { getNatureName } from "./data/nature";
|
||||
import { pokemonPrevolutions } from "./data/pokemon-evolutions";
|
||||
|
||||
export class EggHatchPhase extends Phase {
|
||||
private egg: Egg;
|
||||
|
@ -33,6 +34,7 @@ export class EggHatchPhase extends Phase {
|
|||
private statsContainer: StatsContainer;
|
||||
|
||||
private pokemon: PlayerPokemon;
|
||||
private eggMoveIndex: integer;
|
||||
private canSkip: boolean;
|
||||
private skipped: boolean;
|
||||
private evolutionBgm: AnySound;
|
||||
|
@ -293,8 +295,10 @@ export class EggHatchPhase extends Phase {
|
|||
this.scene.ui.showText(`${this.pokemon.name} hatched from the egg!`, null, () => {
|
||||
this.scene.gameData.updateSpeciesDexIvs(this.pokemon.species.speciesId, this.pokemon.ivs);
|
||||
this.scene.gameData.setPokemonCaught(this.pokemon, true, true).then(() => {
|
||||
this.scene.ui.showText(null, 0);
|
||||
this.end();
|
||||
this.scene.gameData.setEggMoveUnlocked(this.pokemon.species, this.eggMoveIndex).then(() => {
|
||||
this.scene.ui.showText(null, 0);
|
||||
this.end();
|
||||
});
|
||||
});
|
||||
}, null, true, 3000);
|
||||
//this.scene.time.delayedCall(Utils.fixedInt(4250), () => this.scene.playBgm());
|
||||
|
@ -412,7 +416,7 @@ export class EggHatchPhase extends Phase {
|
|||
let speciesPool = Object.keys(speciesStarters)
|
||||
.filter(s => speciesStarters[s] >= minStarterValue && speciesStarters[s] <= maxStarterValue)
|
||||
.map(s => parseInt(s) as Species)
|
||||
.filter(s => getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1);
|
||||
.filter(s => !pokemonPrevolutions.hasOwnProperty(s) && getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1);
|
||||
|
||||
if (this.egg.gachaType === GachaType.TYPE) {
|
||||
let tryOverrideType: boolean;
|
||||
|
@ -474,6 +478,12 @@ export class EggHatchPhase extends Phase {
|
|||
ret.ivs[s] = Math.max(ret.ivs[s], secondaryIvs[s]);
|
||||
}, ret.id, EGG_SEED.toString());
|
||||
|
||||
this.scene.executeWithSeedOffset(() => {
|
||||
const rand = Utils.randSeedInt(10);
|
||||
|
||||
this.eggMoveIndex = rand ? Math.floor((rand - 1) / 3) : 3;
|
||||
}, this.egg.id, EGG_SEED.toString());
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -1712,8 +1712,8 @@ export class TurnEndPhase extends FieldPhase {
|
|||
pokemon.lapseTags(BattlerTagLapseType.TURN_END);
|
||||
|
||||
if (pokemon.summonData.disabledMove && !--pokemon.summonData.disabledTurns) {
|
||||
pokemon.summonData.disabledMove = Moves.NONE;
|
||||
this.scene.pushPhase(new MessagePhase(this.scene, `${allMoves[pokemon.summonData.disabledMove].name} is disabled\nno more!`));
|
||||
pokemon.summonData.disabledMove = Moves.NONE;
|
||||
}
|
||||
|
||||
const hasUsableBerry = !!this.scene.findModifier(m => m instanceof BerryModifier && m.shouldApply([ pokemon ]), pokemon.isPlayer());
|
||||
|
|
|
@ -1925,7 +1925,7 @@ export class PlayerPokemon extends Pokemon {
|
|||
}
|
||||
|
||||
tryPopulateMoveset(moveset: StarterMoveset): boolean {
|
||||
if (!this.getSpeciesForm().validateStarterMoveset(moveset))
|
||||
if (!this.getSpeciesForm().validateStarterMoveset(moveset, this.scene.gameData.starterEggMoveData[this.species.getRootSpeciesId()]))
|
||||
return false;
|
||||
|
||||
this.moveset = moveset.map(m => new PokemonMove(m));
|
||||
|
|
|
@ -25,6 +25,8 @@ import { GameStats } from "./game-stats";
|
|||
import { Tutorial } from "../tutorial";
|
||||
import { BattleSpec } from "../enums/battle-spec";
|
||||
import { Moves } from "../data/enums/moves";
|
||||
import { speciesEggMoves } from "../data/egg-moves";
|
||||
import { allMoves } from "../data/move";
|
||||
|
||||
const saveKey = 'x0i2O7WRiANTqPmZ'; // Temporary; secure encryption is not yet necessary
|
||||
|
||||
|
@ -60,6 +62,7 @@ interface SystemSaveData {
|
|||
gender: PlayerGender;
|
||||
dexData: DexData;
|
||||
starterMoveData: StarterMoveData;
|
||||
starterEggMoveData: StarterEggMoveData;
|
||||
gameStats: GameStats;
|
||||
unlocks: Unlocks;
|
||||
achvUnlocks: AchvUnlocks;
|
||||
|
@ -146,6 +149,10 @@ export interface StarterFormMoveData {
|
|||
[key: integer]: StarterMoveset
|
||||
}
|
||||
|
||||
export interface StarterEggMoveData {
|
||||
[key: integer]: integer
|
||||
}
|
||||
|
||||
export interface TutorialFlags {
|
||||
[key: string]: boolean
|
||||
}
|
||||
|
@ -172,6 +179,8 @@ export class GameData {
|
|||
|
||||
public starterMoveData: StarterMoveData;
|
||||
|
||||
public starterEggMoveData: StarterEggMoveData;
|
||||
|
||||
public gameStats: GameStats;
|
||||
|
||||
public unlocks: Unlocks;
|
||||
|
@ -188,6 +197,7 @@ export class GameData {
|
|||
this.trainerId = Utils.randSeedInt(65536);
|
||||
this.secretId = Utils.randSeedInt(65536);
|
||||
this.starterMoveData = {};
|
||||
this.starterEggMoveData = {};
|
||||
this.gameStats = new GameStats();
|
||||
this.unlocks = {
|
||||
[Unlockables.ENDLESS_MODE]: false,
|
||||
|
@ -204,6 +214,7 @@ export class GameData {
|
|||
};
|
||||
this.eggs = [];
|
||||
this.initDexData();
|
||||
this.initEggMoveData();
|
||||
}
|
||||
|
||||
public saveSystem(): Promise<boolean> {
|
||||
|
@ -220,6 +231,7 @@ export class GameData {
|
|||
gender: this.gender,
|
||||
dexData: this.dexData,
|
||||
starterMoveData: this.starterMoveData,
|
||||
starterEggMoveData: this.starterEggMoveData,
|
||||
gameStats: this.gameStats,
|
||||
unlocks: this.unlocks,
|
||||
achvUnlocks: this.achvUnlocks,
|
||||
|
@ -280,6 +292,13 @@ export class GameData {
|
|||
|
||||
this.starterMoveData = systemData.starterMoveData || {};
|
||||
|
||||
if (systemData.starterEggMoveData)
|
||||
this.starterEggMoveData = systemData.starterEggMoveData;
|
||||
else {
|
||||
this.starterEggMoveData = {};
|
||||
this.initEggMoveData();
|
||||
}
|
||||
|
||||
if (systemData.gameStats)
|
||||
this.gameStats = systemData.gameStats;
|
||||
|
||||
|
@ -806,6 +825,15 @@ export class GameData {
|
|||
this.dexData = data;
|
||||
}
|
||||
|
||||
private initEggMoveData(): void {
|
||||
const data: StarterEggMoveData = {};
|
||||
|
||||
const starterSpeciesIds = Object.keys(speciesEggMoves).map(k => parseInt(k) as Species);
|
||||
|
||||
for (let speciesId of starterSpeciesIds)
|
||||
data[speciesId] = 0;
|
||||
}
|
||||
|
||||
setPokemonSeen(pokemon: Pokemon, incrementCount: boolean = true): void {
|
||||
const dexEntry = this.dexData[pokemon.species.speciesId];
|
||||
dexEntry.seenAttr |= pokemon.getDexAttr();
|
||||
|
@ -822,7 +850,7 @@ export class GameData {
|
|||
}
|
||||
|
||||
setPokemonSpeciesCaught(pokemon: Pokemon, species: PokemonSpecies, incrementCount: boolean = true, fromEgg: boolean = false): Promise<void> {
|
||||
return new Promise<void>((resolve) => {
|
||||
return new Promise<void>(resolve => {
|
||||
const dexEntry = this.dexData[species.speciesId];
|
||||
const caughtAttr = dexEntry.caughtAttr;
|
||||
dexEntry.caughtAttr |= pokemon.getDexAttr();
|
||||
|
@ -868,6 +896,31 @@ export class GameData {
|
|||
});
|
||||
}
|
||||
|
||||
setEggMoveUnlocked(species: PokemonSpecies, eggMoveIndex: integer): Promise<boolean> {
|
||||
return new Promise<boolean>(resolve => {
|
||||
const speciesId = species.speciesId;
|
||||
if (!speciesEggMoves.hasOwnProperty(speciesId) || !speciesEggMoves[speciesId][eggMoveIndex]) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.starterEggMoveData.hasOwnProperty(speciesId))
|
||||
this.starterEggMoveData[speciesId] = 0;
|
||||
|
||||
const value = Math.pow(2, eggMoveIndex);
|
||||
|
||||
if (this.starterEggMoveData[speciesId] & eggMoveIndex) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
this.starterEggMoveData[speciesId] |= value;
|
||||
|
||||
this.scene.playSoundWithoutBgm('level_up_fanfare', 1500);
|
||||
this.scene.ui.showText(`${eggMoveIndex === 3 ? 'Rare ' : ''}Egg Move unlocked: ${allMoves[speciesEggMoves[speciesId][eggMoveIndex]].name}`, null, () => resolve(true), null, true);
|
||||
});
|
||||
}
|
||||
|
||||
updateSpeciesDexIvs(speciesId: Species, ivs: integer[]): void {
|
||||
let dexEntry: DexEntry;
|
||||
do {
|
||||
|
|
|
@ -22,6 +22,7 @@ import { LevelMoves, pokemonFormLevelMoves, pokemonSpeciesLevelMoves } from "../
|
|||
import { allMoves } from "../data/move";
|
||||
import { Type } from "../data/type";
|
||||
import { Moves } from "../data/enums/moves";
|
||||
import { speciesEggMoves } from "../data/egg-moves";
|
||||
|
||||
export type StarterSelectCallback = (starters: Starter[]) => void;
|
||||
|
||||
|
@ -144,12 +145,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||
this.pokemonNameText.setOrigin(0, 0);
|
||||
this.starterSelectContainer.add(this.pokemonNameText);
|
||||
|
||||
this.pokemonGrowthRateLabelText = addTextObject(this.scene, 8, 103, 'Growth Rate:', TextStyle.SUMMARY, { fontSize: '48px' });
|
||||
this.pokemonGrowthRateLabelText = addTextObject(this.scene, 8, 106, 'Growth Rate:', TextStyle.SUMMARY, { fontSize: '36px' });
|
||||
this.pokemonGrowthRateLabelText.setOrigin(0, 0);
|
||||
this.pokemonGrowthRateLabelText.setVisible(false);
|
||||
this.starterSelectContainer.add(this.pokemonGrowthRateLabelText);
|
||||
|
||||
this.pokemonGrowthRateText = addTextObject(this.scene, 44, 103, '', TextStyle.SUMMARY_PINK, { fontSize: '48px' });
|
||||
this.pokemonGrowthRateText = addTextObject(this.scene, 34, 106, '', TextStyle.SUMMARY_PINK, { fontSize: '36px' });
|
||||
this.pokemonGrowthRateText.setOrigin(0, 0);
|
||||
this.starterSelectContainer.add(this.pokemonGrowthRateText);
|
||||
|
||||
|
@ -344,9 +345,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||
|
||||
this.starterSelectContainer.add(this.pokemonMovesContainer);
|
||||
|
||||
this.pokemonEggMovesContainer = this.scene.add.container(102, 94);
|
||||
this.pokemonEggMovesContainer.setScale(0.25);
|
||||
this.pokemonEggMovesContainer.setVisible(false);
|
||||
this.pokemonEggMovesContainer = this.scene.add.container(102, 85);
|
||||
this.pokemonEggMovesContainer.setScale(0.375);
|
||||
|
||||
const eggMovesLabel = addTextObject(this.scene, -46, 0, 'Egg Moves', TextStyle.SUMMARY);
|
||||
eggMovesLabel.setOrigin(0.5, 0);
|
||||
|
@ -617,9 +617,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||
};
|
||||
}).concat({
|
||||
label: 'Cancel',
|
||||
handler: () => {
|
||||
showSwapOptions(this.starterMoveset);
|
||||
}
|
||||
handler: () => showSwapOptions(this.starterMoveset)
|
||||
}),
|
||||
maxOptions: 8,
|
||||
yOffset: 19
|
||||
|
@ -1106,6 +1104,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||
else
|
||||
levelMoves = pokemonSpeciesLevelMoves[species.speciesId];
|
||||
this.speciesStarterMoves.push(...levelMoves.filter(lm => lm[0] <= 5).map(lm => lm[1]));
|
||||
if (speciesEggMoves.hasOwnProperty(species.speciesId)) {
|
||||
for (let em = 0; em < 4; em++) {
|
||||
if (this.scene.gameData.starterEggMoveData[species.speciesId] & Math.pow(2, em))
|
||||
this.speciesStarterMoves.push(speciesEggMoves[species.speciesId][em]);
|
||||
}
|
||||
}
|
||||
|
||||
const speciesMoveData = this.scene.gameData.starterMoveData[species.speciesId];
|
||||
let moveData: StarterMoveset = speciesMoveData
|
||||
|
@ -1134,6 +1138,17 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||
this.pokemonMoveContainers[m].setVisible(!!move);
|
||||
}
|
||||
|
||||
const hasEggMoves = species && speciesEggMoves.hasOwnProperty(species.speciesId);
|
||||
|
||||
for (let em = 0; em < 4; em++) {
|
||||
const eggMove = hasEggMoves ? allMoves[speciesEggMoves[species.speciesId][em]] : null;
|
||||
const eggMoveUnlocked = eggMove && this.scene.gameData.starterEggMoveData.hasOwnProperty(species.speciesId) && this.scene.gameData.starterEggMoveData[species.speciesId] & Math.pow(2, em);
|
||||
this.pokemonEggMoveBgs[em].setFrame(Type[eggMove ? eggMove.type : Type.UNKNOWN].toString().toLowerCase());
|
||||
this.pokemonEggMoveLabels[em].setText(eggMove && eggMoveUnlocked ? eggMove.name : '???');
|
||||
}
|
||||
|
||||
this.pokemonEggMovesContainer.setVisible(hasEggMoves);
|
||||
|
||||
this.pokemonAdditionalMoveCountLabel.setText(`(+${Math.max(this.speciesStarterMoves.length - 4, 0)})`);
|
||||
this.pokemonAdditionalMoveCountLabel.setVisible(this.speciesStarterMoves.length > 4);
|
||||
|
||||
|
|
Loading…
Reference in New Issue