Remove some legacy features and fix a crash

Remove legacy autoplay and quick start features; fix crash related to leech seed on missing source
pull/16/head
Flashfyre 2024-02-27 15:16:06 -05:00
parent 01938dcf83
commit 8bee927e08
4 changed files with 15 additions and 318 deletions

View File

@ -6,7 +6,6 @@ import PokemonSpecies, { PokemonSpeciesFilter, SpeciesFormKey, allSpecies, getPo
import * as Utils from './utils'; import * as Utils from './utils';
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier } from './modifier/modifier'; import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier } from './modifier/modifier';
import { PokeballType } from './data/pokeball'; import { PokeballType } from './data/pokeball';
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';
import { Phase } from './phase'; import { Phase } from './phase';
import { initGameSpeed } from './system/game-speed'; import { initGameSpeed } from './system/game-speed';
@ -53,8 +52,6 @@ import { getTypeRgb } from './data/type';
import PokemonSpriteSparkleHandler from './sprite/pokemon-sprite-sparkle-handler'; import PokemonSpriteSparkleHandler from './sprite/pokemon-sprite-sparkle-handler';
import CharSprite from './ui/char-sprite'; import CharSprite from './ui/char-sprite';
const enableAuto = true;
const quickStart = false;
export const bypassLogin = false; export const bypassLogin = false;
export const startingLevel = 5; export const startingLevel = 5;
export const startingWave = 1; export const startingWave = 1;
@ -77,8 +74,6 @@ export enum Button {
CYCLE_GENDER, CYCLE_GENDER,
CYCLE_ABILITY, CYCLE_ABILITY,
CYCLE_NATURE, CYCLE_NATURE,
QUICK_START,
AUTO,
SPEED_UP, SPEED_UP,
SLOW_DOWN SLOW_DOWN
} }
@ -92,7 +87,6 @@ export type AnySound = Phaser.Sound.WebAudioSound | Phaser.Sound.HTML5AudioSound
export default class BattleScene extends Phaser.Scene { export default class BattleScene extends Phaser.Scene {
public rexUI: UIPlugin; public rexUI: UIPlugin;
public auto: boolean;
public sessionPlayTime: integer = null; public sessionPlayTime: integer = null;
public masterVolume: number = 0.5; public masterVolume: number = 0.5;
public bgmVolume: number = 1; public bgmVolume: number = 1;
@ -104,7 +98,6 @@ export default class BattleScene extends Phaser.Scene {
public experimentalSprites: boolean = false; public experimentalSprites: boolean = false;
public enableTouchControls: boolean = false; public enableTouchControls: boolean = false;
public enableVibration: boolean = false; public enableVibration: boolean = false;
public quickStart: boolean = quickStart;
public finalWave: integer = 200; public finalWave: integer = 200;
public gameData: GameData; public gameData: GameData;
@ -551,8 +544,6 @@ export default class BattleScene extends Phaser.Scene {
let loadPokemonAssets = []; let loadPokemonAssets = [];
this.quickStart = this.quickStart || this.isButtonPressed(Button.QUICK_START);
this.arenaPlayer = new ArenaBase(this, true); this.arenaPlayer = new ArenaBase(this, true);
this.arenaPlayerTransition = new ArenaBase(this, true); this.arenaPlayerTransition = new ArenaBase(this, true);
this.arenaEnemy = new ArenaBase(this, false); this.arenaEnemy = new ArenaBase(this, false);
@ -594,19 +585,6 @@ export default class BattleScene extends Phaser.Scene {
this.reset(); this.reset();
if (this.quickStart) {
this.newBattle();
for (let s = 0; s < 3; s++) {
const playerSpecies = this.randomSpecies(startingWave, startingLevel);
const playerPokemon = this.addPlayerPokemon(playerSpecies, startingLevel, 0, 0);
playerPokemon.setVisible(false);
this.party.push(playerPokemon);
loadPokemonAssets.push(playerPokemon.loadAssets());
}
}
const ui = new UI(this); const ui = new UI(this);
this.uiContainer.add(ui); this.uiContainer.add(ui);
@ -619,16 +597,10 @@ export default class BattleScene extends Phaser.Scene {
initCommonAnims().then(() => loadCommonAnimAssets(this, true)), initCommonAnims().then(() => loadCommonAnimAssets(this, true)),
initMoveAnim(Moves.STRUGGLE).then(() => loadMoveAnimAssets(this, [ Moves.STRUGGLE ], true)) initMoveAnim(Moves.STRUGGLE).then(() => loadMoveAnimAssets(this, [ Moves.STRUGGLE ], true))
]).then(() => { ]).then(() => {
if (enableAuto)
initAutoPlay.apply(this);
if (!this.quickStart) {
this.pushPhase(new LoginPhase(this)); this.pushPhase(new LoginPhase(this));
if (!bypassLogin) if (!bypassLogin)
this.pushPhase(new ConsolidateDataPhase(this)); // TODO: Remove this.pushPhase(new ConsolidateDataPhase(this)); // TODO: Remove
this.pushPhase(new CheckLoadPhase(this)); this.pushPhase(new CheckLoadPhase(this));
} else
this.pushPhase(new EncounterPhase(this));
this.shiftPhase(); this.shiftPhase();
}); });
@ -680,8 +652,6 @@ export default class BattleScene extends Phaser.Scene {
[Button.CYCLE_GENDER]: [keyCodes.G], [Button.CYCLE_GENDER]: [keyCodes.G],
[Button.CYCLE_ABILITY]: [keyCodes.E], [Button.CYCLE_ABILITY]: [keyCodes.E],
[Button.CYCLE_NATURE]: [keyCodes.N], [Button.CYCLE_NATURE]: [keyCodes.N],
[Button.QUICK_START]: [keyCodes.Q],
[Button.AUTO]: [keyCodes.F2],
[Button.SPEED_UP]: [keyCodes.PLUS], [Button.SPEED_UP]: [keyCodes.PLUS],
[Button.SLOW_DOWN]: [keyCodes.MINUS] [Button.SLOW_DOWN]: [keyCodes.MINUS]
}; };
@ -1252,15 +1222,6 @@ export default class BattleScene extends Phaser.Scene {
if (this.ui.getMode() === Mode.SETTINGS) if (this.ui.getMode() === Mode.SETTINGS)
(this.ui.getHandler() as SettingsUiHandler).show([]); (this.ui.getHandler() as SettingsUiHandler).show([]);
} }
} else if (enableAuto) {
if (this.isButtonPressed(Button.AUTO)) {
this.auto = !this.auto;
if (this.auto)
this.gameSpeed = Math.floor(this.gameSpeed);
else if (this.gameSpeed > 5)
this.gameSpeed = 5;
} else
return;
} else } else
return; return;
if (inputSuccess && this.enableVibration) if (inputSuccess && this.enableVibration)

