Add fade back to starter select on game over

This commit is contained in:
Flashfyre 2023-04-21 22:59:09 -04:00
parent b50976d784
commit db31f961ad
7 changed files with 154 additions and 80 deletions

View File

@ -188,7 +188,7 @@ export class SelectBiomePhase extends BattlePhase {
start() {
super.start();
this.scene.arena.fadeOutBgm(2000);
this.scene.arena.fadeOutBgm(2000, true);
const currentBiome = this.scene.arena.biomeType;
@ -1147,8 +1147,8 @@ export class WeatherEffectPhase extends CommonAnimPhase {
const playerPokemon = this.scene.getPlayerPokemon();
const enemyPokemon = this.scene.getEnemyPokemon();
const playerImmune = !!playerPokemon.getTypes().filter(t => this.weather.isTypeDamageImmune(t)).length;
const enemyImmune = !!enemyPokemon.getTypes().filter(t => this.weather.isTypeDamageImmune(t)).length;
const playerImmune = !playerPokemon || !!playerPokemon.getTypes().filter(t => this.weather.isTypeDamageImmune(t)).length;
const enemyImmune = !enemyPokemon || !!enemyPokemon.getTypes().filter(t => this.weather.isTypeDamageImmune(t)).length;
if (!this.playerDelayed && !playerImmune)
inflictDamage(playerPokemon);
@ -1291,9 +1291,9 @@ export class FaintPhase extends PokemonPhase {
this.scene.queueMessage(getPokemonMessage(this.getPokemon(), ' fainted!'), null, true);
if (this.player)
this.scene.unshiftPhase(new SwitchPhase(this.scene, true, false));
else
if (this.player) {
this.scene.unshiftPhase(this.scene.getParty().filter(p => p.hp).length ? new SwitchPhase(this.scene, true, false) : new GameOverPhase(this.scene));
} else
this.scene.unshiftPhase(new VictoryPhase(this.scene));
const pokemon = this.getPokemon();
@ -1396,6 +1396,27 @@ export class VictoryPhase extends PokemonPhase {
}
}
export class GameOverPhase extends BattlePhase {
constructor(scene: BattleScene) {
super(scene);
}
start() {
super.start();
this.scene.time.delayedCall(1000, () => {
this.scene.fadeOutBgm(5000, true);
this.scene.ui.fadeOut(5000).then(() => {
this.scene.clearPhaseQueue();
this.scene.ui.clearText();
this.scene.reset();
this.scene.newBattle();
this.end();
});
});
}
}
export class SwitchPhase extends BattlePhase {
private isModal: boolean;
private doReturn: boolean;

View File

@ -37,12 +37,15 @@ export enum Button {
CYCLE_FORM,
CYCLE_GENDER,
QUICK_START,
RANDOM,
AUTO,
SPEED_UP,
SLOW_DOWN
}
interface PokeballCounts {
[pb: string]: integer;
}
export default class BattleScene extends Phaser.Scene {
public auto: boolean;
public gameSpeed: integer = 1;
@ -65,7 +68,7 @@ export default class BattleScene extends Phaser.Scene {
public arena: Arena;
public trainer: Phaser.GameObjects.Sprite;
public currentBattle: Battle;
public pokeballCounts = Object.fromEntries(Utils.getEnumValues(PokeballType).filter(p => p <= PokeballType.MASTER_BALL).map(t => [ t, 0 ]));
public pokeballCounts: PokeballCounts;
private party: PlayerPokemon[];
private waveCountText: Phaser.GameObjects.Text;
private modifierBar: ModifierBar;
@ -302,7 +305,7 @@ export default class BattleScene extends Phaser.Scene {
this.add.existing(this.enemyModifierBar);
uiContainer.add(this.enemyModifierBar);
this.waveCountText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, '1', TextStyle.BATTLE_INFO);
this.waveCountText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, startingWave.toString(), TextStyle.BATTLE_INFO);
this.waveCountText.setOrigin(1, 0);
this.updateWaveCountPosition();
this.fieldUI.add(this.waveCountText);
@ -311,22 +314,14 @@ export default class BattleScene extends Phaser.Scene {
let loadPokemonAssets = [];
const isRandom = this.isButtonPressed(Button.RANDOM); // For testing purposes
this.quickStart = this.quickStart || isRandom || this.isButtonPressed(Button.QUICK_START);
this.quickStart = this.quickStart || this.isButtonPressed(Button.QUICK_START);
if (isRandom) {
const biomes = Utils.getEnumValues(Biome);
this.newArena(biomes[Utils.randInt(biomes.length)]);
} else
this.newArena(startingBiome);
const biomeKey = this.arena.getBiomeKey();
this.arenaBg = this.add.sprite(0, 0, `${biomeKey}_bg`);
this.arenaBgTransition = this.add.sprite(0, 0, `${biomeKey}_bg`);
this.arenaPlayer = this.add.sprite(340, 20, `${biomeKey}_a`);
this.arenaPlayerTransition = this.add.sprite(40, 20, `${biomeKey}_a`);
this.arenaEnemy = this.add.sprite(-240, 13, `${biomeKey}_b`);
this.arenaNextEnemy = this.add.sprite(-240, 13, `${biomeKey}_b`);
this.arenaBg = this.add.sprite(0, 0, 'plains_bg');
this.arenaBgTransition = this.add.sprite(0, 0, `plains_bg`);
this.arenaPlayer = this.add.sprite(0, 0, `plains_a`);
this.arenaPlayerTransition = this.add.sprite(0, 0, `plains_a`);
this.arenaEnemy = this.add.sprite(0, 0, `plains_b`);
this.arenaNextEnemy = this.add.sprite(0, 0, `plains_b`);
this.arenaBgTransition.setVisible(false);
this.arenaPlayerTransition.setVisible(false);
@ -338,9 +333,7 @@ export default class BattleScene extends Phaser.Scene {
if (this.quickStart) {
for (let s = 0; s < 3; s++) {
const playerSpecies = (!isRandom
? getPokemonSpecies((getPokemonSpecies(s === 0 ? Species.TORCHIC : s === 1 ? Species.TREECKO : Species.MUDKIP)).getSpeciesForLevel(startingLevel, true))
: this.randomSpecies(startingWave, startingLevel));
const playerSpecies = getPokemonSpecies((getPokemonSpecies(s === 0 ? Species.TORCHIC : s === 1 ? Species.TREECKO : Species.MUDKIP)).getSpeciesForLevel(startingLevel, true));
const playerPokemon = new PlayerPokemon(this, playerSpecies, startingLevel, 0);
playerPokemon.setVisible(false);
loadPokemonAssets.push(playerPokemon.loadAssets());
@ -356,7 +349,7 @@ export default class BattleScene extends Phaser.Scene {
frameRate: 16
});
const trainer = this.add.sprite(406, 132, 'trainer_m');
const trainer = this.add.sprite(0, 0, 'trainer_m');
trainer.setOrigin(0.5, 1);
field.add(trainer);
@ -371,6 +364,8 @@ export default class BattleScene extends Phaser.Scene {
showOnStart: true
});
this.reset();
const ui = new UI(this);
this.uiContainer.add(ui);
@ -407,7 +402,6 @@ export default class BattleScene extends Phaser.Scene {
[Button.CYCLE_FORM]: [keyCodes.F],
[Button.CYCLE_GENDER]: [keyCodes.G],
[Button.QUICK_START]: [keyCodes.Q],
[Button.RANDOM]: [keyCodes.R],
[Button.AUTO]: [keyCodes.F2],
[Button.SPEED_UP]: [keyCodes.PLUS],
[Button.SLOW_DOWN]: [keyCodes.MINUS]
@ -436,7 +430,44 @@ export default class BattleScene extends Phaser.Scene {
}
getEnemyPokemon(): EnemyPokemon {
return this.currentBattle.enemyPokemon;
return this.currentBattle?.enemyPokemon;
}
reset(): void {
this.pokeballCounts = Object.fromEntries(Utils.getEnumValues(PokeballType).filter(p => p <= PokeballType.MASTER_BALL).map(t => [ t, 0 ]));
this.modifiers = [];
this.enemyModifiers = [];
this.modifierBar.removeAll(true);
this.enemyModifierBar.removeAll(true);
for (let p of this.getParty())
p.destroy();
this.party = [];
for (let p of this.getEnemyParty())
p.destroy();
this.currentBattle = null;
this.waveCountText.setText(startingWave.toString());
this.newArena(startingBiome);
const biomeKey = this.arena.getBiomeKey();
this.arenaBg.setTexture(`${biomeKey}_bg`);
this.arenaBgTransition.setTexture(`${biomeKey}_bg`);
this.arenaPlayer.setTexture(`${biomeKey}_a`);
this.arenaPlayerTransition.setTexture(`${biomeKey}_a`);
this.arenaEnemy.setTexture(`${biomeKey}_b`);
this.arenaNextEnemy.setTexture(`${biomeKey}_b`);
this.arenaBgTransition.setPosition(0, 0);
this.arenaPlayer.setPosition(340, 20);
this.arenaPlayerTransition.setPosition(40, 2);
this.arenaEnemy.setPosition(-240, 13);
this.arenaNextEnemy.setPosition(-240, 13);
this.trainer.setTexture('trainer_m');
this.trainer.setPosition(406, 132);
}
newBattle(): Battle {
@ -565,8 +596,8 @@ export default class BattleScene extends Phaser.Scene {
this.bgm.resume();
}
fadeOutBgm(destroy?: boolean): void {
this.arena.fadeOutBgm(500, destroy);
fadeOutBgm(duration?: integer, destroy?: boolean): void {
this.arena.fadeOutBgm(duration || 500, destroy);
}
playSoundWithoutBgm(soundName: string, pauseDuration?: integer): void {

View File

@ -40,7 +40,7 @@ export class EvolutionPhase extends BattlePhase {
return;
}
this.scene.fadeOutBgm(false);
this.scene.fadeOutBgm(null, false);
this.evolutionContainer = (this.scene.ui.getHandler() as EvolutionSceneHandler).evolutionContainer;

View File

@ -539,60 +539,60 @@ const modifierPool = {
new WeightedModifierType(modifierTypes.POKEBALL, 6),
new WeightedModifierType(modifierTypes.RARE_CANDY, 2),
new WeightedModifierType(modifierTypes.POTION, (party: Pokemon[]) => {
const thresholdPartyMemberCount = party.filter(p => p.getInverseHp() >= 10 || p.getHpRatio() <= 0.875).length;
const thresholdPartyMemberCount = Math.min(party.filter(p => p.getInverseHp() >= 10 || p.getHpRatio() <= 0.875).length, 3);
return thresholdPartyMemberCount * 3;
}),
new WeightedModifierType(modifierTypes.SUPER_POTION, (party: Pokemon[]) => {
const thresholdPartyMemberCount = party.filter(p => p.getInverseHp() >= 25 || p.getHpRatio() <= 0.75).length;
const thresholdPartyMemberCount = Math.min(party.filter(p => p.getInverseHp() >= 25 || p.getHpRatio() <= 0.75).length, 3);
return thresholdPartyMemberCount;
}),
new WeightedModifierType(modifierTypes.ETHER, (party: Pokemon[]) => {
const thresholdPartyMemberCount = party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length;
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length, 3);
return thresholdPartyMemberCount * 3;
}),
new WeightedModifierType(modifierTypes.MAX_ETHER, (party: Pokemon[]) => {
const thresholdPartyMemberCount = party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length;
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length, 3);
return thresholdPartyMemberCount;
}),
new WeightedModifierType(modifierTypes.TEMP_STAT_BOOSTER, 4),
new WeightedModifierType(modifierTypes.BERRY, 2)
].map(m => { m.setTier(ModifierTier.COMMON); return m; }),
[ModifierTier.GREAT]: [
new WeightedModifierType(modifierTypes.GREAT_BALL, 12),
new WeightedModifierType(modifierTypes.GREAT_BALL, 6),
new WeightedModifierType(modifierTypes.FULL_HEAL, (party: Pokemon[]) => {
const statusEffectPartyMemberCount = party.filter(p => p.hp && !!p.status).length;
return statusEffectPartyMemberCount * 8;
const statusEffectPartyMemberCount = Math.min(party.filter(p => p.hp && !!p.status).length, 3);
return statusEffectPartyMemberCount * 6;
}),
new WeightedModifierType(modifierTypes.REVIVE, (party: Pokemon[]) => {
const faintedPartyMemberCount = party.filter(p => !p.hp).length;
return faintedPartyMemberCount * 6;
const faintedPartyMemberCount = Math.min(party.filter(p => !p.hp).length, 3);
return faintedPartyMemberCount * 9;
}),
new WeightedModifierType(modifierTypes.MAX_REVIVE, (party: Pokemon[]) => {
const faintedPartyMemberCount = party.filter(p => !p.hp).length;
return faintedPartyMemberCount * 2;
const faintedPartyMemberCount = Math.min(party.filter(p => !p.hp).length, 3);
return faintedPartyMemberCount * 3;
}),
new WeightedModifierType(modifierTypes.SACRED_ASH, (party: Pokemon[]) => {
return party.filter(p => !p.hp).length >= Math.ceil(party.length / 2) ? 1 : 0;
}),
new WeightedModifierType(modifierTypes.HYPER_POTION, (party: Pokemon[]) => {
const thresholdPartyMemberCount = party.filter(p => p.getInverseHp() >= 100 || p.getHpRatio() <= 0.625).length;
return thresholdPartyMemberCount * 2;
const thresholdPartyMemberCount = Math.min(party.filter(p => p.getInverseHp() >= 100 || p.getHpRatio() <= 0.625).length, 3);
return thresholdPartyMemberCount * 3;
}),
new WeightedModifierType(modifierTypes.MAX_POTION, (party: Pokemon[]) => {
const thresholdPartyMemberCount = party.filter(p => p.getInverseHp() >= 150 || p.getHpRatio() <= 0.5).length;
return Math.ceil(thresholdPartyMemberCount / 1.5);
const thresholdPartyMemberCount = Math.min(party.filter(p => p.getInverseHp() >= 150 || p.getHpRatio() <= 0.5).length, 3);
return thresholdPartyMemberCount;
}),
new WeightedModifierType(modifierTypes.ELIXIR, (party: Pokemon[]) => {
const thresholdPartyMemberCount = party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length;
return thresholdPartyMemberCount * 2;
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length, 3);
return thresholdPartyMemberCount * 3;
}),
new WeightedModifierType(modifierTypes.MAX_ELIXIR, (party: Pokemon[]) => {
const thresholdPartyMemberCount = party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length;
return Math.ceil(thresholdPartyMemberCount / 1.5);
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length, 3);
return thresholdPartyMemberCount;
}),
new WeightedModifierType(modifierTypes.TM, 4),
new WeightedModifierType(modifierTypes.EXP_SHARE, 2),
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 4)
new WeightedModifierType(modifierTypes.TM, 2),
modifierTypes.EXP_SHARE,
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3)
].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
[ModifierTier.ULTRA]: [
new WeightedModifierType(modifierTypes.ULTRA_BALL, 8),

View File

@ -78,7 +78,7 @@ export abstract class PersistentModifier extends Modifier {
add(modifiers: PersistentModifier[], virtual: boolean): boolean {
for (let modifier of modifiers) {
if (this.match(modifier))
return modifier.incrementStack(modifier.stackCount, virtual);
return modifier.incrementStack(this.stackCount, virtual);
}
if (virtual) {

View File

@ -536,5 +536,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
super.clear();
this.cursor = -1;
this.starterSelectContainer.setVisible(false);
while (this.starterCursors.length)
this.popStarter();
}
}

View File

@ -43,7 +43,7 @@ export default class UI extends Phaser.GameObjects.Container {
private handlers: UiHandler[];
private overlay: Phaser.GameObjects.Rectangle;
private transitioning: boolean;
private overlayActive: boolean;
constructor(scene: BattleScene) {
super(scene, 0, scene.game.canvas.height / 6);
@ -83,7 +83,7 @@ export default class UI extends Phaser.GameObjects.Container {
}
processInput(button: Button): void {
if (this.transitioning)
if (this.overlayActive)
return;
this.getHandler().processInput(button);
@ -121,6 +121,41 @@ export default class UI extends Phaser.GameObjects.Container {
this.scene.sound.play('error');
}
fadeOut(duration: integer): Promise<void> {
return new Promise(resolve => {
if (this.overlayActive) {
resolve();
return;
}
this.overlayActive = true;
this.overlay.setAlpha(0);
this.overlay.setVisible(true);
this.scene.tweens.add({
targets: this.overlay,
alpha: 1,
duration: duration,
ease: 'Sine.easeOut',
onComplete: () => resolve()
});
});
}
fadeIn(duration: integer): Promise<void> {
return new Promise(resolve => {
this.scene.tweens.add({
targets: this.overlay,
alpha: 0,
duration: duration,
ease: 'Sine.easeIn',
onComplete: () => {
this.overlay.setVisible(false);
resolve();
}
});
this.overlayActive = false;
});
}
private setModeInternal(mode: Mode, clear: boolean, forceTransition: boolean, args: any[]): Promise<void> {
return new Promise(resolve => {
if (this.mode === mode && !forceTransition) {
@ -138,28 +173,12 @@ export default class UI extends Phaser.GameObjects.Container {
};
if ((transitionModes.indexOf(this.mode) > -1 || transitionModes.indexOf(mode) > -1)
&& (noTransitionModes.indexOf(this.mode) === -1 && noTransitionModes.indexOf(mode) === -1) && !(this.scene as BattleScene).auto) {
this.transitioning = true;
this.overlay.setAlpha(0);
this.overlay.setVisible(true);
this.scene.tweens.add({
targets: this.overlay,
alpha: 1,
duration: 250,
ease: 'Sine.easeOut',
onComplete: () => {
this.scene.time.delayedCall(100, () => {
doSetMode();
this.scene.tweens.add({
targets: this.overlay,
alpha: 0,
duration: 250,
ease: 'Sine.easeIn',
onComplete: () => this.overlay.setVisible(false)
});
this.transitioning = false;
});
}
});
this.fadeOut(250).then(() => {
this.scene.time.delayedCall(100, () => {
doSetMode();
this.fadeIn(250);
});
})
} else
doSetMode();
});