Add recharging move logic

pull/1/head
Flashfyre 2023-04-20 21:32:48 -04:00
parent bfa95a372e
commit 50b264ad77
7 changed files with 103 additions and 47 deletions

View File

@ -458,16 +458,22 @@ export class CommandPhase extends BattlePhase {
playerPokemon.resetTurnData(); playerPokemon.resetTurnData();
this.scene.getEnemyPokemon().resetTurnData(); this.scene.getEnemyPokemon().resetTurnData();
while (playerPokemon.summonData.moveQueue.length && playerPokemon.summonData.moveQueue[0] const moveQueue = playerPokemon.getMoveQueue();
&& !playerPokemon.moveset[playerPokemon.moveset.findIndex(m => m.moveId === playerPokemon.summonData.moveQueue[0].move)]
.isUsable(playerPokemon.summonData.moveQueue[0].ignorePP))
playerPokemon.summonData.moveQueue.shift();
if (playerPokemon.summonData.moveQueue.length) { while (moveQueue.length && moveQueue[0]
const queuedMove = playerPokemon.summonData.moveQueue[0]; && moveQueue[0].move && (playerPokemon.moveset.find(m => m.moveId === moveQueue[0].move)
|| !playerPokemon.moveset[playerPokemon.moveset.findIndex(m => m.moveId === moveQueue[0].move)].isUsable(moveQueue[0].ignorePP)))
moveQueue.shift();
if (moveQueue.length) {
const queuedMove = moveQueue[0];
if (!queuedMove.move)
this.handleCommand(Command.FIGHT, -1);
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 (playerPokemon.moveset[moveIndex].isUsable(queuedMove.ignorePP))
this.handleCommand(Command.FIGHT, moveIndex); this.handleCommand(Command.FIGHT, moveIndex);
}
} else } else
this.scene.ui.setMode(Mode.COMMAND); this.scene.ui.setMode(Mode.COMMAND);
} }
@ -504,6 +510,12 @@ export class CommandPhase extends BattlePhase {
switch (command) { switch (command) {
case Command.FIGHT: case Command.FIGHT:
if (cursor == -1) {
this.scene.pushPhase(new PlayerMovePhase(this.scene, playerPokemon, new PokemonMove(Moves.NONE)));
success = true;
break;
}
if (playerPokemon.trySelectMove(cursor)) { if (playerPokemon.trySelectMove(cursor)) {
playerMove = playerPokemon.moveset[cursor]; playerMove = playerPokemon.moveset[cursor];
const playerPhase = new PlayerMovePhase(this.scene, playerPokemon, playerMove); const playerPhase = new PlayerMovePhase(this.scene, playerPokemon, playerMove);
@ -724,13 +736,21 @@ export abstract class MovePhase extends BattlePhase {
this.pokemon.lapseTags(BattleTagLapseType.MOVE); this.pokemon.lapseTags(BattleTagLapseType.MOVE);
const doMove = () => { const doMove = () => {
const moveQueue = this.pokemon.getMoveQueue();
if (moveQueue.length && moveQueue[0].move === Moves.NONE) {
moveQueue.shift();
this.cancel();
}
if (this.cancelled) { if (this.cancelled) {
this.pokemon.getMoveHistory().push({ move: Moves.NONE, result: MoveResult.FAILED });
this.end(); this.end();
return; return;
} }
this.scene.unshiftPhase(new MessagePhase(this.scene, getPokemonMessage(this.pokemon, ` used\n${this.move.getName()}!`), 500)); this.scene.unshiftPhase(new MessagePhase(this.scene, getPokemonMessage(this.pokemon, ` used\n${this.move.getName()}!`), 500));
if (!this.pokemon.summonData.moveQueue.length || !this.pokemon.summonData.moveQueue.shift().ignorePP) if (!moveQueue.length || !moveQueue.shift().ignorePP)
this.move.ppUsed++; this.move.ppUsed++;
const failed = new Utils.BooleanHolder(false); const failed = new Utils.BooleanHolder(false);
@ -738,7 +758,7 @@ export abstract class MovePhase extends BattlePhase {
if (!failed.value && this.scene.arena.isMoveWeatherCancelled(this.move.getMove())) if (!failed.value && this.scene.arena.isMoveWeatherCancelled(this.move.getMove()))
failed.value = true; failed.value = true;
if (failed.value) { if (failed.value) {
this.pokemon.summonData.moveHistory.push({ move: this.move.moveId, result: MoveResult.FAILED, virtual: this.move.virtual }); this.pokemon.getMoveHistory().push({ move: this.move.moveId, result: MoveResult.FAILED, virtual: this.move.virtual });
this.scene.unshiftPhase(new MessagePhase(this.scene, 'But it failed!')); this.scene.unshiftPhase(new MessagePhase(this.scene, 'But it failed!'));
} else } else
this.scene.unshiftPhase(this.getEffectPhase()); this.scene.unshiftPhase(this.getEffectPhase());
@ -860,7 +880,7 @@ abstract class MoveEffectPhase extends PokemonPhase {
if (!this.hitCheck()) { if (!this.hitCheck()) {
this.scene.unshiftPhase(new MessagePhase(this.scene, getPokemonMessage(user, '\'s\nattack missed!'))); this.scene.unshiftPhase(new MessagePhase(this.scene, getPokemonMessage(user, '\'s\nattack missed!')));
user.summonData.moveHistory.push({ move: this.move.moveId, result: MoveResult.MISSED, virtual: this.move.virtual }); user.getMoveHistory().push({ move: this.move.moveId, result: MoveResult.MISSED, virtual: this.move.virtual });
applyMoveAttrs(MissEffectAttr, user, target, this.move.getMove()); applyMoveAttrs(MissEffectAttr, user, target, this.move.getMove());
this.end(); this.end();
return; return;
@ -871,7 +891,7 @@ abstract class MoveEffectPhase extends PokemonPhase {
new MoveAnim(this.move.getMove().id as Moves, user, target).play(this.scene, () => { new MoveAnim(this.move.getMove().id as Moves, user, target).play(this.scene, () => {
const result = !isProtected ? target.apply(user, this.move) : MoveResult.NO_EFFECT; const result = !isProtected ? target.apply(user, this.move) : MoveResult.NO_EFFECT;
++user.turnData.hitCount; ++user.turnData.hitCount;
user.summonData.moveHistory.push({ move: this.move.moveId, result: result, virtual: this.move.virtual }); user.getMoveHistory().push({ move: this.move.moveId, result: result, virtual: this.move.virtual });
applyMoveAttrs(MoveEffectAttr, user, target, this.move.getMove()); applyMoveAttrs(MoveEffectAttr, user, target, this.move.getMove());
// Charge attribute with charge effect takes all effect attributes and applies them to charge stage, so ignore them if this is present // Charge attribute with charge effect takes all effect attributes and applies them to charge stage, so ignore them if this is present
if (!isProtected && target.hp && !this.move.getMove().getAttrs(ChargeAttr).filter(ca => (ca as ChargeAttr).chargeEffect).length) if (!isProtected && target.hp && !this.move.getMove().getAttrs(ChargeAttr).filter(ca => (ca as ChargeAttr).chargeEffect).length)
@ -993,7 +1013,7 @@ export class MoveAnimTestPhase extends BattlePhase {
constructor(scene: BattleScene, moveQueue?: Moves[]) { constructor(scene: BattleScene, moveQueue?: Moves[]) {
super(scene); super(scene);
this.moveQueue = moveQueue || Utils.getEnumValues(Moves); this.moveQueue = moveQueue || Utils.getEnumValues(Moves).slice(1);
} }
start() { start() {
@ -1469,7 +1489,7 @@ export class LearnMovePhase extends PartyMemberPokemonPhase {
super.start(); super.start();
const pokemon = this.getPokemon(); const pokemon = this.getPokemon();
const move = allMoves[this.moveId - 1]; const move = allMoves[this.moveId];
const existingMoveIndex = pokemon.moveset.findIndex(m => m?.moveId === move.id); const existingMoveIndex = pokemon.moveset.findIndex(m => m?.moveId === move.id);

View File

@ -18,7 +18,7 @@ import { GameData } from './system/game-data';
import StarterSelectUiHandler from './ui/starter-select-ui-handler'; import StarterSelectUiHandler from './ui/starter-select-ui-handler';
import { TextStyle, addTextObject } from './ui/text'; import { TextStyle, addTextObject } from './ui/text';
import { Moves } from './data/move'; import { Moves } from './data/move';
import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getPlayerModifierTypeOptionsForWave } from './modifier/modifier-type'; import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave } from './modifier/modifier-type';
const enableAuto = true; const enableAuto = true;
export const startingLevel = 5; export const startingLevel = 5;

View File

@ -392,7 +392,7 @@ export function initMoveAnim(move: Moves): Promise<void> {
populateMoveAnim(move, ba[1]); populateMoveAnim(move, ba[1]);
} else } else
populateMoveAnim(move, ba); populateMoveAnim(move, ba);
const chargeAttr = allMoves[move - 1].getAttrs(ChargeAttr) as ChargeAttr[]; const chargeAttr = allMoves[move].getAttrs(ChargeAttr) as ChargeAttr[];
if (chargeAttr.length) if (chargeAttr.length)
initMoveChargeAnim(chargeAttr[0].chargeAnim).then(() => resolve()); initMoveChargeAnim(chargeAttr[0].chargeAnim).then(() => resolve());
else else
@ -459,7 +459,7 @@ export function loadMoveAnimAssets(scene: BattleScene, moveIds: Moves[], startLo
return new Promise(resolve => { return new Promise(resolve => {
const moveAnimations = moveIds.map(m => moveAnims.get(m) as AnimConfig).flat(); const moveAnimations = moveIds.map(m => moveAnims.get(m) as AnimConfig).flat();
for (let moveId of moveIds) { for (let moveId of moveIds) {
const chargeAttr = allMoves[moveId - 1].getAttrs(ChargeAttr) as ChargeAttr[]; const chargeAttr = allMoves[moveId].getAttrs(ChargeAttr) as ChargeAttr[];
if (chargeAttr.length) { if (chargeAttr.length) {
const moveChargeAnims = chargeAnims.get(chargeAttr[0].chargeAnim); const moveChargeAnims = chargeAnims.get(chargeAttr[0].chargeAnim);
moveAnimations.push(moveChargeAnims instanceof AnimConfig ? moveChargeAnims : moveChargeAnims[0]); moveAnimations.push(moveChargeAnims instanceof AnimConfig ? moveChargeAnims : moveChargeAnims[0]);
@ -818,7 +818,7 @@ export function populateAnims() {
const chargeAnimIds = Utils.getEnumValues(ChargeAnim) as ChargeAnim[]; const chargeAnimIds = Utils.getEnumValues(ChargeAnim) as ChargeAnim[];
const commonNamePattern = /name: (?:Common:)?(Opp )?(.*)/; const commonNamePattern = /name: (?:Common:)?(Opp )?(.*)/;
const moveNameToId = {}; const moveNameToId = {};
for (let move of Utils.getEnumValues(Moves)) { for (let move of Utils.getEnumValues(Moves).slice(1)) {
const moveName = Moves[move].toUpperCase().replace(/\_/g, ''); const moveName = Moves[move].toUpperCase().replace(/\_/g, '');
moveNameToId[moveName] = move; moveNameToId[moveName] = move;
} }

View File

@ -5,9 +5,11 @@ import Pokemon from "../pokemon";
import { Stat } from "./pokemon-stat"; import { Stat } from "./pokemon-stat";
import { StatusEffect } from "./status-effect"; import { StatusEffect } from "./status-effect";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { Moves } from "./move";
export enum BattleTagType { export enum BattleTagType {
NONE, NONE,
RECHARGING,
FLINCHED, FLINCHED,
CONFUSED, CONFUSED,
SEEDED, SEEDED,
@ -55,6 +57,27 @@ export class BattleTag {
} }
} }
export class RechargingTag extends BattleTag {
constructor() {
super(BattleTagType.RECHARGING, BattleTagLapseType.MOVE, 1);
}
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
pokemon.getMoveQueue().push({ move: Moves.NONE })
}
lapse(pokemon: Pokemon, lapseType: BattleTagLapseType): boolean {
super.lapse(pokemon, lapseType);
(pokemon.scene.getCurrentPhase() as MovePhase).cancel();
pokemon.scene.unshiftPhase(new MessagePhase(pokemon.scene, getPokemonMessage(pokemon, ' must\nrecharge!')));
return true;
}
}
export class FlinchedTag extends BattleTag { export class FlinchedTag extends BattleTag {
constructor() { constructor() {
super(BattleTagType.FLINCHED, BattleTagLapseType.MOVE, 0); super(BattleTagType.FLINCHED, BattleTagLapseType.MOVE, 0);
@ -293,6 +316,8 @@ export class HideSpriteTag extends BattleTag {
export function getBattleTag(tagType: BattleTagType, turnCount: integer): BattleTag { export function getBattleTag(tagType: BattleTagType, turnCount: integer): BattleTag {
switch (tagType) { switch (tagType) {
case BattleTagType.RECHARGING:
return new RechargingTag();
case BattleTagType.FLINCHED: case BattleTagType.FLINCHED:
return new FlinchedTag(); return new FlinchedTag();
case BattleTagType.CONFUSED: case BattleTagType.CONFUSED:

View File

@ -91,7 +91,8 @@ export class SelfStatusMove extends Move {
} }
export enum Moves { export enum Moves {
POUND = 1, NONE,
POUND,
KARATE_CHOP, KARATE_CHOP,
DOUBLE_SLAP, DOUBLE_SLAP,
COMET_PUNCH, COMET_PUNCH,
@ -979,8 +980,8 @@ export class ChargeAttr extends OverrideMoveEffectAttr {
user.addTag(this.tagType, 1); user.addTag(this.tagType, 1);
if (this.chargeEffect) if (this.chargeEffect)
applyMoveAttrs(MoveEffectAttr, user, target, move); applyMoveAttrs(MoveEffectAttr, user, target, move);
user.summonData.moveHistory.push({ move: move.id, result: MoveResult.OTHER }); user.getMoveHistory().push({ move: move.id, result: MoveResult.OTHER });
user.summonData.moveQueue.push({ move: move.id, ignorePP: true }); user.getMoveQueue().push({ move: move.id, ignorePP: true });
resolve(true); resolve(true);
}); });
} else } else
@ -1249,10 +1250,10 @@ export class FrenzyAttr extends MoveEffectAttr {
if (!super.apply(user, target, move, args)) if (!super.apply(user, target, move, args))
return false; return false;
if (!user.summonData.moveQueue.length) { if (!user.getMoveQueue().length) {
if (!user.getTag(BattleTagType.FRENZY)) { if (!user.getTag(BattleTagType.FRENZY)) {
const turnCount = Utils.randInt(2) + 1; const turnCount = Utils.randInt(2) + 1;
new Array(turnCount).fill(null).map(() => user.summonData.moveQueue.push({ move: move.id, ignorePP: true })); new Array(turnCount).fill(null).map(() => user.getMoveQueue().push({ move: move.id, ignorePP: true }));
user.addTag(BattleTagType.FRENZY, 1); user.addTag(BattleTagType.FRENZY, 1);
} else { } else {
applyMoveAttrs(AddTagAttr, user, target, move, args); applyMoveAttrs(AddTagAttr, user, target, move, args);
@ -1266,8 +1267,8 @@ export class FrenzyAttr extends MoveEffectAttr {
} }
export const frenzyMissFunc = (user: Pokemon, target: Pokemon, move: Move) => { export const frenzyMissFunc = (user: Pokemon, target: Pokemon, move: Move) => {
while (user.summonData.moveQueue.length && user.summonData.moveQueue[0].move === move.id) while (user.getMoveQueue().length && user.getMoveQueue()[0].move === move.id)
user.summonData.moveQueue.shift(); user.getMoveQueue().shift();
user.lapseTag(BattleTagType.FRENZY) user.lapseTag(BattleTagType.FRENZY)
}; };
@ -1344,7 +1345,7 @@ export class RandomMovesetMoveAttr extends OverrideMoveEffectAttr {
if (moves.length) { if (moves.length) {
const move = moves[Utils.randInt(moves.length)]; const move = moves[Utils.randInt(moves.length)];
const moveIndex = user.moveset.findIndex(m => m.moveId === move.moveId); const moveIndex = user.moveset.findIndex(m => m.moveId === move.moveId);
user.summonData.moveQueue.push({ move: move.moveId }); user.getMoveQueue().push({ move: move.moveId });
user.scene.unshiftPhase(user.isPlayer() ? new PlayerMovePhase(user.scene, user as PlayerPokemon, user.moveset[moveIndex], true) : new EnemyMovePhase(user.scene, user as EnemyPokemon, user.moveset[moveIndex], true)); user.scene.unshiftPhase(user.isPlayer() ? new PlayerMovePhase(user.scene, user as PlayerPokemon, user.moveset[moveIndex], true) : new EnemyMovePhase(user.scene, user as EnemyPokemon, user.moveset[moveIndex], true));
return true; return true;
} }
@ -1356,9 +1357,9 @@ export class RandomMovesetMoveAttr extends OverrideMoveEffectAttr {
export class RandomMoveAttr extends OverrideMoveEffectAttr { export class RandomMoveAttr extends OverrideMoveEffectAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
return new Promise(resolve => { return new Promise(resolve => {
const moveIds = Utils.getEnumValues(Moves).filter(m => m !== move.id); const moveIds = Utils.getEnumValues(Moves).filter(m => m && m !== move.id);
const moveId = moveIds[Utils.randInt(moveIds.length)]; const moveId = moveIds[Utils.randInt(moveIds.length)];
user.summonData.moveQueue.push({ move: moveId, ignorePP: true }); user.getMoveQueue().push({ move: moveId, ignorePP: true });
user.scene.unshiftPhase(user.isPlayer() ? new PlayerMovePhase(user.scene, user as PlayerPokemon, new PokemonMove(moveId, 0, 0, true), true) : new EnemyMovePhase(user.scene, user as EnemyPokemon, new PokemonMove(moveId, 0, 0, true), true)); user.scene.unshiftPhase(user.isPlayer() ? new PlayerMovePhase(user.scene, user as PlayerPokemon, new PokemonMove(moveId, 0, 0, true), true) : new EnemyMovePhase(user.scene, user as EnemyPokemon, new PokemonMove(moveId, 0, 0, true), true));
initMoveAnim(moveId).then(() => { initMoveAnim(moveId).then(() => {
loadMoveAnimAssets(user.scene, [ moveId ], true) loadMoveAnimAssets(user.scene, [ moveId ], true)
@ -1369,6 +1370,7 @@ export class RandomMoveAttr extends OverrideMoveEffectAttr {
} }
export const allMoves = [ export const allMoves = [
new StatusMove(Moves.NONE, "-", Type.NORMAL, MoveCategory.STATUS, -1, -1, "", -1, 0, 1),
new AttackMove(Moves.POUND, "Pound", Type.NORMAL, MoveCategory.PHYSICAL, 40, 100, 35, -1, "", -1, 0, 1), new AttackMove(Moves.POUND, "Pound", Type.NORMAL, MoveCategory.PHYSICAL, 40, 100, 35, -1, "", -1, 0, 1),
new AttackMove(Moves.KARATE_CHOP, "Karate Chop", Type.FIGHTING, MoveCategory.PHYSICAL, 50, 100, 25, -1, "High critical hit ratio.", -1, 0, 1, new HighCritAttr()), new AttackMove(Moves.KARATE_CHOP, "Karate Chop", Type.FIGHTING, MoveCategory.PHYSICAL, 50, 100, 25, -1, "High critical hit ratio.", -1, 0, 1, new HighCritAttr()),
new AttackMove(Moves.DOUBLE_SLAP, "Double Slap", Type.NORMAL, MoveCategory.PHYSICAL, 15, 85, 10, -1, "Hits 2-5 times in one turn.", -1, 0, 1, new MultiHitAttr()), new AttackMove(Moves.DOUBLE_SLAP, "Double Slap", Type.NORMAL, MoveCategory.PHYSICAL, 15, 85, 10, -1, "Hits 2-5 times in one turn.", -1, 0, 1, new MultiHitAttr()),
@ -1435,7 +1437,7 @@ export const allMoves = [
new AttackMove(Moves.PSYBEAM, "Psybeam", Type.PSYCHIC, MoveCategory.SPECIAL, 65, 100, 20, 16, "May confuse opponent.", 10, 0, 1, new ConfuseAttr()), new AttackMove(Moves.PSYBEAM, "Psybeam", Type.PSYCHIC, MoveCategory.SPECIAL, 65, 100, 20, 16, "May confuse opponent.", 10, 0, 1, new ConfuseAttr()),
new AttackMove(Moves.BUBBLE_BEAM, "Bubble Beam", Type.WATER, MoveCategory.SPECIAL, 65, 100, 20, -1, "May lower opponent's Speed.", 10, 0, 1, new StatChangeAttr(BattleStat.SPD, -1)), new AttackMove(Moves.BUBBLE_BEAM, "Bubble Beam", Type.WATER, MoveCategory.SPECIAL, 65, 100, 20, -1, "May lower opponent's Speed.", 10, 0, 1, new StatChangeAttr(BattleStat.SPD, -1)),
new AttackMove(Moves.AURORA_BEAM, "Aurora Beam", Type.ICE, MoveCategory.SPECIAL, 65, 100, 20, -1, "May lower opponent's Attack.", 10, 0, 1, new StatChangeAttr(BattleStat.ATK, -1)), new AttackMove(Moves.AURORA_BEAM, "Aurora Beam", Type.ICE, MoveCategory.SPECIAL, 65, 100, 20, -1, "May lower opponent's Attack.", 10, 0, 1, new StatChangeAttr(BattleStat.ATK, -1)),
new AttackMove(Moves.HYPER_BEAM, "Hyper Beam", Type.NORMAL, MoveCategory.SPECIAL, 150, 90, 5, 163, "User must recharge next turn.", -1, 0, 1), new AttackMove(Moves.HYPER_BEAM, "Hyper Beam", Type.NORMAL, MoveCategory.SPECIAL, 150, 90, 5, 163, "User must recharge next turn.", -1, 0, 1, new AddTagAttr(BattleTagType.RECHARGING, true)),
new AttackMove(Moves.PECK, "Peck", Type.FLYING, MoveCategory.PHYSICAL, 35, 100, 35, -1, "", -1, 0, 1), new AttackMove(Moves.PECK, "Peck", Type.FLYING, MoveCategory.PHYSICAL, 35, 100, 35, -1, "", -1, 0, 1),
new AttackMove(Moves.DRILL_PECK, "Drill Peck", Type.FLYING, MoveCategory.PHYSICAL, 80, 100, 20, -1, "", -1, 0, 1), new AttackMove(Moves.DRILL_PECK, "Drill Peck", Type.FLYING, MoveCategory.PHYSICAL, 80, 100, 20, -1, "", -1, 0, 1),
new AttackMove(Moves.SUBMISSION, "Submission", Type.FIGHTING, MoveCategory.PHYSICAL, 80, 80, 20, -1, "User receives recoil damage.", -1, 0, 1, new RecoilAttr()), new AttackMove(Moves.SUBMISSION, "Submission", Type.FIGHTING, MoveCategory.PHYSICAL, 80, 80, 20, -1, "User receives recoil damage.", -1, 0, 1, new RecoilAttr()),
@ -1713,8 +1715,8 @@ export const allMoves = [
new AttackMove(Moves.HYPER_VOICE, "Hyper Voice", Type.NORMAL, MoveCategory.SPECIAL, 90, 100, 10, 117, "", -1, 0, 3), new AttackMove(Moves.HYPER_VOICE, "Hyper Voice", Type.NORMAL, MoveCategory.SPECIAL, 90, 100, 10, 117, "", -1, 0, 3),
new AttackMove(Moves.POISON_FANG, "Poison Fang", Type.POISON, MoveCategory.PHYSICAL, 50, 100, 15, -1, "May badly poison opponent.", 50, 0, 3, new StatusEffectAttr(StatusEffect.TOXIC)), new AttackMove(Moves.POISON_FANG, "Poison Fang", Type.POISON, MoveCategory.PHYSICAL, 50, 100, 15, -1, "May badly poison opponent.", 50, 0, 3, new StatusEffectAttr(StatusEffect.TOXIC)),
new AttackMove(Moves.CRUSH_CLAW, "Crush Claw", Type.NORMAL, MoveCategory.PHYSICAL, 75, 95, 10, -1, "May lower opponent's Defense.", 50, 0, 3, new StatChangeAttr(BattleStat.DEF, -1)), new AttackMove(Moves.CRUSH_CLAW, "Crush Claw", Type.NORMAL, MoveCategory.PHYSICAL, 75, 95, 10, -1, "May lower opponent's Defense.", 50, 0, 3, new StatChangeAttr(BattleStat.DEF, -1)),
new AttackMove(Moves.BLAST_BURN, "Blast Burn", Type.FIRE, MoveCategory.SPECIAL, 150, 90, 5, 153, "User must recharge next turn.", -1, 0, 3), new AttackMove(Moves.BLAST_BURN, "Blast Burn", Type.FIRE, MoveCategory.SPECIAL, 150, 90, 5, 153, "User must recharge next turn.", -1, 0, 3, new AddTagAttr(BattleTagType.RECHARGING, true)),
new AttackMove(Moves.HYDRO_CANNON, "Hydro Cannon", Type.WATER, MoveCategory.SPECIAL, 150, 90, 5, 154, "User must recharge next turn.", -1, 0, 3), new AttackMove(Moves.HYDRO_CANNON, "Hydro Cannon", Type.WATER, MoveCategory.SPECIAL, 150, 90, 5, 154, "User must recharge next turn.", -1, 0, 3, new AddTagAttr(BattleTagType.RECHARGING, true)),
new AttackMove(Moves.METEOR_MASH, "Meteor Mash", Type.STEEL, MoveCategory.PHYSICAL, 90, 90, 10, -1, "May raise user's Attack.", 20, 0, 3, new StatChangeAttr(BattleStat.ATK, 1, true)), new AttackMove(Moves.METEOR_MASH, "Meteor Mash", Type.STEEL, MoveCategory.PHYSICAL, 90, 90, 10, -1, "May raise user's Attack.", 20, 0, 3, new StatChangeAttr(BattleStat.ATK, 1, true)),
new AttackMove(Moves.ASTONISH, "Astonish", Type.GHOST, MoveCategory.PHYSICAL, 30, 100, 15, -1, "May cause flinching.", 30, 0, 3, new FlinchAttr()), new AttackMove(Moves.ASTONISH, "Astonish", Type.GHOST, MoveCategory.PHYSICAL, 30, 100, 15, -1, "May cause flinching.", 30, 0, 3, new FlinchAttr()),
new AttackMove(Moves.WEATHER_BALL, "Weather Ball", Type.NORMAL, MoveCategory.SPECIAL, 50, 100, 10, -1, "Move's power and type changes with the weather.", -1, 0, 3), new AttackMove(Moves.WEATHER_BALL, "Weather Ball", Type.NORMAL, MoveCategory.SPECIAL, 50, 100, 10, -1, "Move's power and type changes with the weather.", -1, 0, 3),
@ -1747,7 +1749,7 @@ export const allMoves = [
new StatusMove(Moves.BLOCK, "Block", Type.NORMAL, -1, 5, -1, "Opponent cannot flee or switch.", -1, 0, 3), new StatusMove(Moves.BLOCK, "Block", Type.NORMAL, -1, 5, -1, "Opponent cannot flee or switch.", -1, 0, 3),
new SelfStatusMove(Moves.HOWL, "Howl", Type.NORMAL, -1, 40, -1, "Raises Attack of allies.", -1, 0, 3, new StatChangeAttr(BattleStat.ATK, 1, true)), // TODO new SelfStatusMove(Moves.HOWL, "Howl", Type.NORMAL, -1, 40, -1, "Raises Attack of allies.", -1, 0, 3, new StatChangeAttr(BattleStat.ATK, 1, true)), // TODO
new AttackMove(Moves.DRAGON_CLAW, "Dragon Claw", Type.DRAGON, MoveCategory.PHYSICAL, 80, 100, 15, 78, "", -1, 0, 3), new AttackMove(Moves.DRAGON_CLAW, "Dragon Claw", Type.DRAGON, MoveCategory.PHYSICAL, 80, 100, 15, 78, "", -1, 0, 3),
new AttackMove(Moves.FRENZY_PLANT, "Frenzy Plant", Type.GRASS, MoveCategory.SPECIAL, 150, 90, 5, 155, "User must recharge next turn.", -1, 0, 3), new AttackMove(Moves.FRENZY_PLANT, "Frenzy Plant", Type.GRASS, MoveCategory.SPECIAL, 150, 90, 5, 155, "User must recharge next turn.", -1, 0, 3, new AddTagAttr(BattleTagType.RECHARGING, true)),
new SelfStatusMove(Moves.BULK_UP, "Bulk Up", Type.FIGHTING, -1, 20, 64, "Raises user's Attack and Defense.", -1, 0, 3, new SelfStatusMove(Moves.BULK_UP, "Bulk Up", Type.FIGHTING, -1, 20, 64, "Raises user's Attack and Defense.", -1, 0, 3,
new StatChangeAttr([ BattleStat.ATK, BattleStat.DEF ], 1, true)), new StatChangeAttr([ BattleStat.ATK, BattleStat.DEF ], 1, true)),
new AttackMove(Moves.BOUNCE, "Bounce", Type.FLYING, MoveCategory.PHYSICAL, 85, 85, 5, -1, "Springs up on first turn, attacks on second. May paralyze opponent.", 30, 0, 3, new AttackMove(Moves.BOUNCE, "Bounce", Type.FLYING, MoveCategory.PHYSICAL, 85, 85, 5, -1, "Springs up on first turn, attacks on second. May paralyze opponent.", 30, 0, 3,
@ -1835,7 +1837,7 @@ export const allMoves = [
new AttackMove(Moves.BRAVE_BIRD, "Brave Bird", Type.FLYING, MoveCategory.PHYSICAL, 120, 100, 15, 164, "User receives recoil damage.", -1, 0, 4, new RecoilAttr()), new AttackMove(Moves.BRAVE_BIRD, "Brave Bird", Type.FLYING, MoveCategory.PHYSICAL, 120, 100, 15, 164, "User receives recoil damage.", -1, 0, 4, new RecoilAttr()),
new AttackMove(Moves.EARTH_POWER, "Earth Power", Type.GROUND, MoveCategory.SPECIAL, 90, 100, 10, 133, "May lower opponent's Special Defense.", 10, 0, 4, new StatChangeAttr(BattleStat.SPDEF, -1)), new AttackMove(Moves.EARTH_POWER, "Earth Power", Type.GROUND, MoveCategory.SPECIAL, 90, 100, 10, 133, "May lower opponent's Special Defense.", 10, 0, 4, new StatChangeAttr(BattleStat.SPDEF, -1)),
new StatusMove(Moves.SWITCHEROO, "Switcheroo", Type.DARK, 100, 10, -1, "Swaps held items with the opponent.", -1, 0, 4), new StatusMove(Moves.SWITCHEROO, "Switcheroo", Type.DARK, 100, 10, -1, "Swaps held items with the opponent.", -1, 0, 4),
new AttackMove(Moves.GIGA_IMPACT, "Giga Impact", Type.NORMAL, MoveCategory.PHYSICAL, 150, 90, 5, 152, "User must recharge next turn.", -1, 0, 4), new AttackMove(Moves.GIGA_IMPACT, "Giga Impact", Type.NORMAL, MoveCategory.PHYSICAL, 150, 90, 5, 152, "User must recharge next turn.", -1, 0, 4, new AddTagAttr(BattleTagType.RECHARGING, true)),
new SelfStatusMove(Moves.NASTY_PLOT, "Nasty Plot", Type.DARK, -1, 20, 140, "Sharply raises user's Special Attack.", -1, 0, 4, new StatChangeAttr(BattleStat.SPATK, 2, true)), new SelfStatusMove(Moves.NASTY_PLOT, "Nasty Plot", Type.DARK, -1, 20, 140, "Sharply raises user's Special Attack.", -1, 0, 4, new StatChangeAttr(BattleStat.SPATK, 2, true)),
new AttackMove(Moves.BULLET_PUNCH, "Bullet Punch", Type.STEEL, MoveCategory.PHYSICAL, 40, 100, 30, -1, "User attacks first.", -1, 1, 4), new AttackMove(Moves.BULLET_PUNCH, "Bullet Punch", Type.STEEL, MoveCategory.PHYSICAL, 40, 100, 30, -1, "User attacks first.", -1, 1, 4),
new AttackMove(Moves.AVALANCHE, "Avalanche", Type.ICE, MoveCategory.PHYSICAL, 60, 100, 10, 46, "Power doubles if user took damage first.", -1, -4, 4), new AttackMove(Moves.AVALANCHE, "Avalanche", Type.ICE, MoveCategory.PHYSICAL, 60, 100, 10, 46, "Power doubles if user took damage first.", -1, -4, 4),
@ -1858,7 +1860,7 @@ export const allMoves = [
new AttackMove(Moves.LAVA_PLUME, "Lava Plume", Type.FIRE, MoveCategory.SPECIAL, 80, 100, 15, -1, "May burn opponent.", 30, 0, 4, new StatusEffectAttr(StatusEffect.BURN)), new AttackMove(Moves.LAVA_PLUME, "Lava Plume", Type.FIRE, MoveCategory.SPECIAL, 80, 100, 15, -1, "May burn opponent.", 30, 0, 4, new StatusEffectAttr(StatusEffect.BURN)),
new AttackMove(Moves.LEAF_STORM, "Leaf Storm", Type.GRASS, MoveCategory.SPECIAL, 130, 90, 5, 159, "Sharply lowers user's Special Attack.", 100, 0, 4, new StatChangeAttr(BattleStat.SPATK, -2, true)), new AttackMove(Moves.LEAF_STORM, "Leaf Storm", Type.GRASS, MoveCategory.SPECIAL, 130, 90, 5, 159, "Sharply lowers user's Special Attack.", 100, 0, 4, new StatChangeAttr(BattleStat.SPATK, -2, true)),
new AttackMove(Moves.POWER_WHIP, "Power Whip", Type.GRASS, MoveCategory.PHYSICAL, 120, 85, 10, -1, "", -1, 0, 4), new AttackMove(Moves.POWER_WHIP, "Power Whip", Type.GRASS, MoveCategory.PHYSICAL, 120, 85, 10, -1, "", -1, 0, 4),
new AttackMove(Moves.ROCK_WRECKER, "Rock Wrecker", Type.ROCK, MoveCategory.PHYSICAL, 150, 90, 5, -1, "User must recharge next turn.", -1, 0, 4), new AttackMove(Moves.ROCK_WRECKER, "Rock Wrecker", Type.ROCK, MoveCategory.PHYSICAL, 150, 90, 5, -1, "User must recharge next turn.", -1, 0, 4, new AddTagAttr(BattleTagType.RECHARGING, true)),
new AttackMove(Moves.CROSS_POISON, "Cross Poison", Type.POISON, MoveCategory.PHYSICAL, 70, 100, 20, -1, "High critical hit ratio. May poison opponent.", 10, 0, 4, new AttackMove(Moves.CROSS_POISON, "Cross Poison", Type.POISON, MoveCategory.PHYSICAL, 70, 100, 20, -1, "High critical hit ratio. May poison opponent.", 10, 0, 4,
new HighCritAttr(), new StatusEffectAttr(StatusEffect.POISON)), new HighCritAttr(), new StatusEffectAttr(StatusEffect.POISON)),
new AttackMove(Moves.GUNK_SHOT, "Gunk Shot", Type.POISON, MoveCategory.PHYSICAL, 120, 80, 5, 102, "May poison opponent.", 30, 0, 4, new StatusEffectAttr(StatusEffect.POISON)), new AttackMove(Moves.GUNK_SHOT, "Gunk Shot", Type.POISON, MoveCategory.PHYSICAL, 120, 80, 5, 102, "May poison opponent.", 30, 0, 4, new StatusEffectAttr(StatusEffect.POISON)),
@ -1880,7 +1882,7 @@ export const allMoves = [
new SelfStatusMove(Moves.HEAL_ORDER, "Heal Order", Type.BUG, -1, 10, -1, "User recovers half its max HP.", -1, 0, 4, new HealAttr(0.5)), new SelfStatusMove(Moves.HEAL_ORDER, "Heal Order", Type.BUG, -1, 10, -1, "User recovers half its max HP.", -1, 0, 4, new HealAttr(0.5)),
new AttackMove(Moves.HEAD_SMASH, "Head Smash", Type.ROCK, MoveCategory.PHYSICAL, 150, 80, 5, -1, "User receives recoil damage.", -1, 0, 4, new RecoilAttr()), new AttackMove(Moves.HEAD_SMASH, "Head Smash", Type.ROCK, MoveCategory.PHYSICAL, 150, 80, 5, -1, "User receives recoil damage.", -1, 0, 4, new RecoilAttr()),
new AttackMove(Moves.DOUBLE_HIT, "Double Hit", Type.NORMAL, MoveCategory.PHYSICAL, 35, 90, 10, -1, "Hits twice in one turn.", -1, 0, 4, new MultiHitAttr(MultiHitType._2)), new AttackMove(Moves.DOUBLE_HIT, "Double Hit", Type.NORMAL, MoveCategory.PHYSICAL, 35, 90, 10, -1, "Hits twice in one turn.", -1, 0, 4, new MultiHitAttr(MultiHitType._2)),
new AttackMove(Moves.ROAR_OF_TIME, "Roar of Time", Type.DRAGON, MoveCategory.SPECIAL, 150, 90, 5, -1, "User must recharge next turn.", -1, 0, 4), new AttackMove(Moves.ROAR_OF_TIME, "Roar of Time", Type.DRAGON, MoveCategory.SPECIAL, 150, 90, 5, -1, "User must recharge next turn.", -1, 0, 4, new AddTagAttr(BattleTagType.RECHARGING, true)),
new AttackMove(Moves.SPACIAL_REND, "Spacial Rend", Type.DRAGON, MoveCategory.SPECIAL, 100, 95, 5, -1, "High critical hit ratio.", -1, 0, 4, new HighCritAttr()), new AttackMove(Moves.SPACIAL_REND, "Spacial Rend", Type.DRAGON, MoveCategory.SPECIAL, 100, 95, 5, -1, "High critical hit ratio.", -1, 0, 4, new HighCritAttr()),
new SelfStatusMove(Moves.LUNAR_DANCE, "Lunar Dance", Type.PSYCHIC, -1, 10, -1, "The user faints but the next Pokémon released is fully healed.", -1, 0, 4, new SacrificialAttr()), // TODO new SelfStatusMove(Moves.LUNAR_DANCE, "Lunar Dance", Type.PSYCHIC, -1, 10, -1, "The user faints but the next Pokémon released is fully healed.", -1, 0, 4, new SacrificialAttr()), // TODO
new AttackMove(Moves.CRUSH_GRIP, "Crush Grip", Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 5, -1, "More powerful when opponent has higher HP.", -1, 0, 4), new AttackMove(Moves.CRUSH_GRIP, "Crush Grip", Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 5, -1, "More powerful when opponent has higher HP.", -1, 0, 4),

View File

@ -299,12 +299,12 @@ export class TmModifierType extends PokemonModifierType {
public moveId: Moves; public moveId: Moves;
constructor(moveId: Moves) { constructor(moveId: Moves) {
super(`TM${Utils.padInt(Object.keys(tmSpecies).indexOf(moveId.toString()) + 1, 3)} - ${allMoves[moveId - 1].name}`, `Teach ${allMoves[moveId - 1].name} to a POKéMON`, (_type, args) => new Modifiers.TmModifier(this, (args[0] as PlayerPokemon).id), super(`TM${Utils.padInt(Object.keys(tmSpecies).indexOf(moveId.toString()) + 1, 3)} - ${allMoves[moveId].name}`, `Teach ${allMoves[moveId].name} to a POKéMON`, (_type, args) => new Modifiers.TmModifier(this, (args[0] as PlayerPokemon).id),
(pokemon: PlayerPokemon) => { (pokemon: PlayerPokemon) => {
if (pokemon.compatibleTms.indexOf(moveId) === -1 || pokemon.moveset.filter(m => m?.moveId === moveId).length) if (pokemon.compatibleTms.indexOf(moveId) === -1 || pokemon.moveset.filter(m => m?.moveId === moveId).length)
return PartyUiHandler.NoEffectMessage; return PartyUiHandler.NoEffectMessage;
return null; return null;
}, `tm_${Type[allMoves[moveId - 1].type].toLowerCase()}`, 'tm'); }, `tm_${Type[allMoves[moveId].type].toLowerCase()}`, 'tm');
this.moveId = moveId; this.moveId = moveId;
} }

View File

@ -382,21 +382,21 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
const attackMovePool = movePool.filter(m => { const attackMovePool = movePool.filter(m => {
const move = allMoves[m - 1]; const move = allMoves[m];
return move.category !== MoveCategory.STATUS; return move.category !== MoveCategory.STATUS;
}); });
if (attackMovePool.length) { if (attackMovePool.length) {
const moveIndex = Utils.randInt(attackMovePool.length); const moveIndex = Utils.randInt(attackMovePool.length);
this.moveset.push(new PokemonMove(attackMovePool[moveIndex], 0, 0)); this.moveset.push(new PokemonMove(attackMovePool[moveIndex], 0, 0));
console.log(allMoves[attackMovePool[moveIndex] - 1]); console.log(allMoves[attackMovePool[moveIndex]]);
movePool.splice(movePool.findIndex(m => m === attackMovePool[moveIndex]), 1); movePool.splice(movePool.findIndex(m => m === attackMovePool[moveIndex]), 1);
} }
while (movePool.length && this.moveset.length < 4) { while (movePool.length && this.moveset.length < 4) {
const moveIndex = Utils.randInt(movePool.length); const moveIndex = Utils.randInt(movePool.length);
this.moveset.push(new PokemonMove(movePool[moveIndex], 0, 0)); this.moveset.push(new PokemonMove(movePool[moveIndex], 0, 0));
console.log(allMoves[movePool[moveIndex] - 1]); console.log(allMoves[movePool[moveIndex]]);
movePool.splice(moveIndex, 1); movePool.splice(moveIndex, 1);
} }
} }
@ -538,6 +538,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.hp = Math.max(this.hp - damage, 0); this.hp = Math.max(this.hp - damage, 0);
if (!this.hp) { if (!this.hp) {
this.scene.pushPhase(new FaintPhase(this.scene, this.isPlayer())); this.scene.pushPhase(new FaintPhase(this.scene, this.isPlayer()));
this.resetSummonData();
(this.isPlayer() ? this.scene.getEnemyPokemon() : this.scene.getPlayerPokemon()).resetBattleSummonData(); (this.isPlayer() ? this.scene.getEnemyPokemon() : this.scene.getPlayerPokemon()).resetBattleSummonData();
} }
} }
@ -592,11 +593,19 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}); });
} }
getMoveHistory(): TurnMove[] {
return this.summonData.moveHistory;
}
getLastXMoves(turnCount?: integer): TurnMove[] { getLastXMoves(turnCount?: integer): TurnMove[] {
const moveHistory = this.summonData.moveHistory; const moveHistory = this.getMoveHistory();
return moveHistory.slice(turnCount >= 0 ? Math.max(moveHistory.length - (turnCount || 1), 0) : 0, moveHistory.length).reverse(); return moveHistory.slice(turnCount >= 0 ? Math.max(moveHistory.length - (turnCount || 1), 0) : 0, moveHistory.length).reverse();
} }
getMoveQueue(): QueuedMove[] {
return this.summonData.moveQueue;
}
cry(soundConfig?: Phaser.Types.Sound.SoundConfig): integer { cry(soundConfig?: Phaser.Types.Sound.SoundConfig): integer {
return this.getSpeciesForm().cry(this.scene, soundConfig); return this.getSpeciesForm().cry(this.scene, soundConfig);
} }
@ -870,14 +879,14 @@ export class EnemyPokemon extends Pokemon {
} }
getNextMove(): PokemonMove { getNextMove(): PokemonMove {
const queuedMove = this.summonData.moveQueue.length const queuedMove = this.getMoveQueue().length
? this.moveset.find(m => m.moveId === this.summonData.moveQueue[0].move) ? this.moveset.find(m => m.moveId === this.getMoveQueue()[0].move)
: null; : null;
if (queuedMove) { if (queuedMove) {
if (queuedMove.isUsable(this.summonData.moveQueue[0].ignorePP)) if (queuedMove.isUsable(this.getMoveQueue()[0].ignorePP))
return queuedMove; return queuedMove;
else { else {
this.summonData.moveQueue.shift(); this.getMoveQueue().shift();
return this.getNextMove(); return this.getNextMove();
} }
} }
@ -1051,7 +1060,7 @@ export class PokemonMove {
} }
getMove(): Move { getMove(): Move {
return allMoves[this.moveId - 1]; return allMoves[this.moveId];
} }
getName(): string { getName(): string {