Add WiP features related to forms and save data
This commit is contained in:
1 parent
bcafa47673
commit
00ad27247c
274 files changed
+1507
-440761
No files matched your search
@@ -91,6 +91,12 @@ export class Arena {
|
||||
return Biome[this.biomeType].toLowerCase();
|
||||
}
|
||||
|
||||
getFormIndex(species: PokemonSpecies) {
|
||||
if (!species.canChangeForm && species.forms?.length)
|
||||
return Utils.randInt(species.forms.length); // TODO: Base on biome
|
||||
return 0;
|
||||
}
|
||||
|
||||
trySetWeather(weather: WeatherType, viaMove: boolean): boolean {
|
||||
if (this.weather?.weatherType === (weather || null))
|
||||
return false;
|
||||
|
||||
+22
-77
@@ -1,6 +1,7 @@
|
||||
import BattleScene from "./battle-scene";
|
||||
import { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult } from "./pokemon";
|
||||
import { applyMoveAttrs, BypassSleepAttr, ChargeAttr, ConditionalMoveAttr, HitsTagAttr, MissEffectAttr, MoveCategory, MoveEffectAttr, MoveHitEffectAttr, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr } from "./move";
|
||||
import * as Utils from './utils';
|
||||
import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, ConditionalMoveAttr, HitsTagAttr, MissEffectAttr, MoveCategory, MoveEffectAttr, MoveHitEffectAttr, Moves, MultiHitAttr, OverrideMoveEffectAttr } from "./move";
|
||||
import { Mode } from './ui/ui';
|
||||
import { Command } from "./ui/command-ui-handler";
|
||||
import { Stat } from "./pokemon-stat";
|
||||
@@ -20,9 +21,8 @@ import PokemonSpecies from "./pokemon-species";
|
||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||
import { BattleTagLapseType, BattleTagType, HideSpriteTag as HiddenTag } from "./battle-tag";
|
||||
import { getPokemonMessage } from "./messages";
|
||||
import { Weather, WeatherType, getRandomWeatherType, getWeatherDamageMessage, getWeatherLapseMessage as getWeatherEffectMessage } from "./weather";
|
||||
import { Moves, allMoves } from "./move";
|
||||
import * as Utils from './utils';
|
||||
import { Starter } from "./ui/starter-select-ui-handler";
|
||||
import { Gender } from "./gender";
|
||||
|
||||
export class SelectStarterPhase extends BattlePhase {
|
||||
constructor(scene: BattleScene) {
|
||||
@@ -34,14 +34,17 @@ export class SelectStarterPhase extends BattlePhase {
|
||||
|
||||
this.scene.sound.play('menu', { loop: true });
|
||||
|
||||
this.scene.ui.setMode(Mode.STARTER_SELECT, (starterSpecies: PokemonSpecies[]) => {
|
||||
this.scene.ui.setMode(Mode.STARTER_SELECT, (starters: Starter[]) => {
|
||||
const party = this.scene.getParty();
|
||||
const loadPokemonAssets: Promise<void>[] = [];
|
||||
for (let species of starterSpecies) {
|
||||
const starter = new PlayerPokemon(this.scene, species, 5);
|
||||
starter.setVisible(false);
|
||||
party.push(starter);
|
||||
loadPokemonAssets.push(starter.loadAssets());
|
||||
for (let starter of starters) {
|
||||
const starterGender = starter.species.malePercent !== null
|
||||
? !starter.female ? Gender.MALE : Gender.FEMALE
|
||||
: Gender.GENDERLESS;
|
||||
const starterPokemon = new PlayerPokemon(this.scene, starter.species, 5, starter.formIndex, starterGender, starter.shiny);
|
||||
starterPokemon.setVisible(false);
|
||||
party.push(starterPokemon);
|
||||
loadPokemonAssets.push(starterPokemon.loadAssets());
|
||||
}
|
||||
Promise.all(loadPokemonAssets).then(() => {
|
||||
this.scene.ui.clearText();
|
||||
@@ -205,8 +208,7 @@ export class SwitchBiomePhase extends BattlePhase {
|
||||
onComplete: () => {
|
||||
this.scene.arenaEnemy.setX(this.scene.arenaEnemy.x - 600);
|
||||
|
||||
this.scene.newArena(this.nextBiome)
|
||||
.trySetWeather(getRandomWeatherType(this.nextBiome), false);
|
||||
this.scene.newArena(this.nextBiome);
|
||||
|
||||
const biomeKey = this.scene.arena.getBiomeKey();
|
||||
const bgTexture = `${biomeKey}_bg`;
|
||||
@@ -396,13 +398,9 @@ export class CheckSwitchPhase extends BattlePhase {
|
||||
|
||||
this.scene.ui.showText('Will you switch\nPOKéMON?', null, () => {
|
||||
this.scene.ui.setMode(Mode.CONFIRM, () => {
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
this.scene.unshiftPhase(new SwitchPhase(this.scene, false, true));
|
||||
this.end();
|
||||
}, () => {
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
this.end();
|
||||
});
|
||||
}, () => this.end());
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -450,12 +448,10 @@ export class CommandPhase extends BattlePhase {
|
||||
let isDelayed = (command: Command, playerMove: PokemonMove, enemyMove: PokemonMove) => {
|
||||
switch (command) {
|
||||
case Command.FIGHT:
|
||||
if (playerMove && enemyMove) {
|
||||
const playerMovePriority = playerMove.getMove().priority;
|
||||
const enemyMovePriority = enemyMove.getMove().priority;
|
||||
if (playerMovePriority !== enemyMovePriority)
|
||||
return playerMovePriority < enemyMovePriority;
|
||||
}
|
||||
const playerMovePriority = playerMove.getMove().priority;
|
||||
const enemyMovePriority = enemyMove.getMove().priority;
|
||||
if (playerMovePriority !== enemyMovePriority)
|
||||
return playerMovePriority < enemyMovePriority;
|
||||
break;
|
||||
case Command.BALL:
|
||||
case Command.POKEMON:
|
||||
@@ -495,9 +491,6 @@ export class CommandPhase extends BattlePhase {
|
||||
}
|
||||
|
||||
if (success) {
|
||||
if (this.scene.arena.weather)
|
||||
this.scene.unshiftPhase(new WeatherEffectPhase(this.scene, this.scene.arena.weather, isDelayed(command, null, null)));
|
||||
|
||||
const enemyMove = enemyPokemon.getNextMove();
|
||||
const enemyPhase = new EnemyMovePhase(this.scene, enemyPokemon, enemyMove);
|
||||
if (isDelayed(command, playerMove, enemyMove))
|
||||
@@ -546,9 +539,6 @@ export class TurnEndPhase extends BattlePhase {
|
||||
playerPokemon.battleSummonData.turnCount++;
|
||||
enemyPokemon.battleSummonData.turnCount++;
|
||||
|
||||
if (this.scene.arena.weather && !this.scene.arena.weather.lapse())
|
||||
this.scene.arena.trySetWeather(WeatherType.NONE, false);
|
||||
|
||||
this.end();
|
||||
}
|
||||
}
|
||||
@@ -643,8 +633,6 @@ export abstract class MovePhase extends BattlePhase {
|
||||
|
||||
const failed = new Utils.BooleanHolder(false);
|
||||
applyMoveAttrs(ConditionalMoveAttr, this.pokemon, target, this.move.getMove(), failed);
|
||||
if (!failed.value && this.scene.arena.isMoveWeatherCancelled(this.move.getMove()))
|
||||
failed.value = true;
|
||||
if (failed.value)
|
||||
this.scene.unshiftPhase(new MessagePhase(this.scene, 'But it failed!'));
|
||||
else
|
||||
@@ -806,12 +794,6 @@ abstract class MoveEffectPhase extends PokemonPhase {
|
||||
if (!this.move.getMove().getAttrs(HitsTagAttr).filter(hta => (hta as HitsTagAttr).tagType === hiddenTag.tagType).length)
|
||||
return false;
|
||||
}
|
||||
|
||||
const moveAccuracy = new Utils.NumberHolder(this.move.getMove().accuracy);
|
||||
applyMoveAttrs(VariableAccuracyAttr, this.getUserPokemon(), this.getTargetPokemon(), this.move.getMove(), moveAccuracy);
|
||||
|
||||
if (moveAccuracy.value === -1)
|
||||
return true;
|
||||
|
||||
if (this.move.getMove().category !== MoveCategory.STATUS) {
|
||||
const userAccuracyLevel = this.getUserPokemon().summonData.battleStats[BattleStat.ACC];
|
||||
@@ -823,9 +805,8 @@ abstract class MoveEffectPhase extends PokemonPhase {
|
||||
? (3 + Math.min(userAccuracyLevel - targetEvasionLevel, 6)) / 3
|
||||
: 3 / (3 + Math.min(targetEvasionLevel - userAccuracyLevel, 6));
|
||||
}
|
||||
return rand <= moveAccuracy.value * accuracyMultiplier;
|
||||
return rand <= this.move.getMove().accuracy * accuracyMultiplier;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1067,41 +1048,8 @@ export class PostTurnStatusEffectPhase extends PokemonPhase {
|
||||
}
|
||||
}
|
||||
|
||||
export class WeatherEffectPhase extends CommonAnimPhase {
|
||||
private weather: Weather;
|
||||
private playerDelayed: boolean;
|
||||
export class WeatherPhase extends BattlePhase {
|
||||
|
||||
constructor(scene: BattleScene, weather: Weather, playerDelayed: boolean) {
|
||||
super(scene, true, CommonAnim.SUNNY + (weather.weatherType - 1));
|
||||
|
||||
this.weather = weather;
|
||||
this.playerDelayed = playerDelayed;
|
||||
}
|
||||
|
||||
start() {
|
||||
if (this.weather.isDamaging()) {
|
||||
const inflictDamage = (pokemon: Pokemon) => {
|
||||
this.scene.unshiftPhase(new MessagePhase(this.scene, getWeatherDamageMessage(this.weather.weatherType, pokemon)));
|
||||
pokemon.damage(Math.ceil(pokemon.getMaxHp() / 16));
|
||||
this.scene.unshiftPhase(new DamagePhase(this.scene, pokemon.isPlayer()));
|
||||
};
|
||||
|
||||
const playerPokemon = this.scene.getPlayerPokemon();
|
||||
const enemyPokemon = this.scene.getEnemyPokemon();
|
||||
|
||||
const playerImmune = !!playerPokemon.getTypes().filter(t => this.weather.isTypeDamageImmune(t)).length;
|
||||
const enemyImmune = !!playerPokemon.getTypes().filter(t => this.weather.isTypeDamageImmune(t)).length;
|
||||
|
||||
if (!this.playerDelayed && !playerImmune)
|
||||
inflictDamage(playerPokemon);
|
||||
if (!enemyImmune)
|
||||
inflictDamage(enemyPokemon);
|
||||
if (this.playerDelayed && !playerImmune)
|
||||
inflictDamage(playerPokemon);
|
||||
}
|
||||
|
||||
this.scene.ui.showText(getWeatherEffectMessage(this.weather.weatherType), null, () => super.start());
|
||||
}
|
||||
}
|
||||
|
||||
export class MessagePhase extends BattlePhase {
|
||||
@@ -1120,10 +1068,7 @@ export class MessagePhase extends BattlePhase {
|
||||
start() {
|
||||
super.start();
|
||||
|
||||
if (this.text)
|
||||
this.scene.ui.showText(this.text, null, () => this.end(), this.callbackDelay || (this.prompt ? 0 : 1500), this.prompt);
|
||||
else
|
||||
this.end();
|
||||
this.scene.ui.showText(this.text, null, () => this.end(), this.callbackDelay || (this.prompt ? 0 : 1500), this.prompt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+23
-6
@@ -14,6 +14,8 @@ import { initCommonAnims, loadCommonAnimAssets, populateAnims } from './battle-a
|
||||
import { BattlePhase } from './battle-phase';
|
||||
import { initGameSpeed } from './game-speed';
|
||||
import { Arena } from './arena';
|
||||
import { SaveData } from './data';
|
||||
import StarterSelectUiHandler from './ui/starter-select-ui-handler';
|
||||
|
||||
const enableAuto = true;
|
||||
|
||||
@@ -24,6 +26,9 @@ export enum Button {
|
||||
RIGHT,
|
||||
ACTION,
|
||||
CANCEL,
|
||||
CYCLE_SHINY,
|
||||
CYCLE_FORM,
|
||||
CYCLE_GENDER,
|
||||
QUICK_START,
|
||||
RANDOM,
|
||||
AUTO,
|
||||
@@ -36,6 +41,8 @@ export default class BattleScene extends Phaser.Scene {
|
||||
public gameSpeed: integer = 1;
|
||||
public quickStart: boolean;
|
||||
|
||||
public saveData: SaveData;
|
||||
|
||||
private phaseQueue: BattlePhase[];
|
||||
private phaseQueuePrepend: BattlePhase[];
|
||||
private currentPhase: BattlePhase;
|
||||
@@ -66,12 +73,11 @@ export default class BattleScene extends Phaser.Scene {
|
||||
|
||||
private blockInput: boolean;
|
||||
|
||||
public trainerId: integer = Utils.randInt(65536);
|
||||
public secretId: integer = Utils.randInt(65536);
|
||||
|
||||
constructor() {
|
||||
super('battle');
|
||||
|
||||
this.saveData = new SaveData(this);
|
||||
|
||||
this.phaseQueue = [];
|
||||
this.phaseQueuePrepend = [];
|
||||
}
|
||||
@@ -307,7 +313,7 @@ export default class BattleScene extends Phaser.Scene {
|
||||
if (this.quickStart) {
|
||||
for (let s = 0; s < 3; s++) {
|
||||
const playerSpecies = !isRandom ? getPokemonSpecies(s === 0 ? Species.TORCHIC : s === 1 ? Species.TREECKO : Species.MUDKIP) : this.randomSpecies(5);
|
||||
const playerPokemon = new PlayerPokemon(this, playerSpecies, 5);
|
||||
const playerPokemon = new PlayerPokemon(this, playerSpecies, 5, 0);
|
||||
playerPokemon.setVisible(false);
|
||||
loadPokemonAssets.push(playerPokemon.loadAssets());
|
||||
|
||||
@@ -365,6 +371,9 @@ export default class BattleScene extends Phaser.Scene {
|
||||
[Button.RIGHT]: [keyCodes.RIGHT, keyCodes.D],
|
||||
[Button.ACTION]: [keyCodes.ENTER, keyCodes.SPACE, keyCodes.Z],
|
||||
[Button.CANCEL]: [keyCodes.BACKSPACE, keyCodes.ESC, keyCodes.X],
|
||||
[Button.CYCLE_SHINY]: [keyCodes.R],
|
||||
[Button.CYCLE_FORM]: [keyCodes.F],
|
||||
[Button.CYCLE_GENDER]: [keyCodes.G],
|
||||
[Button.QUICK_START]: [keyCodes.Q],
|
||||
[Button.RANDOM]: [keyCodes.R],
|
||||
[Button.AUTO]: [keyCodes.F2],
|
||||
@@ -443,6 +452,16 @@ export default class BattleScene extends Phaser.Scene {
|
||||
this.ui.processInput(Button.ACTION);
|
||||
else if (this.isButtonPressed(Button.CANCEL))
|
||||
this.ui.processInput(Button.CANCEL);
|
||||
else if (this.ui?.getHandler() instanceof StarterSelectUiHandler) {
|
||||
if (this.isButtonPressed(Button.CYCLE_SHINY))
|
||||
this.ui.processInput(Button.CYCLE_SHINY);
|
||||
else if (this.isButtonPressed(Button.CYCLE_FORM))
|
||||
this.ui.processInput(Button.CYCLE_FORM);
|
||||
else if (this.isButtonPressed(Button.CYCLE_GENDER))
|
||||
this.ui.processInput(Button.CYCLE_GENDER);
|
||||
else
|
||||
return;
|
||||
}
|
||||
else if (this.isButtonPressed(Button.SPEED_UP)) {
|
||||
if (!this.auto) {
|
||||
if (this.gameSpeed < 2)
|
||||
@@ -581,8 +600,6 @@ export default class BattleScene extends Phaser.Scene {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
updateModifiers(): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
for (let modifier of this.modifiers) {
|
||||
|
||||
+26
-25
@@ -1,4 +1,5 @@
|
||||
import { pokemonEvolutions, SpeciesEvolution } from "./pokemon-evolutions";
|
||||
import { allSpecies } from "./pokemon-species";
|
||||
import { Species } from "./species";
|
||||
import { Type } from './type';
|
||||
import * as Utils from './utils';
|
||||
@@ -233,13 +234,13 @@ export const biomePools: BiomePools = {
|
||||
{ 1: [ Species.STUNKY ], 34: [ Species.SKUNTANK ] },
|
||||
{ 1: [ Species.PATRAT ], 20: [ Species.WATCHOG ] },
|
||||
{ 1: [ Species.LILLIPUP ], 16: [ Species.HERDIER ], 32: [ Species.STOUTLAND ] },
|
||||
Species.TRUBBISH
|
||||
{ 1: [ Species.TRUBBISH ], 36: [ Species.GARBODOR ] }
|
||||
],
|
||||
[BiomePoolTier.UNCOMMON]: [ Species.GARBODOR ],
|
||||
[BiomePoolTier.UNCOMMON]: [ { 1: [ Species.BURMY ], 20: [ Species.WORMADAM ] } ],
|
||||
[BiomePoolTier.RARE]: [],
|
||||
[BiomePoolTier.SUPER_RARE]: [ Species.EEVEE, Species.SMEARGLE ],
|
||||
[BiomePoolTier.ULTRA_RARE]: [ Species.DITTO, Species.CASTFORM ],
|
||||
[BiomePoolTier.BOSS]: [ Species.MUK, Species.WEEZING, Species.SKUNTANK, Species.WATCHOG, Species.STOUTLAND, Species.GARBODOR ],
|
||||
[BiomePoolTier.BOSS]: [ Species.MUK, Species.WEEZING, Species.WORMADAM, Species.SKUNTANK, Species.WATCHOG, Species.STOUTLAND, Species.GARBODOR ],
|
||||
[BiomePoolTier.BOSS_RARE]: [ Species.CASTFORM ],
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: [],
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: []
|
||||
@@ -386,11 +387,11 @@ export const biomePools: BiomePools = {
|
||||
{ 1: [ Species.DWEBBLE ], 34: [ Species.CRUSTLE ] },
|
||||
{ 1: [ Species.TIRTOUGA ], 37: [ Species.CARRACOSTA ] }
|
||||
],
|
||||
[BiomePoolTier.UNCOMMON]: [],
|
||||
[BiomePoolTier.UNCOMMON]: [ { 1: [ Species.BURMY ], 20: [ Species.WORMADAM ] } ],
|
||||
[BiomePoolTier.RARE]: [],
|
||||
[BiomePoolTier.SUPER_RARE]: [],
|
||||
[BiomePoolTier.ULTRA_RARE]: [ Species.KELDEO ],
|
||||
[BiomePoolTier.BOSS]: [ Species.CLOYSTER, Species.KINGLER, Species.STARMIE, Species.CRAWDAUNT, Species.CRUSTLE, Species.CARRACOSTA ],
|
||||
[BiomePoolTier.BOSS]: [ Species.CLOYSTER, Species.KINGLER, Species.STARMIE, Species.CRAWDAUNT, Species.WORMADAM, Species.CRUSTLE, Species.CARRACOSTA ],
|
||||
[BiomePoolTier.BOSS_RARE]: [],
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: [ Species.KELDEO ],
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: []
|
||||
@@ -416,7 +417,7 @@ export const biomePools: BiomePools = {
|
||||
[Biome.SEABED]: {
|
||||
[BiomePoolTier.COMMON]: [ { 1: [ Species.CHINCHOU ], 27: [ Species.LANTURN ] }, Species.REMORAID, Species.CLAMPERL, Species.BASCULIN, { 1: [ Species.FRILLISH ], 40: [ Species.JELLICENT ] } ],
|
||||
[BiomePoolTier.UNCOMMON]: [ { 1: [ Species.TENTACOOL ], 30: [ Species.TENTACRUEL ] }, Species.SHELLDER, Species.LUVDISC, { 1: [ Species.SHELLOS ], 30: [ Species.GASTRODON ] } ],
|
||||
[BiomePoolTier.RARE]: [ Species.QWILFISH, Species.CORSOLA, Species.OCTILLERY, Species.MANTINE, Species.MANTYKE, Species.PHIONE, Species.ALOMOMOLA, { 1: [ Species.TYNAMO ], 39: [ Species.EELEKTRIK ] } ],
|
||||
[BiomePoolTier.RARE]: [ Species.QWILFISH, Species.CORSOLA, Species.OCTILLERY, { 1: [ Species.MANTYKE ], 20: [ Species.MANTINE ] }, Species.PHIONE, Species.ALOMOMOLA, { 1: [ Species.TYNAMO ], 39: [ Species.EELEKTRIK ] } ],
|
||||
[BiomePoolTier.SUPER_RARE]: [ { 1: [ Species.OMANYTE ], 40: [ Species.OMASTAR ] }, { 1: [ Species.KABUTO ], 40: [ Species.KABUTOPS ] }, Species.RELICANTH ],
|
||||
[BiomePoolTier.ULTRA_RARE]: [ Species.FEEBAS, Species.MANAPHY ],
|
||||
[BiomePoolTier.BOSS]: [ Species.LANTURN, Species.QWILFISH, Species.CORSOLA, Species.OCTILLERY, Species.MANTINE, Species.HUNTAIL, Species.GOREBYSS, Species.LUVDISC, Species.JELLICENT, Species.ALOMOMOLA ],
|
||||
@@ -438,19 +439,13 @@ export const biomePools: BiomePools = {
|
||||
{ 1: [ Species.GEODUDE ], 25: [ Species.GRAVELER ] },
|
||||
{ 1: [ Species.RHYHORN ], 42: [ Species.RHYDON ] },
|
||||
{ 1: [ Species.NATU ], 25: [ Species.XATU ] },
|
||||
{ 1: [ Species.SLUGMA ], 38: [ Species.MAGCARGO ] },
|
||||
{ 1: [ Species.ARON ], 32: [ Species.LAIRON ], 42: [ Species.AGGRON ] },
|
||||
{ 1: [ Species.ROGGENROLA ], 25: [ Species.BOLDORE ] },
|
||||
{ 1: [ Species.RUFFLET ], 54: [ Species.BRAVIARY ] },
|
||||
Species.MANDIBUZZ
|
||||
],
|
||||
[BiomePoolTier.RARE]: [
|
||||
Species.MURKROW,
|
||||
{ 1: [ Species.SLUGMA ], 38: [ Species.MAGCARGO ] },
|
||||
Species.SKARMORY,
|
||||
{ 1: [ Species.TORCHIC ], 16: [ Species.COMBUSKEN ], 36: [ Species.BLAZIKEN ] },
|
||||
{ 1: [ Species.SPOINK ], 32: [ Species.GRUMPIG ] },
|
||||
Species.VULLABY
|
||||
],
|
||||
[BiomePoolTier.RARE]: [ Species.MURKROW, Species.SKARMORY, { 1: [ Species.TORCHIC ], 16: [ Species.COMBUSKEN ], 36: [ Species.BLAZIKEN ] }, { 1: [ Species.SPOINK ], 32: [ Species.GRUMPIG ] }, Species.VULLABY ],
|
||||
[BiomePoolTier.SUPER_RARE]: [
|
||||
{ 1: [ Species.LARVITAR ], 30: [ Species.PUPITAR ] },
|
||||
{ 1: [ Species.CRANIDOS ], 30: [ Species.RAMPARDOS ] },
|
||||
@@ -458,10 +453,10 @@ export const biomePools: BiomePools = {
|
||||
{ 1: [ Species.GIBLE ], 24: [ Species.GABITE ], 48: [ Species.GARCHOMP ] },
|
||||
{ 1: [ Species.AXEW ], 38: [ Species.FRAXURE ] }
|
||||
],
|
||||
[BiomePoolTier.ULTRA_RARE]: [ Species.REGISTEEL, Species.TORNADUS ],
|
||||
[BiomePoolTier.ULTRA_RARE]: [ Species.TORNADUS ],
|
||||
[BiomePoolTier.BOSS]: [ Species.PIDGEOT, Species.FEAROW, Species.SKARMORY, Species.SWELLOW, Species.AGGRON, Species.STARAPTOR, Species.UNFEZANT, Species.BRAVIARY, Species.MANDIBUZZ ],
|
||||
[BiomePoolTier.BOSS_RARE]: [ Species.BLAZIKEN, Species.RAMPARDOS, Species.BASTIODON ],
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: [ Species.REGISTEEL, Species.TORNADUS ],
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: [ Species.TORNADUS ],
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: [ Species.HO_OH, Species.RAYQUAZA ]
|
||||
},
|
||||
[Biome.LAND]: {
|
||||
@@ -495,10 +490,10 @@ export const biomePools: BiomePools = {
|
||||
[BiomePoolTier.UNCOMMON]: [ { 1: [ Species.GEODUDE ], 25: [ Species.GRAVELER ] }, { 1: [ Species.MAKUHITA ], 24: [ Species.HARIYAMA ] }, Species.NOSEPASS ],
|
||||
[BiomePoolTier.RARE]: [ Species.ONIX ],
|
||||
[BiomePoolTier.SUPER_RARE]: [ Species.SHUCKLE ],
|
||||
[BiomePoolTier.ULTRA_RARE]: [ Species.UXIE, Species.COBALION ],
|
||||
[BiomePoolTier.ULTRA_RARE]: [ Species.REGISTEEL, Species.UXIE, Species.COBALION ],
|
||||
[BiomePoolTier.BOSS]: [ Species.PARASECT, Species.ONIX, Species.CROBAT, Species.URSARING, Species.EXPLOUD, Species.MAWILE, Species.PROBOPASS, Species.GIGALITH, Species.SWOOBAT ],
|
||||
[BiomePoolTier.BOSS_RARE]: [ Species.SHUCKLE ],
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: [ Species.UXIE ],
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: [ Species.REGISTEEL, Species.UXIE ],
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: [ Species.MEWTWO, Species.COBALION ]
|
||||
},
|
||||
[Biome.DESERT]: {
|
||||
@@ -2633,12 +2628,18 @@ export const biomePools: BiomePools = {
|
||||
]
|
||||
],
|
||||
[ Species.BURMY, Type.BUG, -1, [
|
||||
[ Biome.FOREST, BiomePoolTier.UNCOMMON ]
|
||||
[ Biome.CITY, BiomePoolTier.UNCOMMON ],
|
||||
[ Biome.FOREST, BiomePoolTier.UNCOMMON ],
|
||||
[ Biome.BEACH, BiomePoolTier.UNCOMMON ]
|
||||
]
|
||||
],
|
||||
[ Species.WORMADAM, Type.BUG, Type.GRASS, [
|
||||
[ Biome.CITY, BiomePoolTier.UNCOMMON ],
|
||||
[ Biome.CITY, BiomePoolTier.BOSS ],
|
||||
[ Biome.FOREST, BiomePoolTier.UNCOMMON ],
|
||||
[ Biome.FOREST, BiomePoolTier.BOSS ]
|
||||
[ Biome.FOREST, BiomePoolTier.BOSS ],
|
||||
[ Biome.BEACH, BiomePoolTier.UNCOMMON ],
|
||||
[ Biome.BEACH, BiomePoolTier.BOSS ]
|
||||
]
|
||||
],
|
||||
[ Species.MOTHIM, Type.BUG, Type.FLYING, [
|
||||
@@ -3364,7 +3365,7 @@ export const biomePools: BiomePools = {
|
||||
]
|
||||
],
|
||||
[ Species.GARBODOR, Type.POISON, -1, [
|
||||
[ Biome.CITY, BiomePoolTier.UNCOMMON ],
|
||||
[ Biome.CITY, BiomePoolTier.COMMON ],
|
||||
[ Biome.CITY, BiomePoolTier.BOSS ]
|
||||
]
|
||||
],
|
||||
@@ -3850,7 +3851,7 @@ export const biomePools: BiomePools = {
|
||||
}
|
||||
}
|
||||
|
||||
console.log(beautify(output, null, 2, 180).replace(/( | (?:\{ "\d+": \[ )?| "(?:.*?)": \[ |, (?:(?:\{ )?"\d+": \[ )?)"(.*?)"/g, '$1Species.$2').replace(/"(\d+)": /g, '$1: ').replace(/( )"(.*?)"/g, '$1[PoolTier.$2]').replace(/( )"(.*?)"/g, '$1[Biome.$2]'));
|
||||
console.log(beautify(output, null, 2, 180).replace(/( | (?:\{ "\d+": \[ )?| "(?:.*?)": \[ |, (?:(?:\{ )?"\d+": \[ )?)"(.*?)"/g, '$1Species.$2').replace(/"(\d+)": /g, '$1: ').replace(/( )"(.*?)"/g, '$1[BiomePoolTier.$2]').replace(/( )"(.*?)"/g, '$1[Biome.$2]'));
|
||||
}
|
||||
|
||||
outputPools();
|
||||
@@ -3868,15 +3869,15 @@ export const biomePools: BiomePools = {
|
||||
for (let t of Object.keys(biomePools[b])) {
|
||||
for (let p = 0; p < biomePools[b][t].length; p++) {
|
||||
if (biomePools[b][t][p] === pokemon.speciesId) {
|
||||
poolTier = parseInt(t) as PoolTier;
|
||||
poolTier = parseInt(t) as BiomePoolTier;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (poolTier > -1)
|
||||
pokemonBiomes[pokemon.speciesId - 1][3].push([ Biome[b], PoolTier[poolTier] ]);
|
||||
pokemonBiomes[pokemon.speciesId - 1][3].push([ Biome[b], BiomePoolTier[BiomePoolTier] ]);
|
||||
} else if (biomePoolPredicates[b](pokemon)) {
|
||||
pokemonBiomes[pokemon.speciesId - 1][3].push([ Biome[b], PoolTier[PoolTier.COMMON] ]);
|
||||
pokemonBiomes[pokemon.speciesId - 1][3].push([ Biome[b], BiomePoolTier[BiomePoolTier.COMMON] ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+239
@@ -0,0 +1,239 @@
|
||||
import BattleScene from "./battle-scene";
|
||||
import { Gender } from "./gender";
|
||||
import PokemonSpecies, { allSpecies } from "./pokemon-species";
|
||||
import { Species } from "./species";
|
||||
import * as Utils from "./utils";
|
||||
|
||||
export interface DexData {
|
||||
[key: integer]: DexData | DexEntry
|
||||
}
|
||||
|
||||
export interface DexEntry {
|
||||
seen: boolean;
|
||||
caught: boolean;
|
||||
}
|
||||
|
||||
export interface StarterDexEntry {
|
||||
shiny: boolean;
|
||||
formIndex: integer;
|
||||
female: boolean;
|
||||
entry: DexEntry;
|
||||
}
|
||||
|
||||
export interface StarterDexUnlockTree {
|
||||
shiny: boolean | Map<boolean, StarterDexUnlockTree>
|
||||
formIndex: integer | Map<integer, StarterDexUnlockTree>
|
||||
female: boolean | Map<boolean, StarterDexUnlockTree>
|
||||
key: string,
|
||||
entry: DexEntry
|
||||
}
|
||||
|
||||
export class SaveData {
|
||||
private scene: BattleScene;
|
||||
|
||||
public trainerId: integer;
|
||||
public secretId: integer;
|
||||
|
||||
public dexData: DexData;
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
this.scene = scene;
|
||||
this.trainerId = Utils.randInt(65536);
|
||||
this.secretId = Utils.randInt(65536)
|
||||
this.initDexData();
|
||||
}
|
||||
|
||||
save() {
|
||||
|
||||
}
|
||||
|
||||
load() {
|
||||
|
||||
}
|
||||
|
||||
initDexData() {
|
||||
const data: DexData = {};
|
||||
|
||||
const initDexSubData = (dexData: DexData, count: integer): DexData[] => {
|
||||
const ret: DexData[] = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
const newData: DexData = {};
|
||||
dexData[i] = newData;
|
||||
ret.push(newData);
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
const initDexEntries = (dexData: DexData, count: integer): DexEntry[] => {
|
||||
const ret: DexEntry[] = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
const entry: DexEntry = { seen: true, caught: true };
|
||||
dexData[i] = entry;
|
||||
ret.push(entry);
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
for (let species of allSpecies) {
|
||||
data[species.speciesId] = {};
|
||||
if (species.forms?.length)
|
||||
initDexSubData(data[species.speciesId] as DexData, 2).map(sd => species.malePercent !== null ? initDexSubData(sd, species.forms.length).map(fd => initDexEntries(fd, 2)) : initDexEntries(sd, species.forms.length));
|
||||
else if (species.malePercent !== null)
|
||||
initDexSubData(data[species.speciesId] as DexData, 2).map(sd => initDexEntries(sd, 2));
|
||||
else
|
||||
initDexEntries(data[species.speciesId] as DexData, 2)
|
||||
}
|
||||
|
||||
const defaultStarters: Species[] = [
|
||||
Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE,
|
||||
Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE,
|
||||
Species.TREECKO, Species.TORCHIC, Species.MUDKIP,
|
||||
Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP,
|
||||
Species.SNIVY, Species.TEPIG, Species.OSHAWOTT
|
||||
];
|
||||
|
||||
for (let ds of defaultStarters) {
|
||||
let entry = data[ds][0][Gender.MALE] as DexEntry;
|
||||
entry.seen = true;
|
||||
entry.caught = true;
|
||||
|
||||
entry = data[ds][0][Gender.FEMALE] as DexEntry;
|
||||
entry.seen = true;
|
||||
entry.caught = true;
|
||||
|
||||
entry = data[ds][1][Gender.FEMALE] as DexEntry;
|
||||
entry.seen = true;
|
||||
entry.caught = true;
|
||||
}
|
||||
|
||||
this.dexData = data;
|
||||
}
|
||||
|
||||
getDexEntry(species: PokemonSpecies, shiny: boolean, formIndex: integer, female: boolean) : DexEntry {
|
||||
const shinyIndex = !shiny ? 0 : 1;
|
||||
const genderIndex = !female ? 0 : 1;
|
||||
const data = this.dexData[species.speciesId];
|
||||
if (species.forms?.length) {
|
||||
if (species.malePercent !== null)
|
||||
return data[shinyIndex][formIndex][genderIndex];
|
||||
return data[shinyIndex][formIndex];
|
||||
} else if (species.malePercent !== null)
|
||||
return data[shinyIndex][genderIndex];
|
||||
return data[shinyIndex] as DexEntry;
|
||||
}
|
||||
|
||||
getDefaultStarterDexEntry(species: PokemonSpecies, forceShiny?: boolean, forceFormIndex?: integer, forceFemale?: boolean): StarterDexEntry {
|
||||
const hasForms = !!species.forms?.length;
|
||||
let shiny = false;
|
||||
let formIndex = 0;
|
||||
let female = false;
|
||||
let entry = null;
|
||||
|
||||
const traverseData = (data: DexData, level: integer) => {
|
||||
const keys = Object.keys(data);
|
||||
keys.forEach((key: string, k: integer) => {
|
||||
if (entry)
|
||||
return;
|
||||
|
||||
switch (level) {
|
||||
case 0:
|
||||
shiny = !!k;
|
||||
if (forceShiny !== undefined && shiny !== forceShiny)
|
||||
return;
|
||||
break;
|
||||
case 1:
|
||||
formIndex = k;
|
||||
if (forceFormIndex !== undefined && formIndex !== forceFormIndex)
|
||||
return;
|
||||
break;
|
||||
case 2:
|
||||
female = !!k;
|
||||
if (forceFemale !== undefined && female !== forceFemale)
|
||||
return
|
||||
break;
|
||||
}
|
||||
|
||||
if ('caught' in data[key]) {
|
||||
if (data[key].caught)
|
||||
entry = data[key] as DexEntry;
|
||||
} else
|
||||
traverseData(data[key] as DexData, level + (hasForms ? 1 : 2));
|
||||
});
|
||||
};
|
||||
|
||||
traverseData(this.dexData[species.speciesId] as DexData, 0);
|
||||
|
||||
if (entry) {
|
||||
return {
|
||||
shiny: shiny,
|
||||
formIndex: formIndex,
|
||||
female: female,
|
||||
entry: entry
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
getStarterDexUnlockTree(species: PokemonSpecies): StarterDexUnlockTree {
|
||||
const hasForms = !!species.forms?.length;
|
||||
const hasGender = species.malePercent !== null;
|
||||
|
||||
const getTreeOrValueMap = (key: string, parent?: StarterDexUnlockTree): (Map<any, any>) => {
|
||||
switch (key) {
|
||||
case 'shiny':
|
||||
const shinyMap = new Map<boolean, StarterDexUnlockTree>();
|
||||
for (let s = 0; s < 2; s++) {
|
||||
const props = { shiny: !!s, formIndex: null };
|
||||
shinyMap.set(!!s, {
|
||||
shiny: !!s,
|
||||
formIndex: hasForms ? getTreeOrValueMap('formIndex', props as StarterDexUnlockTree) : null,
|
||||
female: !hasForms && hasGender ? getTreeOrValueMap('female', props as StarterDexUnlockTree) : null,
|
||||
key: hasForms ? 'formIndex' : hasGender ? 'female' : 'entry',
|
||||
entry: hasForms || hasGender ? null : this.dexData[species.speciesId][!s ? 0 : 1]
|
||||
});
|
||||
}
|
||||
return shinyMap;
|
||||
case 'formIndex':
|
||||
const formMap = new Map<integer, StarterDexUnlockTree>();
|
||||
for (let f = 0; f < species.forms.length; f++) {
|
||||
const props = { shiny: parent.shiny, formIndex: f };
|
||||
formMap.set(f, {
|
||||
shiny: parent.shiny,
|
||||
formIndex: f,
|
||||
female: hasGender ? getTreeOrValueMap('female', props as StarterDexUnlockTree) : null,
|
||||
key: hasGender ? 'female' : 'entry',
|
||||
entry: hasGender ? null : this.dexData[species.speciesId][!parent.shiny ? 0 : 1][f]
|
||||
});
|
||||
}
|
||||
return formMap;
|
||||
case 'female':
|
||||
const genderMap = new Map<boolean, StarterDexUnlockTree>();
|
||||
for (let g = 0; g < 2; g++) {
|
||||
genderMap.set(!!g, {
|
||||
shiny: parent.shiny,
|
||||
formIndex: parent.formIndex,
|
||||
female: !!g,
|
||||
key: 'entry',
|
||||
entry: hasForms
|
||||
? this.dexData[species.speciesId][!parent.shiny ? 0 : 1][parent.formIndex as integer][g]
|
||||
: this.dexData[species.speciesId][!parent.shiny ? 0 : 1][g]
|
||||
});
|
||||
}
|
||||
return genderMap;
|
||||
}
|
||||
};
|
||||
|
||||
const root = {
|
||||
shiny: getTreeOrValueMap('shiny'),
|
||||
formIndex: null,
|
||||
female: null,
|
||||
key: 'shiny',
|
||||
entry: null
|
||||
};
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
export enum Gender {
|
||||
GENDERLESS = -1,
|
||||
FEMALE,
|
||||
MALE
|
||||
MALE,
|
||||
FEMALE
|
||||
}
|
||||
|
||||
export function getGenderSymbol(gender: Gender) {
|
||||
|
||||
+1
-1
@@ -199,7 +199,7 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
|
||||
|
||||
const pokemon = this.getPokemon(scene);
|
||||
const pokemonIcon = scene.add.sprite(0, 8, pokemon.species.getIconAtlasKey());
|
||||
pokemonIcon.play(pokemon.species.getIconKey()).stop();
|
||||
pokemonIcon.play(pokemon.getIconKey()).stop();
|
||||
pokemonIcon.setOrigin(0, 0.5);
|
||||
|
||||
container.add(pokemonIcon);
|
||||
|
||||
+935
-888
File diff suppressed because it is too large.
Load diff
+66
-52
@@ -3,7 +3,7 @@ import BattleScene from './battle-scene';
|
||||
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from './battle-info';
|
||||
import Move, { StatChangeAttr, HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariablePowerAttr, Moves, allMoves, MoveCategory } from "./move";
|
||||
import { pokemonLevelMoves } from './pokemon-level-moves';
|
||||
import { default as PokemonSpecies, getPokemonSpecies } from './pokemon-species';
|
||||
import { default as PokemonSpecies, PokemonSpeciesForm, getPokemonSpecies } from './pokemon-species';
|
||||
import * as Utils from './utils';
|
||||
import { Type, getTypeDamageMultiplier } from './type';
|
||||
import { getLevelTotalExp } from './exp';
|
||||
@@ -25,6 +25,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
public id: integer;
|
||||
public name: string;
|
||||
public species: PokemonSpecies;
|
||||
public formIndex: integer;
|
||||
public shiny: boolean;
|
||||
public pokeball: PokeballType;
|
||||
protected battleInfo: BattleInfo;
|
||||
@@ -48,7 +49,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, dataSource?: Pokemon) {
|
||||
constructor(scene: BattleScene, x: number, y: number, species: PokemonSpecies, level: integer, formIndex?: integer, gender?: Gender, shiny?: boolean, dataSource?: Pokemon) {
|
||||
super(scene, x, y);
|
||||
this.name = Utils.toPokemonUpperCase(species.name);
|
||||
this.species = species;
|
||||
@@ -56,13 +57,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
? new PlayerBattleInfo(scene)
|
||||
: new EnemyBattleInfo(scene);
|
||||
this.pokeball = dataSource?.pokeball || PokeballType.POKEBALL;
|
||||
this.level = level;//Utils.randInt(player ? 100 : 30, player ? 41 : 1);
|
||||
this.level = level;
|
||||
this.formIndex = formIndex || 0;
|
||||
if (gender !== undefined)
|
||||
this.gender = gender;
|
||||
if (shiny !== undefined)
|
||||
this.shiny = shiny;
|
||||
this.exp = dataSource?.exp || getLevelTotalExp(this.level, species.growthRate);
|
||||
this.levelExp = dataSource?.levelExp || 0;
|
||||
if (dataSource) {
|
||||
this.id = dataSource.id;
|
||||
this.shiny = dataSource.shiny;
|
||||
this.gender = dataSource.gender;
|
||||
this.hp = dataSource.hp;
|
||||
this.stats = dataSource.stats;
|
||||
this.ivs = dataSource.ivs;
|
||||
@@ -81,36 +85,40 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
Utils.binToDec(Utils.decToBin(this.id).substring(20, 25)),
|
||||
Utils.binToDec(Utils.decToBin(this.id).substring(25, 30))
|
||||
];
|
||||
//} else
|
||||
//this.id = parseInt(Utils.decToBin(this.ivs[Stat.HP]) + Utils.decToBin(this.ivs[Stat.ATK]) + Utils.decToBin(this.ivs[Stat.DEF]) + Utils.decToBin(this.ivs[Stat.SPATK]) + Utils.decToBin(this.ivs[Stat.SPDEF]) + Utils.decToBin(this.ivs[Stat.SPD]) + this.id.toString(2).slice(30));
|
||||
//} else
|
||||
//this.id = parseInt(Utils.decToBin(this.ivs[Stat.HP]) + Utils.decToBin(this.ivs[Stat.ATK]) + Utils.decToBin(this.ivs[Stat.DEF]) + Utils.decToBin(this.ivs[Stat.SPATK]) + Utils.decToBin(this.ivs[Stat.SPDEF]) + Utils.decToBin(this.ivs[Stat.SPD]) + this.id.toString(2).slice(30));
|
||||
|
||||
if (this.species.malePercent === null)
|
||||
this.gender = Gender.GENDERLESS;
|
||||
else {
|
||||
const genderChance = (this.id % 256) * 0.390625;
|
||||
if (genderChance < this.species.malePercent)
|
||||
this.gender = Gender.MALE;
|
||||
else
|
||||
this.gender = Gender.FEMALE;
|
||||
if (this.gender === undefined) {
|
||||
if (this.getSpeciesForm().malePercent === null)
|
||||
this.gender = Gender.GENDERLESS;
|
||||
else {
|
||||
const genderChance = (this.id % 256) * 0.390625;
|
||||
if (genderChance < this.getSpeciesForm().malePercent)
|
||||
this.gender = Gender.MALE;
|
||||
else
|
||||
this.gender = Gender.FEMALE;
|
||||
}
|
||||
}
|
||||
|
||||
const rand1 = Utils.binToDec(Utils.decToBin(this.id).substring(0, 16));
|
||||
const rand2 = Utils.binToDec(Utils.decToBin(this.id).substring(16, 32));
|
||||
|
||||
const E = this.scene.trainerId ^ this.scene.secretId;
|
||||
const E = this.scene.saveData.trainerId ^ this.scene.saveData.secretId;
|
||||
const F = rand1 ^ rand2;
|
||||
|
||||
let shinyThreshold = new Utils.IntegerHolder(32);
|
||||
this.scene.applyModifiers(ShinyRateBoosterModifier, shinyThreshold);
|
||||
console.log(shinyThreshold.value);
|
||||
if (this.shiny === undefined) {
|
||||
let shinyThreshold = new Utils.IntegerHolder(32);
|
||||
this.scene.applyModifiers(ShinyRateBoosterModifier, shinyThreshold);
|
||||
console.log(shinyThreshold.value);
|
||||
|
||||
this.shiny = (E ^ F) < shinyThreshold.value;
|
||||
if ((E ^ F) < 32)
|
||||
console.log('REAL SHINY!!');
|
||||
if (this.shiny)
|
||||
console.log((E ^ F), shinyThreshold.value);
|
||||
/*else
|
||||
this.shiny = Utils.randInt(16) === 0;*/
|
||||
this.shiny = (E ^ F) < shinyThreshold.value;
|
||||
if ((E ^ F) < 32)
|
||||
console.log('REAL SHINY!!');
|
||||
if (this.shiny)
|
||||
console.log((E ^ F), shinyThreshold.value);
|
||||
/*else
|
||||
this.shiny = Utils.randInt(16) === 0;*/
|
||||
}
|
||||
|
||||
this.winCount = 0;
|
||||
}
|
||||
@@ -166,7 +174,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
Promise.allSettled(moveIds.map(m => initMoveAnim(m)))
|
||||
.then(() => {
|
||||
loadMoveAnimAssets(this.scene, moveIds);
|
||||
this.species.loadAssets(this.scene, this.gender === Gender.FEMALE, this.shiny);
|
||||
this.getSpeciesForm().loadAssets(this.scene, this.gender === Gender.FEMALE, this.formIndex, this.shiny);
|
||||
if (this.isPlayer())
|
||||
this.scene.loadAtlas(this.getBattleSpriteKey(), 'pokemon', this.getBattleSpriteAtlasPath());
|
||||
this.scene.load.once(Phaser.Loader.Events.COMPLETE, () => {
|
||||
@@ -203,7 +211,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
getSpriteId(): string {
|
||||
return this.species.getSpriteId(this.gender === Gender.FEMALE, this.shiny);
|
||||
return this.getSpeciesForm().getSpriteId(this.gender === Gender.FEMALE, this.formIndex, this.shiny);
|
||||
}
|
||||
|
||||
getBattleSpriteId(): string {
|
||||
@@ -211,7 +219,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
getSpriteKey(): string {
|
||||
return this.species.getSpriteKey(this.gender === Gender.FEMALE, this.shiny);
|
||||
return this.getSpeciesForm().getSpriteKey(this.gender === Gender.FEMALE, this.formIndex, this.shiny);
|
||||
}
|
||||
|
||||
getBattleSpriteKey(): string {
|
||||
@@ -219,14 +227,19 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
getIconId(): string {
|
||||
// TODO: Add form special cases
|
||||
return this.species.getIconId();
|
||||
return this.getSpeciesForm().getIconId(this.gender === Gender.FEMALE, this.formIndex);
|
||||
}
|
||||
|
||||
getIconKey(): string {
|
||||
return `pkmn_icon__${this.getIconId()}`;
|
||||
}
|
||||
|
||||
getSpeciesForm(): PokemonSpeciesForm {
|
||||
if (!this.species.forms?.length)
|
||||
return this.species;
|
||||
return this.species.forms[this.formIndex];
|
||||
}
|
||||
|
||||
getSprite(): Phaser.GameObjects.Sprite {
|
||||
return this.getAt(0) as Phaser.GameObjects.Sprite;
|
||||
}
|
||||
@@ -262,8 +275,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
calculateStats(): void {
|
||||
if (!this.stats)
|
||||
this.stats = [ 0, 0, 0, 0, 0, 0 ];
|
||||
const baseStats = this.species.baseStats.slice(0);
|
||||
console.log(this.id);
|
||||
const baseStats = this.getSpeciesForm().baseStats.slice(0);
|
||||
this.scene.applyModifiers(PokemonBaseStatBoosterModifier, this, baseStats);
|
||||
const stats = Utils.getEnumValues(Stat);
|
||||
for (let s of stats) {
|
||||
@@ -298,9 +310,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
getTypes(): Type[] {
|
||||
const speciesTypes = [ this.species.type1 ];
|
||||
if (this.species.type2 > -1)
|
||||
speciesTypes.push(this.species.type1);
|
||||
const speciesForm = this.getSpeciesForm();
|
||||
const speciesTypes = [ speciesForm.type1 ];
|
||||
if (speciesForm.type2 !== null)
|
||||
speciesTypes.push(speciesForm.type1);
|
||||
|
||||
if (this.getTag(BattleTagType.IGNORE_FLYING)) {
|
||||
const flyingIndex = speciesTypes.indexOf(Type.FLYING);
|
||||
@@ -425,9 +438,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
|
||||
addExp(exp: integer) {
|
||||
this.exp += exp;
|
||||
while (this.exp >= getLevelTotalExp(this.level + 1, this.species.growthRate))
|
||||
while (this.exp >= getLevelTotalExp(this.level + 1, this.getSpeciesForm().growthRate))
|
||||
this.level++;
|
||||
this.levelExp = this.exp - getLevelTotalExp(this.level, this.species.growthRate);
|
||||
this.levelExp = this.exp - getLevelTotalExp(this.level, this.getSpeciesForm().growthRate);
|
||||
}
|
||||
|
||||
apply(source: Pokemon, battlerMove: PokemonMove): MoveResult {
|
||||
@@ -440,7 +453,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
case MoveCategory.SPECIAL:
|
||||
const isPhysical = moveCategory === MoveCategory.PHYSICAL;
|
||||
const power = new Utils.NumberHolder(move.power);
|
||||
const typeMultiplier = getTypeDamageMultiplier(move.type, this.species.type1) * (this.species.type2 > -1 ? getTypeDamageMultiplier(move.type, this.species.type2) : 1);
|
||||
const typeMultiplier = getTypeDamageMultiplier(move.type, this.getSpeciesForm().type1) * (this.getSpeciesForm().type2 !== null ? getTypeDamageMultiplier(move.type, this.getSpeciesForm().type2) : 1);
|
||||
const weatherTypeMultiplier = this.scene.arena.getAttackTypeMultiplier(move.type);
|
||||
applyMoveAttrs(VariablePowerAttr, source, this, move, power);
|
||||
this.scene.applyModifiers(AttackTypeBoosterModifier, source, power);
|
||||
@@ -449,7 +462,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
const isCritical = Utils.randInt(critChance.value) === 0;
|
||||
const sourceAtk = source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK);
|
||||
const targetDef = this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF);
|
||||
const stabMultiplier = source.species.type1 === move.type || (source.species.type2 > -1 && source.species.type2 === move.type) ? 1.5 : 1;
|
||||
const stabMultiplier = source.species.type1 === move.type || (source.species.type2 !== null && source.species.type2 === move.type) ? 1.5 : 1;
|
||||
const criticalMultiplier = isCritical ? 2 : 1;
|
||||
damage = Math.ceil(((((2 * source.level / 5 + 2) * power.value * sourceAtk / targetDef) / 50) + 2) * stabMultiplier * typeMultiplier * weatherTypeMultiplier * ((Utils.randInt(15) + 85) / 100)) * criticalMultiplier;
|
||||
if (isPhysical && source.status && source.status.effect === StatusEffect.BURN)
|
||||
@@ -573,7 +586,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
cry(soundConfig?: Phaser.Types.Sound.SoundConfig): integer {
|
||||
return this.species.cry(this.scene, soundConfig);
|
||||
return this.getSpeciesForm().cry(this.scene, soundConfig);
|
||||
}
|
||||
|
||||
faintCry(callback: Function) {
|
||||
@@ -639,18 +652,19 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
trySetStatus(effect: StatusEffect): boolean {
|
||||
if (this.status)
|
||||
return false;
|
||||
const speciesForm = this.getSpeciesForm();
|
||||
switch (effect) {
|
||||
case StatusEffect.POISON:
|
||||
case StatusEffect.TOXIC:
|
||||
if (this.species.isOfType(Type.POISON) || this.species.isOfType(Type.STEEL))
|
||||
if (speciesForm.isOfType(Type.POISON) || speciesForm.isOfType(Type.STEEL))
|
||||
return false;
|
||||
break;
|
||||
case StatusEffect.FREEZE:
|
||||
if (this.species.isOfType(Type.ICE))
|
||||
if (speciesForm.isOfType(Type.ICE))
|
||||
return false;
|
||||
break;
|
||||
case StatusEffect.BURN:
|
||||
if (this.species.isOfType(Type.FIRE))
|
||||
if (speciesForm.isOfType(Type.FIRE))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
@@ -682,7 +696,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
|
||||
getExpValue(): integer {
|
||||
// Logic to factor in victor level has been removed for balancing purposes, so the player doesn't have to focus on EXP maxxing
|
||||
return (this.species.baseExp * this.level) / 5 + 1;
|
||||
return (this.getSpeciesForm().baseExp * this.level) / 5 + 1;
|
||||
}
|
||||
|
||||
tint(color: number, alpha?: number, duration?: integer, ease?: string) {
|
||||
@@ -763,10 +777,10 @@ export default interface Pokemon {
|
||||
export class PlayerPokemon extends Pokemon {
|
||||
public compatibleTms: Moves[];
|
||||
|
||||
constructor(scene: BattleScene, species: PokemonSpecies, level: integer, dataSource?: Pokemon) {
|
||||
super(scene, 106, 148, species, level, dataSource);
|
||||
constructor(scene: BattleScene, species: PokemonSpecies, level: integer, formIndex: integer, gender: Gender, shiny: boolean, dataSource?: Pokemon) {
|
||||
super(scene, 106, 148, species, level, formIndex, gender, shiny, dataSource);
|
||||
|
||||
this.species.generateIconAnim(scene);
|
||||
this.getSpeciesForm().generateIconAnim(scene, this.gender === Gender.FEMALE, formIndex);
|
||||
this.generateCompatibleTms();
|
||||
}
|
||||
|
||||
@@ -799,7 +813,7 @@ export class PlayerPokemon extends Pokemon {
|
||||
this.handleSpecialEvolutions(evolution);
|
||||
this.species = getPokemonSpecies(evolution.speciesId);
|
||||
this.name = this.species.name.toUpperCase();
|
||||
this.species.generateIconAnim(this.scene);
|
||||
this.getSpeciesForm().generateIconAnim(this.scene, this.gender === Gender.FEMALE, this.formIndex);
|
||||
this.compatibleTms.splice(0, this.compatibleTms.length);
|
||||
this.generateCompatibleTms();
|
||||
this.loadAssets().then(() => {
|
||||
@@ -813,7 +827,7 @@ export class PlayerPokemon extends Pokemon {
|
||||
if (this.species.speciesId === Species.NINCADA && evolution.speciesId === Species.NINJASK) {
|
||||
const newEvolution = pokemonEvolutions[this.species.speciesId][1];
|
||||
if (newEvolution.condition.predicate(this)) {
|
||||
const newPokemon = new PlayerPokemon(this.scene, this.species, this.level);
|
||||
const newPokemon = new PlayerPokemon(this.scene, this.species, this.level, this.formIndex, this.gender, this.shiny);
|
||||
this.scene.getParty().push(newPokemon);
|
||||
newPokemon.evolve(newEvolution);
|
||||
}
|
||||
@@ -825,7 +839,7 @@ export class EnemyPokemon extends Pokemon {
|
||||
public aiType: AiType;
|
||||
|
||||
constructor(scene: BattleScene, species: PokemonSpecies, level: integer) {
|
||||
super(scene, -66, 84, species, level);
|
||||
super(scene, -66, 84, species, level, scene.arena.getFormIndex(species));
|
||||
|
||||
this.aiType = AiType.SMART_RANDOM;
|
||||
}
|
||||
@@ -921,7 +935,7 @@ export class EnemyPokemon extends Pokemon {
|
||||
let ret: PlayerPokemon = null;
|
||||
|
||||
if (party.length < 6) {
|
||||
const newPokemon = new PlayerPokemon(this.scene, this.species, this.level, this);
|
||||
const newPokemon = new PlayerPokemon(this.scene, this.species, this.level, this.formIndex, this.gender, this.shiny);
|
||||
party.push(newPokemon);
|
||||
ret = newPokemon;
|
||||
}
|
||||
|
||||
@@ -510,8 +510,7 @@ class PartySlot extends Phaser.GameObjects.Container {
|
||||
this.add(slotPb);
|
||||
|
||||
const pokemonIcon = this.scene.add.sprite(slotPb.x, slotPb.y, this.pokemon.species.getIconAtlasKey());
|
||||
console.log(pokemonIcon)
|
||||
pokemonIcon.play(this.pokemon.species.getIconKey());
|
||||
pokemonIcon.play(this.pokemon.getIconKey());
|
||||
this.slotPokemonIcon = pokemonIcon;
|
||||
|
||||
this.add(pokemonIcon);
|
||||
|
||||
@@ -5,8 +5,16 @@ import { TextStyle, addTextObject } from "../text";
|
||||
import { Mode } from "./ui";
|
||||
import * as Utils from "../utils";
|
||||
import MessageUiHandler from "./message-ui-handler";
|
||||
import { StarterDexEntry, StarterDexUnlockTree } from "../data";
|
||||
|
||||
export type StarterSelectCallback = (starterSpecies: PokemonSpecies[]) => void;
|
||||
export type StarterSelectCallback = (starters: Starter[]) => void;
|
||||
|
||||
export interface Starter {
|
||||
species: PokemonSpecies;
|
||||
shiny: boolean;
|
||||
formIndex: integer;
|
||||
female: boolean;
|
||||
}
|
||||
|
||||
export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
private starterSelectContainer: Phaser.GameObjects.Container;
|
||||
@@ -14,15 +22,26 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
private pokemonNumberText: Phaser.GameObjects.Text;
|
||||
private pokemonSprite: Phaser.GameObjects.Sprite;
|
||||
private pokemonNameText: Phaser.GameObjects.Text;
|
||||
private instructionsText: Phaser.GameObjects.Text;
|
||||
private starterSelectMessageBoxContainer: Phaser.GameObjects.Container;
|
||||
|
||||
private genMode: boolean;
|
||||
private shinyCursor: integer = 0;
|
||||
private formCursor: integer = 0;
|
||||
private genderCursor: integer = 0;
|
||||
private genCursor: integer = 0;
|
||||
|
||||
private genSpecies: PokemonSpecies[][] = [];
|
||||
private lastSpecies: PokemonSpecies;
|
||||
private speciesLoaded: Map<Species, boolean> = new Map<Species, boolean>();
|
||||
private starterGens: integer[] = [];
|
||||
private starterCursors: integer[] = [];
|
||||
private starterDetails: [boolean, integer, boolean][] = [];
|
||||
private speciesStarterDexEntry: StarterDexEntry;
|
||||
private speciesStarterDexTree: StarterDexUnlockTree;
|
||||
private canCycleShiny: boolean;
|
||||
private canCycleForm: boolean;
|
||||
private canCycleGender: boolean;
|
||||
|
||||
private assetLoadCancelled: Utils.BooleanHolder;
|
||||
private cursorObj: Phaser.GameObjects.Image;
|
||||
@@ -102,13 +121,16 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
continue;
|
||||
this.speciesLoaded.set(species.speciesId, false);
|
||||
this.genSpecies[g].push(species);
|
||||
species.generateIconAnim(this.scene);
|
||||
const dexEntry = this.scene.saveData.getDefaultStarterDexEntry(species);
|
||||
species.generateIconAnim(this.scene, dexEntry?.female, dexEntry?.formIndex);
|
||||
const x = (s % 9) * 18;
|
||||
const y = Math.floor(s / 9) * 18;
|
||||
const icon = this.scene.add.sprite(x, y, species.getIconAtlasKey());
|
||||
icon.setScale(0.5);
|
||||
icon.setOrigin(0, 0);
|
||||
icon.play(species.getIconKey()).stop();
|
||||
icon.play(species.getIconKey(dexEntry?.female, dexEntry?.formIndex)).stop();
|
||||
if (!dexEntry)
|
||||
icon.setTintFill(0);
|
||||
this.starterSelectGenIconContainers[g].add(icon);
|
||||
s++;
|
||||
}
|
||||
@@ -133,6 +155,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
this.pokemonSprite = this.scene.add.sprite(53, 63, `pkmn__sub`);
|
||||
this.starterSelectContainer.add(this.pokemonSprite);
|
||||
|
||||
this.instructionsText = addTextObject(this.scene, 1, 132, '', TextStyle.PARTY);
|
||||
this.starterSelectContainer.add(this.instructionsText);
|
||||
|
||||
this.starterSelectMessageBoxContainer = this.scene.add.container(0, this.scene.game.canvas.height / 6);
|
||||
this.starterSelectMessageBoxContainer.setVisible(false);
|
||||
this.starterSelectContainer.add(this.starterSelectMessageBoxContainer);
|
||||
@@ -144,6 +169,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
this.message = addTextObject(this.scene, 8, -8, '', TextStyle.WINDOW, { maxLines: 1 });
|
||||
this.message.setOrigin(0, 1);
|
||||
this.starterSelectMessageBoxContainer.add(this.message);
|
||||
|
||||
this.updateInstructions();
|
||||
}
|
||||
|
||||
show(args: any[]): void {
|
||||
@@ -188,7 +215,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
}
|
||||
} else {
|
||||
if (button === Button.ACTION) {
|
||||
if (this.starterCursors.length < 3) {
|
||||
if (!this.speciesStarterDexEntry)
|
||||
ui.playError();
|
||||
else if (this.starterCursors.length < 3) {
|
||||
let isDupe = false;
|
||||
for (let s = 0; s < this.starterCursors.length; s++) {
|
||||
if (this.starterGens[s] === this.genCursor && this.starterCursors[s] === this.cursor) {
|
||||
@@ -201,18 +230,27 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
cursorObj.setVisible(true);
|
||||
cursorObj.setPosition(this.cursorObj.x, this.cursorObj.y);
|
||||
const species = this.genSpecies[this.genCursor][this.cursor];
|
||||
this.starterIcons[this.starterCursors.length].play(species.getIconKey());
|
||||
this.starterIcons[this.starterCursors.length].play(species.getIconKey(this.speciesStarterDexEntry?.female));
|
||||
this.starterGens.push(this.genCursor);
|
||||
this.starterCursors.push(this.cursor);
|
||||
this.starterDetails.push([ !!this.shinyCursor, this.formCursor, !!this.genderCursor ]);
|
||||
if (this.speciesLoaded.get(species.speciesId))
|
||||
species.cry(this.scene);
|
||||
if (this.starterCursors.length === 3) {
|
||||
ui.showText('Begin with these POKéMON?', null, () => {
|
||||
ui.setModeWithoutClear(Mode.CONFIRM, () => {
|
||||
ui.setMode(Mode.STARTER_SELECT);
|
||||
const thisObj = this;
|
||||
const originalStarterSelectCallback = this.starterSelectCallback;
|
||||
this.starterSelectCallback = null;
|
||||
originalStarterSelectCallback(new Array(3).fill(0).map((_, i) => this.genSpecies[this.starterGens[i]][this.starterCursors[i]]));
|
||||
originalStarterSelectCallback(new Array(3).fill(0).map(function (_, i) {
|
||||
return {
|
||||
species: thisObj.genSpecies[thisObj.starterGens[i]][thisObj.starterCursors[i]],
|
||||
shiny: thisObj.starterDetails[i][0],
|
||||
formIndex: thisObj.starterDetails[i][1],
|
||||
female: thisObj.starterDetails[i][2]
|
||||
};
|
||||
}));
|
||||
}, () => {
|
||||
ui.setMode(Mode.STARTER_SELECT);
|
||||
this.popStarter();
|
||||
@@ -235,6 +273,19 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
const rows = Math.ceil(genStarters / 9);
|
||||
const row = Math.floor(this.cursor / 9);
|
||||
switch (button) {
|
||||
case Button.CYCLE_SHINY:
|
||||
if (this.canCycleShiny) {
|
||||
this.setSpeciesDetails(this.lastSpecies, !this.shinyCursor, this.formCursor, !!this.genderCursor);
|
||||
}
|
||||
break;
|
||||
case Button.CYCLE_FORM:
|
||||
if (this.canCycleForm)
|
||||
this.setSpeciesDetails(this.lastSpecies, !!this.shinyCursor, (this.formCursor + 1) % this.lastSpecies.forms.length, !!this.genderCursor);
|
||||
break;
|
||||
case Button.CYCLE_GENDER:
|
||||
if (this.canCycleGender)
|
||||
this.setSpeciesDetails(this.lastSpecies, !!this.shinyCursor, this.formCursor, !this.genderCursor);
|
||||
break;
|
||||
case Button.UP:
|
||||
if (row)
|
||||
success = this.setCursor(this.cursor - 9);
|
||||
@@ -260,6 +311,29 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
}
|
||||
|
||||
updateInstructions(): void {
|
||||
let instructionLines = [
|
||||
'Arrow Keys/WASD: Move'
|
||||
];
|
||||
if (!this.genMode)
|
||||
instructionLines.push('A/Space/Enter: Select');
|
||||
if (this.starterCursors.length)
|
||||
instructionLines.push('X/Backspace/Esc: Undo');
|
||||
if (this.speciesStarterDexTree) {
|
||||
if (this.canCycleShiny)
|
||||
instructionLines.push('R: Cycle Shiny');
|
||||
if (this.canCycleForm)
|
||||
instructionLines.push('F: Cycle Form');
|
||||
if (this.canCycleGender)
|
||||
instructionLines.push('G: Cycle Gender');
|
||||
}
|
||||
|
||||
if (instructionLines.length >= 4)
|
||||
instructionLines[2] += ` ${instructionLines.splice(3, 1)[0]}`;
|
||||
|
||||
this.instructionsText.setText(instructionLines.join('\n'));
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
let changed = false;
|
||||
@@ -283,6 +357,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
this.cursorObj.setPosition(148 + 18 * (cursor % 9), 10 + 18 * Math.floor(cursor / 9));
|
||||
|
||||
this.setSpecies(this.genSpecies[this.genCursor][cursor]);
|
||||
|
||||
this.updateInstructions();
|
||||
}
|
||||
|
||||
return changed;
|
||||
@@ -306,45 +382,119 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
}
|
||||
|
||||
setSpecies(species: PokemonSpecies) {
|
||||
this.pokemonSprite.setVisible(false);
|
||||
this.speciesStarterDexEntry = species ? this.scene.saveData.getDefaultStarterDexEntry(species) : null;
|
||||
this.speciesStarterDexTree = this.speciesStarterDexEntry ? this.scene.saveData.getStarterDexUnlockTree(species) : null;
|
||||
|
||||
if (this.assetLoadCancelled) {
|
||||
this.assetLoadCancelled.value = true;
|
||||
this.assetLoadCancelled = null;
|
||||
}
|
||||
|
||||
if (this.lastSpecies)
|
||||
(this.starterSelectGenIconContainers[this.lastSpecies.generation - 1].getAt(this.genSpecies[this.lastSpecies.generation - 1].indexOf(this.lastSpecies)) as Phaser.GameObjects.Sprite).stop();
|
||||
|
||||
if (species) {
|
||||
this.pokemonNumberText.setText(Utils.padInt(species.speciesId, 3));
|
||||
this.pokemonNameText.setText(species.name.toUpperCase());
|
||||
|
||||
const assetLoadCancelled = new Utils.BooleanHolder(false);
|
||||
this.assetLoadCancelled = assetLoadCancelled;
|
||||
|
||||
const female = Utils.randInt(2) === 1;
|
||||
species.loadAssets(this.scene, female, false, true).then(() => {
|
||||
if (assetLoadCancelled.value)
|
||||
return;
|
||||
this.assetLoadCancelled = null;
|
||||
this.speciesLoaded.set(species.speciesId, true);
|
||||
this.pokemonSprite.play(species.getSpriteKey(female, false));
|
||||
this.pokemonSprite.setVisible(true);
|
||||
});
|
||||
|
||||
(this.starterSelectGenIconContainers[this.genCursor].getAt(this.cursor) as Phaser.GameObjects.Sprite).play(species.getIconKey());
|
||||
} else {
|
||||
this.pokemonNumberText.setText(Utils.padInt(0, 3));
|
||||
this.pokemonNameText.setText('');
|
||||
if (this.lastSpecies) {
|
||||
const defaultStarterDexEntry = this.scene.saveData.getDefaultStarterDexEntry(this.lastSpecies);
|
||||
const lastSpeciesIcon = (this.starterSelectGenIconContainers[this.lastSpecies.generation - 1].getAt(this.genSpecies[this.lastSpecies.generation - 1].indexOf(this.lastSpecies)) as Phaser.GameObjects.Sprite);
|
||||
lastSpeciesIcon.play(this.lastSpecies.getIconKey(!!defaultStarterDexEntry?.female, defaultStarterDexEntry?.formIndex)).stop();
|
||||
}
|
||||
|
||||
this.lastSpecies = species;
|
||||
|
||||
if (species && this.speciesStarterDexEntry) {
|
||||
this.pokemonNumberText.setText(Utils.padInt(species.speciesId, 3));
|
||||
this.pokemonNameText.setText(species.name.toUpperCase());
|
||||
|
||||
this.setSpeciesDetails(species, !!this.speciesStarterDexEntry?.shiny, this.speciesStarterDexEntry?.formIndex || 0, !!this.speciesStarterDexEntry?.female);
|
||||
} else {
|
||||
this.pokemonNumberText.setText(Utils.padInt(0, 3));
|
||||
this.pokemonNameText.setText(species ? '???' : '');
|
||||
|
||||
this.setSpeciesDetails(species, false, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
setSpeciesDetails(species: PokemonSpecies, shiny: boolean, formIndex: integer, female: boolean): void {
|
||||
if (shiny !== undefined)
|
||||
this.shinyCursor = !shiny ? 0 : 1;
|
||||
if (formIndex !== undefined)
|
||||
this.formCursor = formIndex;
|
||||
if (female !== undefined)
|
||||
this.genderCursor = !female ? 0 : 1;
|
||||
|
||||
this.pokemonSprite.setVisible(false);
|
||||
|
||||
if (species) {
|
||||
const defaultDexEntry = this.scene.saveData.getDefaultStarterDexEntry(species, shiny, formIndex, female);
|
||||
const dexEntry = this.scene.saveData.getDexEntry(species, !!this.shinyCursor, this.formCursor, !!this.genderCursor);
|
||||
|
||||
if (!dexEntry.caught) {
|
||||
if (shiny === undefined)
|
||||
shiny = defaultDexEntry.shiny;
|
||||
if (formIndex === undefined)
|
||||
formIndex = defaultDexEntry.formIndex;
|
||||
if (female === undefined)
|
||||
female = defaultDexEntry.female;
|
||||
} else {
|
||||
shiny = !!this.shinyCursor;
|
||||
formIndex = this.formCursor;
|
||||
female = !!this.genderCursor;
|
||||
}
|
||||
|
||||
if (this.assetLoadCancelled) {
|
||||
this.assetLoadCancelled.value = true;
|
||||
this.assetLoadCancelled = null;
|
||||
}
|
||||
|
||||
if (this.speciesStarterDexTree) {
|
||||
const assetLoadCancelled = new Utils.BooleanHolder(false);
|
||||
this.assetLoadCancelled = assetLoadCancelled;
|
||||
|
||||
species.loadAssets(this.scene, female, formIndex, shiny, true).then(() => {
|
||||
if (assetLoadCancelled.value)
|
||||
return;
|
||||
this.assetLoadCancelled = null;
|
||||
this.speciesLoaded.set(species.speciesId, true);
|
||||
this.pokemonSprite.play(species.getSpriteKey(female, formIndex, shiny));
|
||||
this.pokemonSprite.setVisible(true);
|
||||
});
|
||||
|
||||
species.generateIconAnim(this.scene, this.speciesStarterDexEntry.female, this.speciesStarterDexEntry.formIndex);
|
||||
(this.starterSelectGenIconContainers[this.genCursor].getAt(this.cursor) as Phaser.GameObjects.Sprite).play(species.getIconKey(female, formIndex));
|
||||
|
||||
let count: integer;
|
||||
const calcUnlockedCount = (tree: StarterDexUnlockTree, root?: boolean) => {
|
||||
if (root)
|
||||
count = 0;
|
||||
if (!tree.entry) {
|
||||
for (let key of tree[tree.key].keys())
|
||||
calcUnlockedCount(tree[tree.key].get(key));
|
||||
} else if (tree.entry.caught)
|
||||
count++;
|
||||
};
|
||||
|
||||
let tree = this.speciesStarterDexTree;
|
||||
|
||||
calcUnlockedCount(tree, true);
|
||||
this.canCycleShiny = count > 1;
|
||||
tree = (tree.shiny as Map<boolean, StarterDexUnlockTree>).get(!!this.shinyCursor);
|
||||
|
||||
if (this.lastSpecies.forms?.length) {
|
||||
calcUnlockedCount(tree, true);
|
||||
this.canCycleForm = count > 1;
|
||||
tree = (tree.formIndex as Map<integer, StarterDexUnlockTree>).get(this.formCursor);
|
||||
} else
|
||||
this.canCycleForm = false;
|
||||
|
||||
if (this.lastSpecies.malePercent !== null) {
|
||||
calcUnlockedCount(tree, true);
|
||||
this.canCycleGender = count > 1;
|
||||
} else
|
||||
this.canCycleGender = false;
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
this.updateInstructions();
|
||||
}
|
||||
|
||||
popStarter(): void {
|
||||
this.starterGens.pop();
|
||||
this.starterCursors.pop();
|
||||
this.starterDetails.pop();
|
||||
this.starterCursorObjs[this.starterCursors.length].setVisible(false);
|
||||
this.starterIcons[this.starterCursors.length].play('pkmn_icon__000');
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user