More work on double battles for stability

This commit is contained in:
Flashfyre 2023-05-17 11:10:09 -04:00
parent 05432181b6
commit 40cdf64271
7 changed files with 118 additions and 47 deletions

View File

@ -75,7 +75,7 @@ export class CheckLoadPhase extends BattlePhase {
this.scene.pushPhase(new EncounterPhase(this.scene, this.loaded));
this.scene.pushPhase(new SummonPhase(this.scene, 0));
if (this.scene.currentBattle.double)
if (this.scene.currentBattle.double && this.scene.getParty().filter(p => !p.isFainted()).length > 1)
this.scene.pushPhase(new SummonPhase(this.scene, 1));
super.end();
@ -320,10 +320,6 @@ export class NextEncounterPhase extends EncounterPhase {
this.scene.unshiftPhase(new ShinySparklePhase(this.scene, BattlerIndex.ENEMY + e));
});
this.scene.unshiftPhase(new CheckSwitchPhase(this.scene, 0));
if (this.scene.currentBattle.double)
this.scene.unshiftPhase(new CheckSwitchPhase(this.scene, 1));
super.end();
}
}
@ -475,34 +471,35 @@ export class SummonPhase extends PartyMemberPokemonPhase {
const playerPokemon = this.getPokemon();
if (this.fieldIndex === 1) {
this.scene.getPlayerField()[0].setFieldPosition(FieldPosition.LEFT, 250);
if (this.fieldIndex === 1)
playerPokemon.setFieldPosition(FieldPosition.RIGHT, 0);
} else
else
playerPokemon.setFieldPosition(!this.scene.currentBattle.double ? FieldPosition.CENTER : FieldPosition.LEFT);
const xOffset = playerPokemon.getFieldPositionOffset()[0];
const fpOffset = playerPokemon.getFieldPositionOffset();
console.log(fpOffset);
pokeball.setVisible(true);
this.scene.tweens.add({
targets: pokeball,
duration: 650,
x: 100 + xOffset
x: 100 + fpOffset[0]
});
this.scene.tweens.add({
targets: pokeball,
duration: 150,
ease: 'Cubic.easeOut',
y: 70,
y: 70 + fpOffset[1],
onComplete: () => {
this.scene.tweens.add({
targets: pokeball,
duration: 500,
ease: 'Cubic.easeIn',
angle: 1440,
y: 132,
y: 132 + fpOffset[1],
onComplete: () => {
this.scene.sound.play('pb_rel');
pokeball.destroy();
@ -565,10 +562,6 @@ export class SwitchSummonPhase extends SummonPhase {
this.batonPass = batonPass;
}
start() {
super.start();
}
preSummon(): void {
if (!this.doReturn) {
this.switchAndSummon();
@ -619,12 +612,48 @@ export class SwitchSummonPhase extends SummonPhase {
if (this.batonPass)
this.getPokemon().transferSummon(this.lastPokemon);
this.lastPokemon.resetSummonData();
this.lastPokemon?.resetSummonData();
super.end();
}
}
export class ReturnPhase extends SwitchSummonPhase {
constructor(scene: BattleScene, fieldIndex: integer) {
super(scene, fieldIndex, -1, true, false);
}
switchAndSummon(): void {
this.end();
}
summon(): void { }
}
export class ToggleDoublePositionPhase extends BattlePhase {
private double: boolean;
constructor(scene: BattleScene, double: boolean) {
super(scene);
this.double = double;
}
start() {
super.start();
const playerPokemon = this.scene.getPlayerPokemon();
playerPokemon.setFieldPosition(this.double ? FieldPosition.LEFT : FieldPosition.CENTER, 500).then(() => {
if (!this.double && playerPokemon.getFieldIndex() === 1) {
const party = this.scene.getParty();
party[1] = party[0];
party[0] = playerPokemon;
}
this.end();
});
}
}
export class CheckSwitchPhase extends BattlePhase {
protected fieldIndex: integer;
@ -788,8 +817,13 @@ export class CommandPhase extends FieldPhase {
this.scene.ui.setMode(Mode.COMMAND);
}, null, true);
} else if (cursor < 4) {
const targets = this.scene.getEnemyField().filter(p => p.isActive()).map(p => p.getBattlerIndex());
this.scene.currentBattle.turnCommands[this.fieldIndex] = { command: Command.BALL, cursor: cursor };
this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex))
this.scene.currentBattle.turnPokeballCounts[cursor as PokeballType]--;
if (targets.length > 1)
this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex));
else
this.scene.currentBattle.turnCommands[this.fieldIndex].targets = targets;
success = true;
}
break;
@ -859,14 +893,17 @@ export class SelectTargetPhase extends PokemonPhase {
start() {
super.start();
const move = this.scene.currentBattle.turnCommands[this.fieldIndex].move?.move;
const turnCommand = this.scene.currentBattle.turnCommands[this.fieldIndex];
const move = turnCommand.move?.move;
this.scene.ui.setMode(Mode.TARGET_SELECT, this.fieldIndex, move, (cursor: integer) => {
this.scene.ui.setMode(Mode.MESSAGE);
if (cursor === -1) {
if (turnCommand.command === Command.BALL)
this.scene.currentBattle.turnPokeballCounts[turnCommand.cursor]++;
this.scene.currentBattle.turnCommands[this.fieldIndex] = null;
this.scene.unshiftPhase(new CommandPhase(this.scene, this.fieldIndex));
} else
this.scene.currentBattle.turnCommands[this.fieldIndex].targets = [ cursor ];
turnCommand.targets = [ cursor ];
this.end();
});
}
@ -965,7 +1002,7 @@ export class TurnEndPhase extends FieldPhase {
start() {
super.start();
this.scene.currentBattle.incrementTurn();
this.scene.currentBattle.incrementTurn(this.scene);
const handlePokemon = (pokemon: Pokemon) => {
pokemon.lapseTags(BattlerTagLapseType.TURN_END);
@ -1001,10 +1038,6 @@ export class TurnEndPhase extends FieldPhase {
}
export class BattleEndPhase extends BattlePhase {
constructor(scene: BattleScene) {
super(scene);
}
start() {
super.start();
@ -1025,6 +1058,16 @@ export class BattleEndPhase extends BattlePhase {
}
}
export class NewBattlePhase extends BattlePhase {
start() {
super.start();
this.scene.newBattle();
this.end();
}
}
export class CommonAnimPhase extends PokemonPhase {
private anim: CommonAnim;
private targetIndex: integer;
@ -1331,7 +1374,7 @@ class MoveEffectPhase extends PokemonPhase {
}
getTargets(): Pokemon[] {
return this.scene.getField().filter(p => this.targets.indexOf(p.getBattlerIndex()) > -1);
return this.scene.getField().filter(p => p?.isActive() && this.targets.indexOf(p.getBattlerIndex()) > -1);
}
getTarget(): Pokemon {
@ -1789,7 +1832,7 @@ export class VictoryPhase extends PokemonPhase {
this.scene.pushPhase(new BattleEndPhase(this.scene));
if (this.scene.currentBattle.waveIndex < this.scene.finalWave) {
this.scene.pushPhase(new SelectModifierPhase(this.scene));
this.scene.newBattle();
this.scene.pushPhase(new NewBattlePhase(this.scene));
} else
this.scene.pushPhase(new GameOverPhase(this.scene, true));
}
@ -2330,7 +2373,7 @@ export class AttemptRunPhase extends PokemonPhase {
enemyField.forEach(enemyPokemon => enemyPokemon.hp = 0);
this.scene.pushPhase(new BattleEndPhase(this.scene));
this.scene.newBattle();
this.scene.pushPhase(new NewBattlePhase(this.scene));
} else
this.scene.queueMessage('You can\'t escape!', null, true);
@ -2350,7 +2393,7 @@ export class SelectModifierPhase extends BattlePhase {
regenerateModifierPoolThresholds(party);
const modifierCount = new Utils.IntegerHolder(3);
this.scene.applyModifiers(ExtraModifierModifier, true, modifierCount);
const typeOptions: Array<ModifierTypeOption> = getPlayerModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex - 1, modifierCount.value, party);
const typeOptions: Array<ModifierTypeOption> = getPlayerModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, modifierCount.value, party);
const modifierSelectCallback = (cursor: integer) => {
if (cursor < 0) {

View File

@ -1,8 +1,8 @@
import Phaser from 'phaser';
import { Biome } from './data/biome';
import UI from './ui/ui';
import { EncounterPhase, SummonPhase, NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, CheckLoadPhase, TurnInitPhase } from './battle-phases';
import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon';
import { EncounterPhase, SummonPhase, NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, CheckLoadPhase, TurnInitPhase, ReturnPhase, ToggleDoublePositionPhase, CheckSwitchPhase } from './battle-phases';
import Pokemon, { PlayerPokemon, EnemyPokemon, FieldPosition } from './pokemon';
import PokemonSpecies, { allSpecies, getPokemonSpecies, initSpecies } from './data/pokemon-species';
import * as Utils from './utils';
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate } from './modifier/modifier';
@ -510,10 +510,21 @@ export default class BattleScene extends Phaser.Scene {
}
newBattle(waveIndex?: integer, double?: boolean): Battle {
double = (waveIndex || ((this.currentBattle?.waveIndex || (startingWave - 1)) + 1)) % 2 === 0;
const isDouble = double === undefined || double;
console.log(this.currentBattle?.waveIndex);
const lastBattle = this.currentBattle;
this.currentBattle = new Battle(waveIndex || ((this.currentBattle?.waveIndex || (startingWave - 1)) + 1), isDouble);
this.currentBattle.incrementTurn(this);
if (!waveIndex) {
if (this.currentBattle) {
if (lastBattle) {
this.getEnemyField().forEach(enemyPokemon => enemyPokemon.destroy());
if (this.currentBattle.waveIndex % 10)
if (lastBattle.waveIndex % 10)
this.pushPhase(new NextEncounterPhase(this));
else {
this.pushPhase(new SelectBiomePhase(this));
@ -526,13 +537,28 @@ export default class BattleScene extends Phaser.Scene {
this.arena.playBgm();
this.pushPhase(new EncounterPhase(this));
this.pushPhase(new SummonPhase(this, 0));
if (double === undefined || double)
this.pushPhase(new SummonPhase(this, 1));
}
}
}
this.currentBattle = new Battle(waveIndex || ((this.currentBattle?.waveIndex || (startingWave - 1)) + 1), double === undefined || double);
if ((lastBattle?.double || false) !== isDouble) {
const availablePartyMemberCount = this.getParty().filter(p => !p.isFainted()).length;
if (isDouble) {
this.pushPhase(new ToggleDoublePositionPhase(this, true));
if (availablePartyMemberCount > 1)
this.pushPhase(new SummonPhase(this, 1));
} else {
if (availablePartyMemberCount > 1)
this.pushPhase(new ReturnPhase(this, 1));
this.pushPhase(new ToggleDoublePositionPhase(this, false));
}
}
if (lastBattle) {
this.pushPhase(new CheckSwitchPhase(this, 0));
if (lastBattle.double && isDouble)
this.pushPhase(new CheckSwitchPhase(this, 1));
}
}
return this.currentBattle;
}
@ -875,7 +901,7 @@ export default class BattleScene extends Phaser.Scene {
modifiers.splice(modifiers.indexOf(modifier), 1);
}
this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyField()).then(() => {
this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyField().filter(p => p.isActive())).then(() => {
(player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers);
if (!player)
this.updateWaveCountPosition();

View File

@ -1,3 +1,4 @@
import BattleScene, { PokeballCounts } from "./battle-scene";
import { EnemyPokemon, PlayerPokemon, QueuedMove } from "./pokemon";
import { Command } from "./ui/command-ui-handler";
import * as Utils from "./utils";
@ -28,6 +29,7 @@ export default class Battle {
public double: boolean;
public turn: integer;
public turnCommands: TurnCommands;
public turnPokeballCounts: PokeballCounts;
public playerParticipantIds: Set<integer> = new Set<integer>();
public escapeAttempts: integer = 0;
@ -37,8 +39,6 @@ export default class Battle {
this.enemyField = [];
this.double = double;
this.turn = 0;
this.incrementTurn();
}
private getLevelForWave(): number {
@ -59,9 +59,10 @@ export default class Battle {
return this.double ? 2 : 1;
}
incrementTurn(): void {
incrementTurn(scene: BattleScene): void {
this.turn++;
this.turnCommands = Object.fromEntries(Utils.getEnumValues(BattlerIndex).map(bt => [ bt, null ]));
this.turnPokeballCounts = Object.assign({}, scene.pokeballCounts);
}
addParticipant(playerPokemon: PlayerPokemon): void {

View File

@ -2130,7 +2130,7 @@ export type MoveTargetSet = {
}
export function getMoveTargets(user: Pokemon, move: Moves): MoveTargetSet {
const moveTarget = move ? allMoves[move].moveTarget : move === undefined ? undefined : MoveTarget.NEAR_ENEMY;
const moveTarget = move ? allMoves[move].moveTarget : move === undefined ? MoveTarget.NEAR_ENEMY : [];
const opponents = user.getOpponents();
let set: BattlerIndex[] = [];

View File

@ -474,7 +474,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
setMove(moveIndex: integer, moveId: Moves): void {
const move = moveId ? new PokemonMove(moveId) : null;
this.moveset[moveIndex] = move;
if (this.summonData.moveset)
if (this.summonData?.moveset)
this.summonData.moveset[moveIndex] = move;
}

View File

@ -60,12 +60,12 @@ export default class BallUiHandler extends UiHandler {
let success = false;
const pokeballTypeCount = Object.keys(this.scene.pokeballCounts).length;
const pokeballTypeCount = Object.keys(this.scene.currentBattle.turnPokeballCounts).length;
if (button === Button.ACTION || button === Button.CANCEL) {
success = true;
if (button === Button.ACTION && this.cursor < pokeballTypeCount) {
if (this.scene.pokeballCounts[this.cursor]) {
if (this.scene.currentBattle.turnPokeballCounts[this.cursor]) {
if ((this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.BALL, this.cursor)) {
this.scene.ui.setMode(Mode.COMMAND);
this.scene.ui.setMode(Mode.MESSAGE);
@ -93,7 +93,7 @@ export default class BallUiHandler extends UiHandler {
}
updateCounts() {
this.countsText.setText(Object.values(this.scene.pokeballCounts).map(c => `x${c}`).join('\n'));
this.countsText.setText(Object.values(this.scene.currentBattle.turnPokeballCounts).map(c => `x${c}`).join('\n'));
}
setCursor(cursor: integer): boolean {

View File

@ -120,10 +120,11 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
}
this.hpBar.setScale(pokemon.getHpRatio(), 1);
this.lastHpFrame = this.hpBar.scaleX > 0.5 ? 'high' : this.hpBar.scaleX > 0.25 ? 'medium' : 'low';
this.hpBar.setFrame(this.lastHpFrame);
if (this.player)
this.setHpNumbers(pokemon.hp, pokemon.getMaxHp());
this.lastHp = pokemon.hp;
this.lastHpFrame = this.hpBar.scaleX > 0.5 ? 'high' : this.hpBar.scaleX > 0.25 ? 'medium' : 'low';
this.lastMaxHp = pokemon.getMaxHp();
this.setLevel(pokemon.level);