Add tall grass BG and fix a hanging bug with charge moves

pull/1/head
Flashfyre 2023-04-30 23:58:16 -04:00
parent b1be0da013
commit fe298c39e2
8 changed files with 44 additions and 36 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

View File

@ -99,8 +99,6 @@ export class Arena {
getBiomeKey(): string { getBiomeKey(): string {
switch (this.biomeType) { switch (this.biomeType) {
case Biome.TALL_GRASS:
return 'grass';
case Biome.CITY: case Biome.CITY:
return 'dojo'; return 'dojo';
case Biome.LAKE: case Biome.LAKE:

View File

@ -25,7 +25,7 @@ import { Gender } from "./data/gender";
import { Weather, WeatherType, getRandomWeatherType, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather"; import { Weather, WeatherType, getRandomWeatherType, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather";
import { TempBattleStat } from "./data/temp-battle-stat"; import { TempBattleStat } from "./data/temp-battle-stat";
import { ArenaTrapTag, TrickRoomTag } from "./data/arena-tag"; import { ArenaTrapTag, TrickRoomTag } from "./data/arena-tag";
import { PostWeatherLapseAbAttr, PreWeatherDamageAbAttr, ProtectStatAttr, SuppressWeatherEffectAbAttr, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreWeatherEffectAbAttrs } from "./data/ability"; import { ArenaTrapAbAttr, PostWeatherLapseAbAttr, PreWeatherDamageAbAttr, ProtectStatAttr, SuppressWeatherEffectAbAttr, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreWeatherEffectAbAttrs } from "./data/ability";
import { Unlockables, getUnlockableName } from "./system/unlockables"; import { Unlockables, getUnlockableName } from "./system/unlockables";
export class CheckLoadPhase extends BattlePhase { export class CheckLoadPhase extends BattlePhase {
@ -596,11 +596,11 @@ export class CommandPhase extends FieldPhase {
if (moveQueue.length) { if (moveQueue.length) {
const queuedMove = moveQueue[0]; const queuedMove = moveQueue[0];
if (!queuedMove.move) if (!queuedMove.move)
this.handleCommand(Command.FIGHT, -1); this.handleCommand(Command.FIGHT, -1, false);
else { else {
const moveIndex = playerPokemon.moveset.findIndex(m => m.moveId === queuedMove.move); const moveIndex = playerPokemon.moveset.findIndex(m => m.moveId === queuedMove.move);
if (playerPokemon.moveset[moveIndex].isUsable(queuedMove.ignorePP)) if (moveIndex > -1 && playerPokemon.moveset[moveIndex].isUsable(queuedMove.ignorePP))
this.handleCommand(Command.FIGHT, moveIndex); this.handleCommand(Command.FIGHT, moveIndex, queuedMove.ignorePP);
} }
} else } else
this.scene.ui.setMode(Mode.COMMAND); this.scene.ui.setMode(Mode.COMMAND);
@ -614,9 +614,9 @@ export class CommandPhase extends FieldPhase {
let isDelayed = (command: Command, playerMove: PokemonMove, enemyMove: PokemonMove) => { let isDelayed = (command: Command, playerMove: PokemonMove, enemyMove: PokemonMove) => {
switch (command) { switch (command) {
case Command.FIGHT: case Command.FIGHT:
if (playerMove && enemyMove) { if (playerMove || enemyMove) {
const playerMovePriority = playerMove.getMove().priority; const playerMovePriority = playerMove?.getMove()?.priority || 0;
const enemyMovePriority = enemyMove.getMove().priority; const enemyMovePriority = enemyMove?.getMove()?.priority || 0;
if (playerMovePriority !== enemyMovePriority) if (playerMovePriority !== enemyMovePriority)
return playerMovePriority < enemyMovePriority; return playerMovePriority < enemyMovePriority;
} }
@ -641,9 +641,9 @@ export class CommandPhase extends FieldPhase {
break; break;
} }
if (playerPokemon.trySelectMove(cursor)) { if (playerPokemon.trySelectMove(cursor, args[0] as boolean)) {
playerMove = playerPokemon.moveset[cursor]; playerMove = playerPokemon.moveset[cursor];
const playerPhase = new PlayerMovePhase(this.scene, playerPokemon, playerMove); const playerPhase = new PlayerMovePhase(this.scene, playerPokemon, playerMove, false, args[0] as boolean);
this.scene.pushPhase(playerPhase); this.scene.pushPhase(playerPhase);
success = true; success = true;
} else if (cursor < playerPokemon.moveset.length) { } else if (cursor < playerPokemon.moveset.length) {
@ -673,12 +673,13 @@ export class CommandPhase extends FieldPhase {
break; break;
case Command.POKEMON: case Command.POKEMON:
const trapTag = playerPokemon.findTag(t => t instanceof TrappedTag) as TrappedTag; const trapTag = playerPokemon.findTag(t => t instanceof TrappedTag) as TrappedTag;
const arenaTrapped = !!enemyPokemon.getAbility().getAttrs(ArenaTrapAbAttr).length;
const batonPass = args[0] as boolean; const batonPass = args[0] as boolean;
if (batonPass || !trapTag) { if (batonPass || (!trapTag && !arenaTrapped)) {
this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, cursor, true, args[0] as boolean)); this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, cursor, true, args[0] as boolean));
success = true; success = true;
} else } else
this.scene.ui.showText(`${this.scene.getPokemonById(trapTag.sourceId).name}'s ${trapTag.getMoveName()}\nprevents switching!`, null, () => { this.scene.ui.showText(`${this.scene.getPokemonById(trapTag.sourceId).name}'s ${trapTag?.getMoveName() || enemyPokemon.getAbility().name}\nprevents switching!`, null, () => {
this.scene.ui.showText(null, 0); this.scene.ui.showText(null, 0);
}, null, true); }, null, true);
break; break;
@ -692,19 +693,23 @@ export class CommandPhase extends FieldPhase {
if (this.scene.arena.weather) if (this.scene.arena.weather)
this.scene.unshiftPhase(new WeatherEffectPhase(this.scene, this.scene.arena.weather)); this.scene.unshiftPhase(new WeatherEffectPhase(this.scene, this.scene.arena.weather));
const enemyMove = enemyPokemon.getNextMove(); const enemyNextMove = enemyPokemon.getNextMove();
const enemyPhase = new EnemyMovePhase(this.scene, enemyPokemon, enemyMove); let enemyMove: PokemonMove;
if (isDelayed(command, playerMove, enemyMove)) if (enemyNextMove.move) {
this.scene.unshiftPhase(enemyPhase); enemyMove = enemyPokemon.moveset.find(m => m.moveId === enemyNextMove.move) || new PokemonMove(enemyNextMove.move, 0, 0);
else const enemyPhase = new EnemyMovePhase(this.scene, enemyPokemon, enemyMove, false, enemyNextMove.ignorePP);
this.scene.pushPhase(enemyPhase); if (isDelayed(command, playerMove, enemyMove))
this.scene.unshiftPhase(enemyPhase);
else
this.scene.pushPhase(enemyPhase);
}
const statusEffectPhases: PostTurnStatusEffectPhase[] = []; const statusEffectPhases: PostTurnStatusEffectPhase[] = [];
if (playerPokemon.status && playerPokemon.status.isPostTurn()) if (playerPokemon.status && playerPokemon.status.isPostTurn())
statusEffectPhases.push(new PostTurnStatusEffectPhase(this.scene, true)); statusEffectPhases.push(new PostTurnStatusEffectPhase(this.scene, true));
if (enemyPokemon.status && enemyPokemon.status.isPostTurn()) { if (enemyPokemon.status && enemyPokemon.status.isPostTurn()) {
const enemyStatusEffectPhase = new PostTurnStatusEffectPhase(this.scene, false); const enemyStatusEffectPhase = new PostTurnStatusEffectPhase(this.scene, false);
if (isDelayed(command, playerMove, enemyMove)) if (this.isPlayerDelayed())
statusEffectPhases.unshift(enemyStatusEffectPhase); statusEffectPhases.unshift(enemyStatusEffectPhase);
else else
statusEffectPhases.push(enemyStatusEffectPhase); statusEffectPhases.push(enemyStatusEffectPhase);
@ -837,21 +842,23 @@ export abstract class MovePhase extends BattlePhase {
protected pokemon: Pokemon; protected pokemon: Pokemon;
protected move: PokemonMove; protected move: PokemonMove;
protected followUp: boolean; protected followUp: boolean;
protected ignorePp: boolean;
protected cancelled: boolean; protected cancelled: boolean;
constructor(scene: BattleScene, pokemon: Pokemon, move: PokemonMove, followUp?: boolean) { constructor(scene: BattleScene, pokemon: Pokemon, move: PokemonMove, followUp?: boolean, ignorePp?: boolean) {
super(scene); super(scene);
this.pokemon = pokemon; this.pokemon = pokemon;
this.move = move; this.move = move;
this.followUp = !!followUp; this.followUp = !!followUp;
this.ignorePp = !!ignorePp;
this.cancelled = false; this.cancelled = false;
} }
abstract getEffectPhase(): MoveEffectPhase; abstract getEffectPhase(): MoveEffectPhase;
canMove(): boolean { canMove(): boolean {
return !!this.pokemon.hp && this.move.isUsable(); return !!this.pokemon.hp && this.move.isUsable(this.ignorePp);
} }
cancel(): void { cancel(): void {
@ -955,8 +962,8 @@ export abstract class MovePhase extends BattlePhase {
} }
export class PlayerMovePhase extends MovePhase { export class PlayerMovePhase extends MovePhase {
constructor(scene: BattleScene, pokemon: PlayerPokemon, move: PokemonMove, followUp?: boolean) { constructor(scene: BattleScene, pokemon: PlayerPokemon, move: PokemonMove, followUp?: boolean, ignorePp?: boolean) {
super(scene, pokemon, move, followUp); super(scene, pokemon, move, followUp, ignorePp);
} }
getEffectPhase(): MoveEffectPhase { getEffectPhase(): MoveEffectPhase {
@ -965,8 +972,8 @@ export class PlayerMovePhase extends MovePhase {
} }
export class EnemyMovePhase extends MovePhase { export class EnemyMovePhase extends MovePhase {
constructor(scene: BattleScene, pokemon: EnemyPokemon, move: PokemonMove, followUp?: boolean) { constructor(scene: BattleScene, pokemon: EnemyPokemon, move: PokemonMove, followUp?: boolean, ignorePp?: boolean) {
super(scene, pokemon, move, followUp); super(scene, pokemon, move, followUp, ignorePp);
} }
getEffectPhase(): MoveEffectPhase { getEffectPhase(): MoveEffectPhase {

View File

@ -247,6 +247,8 @@ export class ProtectStatAttr extends PreStatChangeAbAttr {
} }
} }
export class ArenaTrapAbAttr extends AbAttr { }
export class PreWeatherEffectAbAttr extends AbAttr { export class PreWeatherEffectAbAttr extends AbAttr {
applyPreWeatherEffect(pokemon: Pokemon, weather: Weather, cancelled: Utils.BooleanHolder, args: any[]): boolean { applyPreWeatherEffect(pokemon: Pokemon, weather: Weather, cancelled: Utils.BooleanHolder, args: any[]): boolean {
return false; return false;
@ -636,7 +638,8 @@ export function initAbilities() {
abilities.push( abilities.push(
new Ability(Abilities.AIR_LOCK, "Air Lock", "Eliminates the effects of all weather.", 3) new Ability(Abilities.AIR_LOCK, "Air Lock", "Eliminates the effects of all weather.", 3)
.attr(SuppressWeatherEffectAbAttr, true), .attr(SuppressWeatherEffectAbAttr, true),
new Ability(Abilities.ARENA_TRAP, "Arena Trap (N)", "Prevents the foe from fleeing.", 3), new Ability(Abilities.ARENA_TRAP, "Arena Trap", "Prevents the foe from fleeing.", 3)
.attr(ArenaTrapAbAttr),
new Ability(Abilities.BATTLE_ARMOR, "Battle Armor (N)", "The POKéMON is protected against critical hits.", 3), new Ability(Abilities.BATTLE_ARMOR, "Battle Armor (N)", "The POKéMON is protected against critical hits.", 3),
new Ability(Abilities.BLAZE, "Blaze", "Powers up FIRE-type moves in a pinch.", 3) new Ability(Abilities.BLAZE, "Blaze", "Powers up FIRE-type moves in a pinch.", 3)
.attr(LowHpMoveTypePowerBoostAbAttr, Type.FIRE), .attr(LowHpMoveTypePowerBoostAbAttr, Type.FIRE),

View File

@ -431,11 +431,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
} }
trySelectMove(moveIndex: integer): boolean { trySelectMove(moveIndex: integer, ignorePp?: boolean): boolean {
const move = this.moveset.length > moveIndex const move = this.moveset.length > moveIndex
? this.moveset[moveIndex] ? this.moveset[moveIndex]
: null; : null;
return move?.isUsable(); return move?.isUsable(ignorePp);
} }
showInfo() { showInfo() {
@ -991,13 +991,13 @@ export class EnemyPokemon extends Pokemon {
} }
} }
getNextMove(): PokemonMove { getNextMove(): QueuedMove {
const queuedMove = this.getMoveQueue().length const queuedMove = this.getMoveQueue().length
? this.moveset.find(m => m.moveId === this.getMoveQueue()[0].move) ? this.moveset.find(m => m.moveId === this.getMoveQueue()[0].move)
: null; : null;
if (queuedMove) { if (queuedMove) {
if (queuedMove.isUsable(this.getMoveQueue()[0].ignorePP)) if (queuedMove.isUsable(this.getMoveQueue()[0].ignorePP))
return queuedMove; return { move: queuedMove.moveId, ignorePP: this.getMoveQueue()[0].ignorePP };
else { else {
this.getMoveQueue().shift(); this.getMoveQueue().shift();
return this.getNextMove(); return this.getNextMove();
@ -1007,10 +1007,10 @@ export class EnemyPokemon extends Pokemon {
const movePool = this.moveset.filter(m => m.isUsable()); const movePool = this.moveset.filter(m => m.isUsable());
if (movePool.length) { if (movePool.length) {
if (movePool.length === 1) if (movePool.length === 1)
return movePool[0]; return { move: movePool[0].moveId };
switch (this.aiType) { switch (this.aiType) {
case AiType.RANDOM: case AiType.RANDOM:
return movePool[Utils.randInt(movePool.length)]; return { move: movePool[Utils.randInt(movePool.length)].moveId };
case AiType.SMART_RANDOM: case AiType.SMART_RANDOM:
case AiType.SMART: case AiType.SMART:
const target = this.scene.getPlayerPokemon(); const target = this.scene.getPlayerPokemon();
@ -1072,11 +1072,11 @@ export class EnemyPokemon extends Pokemon {
r++; r++;
} }
console.log(movePool.map(m => m.getName()), moveScores, r, sortedMovePool.map(m => m.getName())); console.log(movePool.map(m => m.getName()), moveScores, r, sortedMovePool.map(m => m.getName()));
return sortedMovePool[r]; return { move: sortedMovePool[r].moveId };
} }
} }
return new PokemonMove(Moves.STRUGGLE, 0, 0); return { move: Moves.STRUGGLE };
} }
isPlayer() { isPlayer() {

View File

@ -49,7 +49,7 @@ export default class FightUiHandler extends UiHandler {
if (button === Button.CANCEL || button === Button.ACTION) { if (button === Button.CANCEL || button === Button.ACTION) {
if (button === Button.ACTION) { if (button === Button.ACTION) {
if ((this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, this.cursor)) if ((this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, this.cursor, false))
success = true; success = true;
else else
ui.playError(); ui.playError();