View File

@ -243,6 +243,8 @@ export class InfatuatedTag extends BattlerTag {
} }
export class SeedTag extends BattlerTag { export class SeedTag extends BattlerTag {
private sourceIndex: integer;
constructor(sourceId: integer) { constructor(sourceId: integer) {
super(BattlerTagType.SEEDED, BattlerTagLapseType.AFTER_MOVE, 1, Moves.LEECH_SEED, sourceId); super(BattlerTagType.SEEDED, BattlerTagLapseType.AFTER_MOVE, 1, Moves.LEECH_SEED, sourceId);
} }
@ -251,13 +253,15 @@ export class SeedTag extends BattlerTag {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' was seeded!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' was seeded!'));
this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex();
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) { if (ret) {
const source = pokemon.scene.getPokemonById(this.sourceId); const source = pokemon.getOpponents().find(o => o.getBattlerIndex() === this.sourceIndex);
if (source) {
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, source.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.LEECH_SEED)); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, source.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.LEECH_SEED));
const damage = Math.max(Math.floor(pokemon.getMaxHp() / 8), 1); const damage = Math.max(Math.floor(pokemon.getMaxHp() / 8), 1);
@ -265,6 +269,7 @@ export class SeedTag extends BattlerTag {
pokemon.damage(damage); pokemon.damage(damage);
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, source.getBattlerIndex(), damage, getPokemonMessage(pokemon, '\'s health is\nsapped by Leech Seed!'), false, true)); pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, source.getBattlerIndex(), damage, getPokemonMessage(pokemon, '\'s health is\nsapped by Leech Seed!'), false, true));
} }
}
return ret; return ret;
} }

