Add form change system

This commit is contained in:
Flashfyre 2024-01-09 23:34:43 -05:00
parent e0b3ca064d
commit 6084d3aaa6
26 changed files with 3252 additions and 2365 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 B

View File

@ -39,6 +39,8 @@ import { vouchers } from "./system/voucher";
import { loggedInUser, updateUserInfo } from "./account"; import { loggedInUser, updateUserInfo } from "./account";
import { GameDataType } from "./system/game-data"; import { GameDataType } from "./system/game-data";
import { addPokeballCaptureStars, addPokeballOpenParticles } from "./anims"; import { addPokeballCaptureStars, addPokeballOpenParticles } from "./anims";
import { getPokemonSpecies } from "./data/pokemon-species";
import { SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangeMoveUsedTrigger } from "./data/pokemon-forms";
export class LoginPhase extends BattlePhase { export class LoginPhase extends BattlePhase {
private showText: boolean; private showText: boolean;
@ -883,6 +885,8 @@ export class SummonPhase extends PartyMemberPokemonPhase {
pokemon.resetTurnData(); pokemon.resetTurnData();
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true);
this.queuePostSummon(); this.queuePostSummon();
} }
@ -938,6 +942,7 @@ export class SwitchSummonPhase extends SummonPhase {
onComplete: () => { onComplete: () => {
pokemon.setVisible(false); pokemon.setVisible(false);
this.scene.field.remove(pokemon); this.scene.field.remove(pokemon);
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true);
this.scene.time.delayedCall(750, () => this.switchAndSummon()); this.scene.time.delayedCall(750, () => this.switchAndSummon());
} }
}); });
@ -974,6 +979,8 @@ export class SwitchSummonPhase extends SummonPhase {
pokemon.transferSummon(this.lastPokemon); pokemon.transferSummon(this.lastPokemon);
this.lastPokemon?.resetSummonData(); this.lastPokemon?.resetSummonData();
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true);
} }
queuePostSummon(): void { queuePostSummon(): void {
@ -997,6 +1004,8 @@ export class ReturnPhase extends SwitchSummonPhase {
pokemon.resetTurnData(); pokemon.resetTurnData();
pokemon.resetSummonData(); pokemon.resetSummonData();
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger);
} }
} }
@ -1844,6 +1853,8 @@ export class MoveEffectPhase extends PokemonPhase {
const hitResult = !isProtected ? target.apply(user, this.move) : HitResult.NO_EFFECT; const hitResult = !isProtected ? target.apply(user, this.move) : HitResult.NO_EFFECT;
this.scene.triggerPokemonFormChange(user, SpeciesFormChangeMoveUsedTrigger);
applyAttrs.push(new Promise(resolve => { applyAttrs.push(new Promise(resolve => {
applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && (attr as MoveEffectAttr).trigger === MoveEffectTrigger.PRE_APPLY, applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveEffectAttr && (attr as MoveEffectAttr).trigger === MoveEffectTrigger.PRE_APPLY,
user, target, this.move.getMove()).then(() => { user, target, this.move.getMove()).then(() => {
@ -2806,7 +2817,7 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase {
if (!pokemon.pauseEvolutions) { if (!pokemon.pauseEvolutions) {
const evolution = pokemon.getEvolution(); const evolution = pokemon.getEvolution();
if (evolution) if (evolution)
this.scene.unshiftPhase(new EvolutionPhase(this.scene, this.partyMemberIndex, evolution, this.lastLevel)); this.scene.unshiftPhase(new EvolutionPhase(this.scene, pokemon as PlayerPokemon, evolution, this.lastLevel));
} }
} }
} }
@ -2846,7 +2857,10 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
.then(() => { .then(() => {
this.scene.ui.setMode(messageMode).then(() => { this.scene.ui.setMode(messageMode).then(() => {
this.scene.playSoundWithoutBgm('level_up_fanfare', 1500); this.scene.playSoundWithoutBgm('level_up_fanfare', 1500);
this.scene.ui.showText(`${pokemon.name} learned\n${move.name}!`, null, () => this.end(), messageMode === Mode.EVOLUTION_SCENE ? 1000 : null, true); this.scene.ui.showText(`${pokemon.name} learned\n${move.name}!`, null, () => {
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeMoveLearnedTrigger, true);
this.end();
}, messageMode === Mode.EVOLUTION_SCENE ? 1000 : null, true);
}); });
}); });
}); });

View File

@ -5,7 +5,7 @@ import { EncounterPhase, SummonPhase, NextEncounterPhase, NewBiomeEncounterPhase
import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon'; import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon';
import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies, initSpecies, speciesStarters } from './data/pokemon-species'; import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies, initSpecies, speciesStarters } from './data/pokemon-species';
import * as Utils from './utils'; import * as Utils from './utils';
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier } from './modifier/modifier'; import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier } from './modifier/modifier';
import { PokeballType } from './data/pokeball'; import { PokeballType } from './data/pokeball';
import { initAutoPlay } from './system/auto-play'; import { initAutoPlay } from './system/auto-play';
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from './data/battle-anims'; import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from './data/battle-anims';
@ -43,6 +43,8 @@ import UIPlugin from 'phaser3-rex-plugins/templates/ui/ui-plugin';
import { WindowVariant, getWindowVariantSuffix } from './ui/window'; import { WindowVariant, getWindowVariantSuffix } from './ui/window';
import PokemonData from './system/pokemon-data'; import PokemonData from './system/pokemon-data';
import { Nature } from './data/nature'; import { Nature } from './data/nature';
import { SpeciesFormChangeTimeOfDayTrigger, SpeciesFormChangeTrigger, getSpeciesFormChangeMessage, pokemonFormChanges } from './data/pokemon-forms';
import { FormChangePhase, QuietFormChangePhase } from './form-change-phase';
const enableAuto = true; const enableAuto = true;
const quickStart = false; const quickStart = false;
@ -99,6 +101,7 @@ export default class BattleScene extends Phaser.Scene {
private phaseQueuePrepend: BattlePhase[]; private phaseQueuePrepend: BattlePhase[];
private phaseQueuePrependSpliceIndex: integer; private phaseQueuePrependSpliceIndex: integer;
private currentPhase: BattlePhase; private currentPhase: BattlePhase;
private standbyPhase: BattlePhase;
public field: Phaser.GameObjects.Container; public field: Phaser.GameObjects.Container;
public fieldUI: Phaser.GameObjects.Container; public fieldUI: Phaser.GameObjects.Container;
public pbTray: PokeballTray; public pbTray: PokeballTray;
@ -381,6 +384,7 @@ export default class BattleScene extends Phaser.Scene {
this.loadBgm('level_up_fanfare', 'bw/level_up_fanfare.mp3'); this.loadBgm('level_up_fanfare', 'bw/level_up_fanfare.mp3');
this.loadBgm('item_fanfare', 'bw/item_fanfare.mp3'); this.loadBgm('item_fanfare', 'bw/item_fanfare.mp3');
this.loadBgm('minor_fanfare', 'bw/minor_fanfare.mp3');
this.loadBgm('heal', 'bw/heal.mp3'); this.loadBgm('heal', 'bw/heal.mp3');
this.loadBgm('victory_trainer', 'bw/victory_trainer.mp3'); this.loadBgm('victory_trainer', 'bw/victory_trainer.mp3');
this.loadBgm('victory_gym', 'bw/victory_gym.mp3'); this.loadBgm('victory_gym', 'bw/victory_gym.mp3');
@ -806,9 +810,12 @@ export default class BattleScene extends Phaser.Scene {
this.arena.removeAllTags(); this.arena.removeAllTags();
playerField.forEach((_, p) => this.unshiftPhase(new ReturnPhase(this, p))); playerField.forEach((_, p) => this.unshiftPhase(new ReturnPhase(this, p)));
this.unshiftPhase(new ShowTrainerPhase(this)); this.unshiftPhase(new ShowTrainerPhase(this));
}
for (let pokemon of this.getParty()) { for (let pokemon of this.getParty()) {
if (pokemon) if (pokemon) {
if (resetArenaState)
pokemon.resetBattleData(); pokemon.resetBattleData();
this.triggerPokemonFormChange(pokemon, SpeciesFormChangeTimeOfDayTrigger);
} }
} }
if (this.gameMode === GameMode.CLASSIC && !isNewBiome) if (this.gameMode === GameMode.CLASSIC && !isNewBiome)
@ -843,7 +850,7 @@ export default class BattleScene extends Phaser.Scene {
return this.arena; return this.arena;
} }
getSpeciesFormIndex(species: PokemonSpecies, gender?: Gender, ignoreArena?: boolean): integer { getSpeciesFormIndex(species: PokemonSpecies, gender?: Gender, nature?: Nature, ignoreArena?: boolean): integer {
if (!species.forms?.length) if (!species.forms?.length)
return 0; return 0;
@ -856,6 +863,11 @@ export default class BattleScene extends Phaser.Scene {
case Species.MEOWSTIC: case Species.MEOWSTIC:
case Species.INDEEDEE: case Species.INDEEDEE:
return gender === Gender.FEMALE ? 1 : 0; return gender === Gender.FEMALE ? 1 : 0;
case Species.TOXTRICITY:
const lowkeyNatures = [ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ];
if (nature !== undefined && lowkeyNatures.indexOf(nature) > -1)
return 1;
return 0;
} }
if (ignoreArena) { if (ignoreArena) {
@ -1292,6 +1304,10 @@ export default class BattleScene extends Phaser.Scene {
return this.currentPhase; return this.currentPhase;
} }
getStandbyPhase(): BattlePhase {
return this.standbyPhase;
}
pushPhase(phase: BattlePhase): void { pushPhase(phase: BattlePhase): void {
this.phaseQueue.push(phase); this.phaseQueue.push(phase);
} }
@ -1316,6 +1332,12 @@ export default class BattleScene extends Phaser.Scene {
} }
shiftPhase(): void { shiftPhase(): void {
if (this.standbyPhase) {
this.currentPhase = this.standbyPhase;
this.standbyPhase = null;
return;
}
if (this.phaseQueuePrependSpliceIndex > -1) if (this.phaseQueuePrependSpliceIndex > -1)
this.clearPhaseQueueSplice(); this.clearPhaseQueueSplice();
if (this.phaseQueuePrepend.length) { if (this.phaseQueuePrepend.length) {
@ -1328,6 +1350,17 @@ export default class BattleScene extends Phaser.Scene {
this.currentPhase.start(); this.currentPhase.start();
} }
overridePhase(phase: BattlePhase): boolean {
if (this.standbyPhase)
return false;
this.standbyPhase = this.currentPhase;
this.currentPhase = phase;
phase.start();
return true;
}
queueMessage(message: string, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer, defer?: boolean) { queueMessage(message: string, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer, defer?: boolean) {
const phase = new MessagePhase(this, message, callbackDelay, prompt, promptDelay); const phase = new MessagePhase(this, message, callbackDelay, prompt, promptDelay);
if (!defer) if (!defer)
@ -1346,6 +1379,8 @@ export default class BattleScene extends Phaser.Scene {
this.validateAchvs(ModifierAchv, modifier); this.validateAchvs(ModifierAchv, modifier);
if (modifier instanceof PersistentModifier) { if (modifier instanceof PersistentModifier) {
if ((modifier as PersistentModifier).add(this.modifiers, !!virtual, this)) { if ((modifier as PersistentModifier).add(this.modifiers, !!virtual, this)) {
if (modifier instanceof PokemonFormChangeItemModifier)
modifier.apply([ this.getPokemonById(modifier.pokemonId) ]);
if (playSound && !this.sound.get(soundName)) if (playSound && !this.sound.get(soundName))
this.playSound(soundName); this.playSound(soundName);
} else if (!virtual) { } else if (!virtual) {
@ -1587,6 +1622,28 @@ export default class BattleScene extends Phaser.Scene {
return null; return null;
} }
triggerPokemonFormChange(pokemon: Pokemon, formChangeTriggerType: { new(...args: any[]): SpeciesFormChangeTrigger }, delayed: boolean = false, modal: boolean = false): boolean {
if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId)) {
const matchingFormChange = pokemonFormChanges[pokemon.species.speciesId].find(fc => fc.findTrigger(formChangeTriggerType) && fc.canChange(pokemon));
if (matchingFormChange) {
let phase: BattlePhase;
if (pokemon instanceof PlayerPokemon && !matchingFormChange.quiet)
phase = new FormChangePhase(this, pokemon, matchingFormChange, modal);
else
phase = new QuietFormChangePhase(this, pokemon, matchingFormChange);
if (!matchingFormChange.quiet && modal)
this.overridePhase(phase);
else if (delayed)
this.pushPhase(phase);
else
this.unshiftPhase(phase);
return true;
}
}
return false;
}
validateAchvs(achvType: { new(...args: any[]): Achv }, ...args: any[]): void { validateAchvs(achvType: { new(...args: any[]): Achv }, ...args: any[]): void {
const filteredAchvs = Object.values(achvs).filter(a => a instanceof achvType); const filteredAchvs = Object.values(achvs).filter(a => a instanceof achvType);
for (let achv of filteredAchvs) for (let achv of filteredAchvs)

View File

@ -12,14 +12,14 @@ import { SpeciesFormKey } from "./pokemon-species";
import { WeatherType } from "./weather"; import { WeatherType } from "./weather";
import { Biome } from "./biome"; import { Biome } from "./biome";
import { TimeOfDay } from "../arena"; import { TimeOfDay } from "../arena";
import { Nature } from "./nature";
export enum SpeciesWildEvolutionDelay { export enum SpeciesWildEvolutionDelay {
NONE, NONE,
SHORT, SHORT,
MEDIUM, MEDIUM,
LONG, LONG,
VERY_LONG, VERY_LONG
MEGA
} }
export enum EvolutionItem { export enum EvolutionItem {
@ -34,56 +34,7 @@ export enum EvolutionItem {
ICE_STONE, ICE_STONE,
DUSK_STONE, DUSK_STONE,
DAWN_STONE, DAWN_STONE,
SHINY_STONE, SHINY_STONE
ABOMASITE = 100,
ABSOLITE,
AERODACTYLITE,
AGGRONITE,
ALAKAZITE,
ALTARIANITE,
AMPHAROSITE,
AUDINITE,
BANETTITE,
BEEDRILLITE,
BLASTOISINITE,
BLAZIKENITE,
CAMERUPTITE,
CHARIZARDITE_X,
CHARIZARDITE_Y,
DIANCITE,
GALLADITE,
GARCHOMPITE,
GARDEVOIRITE,
GENGARITE,
GLALITITE,
GYARADOSITE,
HERACRONITE,
HOUNDOOMINITE,
KANGASKHANITE,
LATIASITE,
LATIOSITE,
LOPUNNITE,
LUCARIONITE,
MANECTITE,
MAWILITE,
MEDICHAMITE,
METAGROSSITE,
MEWTWONITE_X,
MEWTWONITE_Y,
PIDGEOTITE,
PINSIRITE,
RAYQUAZITE,
SABLENITE,
SALAMENCITE,
SCEPTILITE,
SCIZORITE,
SHARPEDONITE,
SLOWBRONITE,
STEELIXITE,
SWAMPERTITE,
TYRANITARITE,
VENUSAURITE,
} }
export type EvolutionConditionPredicate = (p: Pokemon) => boolean; export type EvolutionConditionPredicate = (p: Pokemon) => boolean;
@ -1068,7 +1019,9 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.BARRASKEWDA, 26, null, null) new SpeciesEvolution(Species.BARRASKEWDA, 26, null, null)
], ],
[Species.TOXEL]: [ [Species.TOXEL]: [
new SpeciesEvolution(Species.TOXTRICITY, 30, null, null) new SpeciesFormEvolution(Species.TOXTRICITY, '', 'lowkey', 30, null,
new SpeciesEvolutionCondition(p => [ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ].indexOf(p.nature) > -1)),
new SpeciesFormEvolution(Species.TOXTRICITY, '', 'amped', 30, null, null)
], ],
[Species.SIZZLIPEDE]: [ [Species.SIZZLIPEDE]: [
new SpeciesEvolution(Species.CENTISKORCH, 28, null, null) new SpeciesEvolution(Species.CENTISKORCH, 28, null, null)
@ -1618,146 +1571,6 @@ export const pokemonEvolutions: PokemonEvolutions = {
], ],
[Species.GIMMIGHOUL]: [ [Species.GIMMIGHOUL]: [
new SpeciesEvolution(Species.GHOLDENGO, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.GHOLDENGO, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.VERY_LONG)
],
[Species.VENUSAUR]: [
new SpeciesFormEvolution(Species.VENUSAUR, '', SpeciesFormKey.MEGA, 1, EvolutionItem.VENUSAURITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.BLASTOISE]: [
new SpeciesFormEvolution(Species.BLASTOISE, '', SpeciesFormKey.MEGA, 1, EvolutionItem.BLASTOISINITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.CHARIZARD]: [
new SpeciesFormEvolution(Species.CHARIZARD, '', SpeciesFormKey.MEGA_X, 1, EvolutionItem.CHARIZARDITE_X, null, SpeciesWildEvolutionDelay.MEGA),
new SpeciesFormEvolution(Species.CHARIZARD, '', SpeciesFormKey.MEGA_Y, 1, EvolutionItem.CHARIZARDITE_Y, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.BEEDRILL]: [
new SpeciesFormEvolution(Species.BEEDRILL, '', SpeciesFormKey.MEGA, 1, EvolutionItem.BEEDRILLITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.PIDGEOT]: [
new SpeciesFormEvolution(Species.PIDGEOT, '', SpeciesFormKey.MEGA, 1, EvolutionItem.PIDGEOTITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.ALAKAZAM]: [
new SpeciesFormEvolution(Species.ALAKAZAM, '', SpeciesFormKey.MEGA, 1, EvolutionItem.ALAKAZITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.SLOWBRO]: [
new SpeciesFormEvolution(Species.SLOWBRO, '', SpeciesFormKey.MEGA, 1, EvolutionItem.SLOWBRONITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.GENGAR]: [
new SpeciesFormEvolution(Species.GENGAR, '', SpeciesFormKey.MEGA, 1, EvolutionItem.GENGARITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.KANGASKHAN]: [
new SpeciesFormEvolution(Species.KANGASKHAN, '', SpeciesFormKey.MEGA, 1, EvolutionItem.KANGASKHANITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.PINSIR]: [
new SpeciesFormEvolution(Species.PINSIR, '', SpeciesFormKey.MEGA, 1, EvolutionItem.PINSIRITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.GYARADOS]: [
new SpeciesFormEvolution(Species.GYARADOS, '', SpeciesFormKey.MEGA, 1, EvolutionItem.GYARADOSITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.AERODACTYL]: [
new SpeciesFormEvolution(Species.AERODACTYL, '', SpeciesFormKey.MEGA, 1, EvolutionItem.AERODACTYLITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.MEWTWO]: [
new SpeciesFormEvolution(Species.MEWTWO, '', SpeciesFormKey.MEGA_X, 1, EvolutionItem.MEWTWONITE_X, null, SpeciesWildEvolutionDelay.MEGA),
new SpeciesFormEvolution(Species.MEWTWO, '', SpeciesFormKey.MEGA_Y, 1, EvolutionItem.MEWTWONITE_Y, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.AMPHAROS]: [
new SpeciesFormEvolution(Species.AMPHAROS, '', SpeciesFormKey.MEGA, 1, EvolutionItem.AMPHAROSITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.STEELIX]: [
new SpeciesFormEvolution(Species.STEELIX, '', SpeciesFormKey.MEGA, 1, EvolutionItem.STEELIXITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.SCIZOR]: [
new SpeciesFormEvolution(Species.SCIZOR, '', SpeciesFormKey.MEGA, 1, EvolutionItem.SCIZORITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.HERACROSS]: [
new SpeciesFormEvolution(Species.HERACROSS, '', SpeciesFormKey.MEGA, 1, EvolutionItem.HERACRONITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.HOUNDOOM]: [
new SpeciesFormEvolution(Species.HOUNDOOM, '', SpeciesFormKey.MEGA, 1, EvolutionItem.HOUNDOOMINITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.TYRANITAR]: [
new SpeciesFormEvolution(Species.TYRANITAR, '', SpeciesFormKey.MEGA, 1, EvolutionItem.TYRANITARITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.SCEPTILE]: [
new SpeciesFormEvolution(Species.SCEPTILE, '', SpeciesFormKey.MEGA, 1, EvolutionItem.SCEPTILITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.BLAZIKEN]: [
new SpeciesFormEvolution(Species.BLAZIKEN, '', SpeciesFormKey.MEGA, 1, EvolutionItem.BLAZIKENITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.SWAMPERT]: [
new SpeciesFormEvolution(Species.SWAMPERT, '', SpeciesFormKey.MEGA, 1, EvolutionItem.SWAMPERTITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.GARDEVOIR]: [
new SpeciesFormEvolution(Species.GARDEVOIR, '', SpeciesFormKey.MEGA, 1, EvolutionItem.GARDEVOIRITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.SABLEYE]: [
new SpeciesFormEvolution(Species.SABLEYE, '', SpeciesFormKey.MEGA, 1, EvolutionItem.SABLENITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.MAWILE]: [
new SpeciesFormEvolution(Species.MAWILE, '', SpeciesFormKey.MEGA, 1, EvolutionItem.MAWILITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.AGGRON]: [
new SpeciesFormEvolution(Species.AGGRON, '', SpeciesFormKey.MEGA, 1, EvolutionItem.AGGRONITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.MEDICHAM]: [
new SpeciesFormEvolution(Species.MEDICHAM, '', SpeciesFormKey.MEGA, 1, EvolutionItem.MEDICHAMITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.MANECTRIC]: [
new SpeciesFormEvolution(Species.MANECTRIC, '', SpeciesFormKey.MEGA, 1, EvolutionItem.MANECTITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.SHARPEDO]: [
new SpeciesFormEvolution(Species.SHARPEDO, '', SpeciesFormKey.MEGA, 1, EvolutionItem.SHARPEDONITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.CAMERUPT]: [
new SpeciesFormEvolution(Species.CAMERUPT, '', SpeciesFormKey.MEGA, 1, EvolutionItem.CAMERUPTITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.ALTARIA]: [
new SpeciesFormEvolution(Species.ALTARIA, '', SpeciesFormKey.MEGA, 1, EvolutionItem.ALTARIANITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.BANETTE]: [
new SpeciesFormEvolution(Species.BANETTE, '', SpeciesFormKey.MEGA, 1, EvolutionItem.BANETTITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.ABSOL]: [
new SpeciesFormEvolution(Species.ABSOL, '', SpeciesFormKey.MEGA, 1, EvolutionItem.ABSOLITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.GLALIE]: [
new SpeciesFormEvolution(Species.GLALIE, '', SpeciesFormKey.MEGA, 1, EvolutionItem.GLALITITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.SALAMENCE]: [
new SpeciesFormEvolution(Species.SALAMENCE, '', SpeciesFormKey.MEGA, 1, EvolutionItem.SALAMENCITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.METAGROSS]: [
new SpeciesFormEvolution(Species.METAGROSS, '', SpeciesFormKey.MEGA, 1, EvolutionItem.METAGROSSITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.LATIAS]: [
new SpeciesFormEvolution(Species.LATIAS, '', SpeciesFormKey.MEGA, 1, EvolutionItem.LATIASITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.LATIOS]: [
new SpeciesFormEvolution(Species.LATIOS, '', SpeciesFormKey.MEGA, 1, EvolutionItem.LATIOSITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.RAYQUAZA]: [
new SpeciesFormEvolution(Species.RAYQUAZA, '', SpeciesFormKey.MEGA, 1, EvolutionItem.RAYQUAZITE, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.DRAGON_ASCENT).length > 0), SpeciesWildEvolutionDelay.MEGA)
],
[Species.LOPUNNY]: [
new SpeciesFormEvolution(Species.LOPUNNY, '', SpeciesFormKey.MEGA, 1, EvolutionItem.LOPUNNITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.GARCHOMP]: [
new SpeciesFormEvolution(Species.GARCHOMP, '', SpeciesFormKey.MEGA, 1, EvolutionItem.GARCHOMPITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.LUCARIO]: [
new SpeciesFormEvolution(Species.LUCARIO, '', SpeciesFormKey.MEGA, 1, EvolutionItem.LUCARIONITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.ABOMASNOW]: [
new SpeciesFormEvolution(Species.ABOMASNOW, '', SpeciesFormKey.MEGA, 1, EvolutionItem.ABOMASITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.GALLADE]: [
new SpeciesFormEvolution(Species.GALLADE, '', SpeciesFormKey.MEGA, 1, EvolutionItem.GALLADITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.AUDINO]: [
new SpeciesFormEvolution(Species.AUDINO, '', SpeciesFormKey.MEGA, 1, EvolutionItem.AUDINITE, null, SpeciesWildEvolutionDelay.MEGA)
],
[Species.DIANCIE]: [
new SpeciesFormEvolution(Species.DIANCIE, '', SpeciesFormKey.MEGA, 1, EvolutionItem.DIANCITE, null, SpeciesWildEvolutionDelay.MEGA)
] ]
}; };

462
src/data/pokemon-forms.ts Normal file
View File

@ -0,0 +1,462 @@
import { TimeOfDay } from "../arena";
import { PokemonFormChangeItemModifier } from "../modifier/modifier";
import Pokemon from "../pokemon";
import { Moves } from "./move";
import { SpeciesFormKey } from "./pokemon-species";
import { Species } from "./species";
import { StatusEffect } from "./status-effect";
export enum FormChangeItem {
NONE,
ABOMASITE,
ABSOLITE,
AERODACTYLITE,
AGGRONITE,
ALAKAZITE,
ALTARIANITE,
AMPHAROSITE,
AUDINITE,
BANETTITE,
BEEDRILLITE,
BLASTOISINITE,
BLAZIKENITE,
CAMERUPTITE,
CHARIZARDITE_X,
CHARIZARDITE_Y,
DIANCITE,
GALLADITE,
GARCHOMPITE,
GARDEVOIRITE,
GENGARITE,
GLALITITE,
GYARADOSITE,
HERACRONITE,
HOUNDOOMINITE,
KANGASKHANITE,
LATIASITE,
LATIOSITE,
LOPUNNITE,
LUCARIONITE,
MANECTITE,
MAWILITE,
MEDICHAMITE,
METAGROSSITE,
MEWTWONITE_X,
MEWTWONITE_Y,
PIDGEOTITE,
PINSIRITE,
RAYQUAZITE,
SABLENITE,
SALAMENCITE,
SCEPTILITE,
SCIZORITE,
SHARPEDONITE,
SLOWBRONITE,
STEELIXITE,
SWAMPERTITE,
TYRANITARITE,
VENUSAURITE,
BLUE_ORB = 50,
RED_ORB,
ADAMANT_CRYSTAL,
LUSTROUS_ORB,
GRISEOUS_CORE,
REVEAL_GLASS,
GRACIDEA
}
export type SpeciesFormChangeConditionPredicate = (p: Pokemon) => boolean;
export type SpeciesFormChangeConditionEnforceFunc = (p: Pokemon) => void;
export class SpeciesFormChange {
public speciesId: Species;
public preFormKey: string;
public formKey: string;
public trigger: SpeciesFormChangeTrigger;
public quiet: boolean;
constructor(speciesId: Species, preFormKey: string, evoFormKey: string, trigger: SpeciesFormChangeTrigger, quiet: boolean = false) {
this.speciesId = speciesId;
this.preFormKey = preFormKey;
this.formKey = evoFormKey;
this.trigger = trigger;
this.quiet = quiet;
}
canChange(pokemon: Pokemon): boolean {
if (pokemon.species.speciesId !== this.speciesId)
return false;
if (!pokemon.species.forms.length)
return false;
const formKeys = pokemon.species.forms.map(f => f.formKey);
if (formKeys[pokemon.formIndex] !== this.preFormKey)
return false;
if (formKeys[pokemon.formIndex] === this.formKey)
return false;
if (!this.trigger.canChange(pokemon))
return false;
return true;
}
findTrigger(triggerType: { new(...args: any[]): SpeciesFormChangeTrigger }): SpeciesFormChangeTrigger {
if (!this.trigger.hasTriggerType(triggerType))
return null;
let trigger = this.trigger;
if (trigger instanceof SpeciesFormChangeCompoundTrigger)
return trigger.triggers.find(t => t.hasTriggerType(triggerType));
return trigger;
}
}
export class SpeciesFormChangeCondition {
public predicate: SpeciesFormChangeConditionPredicate;
public enforceFunc: SpeciesFormChangeConditionEnforceFunc;
constructor(predicate: SpeciesFormChangeConditionPredicate, enforceFunc?: SpeciesFormChangeConditionEnforceFunc) {
this.predicate = predicate;
this.enforceFunc = enforceFunc;
}
}
export abstract class SpeciesFormChangeTrigger {
canChange(pokemon: Pokemon): boolean {
return true;
}
hasTriggerType(triggerType: { new(...args: any[]): SpeciesFormChangeTrigger }): boolean {
return this instanceof triggerType;
}
}
export class SpeciesFormChangeCompoundTrigger {
public triggers: SpeciesFormChangeTrigger[];
constructor(...triggers: SpeciesFormChangeTrigger[]) {
this.triggers = triggers;
}
canChange(pokemon: Pokemon): boolean {
for (let trigger of this.triggers) {
if (!trigger.canChange(pokemon))
return false;
}
return true;
}
hasTriggerType(triggerType: { new(...args: any[]): SpeciesFormChangeTrigger }): boolean {
return !!this.triggers.find(t => t.hasTriggerType(triggerType));
}
}
export class SpeciesFormChangeItemTrigger extends SpeciesFormChangeTrigger {
public item: FormChangeItem;
public active: boolean;
constructor(item: FormChangeItem, active: boolean = true) {
super();
this.item = item;
this.active = active;
}
canChange(pokemon: Pokemon): boolean {
return !!pokemon.scene.findModifier(m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === pokemon.id && m.formChangeItem === this.item && m.active === this.active && (!pokemon.formIndex === this.active));
}
}
export class SpeciesFormChangeTimeOfDayTrigger extends SpeciesFormChangeTrigger {
public timesOfDay: TimeOfDay[];
constructor(...timesOfDay: TimeOfDay[]) {
super();
this.timesOfDay = timesOfDay;
}
canChange(pokemon: Pokemon): boolean {
return this.timesOfDay.indexOf(pokemon.scene.arena.getTimeOfDay()) > -1;
}
}
export class SpeciesFormChangeActiveTrigger extends SpeciesFormChangeTrigger {
public active: boolean;
constructor(active: boolean = false) {
super();
this.active = active;
}
canChange(pokemon: Pokemon): boolean {
return pokemon.isActive(true) === this.active;
}
}
export class SpeciesFormChangeStatusEffectTrigger extends SpeciesFormChangeTrigger {
public statusEffects: StatusEffect[];
public invert: boolean;
constructor(statusEffects: StatusEffect | StatusEffect[], invert: boolean = false) {
super();
if (!Array.isArray(statusEffects))
statusEffects = [ statusEffects ];
this.statusEffects = statusEffects;
this.invert = invert;
}
canChange(pokemon: Pokemon): boolean {
return (this.statusEffects.indexOf(pokemon.status?.effect || StatusEffect.NONE) > -1) !== this.invert;
}
}
export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigger {
public move: Moves;
public known: boolean;
constructor(move: Moves, known: boolean = true) {
super();
this.move = move;
this.known = known;
}
canChange(pokemon: Pokemon): boolean {
return (!!pokemon.moveset.filter(m => m.moveId === this.move).length) === this.known;
}
}
export class SpeciesFormChangeMoveUsedTrigger extends SpeciesFormChangeTrigger {
public move: Moves;
public used: boolean;
constructor(move: Moves, used: boolean = true) {
super();
this.move = move;
this.used = used;
}
canChange(pokemon: Pokemon): boolean {
return pokemon.summonData && !!pokemon.getLastXMoves(1).filter(m => m.move === this.move).length === this.used;
}
}
export function getSpeciesFormChangeMessage(pokemon: Pokemon, formChange: SpeciesFormChange, preName: string): string {
const isMega = formChange.formKey.indexOf(SpeciesFormKey.MEGA) > -1;
const isRevert = !isMega && formChange.formKey === pokemon.species.forms[0].formKey;
const prefix = !pokemon.isPlayer() ? pokemon.hasTrainer() ? 'Foe ' : 'Wild ' : 'Your ';
if (isMega)
return `${prefix}${preName} mega-evolved\ninto ${pokemon.name}!`;
if (isRevert)
return `${prefix}${pokemon.name} reverted\nto its original form!`;
return `${prefix}${preName} changed form!`;
}
interface PokemonFormChanges {
[key: string]: SpeciesFormChange[]
}
export const pokemonFormChanges: PokemonFormChanges = {
[Species.VENUSAUR]: [
new SpeciesFormChange(Species.VENUSAUR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.VENUSAURITE))
],
[Species.BLASTOISE]: [
new SpeciesFormChange(Species.BLASTOISE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BLASTOISINITE))
],
[Species.CHARIZARD]: [
new SpeciesFormChange(Species.CHARIZARD, '', SpeciesFormKey.MEGA_X, new SpeciesFormChangeItemTrigger(FormChangeItem.CHARIZARDITE_X)),
new SpeciesFormChange(Species.CHARIZARD, '', SpeciesFormKey.MEGA_Y, new SpeciesFormChangeItemTrigger(FormChangeItem.CHARIZARDITE_Y))
],
[Species.BEEDRILL]: [
new SpeciesFormChange(Species.BEEDRILL, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BEEDRILLITE))
],
[Species.PIDGEOT]: [
new SpeciesFormChange(Species.PIDGEOT, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.PIDGEOTITE))
],
[Species.ALAKAZAM]: [
new SpeciesFormChange(Species.ALAKAZAM, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALAKAZITE))
],
[Species.SLOWBRO]: [
new SpeciesFormChange(Species.SLOWBRO, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SLOWBRONITE))
],
[Species.GENGAR]: [
new SpeciesFormChange(Species.GENGAR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GENGARITE))
],
[Species.KANGASKHAN]: [
new SpeciesFormChange(Species.KANGASKHAN, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.KANGASKHANITE))
],
[Species.PINSIR]: [
new SpeciesFormChange(Species.PINSIR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.PINSIRITE))
],
[Species.GYARADOS]: [
new SpeciesFormChange(Species.GYARADOS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GYARADOSITE))
],
[Species.AERODACTYL]: [
new SpeciesFormChange(Species.AERODACTYL, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AERODACTYLITE))
],
[Species.MEWTWO]: [
new SpeciesFormChange(Species.MEWTWO, '', SpeciesFormKey.MEGA_X, new SpeciesFormChangeItemTrigger(FormChangeItem.MEWTWONITE_X)),
new SpeciesFormChange(Species.MEWTWO, '', SpeciesFormKey.MEGA_Y, new SpeciesFormChangeItemTrigger(FormChangeItem.MEWTWONITE_Y))
],
[Species.AMPHAROS]: [
new SpeciesFormChange(Species.AMPHAROS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AMPHAROSITE))
],
[Species.STEELIX]: [
new SpeciesFormChange(Species.STEELIX, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.STEELIXITE))
],
[Species.SCIZOR]: [
new SpeciesFormChange(Species.SCIZOR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SCIZORITE))
],
[Species.HERACROSS]: [
new SpeciesFormChange(Species.HERACROSS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.HERACRONITE))
],
[Species.HOUNDOOM]: [
new SpeciesFormChange(Species.HOUNDOOM, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.HOUNDOOMINITE))
],
[Species.TYRANITAR]: [
new SpeciesFormChange(Species.TYRANITAR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.TYRANITARITE))
],
[Species.SCEPTILE]: [
new SpeciesFormChange(Species.SCEPTILE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SCEPTILITE))
],
[Species.BLAZIKEN]: [
new SpeciesFormChange(Species.BLAZIKEN, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BLAZIKENITE))
],
[Species.SWAMPERT]: [
new SpeciesFormChange(Species.SWAMPERT, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SWAMPERTITE))
],
[Species.GARDEVOIR]: [
new SpeciesFormChange(Species.GARDEVOIR, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GARDEVOIRITE))
],
[Species.SABLEYE]: [
new SpeciesFormChange(Species.SABLEYE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SABLENITE))
],
[Species.MAWILE]: [
new SpeciesFormChange(Species.MAWILE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MAWILITE))
],
[Species.AGGRON]: [
new SpeciesFormChange(Species.AGGRON, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AGGRONITE))
],
[Species.MEDICHAM]: [
new SpeciesFormChange(Species.MEDICHAM, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MEDICHAMITE))
],
[Species.MANECTRIC]: [
new SpeciesFormChange(Species.MANECTRIC, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.MANECTITE))
],
[Species.SHARPEDO]: [
new SpeciesFormChange(Species.SHARPEDO, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SHARPEDONITE))
],
[Species.CAMERUPT]: [
new SpeciesFormChange(Species.CAMERUPT, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.CAMERUPTITE))
],
[Species.ALTARIA]: [
new SpeciesFormChange(Species.ALTARIA, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALTARIANITE))
],
[Species.BANETTE]: [
new SpeciesFormChange(Species.BANETTE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.BANETTITE))
],
[Species.ABSOL]: [
new SpeciesFormChange(Species.ABSOL, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ABSOLITE))
],
[Species.GLALIE]: [
new SpeciesFormChange(Species.GLALIE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GLALITITE))
],
[Species.SALAMENCE]: [
new SpeciesFormChange(Species.SALAMENCE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.SALAMENCITE))
],
[Species.METAGROSS]: [
new SpeciesFormChange(Species.METAGROSS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.METAGROSSITE))
],
[Species.LATIAS]: [
new SpeciesFormChange(Species.LATIAS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LATIASITE))
],
[Species.LATIOS]: [
new SpeciesFormChange(Species.LATIOS, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LATIOSITE))
],
[Species.KYOGRE]: [
new SpeciesFormChange(Species.KYOGRE, '', SpeciesFormKey.PRIMAL, new SpeciesFormChangeItemTrigger(FormChangeItem.BLUE_ORB))
],
[Species.GROUDON]: [
new SpeciesFormChange(Species.GROUDON, '', SpeciesFormKey.PRIMAL, new SpeciesFormChangeItemTrigger(FormChangeItem.RED_ORB))
],
[Species.RAYQUAZA]: [
new SpeciesFormChange(Species.RAYQUAZA, '', SpeciesFormKey.MEGA, new SpeciesFormChangeCompoundTrigger(new SpeciesFormChangeItemTrigger(FormChangeItem.RAYQUAZITE), new SpeciesFormChangeMoveLearnedTrigger(Moves.DRAGON_ASCENT)))
],
[Species.LOPUNNY]: [
new SpeciesFormChange(Species.LOPUNNY, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LOPUNNITE))
],
[Species.GARCHOMP]: [
new SpeciesFormChange(Species.GARCHOMP, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GARCHOMPITE))
],
[Species.LUCARIO]: [
new SpeciesFormChange(Species.LUCARIO, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LUCARIONITE))
],
[Species.ABOMASNOW]: [
new SpeciesFormChange(Species.ABOMASNOW, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ABOMASITE))
],
[Species.GALLADE]: [
new SpeciesFormChange(Species.GALLADE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.GALLADITE))
],
[Species.AUDINO]: [
new SpeciesFormChange(Species.AUDINO, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.AUDINITE))
],
[Species.DIALGA]: [
new SpeciesFormChange(Species.DIALGA, '', SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.ADAMANT_CRYSTAL))
],
[Species.PALKIA]: [
new SpeciesFormChange(Species.PALKIA, '', SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.LUSTROUS_ORB))
],
[Species.GIRATINA]: [
new SpeciesFormChange(Species.GIRATINA, '', SpeciesFormKey.ORIGIN, new SpeciesFormChangeItemTrigger(FormChangeItem.GRISEOUS_CORE))
],
[Species.SHAYMIN]: [
new SpeciesFormChange(Species.SHAYMIN, 'land', 'sky', new SpeciesFormChangeCompoundTrigger(new SpeciesFormChangeTimeOfDayTrigger(TimeOfDay.DAY, TimeOfDay.DUSK),
new SpeciesFormChangeItemTrigger(FormChangeItem.GRACIDEA), new SpeciesFormChangeStatusEffectTrigger(StatusEffect.FREEZE, true))),
new SpeciesFormChange(Species.SHAYMIN, 'sky', 'land', new SpeciesFormChangeTimeOfDayTrigger(TimeOfDay.DAWN, TimeOfDay.NIGHT)),
new SpeciesFormChange(Species.SHAYMIN, 'sky', 'land', new SpeciesFormChangeStatusEffectTrigger(StatusEffect.FREEZE))
],
[Species.TORNADUS]: [
new SpeciesFormChange(Species.TORNADUS, SpeciesFormKey.INCARNATE, SpeciesFormKey.THERIAN, new SpeciesFormChangeItemTrigger(FormChangeItem.REVEAL_GLASS))
],
[Species.THUNDURUS]: [
new SpeciesFormChange(Species.THUNDURUS, SpeciesFormKey.INCARNATE, SpeciesFormKey.THERIAN, new SpeciesFormChangeItemTrigger(FormChangeItem.REVEAL_GLASS))
],
[Species.LANDORUS]: [
new SpeciesFormChange(Species.LANDORUS, SpeciesFormKey.INCARNATE, SpeciesFormKey.THERIAN, new SpeciesFormChangeItemTrigger(FormChangeItem.REVEAL_GLASS))
],
[Species.KELDEO]: [
new SpeciesFormChange(Species.KELDEO, 'ordinary', 'resolute', new SpeciesFormChangeMoveLearnedTrigger(Moves.SACRED_SWORD)),
new SpeciesFormChange(Species.KELDEO, 'resolute', 'ordinary', new SpeciesFormChangeMoveLearnedTrigger(Moves.SACRED_SWORD, false))
],
[Species.MELOETTA]: [
new SpeciesFormChange(Species.MELOETTA, 'aria', 'pirouette', new SpeciesFormChangeMoveUsedTrigger(Moves.RELIC_SONG), true),
new SpeciesFormChange(Species.MELOETTA, 'pirouette', 'aria', new SpeciesFormChangeMoveUsedTrigger(Moves.RELIC_SONG), true),
new SpeciesFormChange(Species.MELOETTA, 'pirouette', 'aria', new SpeciesFormChangeActiveTrigger(false), true)
],
[Species.DIANCIE]: [
new SpeciesFormChange(Species.DIANCIE, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.DIANCITE))
],
[Species.ENAMORUS]: [
new SpeciesFormChange(Species.ENAMORUS, SpeciesFormKey.INCARNATE, SpeciesFormKey.THERIAN, new SpeciesFormChangeItemTrigger(FormChangeItem.REVEAL_GLASS))
]
};
{
const formChangeKeys = Object.keys(pokemonFormChanges);
formChangeKeys.forEach(pk => {
const formChanges = pokemonFormChanges[pk];
let newFormChanges: SpeciesFormChange[] = [];
for (let fc of formChanges) {
const itemTrigger = fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger;
if (itemTrigger && !formChanges.find(c => fc.formKey === c.preFormKey && fc.preFormKey === c.formKey))
newFormChanges.push(new SpeciesFormChange(fc.speciesId, fc.formKey, fc.preFormKey, new SpeciesFormChangeItemTrigger(itemTrigger.item, false)));
}
formChanges.push(...newFormChanges);
});
}

View File

@ -510,7 +510,11 @@ export class PokemonForm extends PokemonSpeciesForm {
export enum SpeciesFormKey { export enum SpeciesFormKey {
MEGA = "mega", MEGA = "mega",
MEGA_X = "mega-x", MEGA_X = "mega-x",
MEGA_Y = "mega-y" MEGA_Y = "mega-y",
PRIMAL = "primal",
ORIGIN = "origin",
INCARNATE = "incarnate",
THERIAN = "therian"
} }
export const allSpecies: PokemonSpecies[] = []; export const allSpecies: PokemonSpecies[] = [];
@ -1711,7 +1715,7 @@ export function initSpecies() {
new PokemonSpecies(Species.SANDYGAST, "Sandygast", 7, false, false, false, "Sand Heap Pokémon", Type.GHOST, Type.GROUND, 0.5, 70, Abilities.WATER_COMPACTION, Abilities.NONE, Abilities.SAND_VEIL, 320, 55, 55, 80, 70, 45, 15, 140, 50, 64, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.SANDYGAST, "Sandygast", 7, false, false, false, "Sand Heap Pokémon", Type.GHOST, Type.GROUND, 0.5, 70, Abilities.WATER_COMPACTION, Abilities.NONE, Abilities.SAND_VEIL, 320, 55, 55, 80, 70, 45, 15, 140, 50, 64, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.PALOSSAND, "Palossand", 7, false, false, false, "Sand Castle Pokémon", Type.GHOST, Type.GROUND, 1.3, 250, Abilities.WATER_COMPACTION, Abilities.NONE, Abilities.SAND_VEIL, 480, 85, 75, 110, 100, 75, 35, 60, 50, 168, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.PALOSSAND, "Palossand", 7, false, false, false, "Sand Castle Pokémon", Type.GHOST, Type.GROUND, 1.3, 250, Abilities.WATER_COMPACTION, Abilities.NONE, Abilities.SAND_VEIL, 480, 85, 75, 110, 100, 75, 35, 60, 50, 168, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.PYUKUMUKU, "Pyukumuku", 7, false, false, false, "Sea Cucumber Pokémon", Type.WATER, null, 0.3, 1.2, Abilities.INNARDS_OUT, Abilities.NONE, Abilities.UNAWARE, 410, 55, 60, 130, 30, 130, 5, 60, 50, 144, GrowthRate.FAST, 50, false), new PokemonSpecies(Species.PYUKUMUKU, "Pyukumuku", 7, false, false, false, "Sea Cucumber Pokémon", Type.WATER, null, 0.3, 1.2, Abilities.INNARDS_OUT, Abilities.NONE, Abilities.UNAWARE, 410, 55, 60, 130, 30, 130, 5, 60, 50, 144, GrowthRate.FAST, 50, false),
new PokemonSpecies(Species.TYPE_NULL, "Type: Null", 7, false, false, false, "Synthetic Pokémon", Type.NORMAL, null, 1.9, 120.5, Abilities.BATTLE_ARMOR, Abilities.NONE, Abilities.NONE, 534, 95, 95, 95, 95, 95, 59, 3, 0, 107, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.TYPE_NULL, "Type: Null", 7, true, false, false, "Synthetic Pokémon", Type.NORMAL, null, 1.9, 120.5, Abilities.BATTLE_ARMOR, Abilities.NONE, Abilities.NONE, 534, 95, 95, 95, 95, 95, 59, 3, 0, 107, GrowthRate.SLOW, null, false),
new PokemonSpecies(Species.SILVALLY, "Silvally", 7, true, false, false, "Synthetic Pokémon", Type.NORMAL, null, 2.3, 100.5, Abilities.RKS_SYSTEM, Abilities.NONE, Abilities.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285, GrowthRate.SLOW, null, false, false, new PokemonSpecies(Species.SILVALLY, "Silvally", 7, true, false, false, "Synthetic Pokémon", Type.NORMAL, null, 2.3, 100.5, Abilities.RKS_SYSTEM, Abilities.NONE, Abilities.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285, GrowthRate.SLOW, null, false, false,
new PokemonForm("Type: Normal", "normal", Type.NORMAL, null, 2.3, 100.5, Abilities.RKS_SYSTEM, Abilities.NONE, Abilities.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285, false, ""), new PokemonForm("Type: Normal", "normal", Type.NORMAL, null, 2.3, 100.5, Abilities.RKS_SYSTEM, Abilities.NONE, Abilities.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285, false, ""),
new PokemonForm("Type: Fighting", "fighting", Type.FIGHTING, null, 2.3, 100.5, Abilities.RKS_SYSTEM, Abilities.NONE, Abilities.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285), new PokemonForm("Type: Fighting", "fighting", Type.FIGHTING, null, 2.3, 100.5, Abilities.RKS_SYSTEM, Abilities.NONE, Abilities.NONE, 570, 95, 95, 95, 95, 95, 95, 3, 0, 285),

View File

@ -445,11 +445,3 @@ export class EggHatchPhase extends BattlePhase {
return ret; return ret;
} }
} }
export class EndEvolutionPhase extends BattlePhase {
start() {
super.start();
this.scene.ui.setModeForceTransition(Mode.MESSAGE).then(() => this.end());
}
}

View File

@ -6,39 +6,47 @@ import EvolutionSceneHandler from "./ui/evolution-scene-handler";
import * as Utils from "./utils"; import * as Utils from "./utils";
import { Mode } from "./ui/ui"; import { Mode } from "./ui/ui";
import { LearnMovePhase } from "./battle-phases"; import { LearnMovePhase } from "./battle-phases";
import { SpeciesFormKey } from "./data/pokemon-species";
import { achvs } from "./system/achv";
import { cos, sin } from "./anims"; import { cos, sin } from "./anims";
import { PlayerPokemon } from "./pokemon";
export class EvolutionPhase extends BattlePhase { export class EvolutionPhase extends BattlePhase {
private partyMemberIndex: integer; protected pokemon: PlayerPokemon;
protected lastLevel: integer;
private evolution: SpeciesEvolution; private evolution: SpeciesEvolution;
private lastLevel: integer;
private evolutionContainer: Phaser.GameObjects.Container; protected evolutionContainer: Phaser.GameObjects.Container;
private evolutionBaseBg: Phaser.GameObjects.Image; protected evolutionBaseBg: Phaser.GameObjects.Image;
private evolutionBg: Phaser.GameObjects.Video; protected evolutionBg: Phaser.GameObjects.Video;
private evolutionBgOverlay: Phaser.GameObjects.Rectangle; protected evolutionBgOverlay: Phaser.GameObjects.Rectangle;
private evolutionOverlay: Phaser.GameObjects.Rectangle; protected evolutionOverlay: Phaser.GameObjects.Rectangle;
private pokemonSprite: Phaser.GameObjects.Sprite; protected pokemonSprite: Phaser.GameObjects.Sprite;
private pokemonTintSprite: Phaser.GameObjects.Sprite; protected pokemonTintSprite: Phaser.GameObjects.Sprite;
private pokemonEvoSprite: Phaser.GameObjects.Sprite; protected pokemonEvoSprite: Phaser.GameObjects.Sprite;
private pokemonEvoTintSprite: Phaser.GameObjects.Sprite; protected pokemonEvoTintSprite: Phaser.GameObjects.Sprite;
constructor(scene: BattleScene, partyMemberIndex: integer, evolution: SpeciesEvolution, lastLevel: integer) { constructor(scene: BattleScene, pokemon: PlayerPokemon, evolution: SpeciesEvolution, lastLevel: integer) {
super(scene); super(scene);
this.partyMemberIndex = partyMemberIndex; this.pokemon = pokemon;
this.evolution = evolution; this.evolution = evolution;
this.lastLevel = lastLevel; this.lastLevel = lastLevel;
} }
validate(): boolean {
return !!this.evolution;
}
setMode(): Promise<void> {
return this.scene.ui.setModeForceTransition(Mode.EVOLUTION_SCENE);
}
start() { start() {
super.start(); super.start();
this.scene.ui.setModeForceTransition(Mode.EVOLUTION_SCENE).then(() => { this.setMode().then(() => {
if (!this.evolution) if (!this.validate())
return this.end(); return this.end();
this.scene.fadeOutBgm(null, false); this.scene.fadeOutBgm(null, false);
@ -75,29 +83,34 @@ export class EvolutionPhase extends BattlePhase {
this.pokemonEvoTintSprite.setVisible(false); this.pokemonEvoTintSprite.setVisible(false);
this.pokemonEvoTintSprite.setTintFill(0xFFFFFF); this.pokemonEvoTintSprite.setTintFill(0xFFFFFF);
this.evolutionOverlay = this.scene.add.rectangle(0, -this.scene.game.canvas.height / 6, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6, 0xFFFFFF); this.evolutionOverlay = this.scene.add.rectangle(0, -this.scene.game.canvas.height / 6, this.scene.game.canvas.width / 6, (this.scene.game.canvas.height / 6) - 48, 0xFFFFFF);
this.evolutionOverlay.setOrigin(0, 0); this.evolutionOverlay.setOrigin(0, 0);
this.evolutionOverlay.setAlpha(0); this.evolutionOverlay.setAlpha(0);
this.scene.fieldUI.add(this.evolutionOverlay); this.scene.ui.add(this.evolutionOverlay);
const pokemon = this.scene.getParty()[this.partyMemberIndex];
const preName = pokemon.name;
[ this.pokemonSprite, this.pokemonTintSprite, this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => { [ this.pokemonSprite, this.pokemonTintSprite, this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => {
sprite.play(pokemon.getSpriteKey(true)); sprite.play(this.pokemon.getSpriteKey(true));
sprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false }); sprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false });
sprite.pipelineData['ignoreTimeTint'] = true; sprite.pipelineData['ignoreTimeTint'] = true;
[ 'spriteColors', 'fusionSpriteColors' ].map(k => { [ 'spriteColors', 'fusionSpriteColors' ].map(k => {
if (pokemon.summonData?.speciesForm) if (this.pokemon.summonData?.speciesForm)
k += 'Base'; k += 'Base';
sprite.pipelineData[k] = pokemon.getSprite().pipelineData[k]; sprite.pipelineData[k] = this.pokemon.getSprite().pipelineData[k];
}); });
}); });
this.doEvolution();
});
}
doEvolution(): void {
const evolutionHandler = this.scene.ui.getHandler() as EvolutionSceneHandler;
const preName = this.pokemon.name;
this.scene.ui.showText(`What?\n${preName} is evolving!`, null, () => { this.scene.ui.showText(`What?\n${preName} is evolving!`, null, () => {
pokemon.cry(); this.pokemon.cry();
pokemon.getPossibleEvolution(this.evolution).then(evolvedPokemon => { this.pokemon.getPossibleEvolution(this.evolution).then(evolvedPokemon => {
[ this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => { [ this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => {
sprite.play(evolvedPokemon.getSpriteKey(true)); sprite.play(evolvedPokemon.getSpriteKey(true));
@ -173,7 +186,7 @@ export class EvolutionPhase extends BattlePhase {
}; };
this.scene.ui.setOverlayMode(Mode.CONFIRM, () => { this.scene.ui.setOverlayMode(Mode.CONFIRM, () => {
this.scene.ui.revertMode(); this.scene.ui.revertMode();
pokemon.pauseEvolutions = true; this.pokemon.pauseEvolutions = true;
this.scene.ui.showText(`Evolutions have been paused for ${preName}.`, null, end, 3000); this.scene.ui.showText(`Evolutions have been paused for ${preName}.`, null, end, 3000);
}, () => { }, () => {
this.scene.ui.revertMode(); this.scene.ui.revertMode();
@ -190,10 +203,10 @@ export class EvolutionPhase extends BattlePhase {
this.scene.time.delayedCall(900, () => { this.scene.time.delayedCall(900, () => {
evolutionHandler.canCancel = false; evolutionHandler.canCancel = false;
pokemon.evolve(this.evolution).then(() => { this.pokemon.evolve(this.evolution).then(() => {
const levelMoves = pokemon.getLevelMoves(this.lastLevel + 1, true); const levelMoves = this.pokemon.getLevelMoves(this.lastLevel + 1, true);
for (let lm of levelMoves) for (let lm of levelMoves)
this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.partyMemberIndex, lm)); this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.scene.getParty().indexOf(this.pokemon), lm));
this.scene.unshiftPhase(new EndEvolutionPhase(this.scene)); this.scene.unshiftPhase(new EndEvolutionPhase(this.scene));
this.scene.playSound('shine'); this.scene.playSound('shine');
@ -220,14 +233,12 @@ export class EvolutionPhase extends BattlePhase {
onComplete: () => { onComplete: () => {
SoundFade.fadeOut(this.scene, evolutionBgm, 100); SoundFade.fadeOut(this.scene, evolutionBgm, 100);
this.scene.time.delayedCall(250, () => { this.scene.time.delayedCall(250, () => {
pokemon.cry(); this.pokemon.cry();
this.scene.time.delayedCall(1250, () => { this.scene.time.delayedCall(1250, () => {
this.scene.playSoundWithoutBgm('evolution_fanfare'); this.scene.playSoundWithoutBgm('evolution_fanfare');
if (this.evolution.evoFormKey && this.evolution.evoFormKey.indexOf(SpeciesFormKey.MEGA) > -1)
this.scene.validateAchv(achvs.MEGA_EVOLVE);
evolvedPokemon.destroy(); evolvedPokemon.destroy();
this.scene.ui.showText(`Congratulations! Your ${preName}\nevolved into ${pokemon.name}!`, null, () => this.end(), null, true, 3000); this.scene.ui.showText(`Congratulations! Your ${preName}\nevolved into ${this.pokemon.name}!`, null, () => this.end(), null, true, Utils.fixedInt(4000));
this.scene.time.delayedCall(Utils.fixedInt(4250), () => this.scene.playBgm()); this.scene.time.delayedCall(Utils.fixedInt(4250), () => this.scene.playBgm());
}); });
}); });
@ -249,7 +260,6 @@ export class EvolutionPhase extends BattlePhase {
}); });
}); });
}, 1000); }, 1000);
});
} }
doSpiralUpward() { doSpiralUpward() {
@ -288,10 +298,10 @@ export class EvolutionPhase extends BattlePhase {
}); });
} }
doCycle(l: number): Promise<boolean> { doCycle(l: number, lastCycle: integer = 15): Promise<boolean> {
return new Promise(resolve => { return new Promise(resolve => {
const evolutionHandler = this.scene.ui.getHandler() as EvolutionSceneHandler; const evolutionHandler = this.scene.ui.getHandler() as EvolutionSceneHandler;
const isLastCycle = l === 15; const isLastCycle = l === lastCycle;
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.pokemonTintSprite, targets: this.pokemonTintSprite,
scale: 0.25, scale: 0.25,
@ -308,8 +318,8 @@ export class EvolutionPhase extends BattlePhase {
onComplete: () => { onComplete: () => {
if (evolutionHandler.cancelled) if (evolutionHandler.cancelled)
return resolve(false); return resolve(false);
if (l < 15) if (l < lastCycle)
this.doCycle(l + 0.5).then(success => resolve(success)); this.doCycle(l + 0.5, lastCycle).then(success => resolve(success));
else { else {
this.pokemonTintSprite.setVisible(false); this.pokemonTintSprite.setVisible(false);
resolve(true); resolve(true);

188
src/form-change-phase.ts Normal file
View File

@ -0,0 +1,188 @@
import BattleScene from "./battle-scene";
import * as Utils from "./utils";
import { SpeciesFormKey } from "./data/pokemon-species";
import { achvs } from "./system/achv";
import { SpeciesFormChange, getSpeciesFormChangeMessage } from "./data/pokemon-forms";
import { EndEvolutionPhase, EvolutionPhase } from "./evolution-phase";
import Pokemon, { PlayerPokemon } from "./pokemon";
import { Mode } from "./ui/ui";
import PartyUiHandler from "./ui/party-ui-handler";
import { BattlePhase } from "./battle-phase";
export class FormChangePhase extends EvolutionPhase {
private formChange: SpeciesFormChange;
private modal: boolean;
constructor(scene: BattleScene, pokemon: PlayerPokemon, formChange: SpeciesFormChange, modal: boolean) {
super(scene, pokemon, null, 0);
this.formChange = formChange;
this.modal = modal;
}
validate(): boolean {
return !!this.formChange;
}
setMode(): Promise<void> {
if (!this.modal)
return super.setMode();
return this.scene.ui.setOverlayMode(Mode.EVOLUTION_SCENE);
}
doEvolution(): void {
const preName = this.pokemon.name;
this.pokemon.getPossibleForm(this.formChange).then(transformedPokemon => {
[ this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => {
sprite.play(transformedPokemon.getSpriteKey(true));
sprite.pipelineData['ignoreTimeTint'] = true;
[ 'spriteColors', 'fusionSpriteColors' ].map(k => {
if (transformedPokemon.summonData?.speciesForm)
k += 'Base';
sprite.pipelineData[k] = transformedPokemon.getSprite().pipelineData[k];
});
});
this.scene.time.delayedCall(250, () => {
this.scene.tweens.add({
targets: this.evolutionBgOverlay,
alpha: 1,
delay: 500,
duration: 1500,
ease: 'Sine.easeOut',
onComplete: () => {
this.scene.time.delayedCall(1000, () => {
this.scene.tweens.add({
targets: this.evolutionBgOverlay,
alpha: 0,
duration: 250
});
this.evolutionBg.setVisible(true);
this.evolutionBg.play();
});
this.scene.playSound('charge');
this.doSpiralUpward();
this.scene.tweens.addCounter({
from: 0,
to: 1,
duration: 2000,
onUpdate: t => {
this.pokemonTintSprite.setAlpha(t.getValue());
},
onComplete: () => {
this.pokemonSprite.setVisible(false);
this.scene.time.delayedCall(1100, () => {
this.scene.playSound('beam');
this.doArcDownward();
this.scene.time.delayedCall(1000, () => {
this.pokemonEvoTintSprite.setScale(0.25);
this.pokemonEvoTintSprite.setVisible(true);
this.doCycle(1, 1).then(_success => {
this.scene.playSound('sparkle');
this.pokemonEvoSprite.setVisible(true);
this.doCircleInward();
this.scene.time.delayedCall(900, () => {
this.pokemon.changeForm(this.formChange).then(() => {
if (!this.modal)
this.scene.unshiftPhase(new EndEvolutionPhase(this.scene));
this.scene.playSound('shine');
this.doSpray();
this.scene.tweens.add({
targets: this.evolutionOverlay,
alpha: 1,
duration: 250,
easing: 'Sine.easeIn',
onComplete: () => {
this.evolutionBgOverlay.setAlpha(1);
this.evolutionBg.setVisible(false);
this.scene.tweens.add({
targets: [ this.evolutionOverlay, this.pokemonEvoTintSprite ],
alpha: 0,
duration: 2000,
delay: 150,
easing: 'Sine.easeIn',
onComplete: () => {
this.scene.tweens.add({
targets: this.evolutionBgOverlay,
alpha: 0,
duration: 250,
onComplete: () => {
this.scene.time.delayedCall(250, () => {
this.pokemon.cry();
this.scene.time.delayedCall(1250, () => {
const isMega = this.formChange.formKey.indexOf(SpeciesFormKey.MEGA) > -1;
const isRevert = !isMega && this.formChange.formKey === this.pokemon.species.forms[0].formKey;
let playEvolutionFanfare = false;
if (isMega) {
this.scene.validateAchv(achvs.MEGA_EVOLVE);
playEvolutionFanfare = true;
}
const delay = playEvolutionFanfare ? 4000 : 1750;
this.scene.playSoundWithoutBgm(playEvolutionFanfare ? 'evolution_fanfare' : 'minor_fanfare');
transformedPokemon.destroy();
this.scene.ui.showText(getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName), null, () => this.end(), null, true, Utils.fixedInt(delay));
this.scene.time.delayedCall(Utils.fixedInt(delay + 250), () => this.scene.playBgm());
});
});
}
});
}
});
}
});
});
});
});
});
});
}
})
}
});
});
});
}
end(): void {
if (this.modal) {
this.scene.ui.revertMode().then(() => {
if (this.scene.ui.getMode() === Mode.PARTY) {
const partyUiHandler = this.scene.ui.getHandler() as PartyUiHandler;
partyUiHandler.clearPartySlots();
partyUiHandler.populatePartySlots();
}
super.end();
});
} else
super.end();
}
}
export class QuietFormChangePhase extends BattlePhase {
protected pokemon: Pokemon;
protected formChange: SpeciesFormChange;
constructor(scene: BattleScene, pokemon: Pokemon, formChange: SpeciesFormChange) {
super(scene);
this.pokemon = pokemon;
this.formChange = formChange;
}
start(): void {
super.start();
if (this.pokemon.formIndex === this.pokemon.species.forms.findIndex(f => f.formKey === this.formChange.formKey))
return this.end();
const preName = this.pokemon.name;
this.pokemon.changeForm(this.formChange).then(() => {
this.scene.ui.showText(getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName), null, () => this.end(), Utils.fixedInt(1500));
});
}
}

View File

@ -16,6 +16,7 @@ import { StatusEffect, getStatusEffectDescriptor } from '../data/status-effect';
import { SpeciesFormKey } from '../data/pokemon-species'; import { SpeciesFormKey } from '../data/pokemon-species';
import BattleScene from '../battle-scene'; import BattleScene from '../battle-scene';
import { VoucherType, getVoucherTypeIcon, getVoucherTypeName } from '../system/voucher'; import { VoucherType, getVoucherTypeIcon, getVoucherTypeName } from '../system/voucher';
import { FormChangeItem, SpeciesFormChangeItemTrigger, pokemonFormChanges } from '../data/pokemon-forms';
type Modifier = Modifiers.Modifier; type Modifier = Modifiers.Modifier;
@ -446,6 +447,26 @@ export class EvolutionItemModifierType extends PokemonModifierType implements Ge
} }
} }
export class FormChangeItemModifierType extends PokemonModifierType implements GeneratedPersistentModifierType {
public formChangeItem: FormChangeItem;
constructor(formChangeItem: FormChangeItem) {
super(Utils.toReadableString(FormChangeItem[formChangeItem]), `Causes certain Pokémon to change form`, (_type, args) => new Modifiers.PokemonFormChangeItemModifier(this, (args[0] as PlayerPokemon).id, formChangeItem, true),
(pokemon: PlayerPokemon) => {
if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId) && !!pokemonFormChanges[pokemon.species.speciesId].find(fc => fc.trigger.hasTriggerType(SpeciesFormChangeItemTrigger)))
return null;
return PartyUiHandler.NoEffectMessage;
}, FormChangeItem[formChangeItem].toLowerCase());
this.formChangeItem = formChangeItem;
}
getPregenArgs(): any[] {
return [ this.formChangeItem ];
}
}
export class FusePokemonModifierType extends PokemonModifierType { export class FusePokemonModifierType extends PokemonModifierType {
constructor(name: string, iconImage?: string) { constructor(name: string, iconImage?: string) {
super(name, 'Combines two Pokémon (transfers ability, splits base stats and types, shares move pool)', (_type, args) => new Modifiers.FusePokemonModifier(this, (args[0] as PlayerPokemon).id, (args[1] as PlayerPokemon).id), super(name, 'Combines two Pokémon (transfers ability, splits base stats and types, shares move pool)', (_type, args) => new Modifiers.FusePokemonModifier(this, (args[0] as PlayerPokemon).id, (args[1] as PlayerPokemon).id),
@ -524,7 +545,7 @@ class TmModifierTypeGenerator extends ModifierTypeGenerator {
} }
class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator { class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator {
constructor(mega: boolean) { constructor() {
super((party: Pokemon[], pregenArgs?: any[]) => { super((party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs) if (pregenArgs)
return new EvolutionItemModifierType(pregenArgs[0] as EvolutionItem); return new EvolutionItemModifierType(pregenArgs[0] as EvolutionItem);
@ -532,7 +553,7 @@ class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator {
const evolutionItemPool = party.filter(p => pokemonEvolutions.hasOwnProperty(p.species.speciesId)).map(p => { const evolutionItemPool = party.filter(p => pokemonEvolutions.hasOwnProperty(p.species.speciesId)).map(p => {
const evolutions = pokemonEvolutions[p.species.speciesId]; const evolutions = pokemonEvolutions[p.species.speciesId];
return evolutions.filter(e => e.item !== EvolutionItem.NONE && (e.evoFormKey === null || (e.preFormKey || '') === p.getFormKey()) && (!e.condition || e.condition.predicate(p))); return evolutions.filter(e => e.item !== EvolutionItem.NONE && (e.evoFormKey === null || (e.preFormKey || '') === p.getFormKey()) && (!e.condition || e.condition.predicate(p)));
}).flat().filter(e => (e.item >= 100) === mega).flatMap(e => e.item); }).flat().flatMap(e => e.item);
if (!evolutionItemPool.length) if (!evolutionItemPool.length)
return null; return null;
@ -542,6 +563,26 @@ class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator {
} }
} }
class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator {
constructor() {
super((party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs)
return new FormChangeItemModifierType(pregenArgs[0] as FormChangeItem);
const formChangeItemPool = party.filter(p => pokemonFormChanges.hasOwnProperty(p.species.speciesId)).map(p => {
const formChanges = pokemonFormChanges[p.species.speciesId];
return formChanges.filter(fc => fc.formKey.indexOf(SpeciesFormKey.MEGA) === -1 || party[0].scene.getModifiers(Modifiers.MegaEvolutionAccessModifier).length)
.map(fc => fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger).filter(t => t && t.active);
}).flat().flatMap(fc => fc.item);
if (!formChangeItemPool.length)
return null;
return new FormChangeItemModifierType(formChangeItemPool[Utils.randSeedInt(formChangeItemPool.length)]);
});
}
}
export class ContactHeldItemTransferChanceModifierType extends PokemonHeldItemModifierType { export class ContactHeldItemTransferChanceModifierType extends PokemonHeldItemModifierType {
constructor(name: string, chancePercent: integer, iconImage?: string, group?: string, soundName?: string) { constructor(name: string, chancePercent: integer, iconImage?: string, group?: string, soundName?: string) {
super(name, `Upon attacking, there is a ${chancePercent}% chance the foe's held item will be stolen`, (type, args) => new Modifiers.ContactHeldItemTransferChanceModifier(type, (args[0] as Pokemon).id, chancePercent), iconImage, group, soundName); super(name, `Upon attacking, there is a ${chancePercent}% chance the foe's held item will be stolen`, (type, args) => new Modifiers.ContactHeldItemTransferChanceModifier(type, (args[0] as Pokemon).id, chancePercent), iconImage, group, soundName);
@ -593,8 +634,8 @@ export const modifierTypes = {
RARE_CANDY: () => new PokemonLevelIncrementModifierType('Rare Candy'), RARE_CANDY: () => new PokemonLevelIncrementModifierType('Rare Candy'),
RARER_CANDY: () => new AllPokemonLevelIncrementModifierType('Rarer Candy'), RARER_CANDY: () => new AllPokemonLevelIncrementModifierType('Rarer Candy'),
EVOLUTION_ITEM: () => new EvolutionItemModifierTypeGenerator(false), EVOLUTION_ITEM: () => new EvolutionItemModifierTypeGenerator(),
MEGA_EVOLUTION_ITEM: () => new EvolutionItemModifierTypeGenerator(true), FORM_CHANGE_ITEM: () => new FormChangeItemModifierTypeGenerator(),
MEGA_BRACELET: () => new ModifierType('Mega Bracelet', 'Mega stones become available', (type, _args) => new Modifiers.MegaEvolutionAccessModifier(type)), MEGA_BRACELET: () => new ModifierType('Mega Bracelet', 'Mega stones become available', (type, _args) => new Modifiers.MegaEvolutionAccessModifier(type)),
@ -838,7 +879,7 @@ const modifierPool = {
new WeightedModifierType(modifierTypes.ABILITY_CHARM, 2), new WeightedModifierType(modifierTypes.ABILITY_CHARM, 2),
new WeightedModifierType(modifierTypes.IV_SCANNER, 2), new WeightedModifierType(modifierTypes.IV_SCANNER, 2),
new WeightedModifierType(modifierTypes.EXP_BALANCE, 1), new WeightedModifierType(modifierTypes.EXP_BALANCE, 1),
new WeightedModifierType(modifierTypes.MEGA_EVOLUTION_ITEM, (party: Pokemon[]) => party[0].scene.getModifiers(Modifiers.MegaEvolutionAccessModifier).length && !party.filter(p => p.getFormKey().indexOf(SpeciesFormKey.MEGA) > -1).length ? 1 : 0), new WeightedModifierType(modifierTypes.FORM_CHANGE_ITEM, 1),
new WeightedModifierType(modifierTypes.REVERSE_DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode !== GameMode.SPLICED_ENDLESS && party.filter(p => p.fusionSpecies).length ? 3 : 0), new WeightedModifierType(modifierTypes.REVERSE_DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode !== GameMode.SPLICED_ENDLESS && party.filter(p => p.fusionSpecies).length ? 3 : 0),
].map(m => { m.setTier(ModifierTier.ULTRA); return m; }), ].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
[ModifierTier.MASTER]: [ [ModifierTier.MASTER]: [

View File

@ -17,6 +17,7 @@ import { StatusEffect, getStatusEffectDescriptor } from '../data/status-effect';
import { MoneyAchv } from '../system/achv'; import { MoneyAchv } from '../system/achv';
import { VoucherType } from '../system/voucher'; import { VoucherType } from '../system/voucher';
import { PreventBerryUseAbAttr, applyAbAttrs } from '../data/ability'; import { PreventBerryUseAbAttr, applyAbAttrs } from '../data/ability';
import { FormChangeItem, SpeciesFormChangeItemTrigger } from '../data/pokemon-forms';
type ModifierType = ModifierTypes.ModifierType; type ModifierType = ModifierTypes.ModifierType;
export type ModifierPredicate = (modifier: Modifier) => boolean; export type ModifierPredicate = (modifier: Modifier) => boolean;
@ -990,7 +991,7 @@ export class EvolutionItemModifier extends ConsumablePokemonModifier {
&& (!e.condition || e.condition.predicate(pokemon))); && (!e.condition || e.condition.predicate(pokemon)));
if (matchingEvolution) { if (matchingEvolution) {
pokemon.scene.unshiftPhase(new EvolutionPhase(pokemon.scene, pokemon.scene.getParty().indexOf(pokemon), matchingEvolution, pokemon.level - 1)); pokemon.scene.unshiftPhase(new EvolutionPhase(pokemon.scene, pokemon, matchingEvolution, pokemon.level - 1));
return true; return true;
} }
@ -1260,6 +1261,39 @@ export class PokemonNatureWeightModifier extends PokemonHeldItemModifier {
} }
} }
export class PokemonFormChangeItemModifier extends PokemonHeldItemModifier {
public formChangeItem: FormChangeItem;
public active: boolean;
constructor(type: ModifierTypes.FormChangeItemModifierType, pokemonId: integer, formChangeItem: FormChangeItem, active: boolean, stackCount?: integer) {
super(type, pokemonId, stackCount);
this.formChangeItem = formChangeItem;
this.active = active;
}
matchType(modifier: Modifier): boolean {
return modifier instanceof PokemonFormChangeItemModifier && modifier.formChangeItem === this.formChangeItem;
}
clone(): PersistentModifier {
return new PokemonFormChangeItemModifier(this.type as ModifierTypes.FormChangeItemModifierType, this.pokemonId, this.formChangeItem, this.active, this.stackCount);
}
getArgs(): any[] {
return super.getArgs().concat(this.formChangeItem, this.active);
}
apply(args: any[]): boolean {
const pokemon = args[0] as Pokemon;
return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger);
}
getMaxHeldItemCount(pokemon: Pokemon): integer {
return 1;
}
}
export class MoneyMultiplierModifier extends PersistentModifier { export class MoneyMultiplierModifier extends PersistentModifier {
constructor(type: ModifierType, stackCount?: integer) { constructor(type: ModifierType, stackCount?: integer) {
super(type, stackCount); super(type, stackCount);

View File

@ -34,6 +34,7 @@ import { DamageAchv, achvs } from './system/achv';
import { DexAttr } from './system/game-data'; import { DexAttr } from './system/game-data';
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from '@material/material-color-utilities'; import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from '@material/material-color-utilities';
import { Nature, getNatureStatMultiplier } from './data/nature'; import { Nature, getNatureStatMultiplier } from './data/nature';
import { SpeciesFormChange, SpeciesFormChangeMoveUsedTrigger, SpeciesFormChangeStatusEffectTrigger } from './data/pokemon-forms';
export enum FieldPosition { export enum FieldPosition {
CENTER, CENTER,
@ -146,10 +147,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
Utils.binToDec(Utils.decToBin(this.id).substring(25, 30)) Utils.binToDec(Utils.decToBin(this.id).substring(25, 30))
]; ];
this.nature = nature !== undefined
? nature
: Utils.randSeedInt(25) as Nature;
if (this.gender === undefined) { if (this.gender === undefined) {
if (this.species.malePercent === null) if (this.species.malePercent === null)
this.gender = Gender.GENDERLESS; this.gender = Gender.GENDERLESS;
@ -163,11 +160,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
if (this.formIndex === undefined) if (this.formIndex === undefined)
this.formIndex = this.scene.getSpeciesFormIndex(species, this.gender, this.isPlayer()); this.formIndex = this.scene.getSpeciesFormIndex(species, this.gender, this.nature, this.isPlayer());
if (this.shiny === undefined) if (this.shiny === undefined)
this.trySetShiny(); this.trySetShiny();
if (nature !== undefined)
this.setNature(nature);
else
this.generateNature();
this.friendship = species.baseFriendship; this.friendship = species.baseFriendship;
this.metLevel = level; this.metLevel = level;
this.metBiome = scene.currentBattle ? scene.arena.biomeType : -1; this.metBiome = scene.currentBattle ? scene.arena.biomeType : -1;
@ -544,6 +546,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.calculateStats(); this.calculateStats();
} }
generateNature(naturePool?: Nature[]): void {
if (naturePool === undefined)
naturePool = Utils.getEnumValues(Nature);
const nature = naturePool[Utils.randSeedInt(naturePool.length)];
this.setNature(nature);
}
getMaxHp(): integer { getMaxHp(): integer {
return this.getStat(Stat.HP); return this.getStat(Stat.HP);
} }
@ -796,7 +805,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.fusionGender = Gender.FEMALE; this.fusionGender = Gender.FEMALE;
} }
this.fusionFormIndex = this.scene.getSpeciesFormIndex(this.fusionSpecies, this.fusionGender, true); this.fusionFormIndex = this.scene.getSpeciesFormIndex(this.fusionSpecies, this.fusionGender, this.nature, true);
this.generateName(); this.generateName();
} }
@ -1227,6 +1236,22 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return this.summonData.moveQueue; return this.summonData.moveQueue;
} }
changeForm(formChange: SpeciesFormChange): Promise<void> {
return new Promise(resolve => {
this.formIndex = Math.max(this.species.forms.findIndex(f => f.formKey === formChange.formKey), 0);
this.generateName();
const abilityCount = this.getSpeciesForm().getAbilityCount();
if (this.abilityIndex >= abilityCount) // Shouldn't happen
this.abilityIndex = abilityCount - 1;
this.scene.gameData.setPokemonSeen(this, true);
this.loadAssets().then(() => {
this.calculateStats();
this.scene.updateModifiers(this.isPlayer(), true);
this.updateInfo().then(() => resolve());
});
});
}
cry(soundConfig?: Phaser.Types.Sound.SoundConfig): AnySound { cry(soundConfig?: Phaser.Types.Sound.SoundConfig): AnySound {
const cry = this.getSpeciesForm().cry(this.scene, soundConfig); const cry = this.getSpeciesForm().cry(this.scene, soundConfig);
let duration = cry.totalDuration * 1000; let duration = cry.totalDuration * 1000;
@ -1430,6 +1455,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
this.status = new Status(effect, 0, cureTurn); this.status = new Status(effect, 0, cureTurn);
if (effect !== StatusEffect.FAINT)
this.scene.triggerPokemonFormChange(this, SpeciesFormChangeStatusEffectTrigger, true);
return true; return true;
} }
@ -1462,6 +1491,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.battleSummonData = new PokemonBattleSummonData(); this.battleSummonData = new PokemonBattleSummonData();
if (this.getTag(BattlerTagType.SEEDED)) if (this.getTag(BattlerTagType.SEEDED))
this.lapseTag(BattlerTagType.SEEDED); this.lapseTag(BattlerTagType.SEEDED);
this.scene.triggerPokemonFormChange(this, SpeciesFormChangeMoveUsedTrigger, true);
} }
resetTurnData(): void { resetTurnData(): void {
@ -1876,6 +1906,33 @@ export class PlayerPokemon extends Pokemon {
} }
} }
getPossibleForm(formChange: SpeciesFormChange): Promise<Pokemon> {
return new Promise(resolve => {
const formIndex = Math.max(this.species.forms.findIndex(f => f.formKey === formChange.formKey), 0);
const ret = this.scene.addPlayerPokemon(this.species, this.level, this.abilityIndex, formIndex, this.gender, this.shiny, this.ivs, this.nature, this);
ret.loadAssets().then(() => resolve(ret));
});
}
changeForm(formChange: SpeciesFormChange): Promise<void> {
return new Promise(resolve => {
this.formIndex = Math.max(this.species.forms.findIndex(f => f.formKey === formChange.formKey), 0);
this.generateName();
const abilityCount = this.getSpeciesForm().getAbilityCount();
if (this.abilityIndex >= abilityCount) // Shouldn't happen
this.abilityIndex = abilityCount - 1;
this.compatibleTms.splice(0, this.compatibleTms.length);
this.generateCompatibleTms();
this.scene.gameData.setPokemonSeen(this, false);
this.scene.gameData.setPokemonCaught(this, false);
this.loadAssets().then(() => {
this.calculateStats();
this.scene.updateModifiers(true, true);
this.updateInfo().then(() => resolve());
});
});
}
isFusion(): boolean { isFusion(): boolean {
return !!(this.fusionSpecies || (this.species.speciesId === Species.KYUREM && this.formIndex)); return !!(this.fusionSpecies || (this.species.speciesId === Species.KYUREM && this.formIndex));
} }
@ -2160,8 +2217,6 @@ export class EnemyPokemon extends Pokemon {
if (this.isFainted()) if (this.isFainted())
return 0; return 0;
let clearedSegment = false;
if (!ignoreSegments && this.isBoss()) { if (!ignoreSegments && this.isBoss()) {
const segmentSize = this.getMaxHp() / this.bossSegments; const segmentSize = this.getMaxHp() / this.bossSegments;
for (let s = this.bossSegments - 1; s > 0; s--) { for (let s = this.bossSegments - 1; s > 0; s--) {
@ -2169,7 +2224,6 @@ export class EnemyPokemon extends Pokemon {
if (this.hp > hpThreshold) { if (this.hp > hpThreshold) {
if (this.hp - damage < hpThreshold) { if (this.hp - damage < hpThreshold) {
damage = this.hp - hpThreshold; damage = this.hp - hpThreshold;
clearedSegment = true;
this.handleBossSegmentCleared(s); this.handleBossSegmentCleared(s);
} }
break; break;

View File

@ -1,6 +1,6 @@
import BattleScene, { Button } from "../battle-scene"; import BattleScene, { Button } from "../battle-scene";
import { addTextObject, TextStyle } from "./text"; import { addTextObject, TextStyle } from "./text";
import UI, { Mode } from "./ui"; import { Mode } from "./ui";
import * as Utils from "../utils"; import * as Utils from "../utils";
import MessageUiHandler from "./message-ui-handler"; import MessageUiHandler from "./message-ui-handler";
import { getStatName, Stat } from "../data/pokemon-stat"; import { getStatName, Stat } from "../data/pokemon-stat";

View File

@ -44,11 +44,18 @@ export default class CommandUiHandler extends UiHandler {
this.commandsContainer.setVisible(true); this.commandsContainer.setVisible(true);
let commandPhase: CommandPhase;
let currentPhase = this.scene.getCurrentPhase();
if (currentPhase instanceof CommandPhase)
commandPhase = currentPhase;
else
commandPhase = this.scene.getStandbyPhase() as CommandPhase;
const messageHandler = this.getUi().getMessageHandler(); const messageHandler = this.getUi().getMessageHandler();
messageHandler.commandWindow.setVisible(true); messageHandler.commandWindow.setVisible(true);
messageHandler.movesWindowContainer.setVisible(false); messageHandler.movesWindowContainer.setVisible(false);
messageHandler.message.setWordWrapWidth(1110); messageHandler.message.setWordWrapWidth(1110);
messageHandler.showText(`What will\n${(this.scene.getCurrentPhase() as CommandPhase).getPokemon().name} do?`, 0); messageHandler.showText(`What will\n${commandPhase.getPokemon().name} do?`, 0);
this.setCursor(this.getCursor()); this.setCursor(this.getCursor());
return true; return true;
@ -118,8 +125,6 @@ export default class CommandUiHandler extends UiHandler {
} }
setCursor(cursor: integer): boolean { setCursor(cursor: integer): boolean {
const ui = this.getUi();
const changed = this.getCursor() !== cursor; const changed = this.getCursor() !== cursor;
if (changed) { if (changed) {
if (!this.fieldIndex) if (!this.fieldIndex)
@ -140,6 +145,7 @@ export default class CommandUiHandler extends UiHandler {
clear(): void { clear(): void {
super.clear(); super.clear();
this.getUi().getMessageHandler().commandWindow.setVisible(false);
this.commandsContainer.setVisible(false); this.commandsContainer.setVisible(false);
this.getUi().getMessageHandler().clearText(); this.getUi().getMessageHandler().clearText();
this.eraseCursor(); this.eraseCursor();

View File

@ -1,9 +1,12 @@
import BattleScene, { Button } from "../battle-scene"; import BattleScene, { Button } from "../battle-scene";
import MessageUiHandler from "./message-ui-handler";
import { TextStyle, addTextObject } from "./text";
import { Mode } from "./ui"; import { Mode } from "./ui";
import UiHandler from "./ui-handler";
export default class EvolutionSceneHandler extends UiHandler { export default class EvolutionSceneHandler extends MessageUiHandler {
public evolutionContainer: Phaser.GameObjects.Container; public evolutionContainer: Phaser.GameObjects.Container;
public messageBg: Phaser.GameObjects.Image;
public messageContainer: Phaser.GameObjects.Container;
public canCancel: boolean; public canCancel: boolean;
public cancelled: boolean; public cancelled: boolean;
@ -15,14 +18,48 @@ export default class EvolutionSceneHandler extends UiHandler {
this.canCancel = false; this.canCancel = false;
this.cancelled = false; this.cancelled = false;
const ui = this.getUi();
this.evolutionContainer = this.scene.add.container(0, -this.scene.game.canvas.height / 6); this.evolutionContainer = this.scene.add.container(0, -this.scene.game.canvas.height / 6);
this.scene.fieldUI.add(this.evolutionContainer); ui.add(this.evolutionContainer);
const messageBg = this.scene.add.image(0, 0, 'bg');
messageBg.setOrigin(0, 1);
messageBg.setVisible(false);
ui.add(messageBg);
this.messageBg = messageBg;
this.messageContainer = this.scene.add.container(12, -39);
this.messageContainer.setVisible(false);
ui.add(this.messageContainer);
const message = addTextObject(this.scene, 0, 0, '', TextStyle.MESSAGE, {
maxLines: 2,
wordWrap: {
width: 1780
}
});
this.messageContainer.add(message);
this.message = message;
const prompt = this.scene.add.sprite(0, 0, 'prompt');
prompt.setVisible(false);
prompt.setOrigin(0, 0);
this.messageContainer.add(prompt);
this.prompt = prompt;
} }
show(_args: any[]): boolean { show(_args: any[]): boolean {
super.show(_args); super.show(_args);
this.scene.fieldUI.bringToTop(this.evolutionContainer); this.scene.ui.bringToTop(this.evolutionContainer);
this.scene.ui.bringToTop(this.messageBg);
this.scene.ui.bringToTop(this.messageContainer);
this.messageBg.setVisible(true);
this.messageContainer.setVisible(true);
return true; return true;
} }
@ -33,7 +70,18 @@ export default class EvolutionSceneHandler extends UiHandler {
return true; return true;
} }
return this.scene.ui.getMessageHandler().processInput(button); const ui = this.getUi();
if (this.awaitingActionInput) {
if (button === Button.CANCEL || button === Button.ACTION) {
if (this.onActionInput) {
ui.playSelect();
const originalOnActionInput = this.onActionInput;
this.onActionInput = null;
originalOnActionInput();
return true;
}
}
}
} }
setCursor(_cursor: integer): boolean { setCursor(_cursor: integer): boolean {
@ -41,8 +89,11 @@ export default class EvolutionSceneHandler extends UiHandler {
} }
clear() { clear() {
this.clearText();
this.canCancel = false; this.canCancel = false;
this.cancelled = false; this.cancelled = false;
this.evolutionContainer.removeAll(true); this.evolutionContainer.removeAll(true);
this.messageContainer.setVisible(false);
this.messageBg.setVisible(false);
} }
} }

View File

@ -6,13 +6,14 @@ import { Command } from "./command-ui-handler";
import MessageUiHandler from "./message-ui-handler"; import MessageUiHandler from "./message-ui-handler";
import { Mode } from "./ui"; import { Mode } from "./ui";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { PokemonHeldItemModifier, SwitchEffectTransferModifier } from "../modifier/modifier"; import { PokemonFormChangeItemModifier, PokemonHeldItemModifier, SwitchEffectTransferModifier } from "../modifier/modifier";
import { Moves, allMoves } from "../data/move"; import { Moves, allMoves } from "../data/move";
import { getGenderColor, getGenderSymbol } from "../data/gender"; import { getGenderColor, getGenderSymbol } from "../data/gender";
import { StatusEffect } from "../data/status-effect"; import { StatusEffect } from "../data/status-effect";
import PokemonIconAnimHandler, { PokemonIconAnimMode } from "./pokemon-icon-anim-handler"; import PokemonIconAnimHandler, { PokemonIconAnimMode } from "./pokemon-icon-anim-handler";
import { pokemonEvolutions } from "../data/pokemon-evolutions"; import { pokemonEvolutions } from "../data/pokemon-evolutions";
import { addWindow } from "./window"; import { addWindow } from "./window";
import { SpeciesFormChangeItemTrigger } from "../data/pokemon-forms";
const defaultMessage = 'Choose a Pokémon.'; const defaultMessage = 'Choose a Pokémon.';
@ -38,11 +39,12 @@ export enum PartyOption {
TRANSFER, TRANSFER,
SPLICE, SPLICE,
SUMMARY, SUMMARY,
UNPAUSE_EVO, UNPAUSE_EVOLUTION,
RELEASE, RELEASE,
SCROLL_UP = 1000, SCROLL_UP = 1000,
SCROLL_DOWN = 1001, SCROLL_DOWN = 1001,
MOVE_1 = 2000, FORM_CHANGE_ITEM = 2000,
MOVE_1 = 3000,
MOVE_2, MOVE_2,
MOVE_3, MOVE_3,
MOVE_4 MOVE_4
@ -72,6 +74,7 @@ export default class PartyUiHandler extends MessageUiHandler {
private optionsScrollCursor: integer = 0; private optionsScrollCursor: integer = 0;
private optionsScrollTotal: integer = 0; private optionsScrollTotal: integer = 0;
private optionsContainer: Phaser.GameObjects.Container; private optionsContainer: Phaser.GameObjects.Container;
private optionsBg: Phaser.GameObjects.NineSlice;
private optionsCursorObj: Phaser.GameObjects.Image; private optionsCursorObj: Phaser.GameObjects.Image;
private options: integer[]; private options: integer[];
@ -228,7 +231,7 @@ export default class PartyUiHandler extends MessageUiHandler {
} }
ui.playSelect(); ui.playSelect();
return true; return true;
} else if ((option !== PartyOption.SUMMARY && option !== PartyOption.UNPAUSE_EVO && option !== PartyOption.RELEASE && option !== PartyOption.CANCEL) } else if ((option !== PartyOption.SUMMARY && option !== PartyOption.UNPAUSE_EVOLUTION && option !== PartyOption.RELEASE && option !== PartyOption.CANCEL)
|| (option === PartyOption.RELEASE && this.partyUiMode === PartyUiMode.RELEASE)) { || (option === PartyOption.RELEASE && this.partyUiMode === PartyUiMode.RELEASE)) {
let filterResult: string; let filterResult: string;
if (option !== PartyOption.TRANSFER && option !== PartyOption.SPLICE) { if (option !== PartyOption.TRANSFER && option !== PartyOption.SPLICE) {
@ -262,8 +265,23 @@ export default class PartyUiHandler extends MessageUiHandler {
this.selectCallback = null; this.selectCallback = null;
selectCallback(this.cursor, option); selectCallback(this.cursor, option);
} }
} else {
if (option >= PartyOption.FORM_CHANGE_ITEM && this.scene.getCurrentPhase() instanceof CommandPhase) {
switch (this.partyUiMode) {
case PartyUiMode.SWITCH:
case PartyUiMode.FAINT_SWITCH:
case PartyUiMode.POST_BATTLE_SWITCH:
let formChangeItemModifiers = this.scene.findModifiers(m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === pokemon.id) as PokemonFormChangeItemModifier[];
if (formChangeItemModifiers.find(m => m.active))
formChangeItemModifiers = formChangeItemModifiers.filter(m => m.active);
const modifier = formChangeItemModifiers[option - PartyOption.FORM_CHANGE_ITEM];
modifier.active = !modifier.active;
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger, false, true);
break;
}
} else if (this.cursor) } else if (this.cursor)
(this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.POKEMON, this.cursor, option === PartyOption.PASS_BATON); (this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.POKEMON, this.cursor, option === PartyOption.PASS_BATON);
}
if (this.partyUiMode !== PartyUiMode.MODIFIER && this.partyUiMode !== PartyUiMode.TM_MODIFIER && this.partyUiMode !== PartyUiMode.MOVE_MODIFIER) if (this.partyUiMode !== PartyUiMode.MODIFIER && this.partyUiMode !== PartyUiMode.TM_MODIFIER && this.partyUiMode !== PartyUiMode.MOVE_MODIFIER)
ui.playSelect(); ui.playSelect();
return true; return true;
@ -275,7 +293,7 @@ export default class PartyUiHandler extends MessageUiHandler {
ui.playSelect(); ui.playSelect();
ui.setModeWithoutClear(Mode.SUMMARY, pokemon).then(() => this.clearOptions()); ui.setModeWithoutClear(Mode.SUMMARY, pokemon).then(() => this.clearOptions());
return true; return true;
} else if (option === PartyOption.UNPAUSE_EVO) { } else if (option === PartyOption.UNPAUSE_EVOLUTION) {
this.clearOptions(); this.clearOptions();
ui.playSelect(); ui.playSelect();
pokemon.pauseEvolutions = false; pokemon.pauseEvolutions = false;
@ -356,7 +374,7 @@ export default class PartyUiHandler extends MessageUiHandler {
break; break;
case Button.RIGHT: case Button.RIGHT:
const battlerCount = this.scene.currentBattle.getBattlerCount(); const battlerCount = this.scene.currentBattle.getBattlerCount();
if (slotCount && this.cursor < battlerCount) if (slotCount > battlerCount && this.cursor < battlerCount)
success = this.setCursor(this.lastCursor < 6 ? this.lastCursor || battlerCount : battlerCount); success = this.setCursor(this.lastCursor < 6 ? this.lastCursor || battlerCount : battlerCount);
break; break;
} }
@ -423,8 +441,7 @@ export default class PartyUiHandler extends MessageUiHandler {
this.optionsCursorObj.setOrigin(0, 0); this.optionsCursorObj.setOrigin(0, 0);
this.optionsContainer.add(this.optionsCursorObj); this.optionsContainer.add(this.optionsCursorObj);
} }
const wideOptions = this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER; this.optionsCursorObj.setPosition(8 - this.optionsBg.displayWidth, -19 - (16 * ((this.options.length - 1) - this.optionsCursor)));
this.optionsCursorObj.setPosition(-86 - (wideOptions ? 50 : 0), -19 - (16 * ((this.options.length - 1) - this.optionsCursor)));
} else { } else {
changed = this.cursor !== cursor; changed = this.cursor !== cursor;
if (changed) { if (changed) {
@ -485,9 +502,7 @@ export default class PartyUiHandler extends MessageUiHandler {
this.updateOptions(); this.updateOptions();
const wideOptions = this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER; this.partyMessageBox.setSize(262 - Math.max(this.optionsBg.displayWidth - 56, 0), 30);
this.partyMessageBox.setSize(262 - (wideOptions ? 88 : 38), 30);
this.setCursor(0); this.setCursor(0);
} }
@ -512,6 +527,8 @@ export default class PartyUiHandler extends MessageUiHandler {
this.eraseOptionsCursor(); this.eraseOptionsCursor();
} }
let formChangeItemModifiers: PokemonFormChangeItemModifier[];
if (this.partyUiMode !== PartyUiMode.MOVE_MODIFIER && this.partyUiMode !== PartyUiMode.REMEMBER_MOVE_MODIFIER && (this.transferMode || this.partyUiMode !== PartyUiMode.MODIFIER_TRANSFER)) { if (this.partyUiMode !== PartyUiMode.MOVE_MODIFIER && this.partyUiMode !== PartyUiMode.REMEMBER_MOVE_MODIFIER && (this.transferMode || this.partyUiMode !== PartyUiMode.MODIFIER_TRANSFER)) {
switch (this.partyUiMode) { switch (this.partyUiMode) {
case PartyUiMode.SWITCH: case PartyUiMode.SWITCH:
@ -524,6 +541,13 @@ export default class PartyUiHandler extends MessageUiHandler {
&& (m as SwitchEffectTransferModifier).pokemonId === this.scene.getPlayerField()[this.fieldIndex].id)) && (m as SwitchEffectTransferModifier).pokemonId === this.scene.getPlayerField()[this.fieldIndex].id))
this.options.push(PartyOption.PASS_BATON); this.options.push(PartyOption.PASS_BATON);
} }
if (this.scene.getCurrentPhase() instanceof CommandPhase) {
formChangeItemModifiers = this.scene.findModifiers(m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === pokemon.id) as PokemonFormChangeItemModifier[];
if (formChangeItemModifiers.find(m => m.active))
formChangeItemModifiers = formChangeItemModifiers.filter(m => m.active);
for (let i = 0; i < formChangeItemModifiers.length; i++)
this.options.push(PartyOption.FORM_CHANGE_ITEM + i);
}
break; break;
case PartyUiMode.MODIFIER: case PartyUiMode.MODIFIER:
this.options.push(PartyOption.APPLY); this.options.push(PartyOption.APPLY);
@ -549,7 +573,7 @@ export default class PartyUiHandler extends MessageUiHandler {
this.options.push(PartyOption.SUMMARY); this.options.push(PartyOption.SUMMARY);
if (pokemon.pauseEvolutions && pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId)) if (pokemon.pauseEvolutions && pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId))
this.options.push(PartyOption.UNPAUSE_EVO); this.options.push(PartyOption.UNPAUSE_EVOLUTION);
if (this.partyUiMode === PartyUiMode.SWITCH) if (this.partyUiMode === PartyUiMode.SWITCH)
this.options.push(PartyOption.RELEASE); this.options.push(PartyOption.RELEASE);
@ -582,14 +606,17 @@ export default class PartyUiHandler extends MessageUiHandler {
this.options.push(PartyOption.CANCEL); this.options.push(PartyOption.CANCEL);
const optionBg = addWindow(this.scene, 0, 0, wideOptions ? 144 : 94, 16 * this.options.length + 13); this.optionsBg = addWindow(this.scene, 0, 0, 0, 16 * this.options.length + 13);
optionBg.setOrigin(1, 1); this.optionsBg.setOrigin(1, 1);
this.optionsContainer.add(optionBg); this.optionsContainer.add(this.optionsBg);
optionStartIndex = 0; optionStartIndex = 0;
optionEndIndex = this.options.length; optionEndIndex = this.options.length;
let widestOptionWidth = 0;
let optionTexts: Phaser.GameObjects.Text[] = [];
for (let o = optionStartIndex; o < optionEndIndex; o++) { for (let o = optionStartIndex; o < optionEndIndex; o++) {
const option = this.options[this.options.length - (o + 1)]; const option = this.options[this.options.length - (o + 1)];
let altText = false; let altText = false;
@ -602,10 +629,11 @@ export default class PartyUiHandler extends MessageUiHandler {
case PartyOption.MOVE_4: case PartyOption.MOVE_4:
optionName = pokemon.moveset[option - PartyOption.MOVE_1].getName(); optionName = pokemon.moveset[option - PartyOption.MOVE_1].getName();
break; break;
case PartyOption.UNPAUSE_EVO:
optionName = 'Unpause Evo.';
break;
default: default:
if (formChangeItemModifiers && option >= PartyOption.FORM_CHANGE_ITEM) {
const modifier = formChangeItemModifiers[option - PartyOption.FORM_CHANGE_ITEM];
optionName = `${modifier.active ? 'Deactivate' : 'Activate'} ${modifier.type.name}`;
} else
optionName = Utils.toReadableString(PartyOption[option]); optionName = Utils.toReadableString(PartyOption[option]);
break; break;
} }
@ -625,15 +653,23 @@ export default class PartyUiHandler extends MessageUiHandler {
} }
const yCoord = -6 - 16 * o; const yCoord = -6 - 16 * o;
const optionText = addTextObject(this.scene, -79 - (wideOptions ? 50 : 0), yCoord - 16, optionName, TextStyle.WINDOW); const optionText = addTextObject(this.scene, 0, yCoord - 16, optionName, TextStyle.WINDOW);
if (altText) { if (altText) {
optionText.setColor('#40c8f8'); optionText.setColor('#40c8f8');
optionText.setShadowColor('#006090') optionText.setShadowColor('#006090')
} }
optionText.setOrigin(0, 0); optionText.setOrigin(0, 0);
optionTexts.push(optionText);
widestOptionWidth = Math.max(optionText.displayWidth, widestOptionWidth);
this.optionsContainer.add(optionText); this.optionsContainer.add(optionText);
} }
this.optionsBg.width = Math.max(widestOptionWidth + 24, 94);
for (let optionText of optionTexts)
optionText.x = 15 - this.optionsBg.width;
} }
startTransfer(): void { startTransfer(): void {

View File

@ -345,6 +345,7 @@ export default class UI extends Phaser.GameObjects.Container {
const touchControls = document.getElementById('touchControls'); const touchControls = document.getElementById('touchControls');
if (touchControls) if (touchControls)
touchControls.dataset.uiMode = Mode[this.mode]; touchControls.dataset.uiMode = Mode[this.mode];
resolve(true);
}; };
if (noTransitionModes.indexOf(lastMode) === -1) { if (noTransitionModes.indexOf(lastMode) === -1) {
@ -356,8 +357,6 @@ export default class UI extends Phaser.GameObjects.Container {
}); });
} else } else
doRevertMode(); doRevertMode();
resolve(true);
}); });
} }