View File

@ -1,266 +0,0 @@
import { SelectModifierPhase } from "../phases";
import BattleScene, { Button } from "../battle-scene";
import { ModifierType, ModifierTypeOption, PokemonBaseStatBoosterModifierType, PokemonHpRestoreModifierType, PokemonReviveModifierType } from "../modifier/modifier-type";
import Pokemon, { AiType, EnemyPokemon, PlayerPokemon, PokemonMove } from "../pokemon";
import { Species } from "../data/enums/species";
import BattleMessageUiHandler from "../ui/battle-message-ui-handler";
import CommandUiHandler from "../ui/command-ui-handler";
import FightUiHandler from "../ui/fight-ui-handler";
import MessageUiHandler from "../ui/message-ui-handler";
import ModifierSelectUiHandler from "../ui/modifier-select-ui-handler";
import PartyUiHandler, { PartyUiMode } from "../ui/party-ui-handler";
import ConfirmUiHandler from "../ui/confirm-ui-handler";
import { Mode } from "../ui/ui";
import { ModifierTier } from "../modifier/modifier-tier";
export function initAutoPlay() {
const thisArg = this as BattleScene;
PlayerPokemon.prototype.getNextMove = EnemyPokemon.prototype.getNextMove;
const playerPokemon = this.getParty()[0] as PlayerPokemon;
const messageUiHandler = this.ui.handlers[Mode.MESSAGE] as BattleMessageUiHandler;
const commandUiHandler = this.ui.handlers[Mode.COMMAND] as CommandUiHandler;
const fightUiHandler = this.ui.handlers[Mode.FIGHT] as FightUiHandler;
const partyUiHandler = this.ui.handlers[Mode.PARTY] as PartyUiHandler;
const confirmUiHandler = this.ui.handlers[Mode.CONFIRM] as ConfirmUiHandler;
const modifierSelectUiHandler = this.ui.handlers[Mode.MODIFIER_SELECT] as ModifierSelectUiHandler;
const getBestPartyMemberIndex = () => {
const enemyPokemon = thisArg.getEnemyPokemon();
const party = thisArg.getParty();
let bestPartyMemberIndex = -1;
let bestPartyMemberEffectiveness = 0.5;
for (let p = 0; p < party.length; p++) {
const pokemon = party[p];
if (pokemon.getHpRatio() <= 0.2)
continue;
const effectiveness = enemyPokemon
? getMaxMoveEffectiveness(pokemon, enemyPokemon) / getMaxMoveEffectiveness(enemyPokemon, pokemon)
: 1;
if (effectiveness > bestPartyMemberEffectiveness) {
bestPartyMemberIndex = p;
bestPartyMemberEffectiveness = effectiveness;
}
if (enemyPokemon)
console.log(p, Species[pokemon.species.speciesId], '->', Species[enemyPokemon.species.speciesId], effectiveness);
}
if (bestPartyMemberIndex === -1) {
let highestHpValue = -1;
for (let p = 0; p < party.length; p++) {
const pokemon = party[p];
if (pokemon.hp > highestHpValue) {
highestHpValue = pokemon.hp;
bestPartyMemberIndex = p;
}
}
}
return bestPartyMemberIndex;
};
const getMaxMoveEffectiveness = (attacker: Pokemon, defender: Pokemon) => {
let maxEffectiveness = 0.5;
for (let m of attacker.getMoveset()) {
const moveType = m.getMove().type;
const effectiveness = defender.getAttackMoveEffectiveness(moveType);
if (effectiveness > maxEffectiveness)
maxEffectiveness = effectiveness;
}
return maxEffectiveness;
};
let nextPartyMemberIndex = -1;
const originalMessageUiHandlerShowText = MessageUiHandler.prototype.showText;
MessageUiHandler.prototype.showText = function (text: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer) {
if (thisArg.auto) {
delay = 1;
callbackDelay = 0;
promptDelay = 0;
}
originalMessageUiHandlerShowText.apply(this, [ text, delay, callback, callbackDelay, prompt, promptDelay ]);
};
const originalMessageUiHandlerShowPrompt = MessageUiHandler.prototype.showPrompt;
MessageUiHandler.prototype.showPrompt = function (callback: Function, callbackDelay: integer) {
if (thisArg.auto)
callbackDelay = 0;
originalMessageUiHandlerShowPrompt.apply(this, [ callback, callbackDelay ]);
if (thisArg.auto)
thisArg.time.delayedCall(20, () => this.processInput(Button.ACTION));
};
const originalMessageUiHandlerPromptLevelUpStats = messageUiHandler.promptLevelUpStats;
messageUiHandler.promptLevelUpStats = function (partyMemberIndex: integer, prevStats: integer[], showTotals: boolean): Promise<void> {
return new Promise(resolve => {
originalMessageUiHandlerPromptLevelUpStats.apply(this, [ partyMemberIndex, prevStats, showTotals ]).then(() => resolve());
if (thisArg.auto)
thisArg.time.delayedCall(20, () => this.processInput(Button.ACTION));
});
};
const originalCommandUiHandlerShow = commandUiHandler.show;
commandUiHandler.show = function (args: any[]) {
originalCommandUiHandlerShow.apply(this, [ args ]);
if (thisArg.auto) {
thisArg.time.delayedCall(20, () => {
const bestPartyMemberIndex = getBestPartyMemberIndex();
if (bestPartyMemberIndex) {
console.log(bestPartyMemberIndex, thisArg.getParty())
console.log('Switching to ', Species[thisArg.getParty()[bestPartyMemberIndex].species.speciesId]);
nextPartyMemberIndex = bestPartyMemberIndex;
commandUiHandler.setCursor(2);
thisArg.time.delayedCall(20, () => this.processInput(Button.ACTION));
} else {
commandUiHandler.setCursor(0);
thisArg.time.delayedCall(20, () => this.processInput(Button.ACTION));
}
});
}
};
const originalFightUiHandlerShow = fightUiHandler.show;
fightUiHandler.show = function (args: any[]) {
originalFightUiHandlerShow.apply(this, [ args ]);
if (thisArg.auto) {
if (!playerPokemon.aiType)
playerPokemon.aiType = AiType.SMART;
thisArg.time.delayedCall(20, () => {
const nextMove = playerPokemon.getNextMove() as PokemonMove;
fightUiHandler.setCursor(playerPokemon.getMoveset().indexOf(nextMove));
thisArg.time.delayedCall(20, () => this.processInput(Button.ACTION));
});
}
};
const originalPartyUiHandlerShow = partyUiHandler.show;
partyUiHandler.show = function (args: any[]) {
originalPartyUiHandlerShow.apply(this, [ args ]);
if (thisArg.auto) {
thisArg.time.delayedCall(20, () => {
if (nextPartyMemberIndex === -1)
nextPartyMemberIndex = getBestPartyMemberIndex();
partyUiHandler.setCursor(nextPartyMemberIndex);
nextPartyMemberIndex = -1;
if ((partyUiHandler.partyUiMode === PartyUiMode.MODIFIER || partyUiHandler.partyUiMode === PartyUiMode.TM_MODIFIER) || partyUiHandler.getCursor()) {
this.processInput(Button.ACTION);
thisArg.time.delayedCall(250, () => this.processInput(Button.ACTION));
} else
this.processInput(Button.CANCEL);
});
}
};
const originalSwitchCheckUiHandlerShow = confirmUiHandler.show;
confirmUiHandler.show = function (args: any[]) {
originalSwitchCheckUiHandlerShow.apply(this, [ args ]);
if (thisArg.auto) {
const bestPartyMemberIndex = getBestPartyMemberIndex();
thisArg.time.delayedCall(20, () => {
if (bestPartyMemberIndex)
nextPartyMemberIndex = bestPartyMemberIndex;
confirmUiHandler.setCursor(bestPartyMemberIndex ? 1 : 0);
thisArg.time.delayedCall(20, () => this.processInput(Button.ACTION));
});
}
}
const tryGetBestModifier = (modifierTypeOptions: Array<ModifierTypeOption>, predicate: Function) => {
for (let mt = 0; mt < modifierTypeOptions.length; mt++) {
const modifierTypeOption = modifierTypeOptions[mt];
if (predicate(modifierTypeOption.type)) {
return mt;
}
}
return -1;
};
const originalModifierSelectUiHandlerShow = modifierSelectUiHandler.show;
modifierSelectUiHandler.show = function (args: any[]) {
if (!thisArg.auto) {
originalModifierSelectUiHandlerShow.apply(this, [ args ]);
return;
}
if (modifierSelectUiHandler.active)
return;
thisArg.time.delayedCall(20, () => {
originalModifierSelectUiHandlerShow.apply(this, [ args ]);
const party = thisArg.getParty();
const modifierTypeOptions = modifierSelectUiHandler.options.map(o => o.modifierTypeOption);
const faintedPartyMemberIndex = party.findIndex(p => p.isFainted());
const lowHpPartyMemberIndex = party.findIndex(p => p.getHpRatio() <= 0.5);
const criticalHpPartyMemberIndex = party.findIndex(p => p.getHpRatio() <= 0.25);
let optionIndex = tryGetBestModifier(modifierTypeOptions, (modifierType: ModifierType) => {
if (modifierType instanceof PokemonHpRestoreModifierType) {
if (modifierType instanceof PokemonReviveModifierType) {
if (faintedPartyMemberIndex > -1) {
nextPartyMemberIndex = faintedPartyMemberIndex;
return true;
}
} else if (criticalHpPartyMemberIndex > -1){
nextPartyMemberIndex = criticalHpPartyMemberIndex;
return true;
}
}
});
if (optionIndex === -1) {
optionIndex = tryGetBestModifier(modifierTypeOptions, (modifierType: ModifierType) => {
if (modifierType.tier >= ModifierTier.ULTRA) {
nextPartyMemberIndex = 0;
return true;
}
});
}
if (optionIndex === -1) {
optionIndex = tryGetBestModifier(modifierTypeOptions, (modifierType: ModifierType) => {
if (modifierType instanceof PokemonBaseStatBoosterModifierType) {
nextPartyMemberIndex = 0;
return true;
}
});
}
if (optionIndex === -1) {
optionIndex = tryGetBestModifier(modifierTypeOptions, (modifierType: ModifierType) => {
if (lowHpPartyMemberIndex && modifierType instanceof PokemonHpRestoreModifierType && !(ModifierType instanceof PokemonReviveModifierType)) {
nextPartyMemberIndex = lowHpPartyMemberIndex;
return true;
}
});
}
if (optionIndex === -1)
optionIndex = 0;
const trySelectModifier = () => {
modifierSelectUiHandler.setCursor(optionIndex);
thisArg.time.delayedCall(20, () => {
modifierSelectUiHandler.processInput(Button.ACTION);
thisArg.time.delayedCall(250, () => {
console.log(modifierTypeOptions[optionIndex]?.type.name);
if (thisArg.getCurrentPhase() instanceof SelectModifierPhase) {
if (optionIndex < modifierSelectUiHandler.options.length - 1) {
optionIndex++;
thisArg.time.delayedCall(250, () => trySelectModifier());
} else
modifierSelectUiHandler.processInput(Button.CANCEL);
}
});
});
};
thisArg.time.delayedCall(4000, () => trySelectModifier());
});
}
}

View File

@ -219,9 +219,6 @@ export class GameData {
public saveSystem(): Promise<boolean> { public saveSystem(): Promise<boolean> {
return new Promise<boolean>(resolve => { return new Promise<boolean>(resolve => {
if (this.scene.quickStart)
return resolve(true);
updateUserInfo().then((success: boolean) => { updateUserInfo().then((success: boolean) => {
if (!success) if (!success)
return resolve(false); return resolve(false);