mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-04 07:22:19 +02:00
Add WiP logic for double battles
This commit is contained in:
parent
0757fd88a4
commit
c123119d48
@ -161,7 +161,7 @@ export class Arena {
|
|||||||
this.weather = weather ? new Weather(weather, viaMove ? 5 : 0) : null;
|
this.weather = weather ? new Weather(weather, viaMove ? 5 : 0) : null;
|
||||||
|
|
||||||
if (this.weather) {
|
if (this.weather) {
|
||||||
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, true, CommonAnim.SUNNY + (weather - 1)));
|
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, true, 0, 0, CommonAnim.SUNNY + (weather - 1)));
|
||||||
this.scene.queueMessage(getWeatherStartMessage(weather));
|
this.scene.queueMessage(getWeatherStartMessage(weather));
|
||||||
} else
|
} else
|
||||||
this.scene.queueMessage(getWeatherClearMessage(oldWeatherType));
|
this.scene.queueMessage(getWeatherClearMessage(oldWeatherType));
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
import Phaser from 'phaser';
|
import Phaser from 'phaser';
|
||||||
import { Biome } from './data/biome';
|
import { Biome } from './data/biome';
|
||||||
import UI from './ui/ui';
|
import UI from './ui/ui';
|
||||||
import { EncounterPhase, SummonPhase, CommandPhase, NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, CheckLoadPhase } from './battle-phases';
|
import { EncounterPhase, SummonPhase, NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, CheckLoadPhase, TurnInitPhase } from './battle-phases';
|
||||||
import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon';
|
import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon';
|
||||||
import PokemonSpecies, { allSpecies, getPokemonSpecies, initSpecies } from './data/pokemon-species';
|
import PokemonSpecies, { allSpecies, getPokemonSpecies, initSpecies } from './data/pokemon-species';
|
||||||
import * as Utils from './utils';
|
import * as Utils from './utils';
|
||||||
@ -9,7 +9,6 @@ import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, P
|
|||||||
import { PokeballType } from './data/pokeball';
|
import { PokeballType } from './data/pokeball';
|
||||||
import { Species } from './data/species';
|
import { Species } from './data/species';
|
||||||
import { initAutoPlay } from './system/auto-play';
|
import { initAutoPlay } from './system/auto-play';
|
||||||
import { Battle } from './battle';
|
|
||||||
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from './data/battle-anims';
|
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from './data/battle-anims';
|
||||||
import { BattlePhase } from './battle-phase';
|
import { BattlePhase } from './battle-phase';
|
||||||
import { initGameSpeed } from './system/game-speed';
|
import { initGameSpeed } from './system/game-speed';
|
||||||
@ -21,6 +20,7 @@ import { Moves, initMoves } from './data/move';
|
|||||||
import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave } from './modifier/modifier-type';
|
import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave } from './modifier/modifier-type';
|
||||||
import AbilityBar from './ui/ability-bar';
|
import AbilityBar from './ui/ability-bar';
|
||||||
import { BlockItemTheftAbAttr, applyAbAttrs, initAbilities } from './data/ability';
|
import { BlockItemTheftAbAttr, applyAbAttrs, initAbilities } from './data/ability';
|
||||||
|
import Battle from './battle';
|
||||||
|
|
||||||
const enableAuto = true;
|
const enableAuto = true;
|
||||||
const quickStart = false;
|
const quickStart = false;
|
||||||
@ -446,21 +446,35 @@ export default class BattleScene extends Phaser.Scene {
|
|||||||
return this.party;
|
return this.party;
|
||||||
}
|
}
|
||||||
|
|
||||||
getEnemyParty(): EnemyPokemon[] {
|
|
||||||
return this.getEnemyPokemon() ? [ this.getEnemyPokemon() ] : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
getPlayerPokemon(): PlayerPokemon {
|
getPlayerPokemon(): PlayerPokemon {
|
||||||
return this.getParty()[0];
|
return this.getParty()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPlayerField(): PlayerPokemon[] {
|
||||||
|
const party = this.getParty();
|
||||||
|
return party.slice(0, Math.min(party.length, this.currentBattle?.double ? 2 : 1));
|
||||||
|
}
|
||||||
|
|
||||||
getEnemyPokemon(): EnemyPokemon {
|
getEnemyPokemon(): EnemyPokemon {
|
||||||
return this.currentBattle?.enemyPokemon;
|
return this.currentBattle?.enemyField[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
getEnemyField(): EnemyPokemon[] {
|
||||||
|
return this.currentBattle?.enemyField || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
getField(): Pokemon[] {
|
||||||
|
const ret = new Array(4).fill(null);
|
||||||
|
const playerField = this.getPlayerField();
|
||||||
|
const enemyField = this.getEnemyField();
|
||||||
|
ret.splice(0, playerField.length, ...playerField);
|
||||||
|
ret.splice(2, enemyField.length, ...enemyField);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPokemonById(pokemonId: integer): Pokemon {
|
getPokemonById(pokemonId: integer): Pokemon {
|
||||||
const findInParty = (party: Pokemon[]) => party.find(p => p.id === pokemonId);
|
const findInParty = (party: Pokemon[]) => party.find(p => p.id === pokemonId);
|
||||||
return findInParty(this.getParty()) || findInParty(this.getEnemyParty());
|
return findInParty(this.getParty()) || findInParty(this.getEnemyField());
|
||||||
}
|
}
|
||||||
|
|
||||||
reset(): void {
|
reset(): void {
|
||||||
@ -475,7 +489,7 @@ export default class BattleScene extends Phaser.Scene {
|
|||||||
for (let p of this.getParty())
|
for (let p of this.getParty())
|
||||||
p.destroy();
|
p.destroy();
|
||||||
this.party = [];
|
this.party = [];
|
||||||
for (let p of this.getEnemyParty())
|
for (let p of this.getEnemyField())
|
||||||
p.destroy();
|
p.destroy();
|
||||||
|
|
||||||
this.currentBattle = null;
|
this.currentBattle = null;
|
||||||
@ -493,10 +507,10 @@ export default class BattleScene extends Phaser.Scene {
|
|||||||
this.trainer.setPosition(406, 132);
|
this.trainer.setPosition(406, 132);
|
||||||
}
|
}
|
||||||
|
|
||||||
newBattle(waveIndex?: integer): Battle {
|
newBattle(waveIndex?: integer, double?: boolean): Battle {
|
||||||
if (!waveIndex) {
|
if (!waveIndex) {
|
||||||
if (this.currentBattle) {
|
if (this.currentBattle) {
|
||||||
this.getEnemyPokemon().destroy();
|
this.getEnemyField().forEach(enemyPokemon => enemyPokemon.destroy());
|
||||||
if (this.currentBattle.waveIndex % 10)
|
if (this.currentBattle.waveIndex % 10)
|
||||||
this.pushPhase(new NextEncounterPhase(this));
|
this.pushPhase(new NextEncounterPhase(this));
|
||||||
else {
|
else {
|
||||||
@ -509,12 +523,14 @@ export default class BattleScene extends Phaser.Scene {
|
|||||||
else {
|
else {
|
||||||
this.arena.playBgm();
|
this.arena.playBgm();
|
||||||
this.pushPhase(new EncounterPhase(this));
|
this.pushPhase(new EncounterPhase(this));
|
||||||
this.pushPhase(new SummonPhase(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));
|
this.currentBattle = new Battle(waveIndex || ((this.currentBattle?.waveIndex || (startingWave - 1)) + 1), double === undefined || double);
|
||||||
|
|
||||||
return this.currentBattle;
|
return this.currentBattle;
|
||||||
}
|
}
|
||||||
@ -699,7 +715,7 @@ export default class BattleScene extends Phaser.Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
populatePhaseQueue(): void {
|
populatePhaseQueue(): void {
|
||||||
this.phaseQueue.push(new CommandPhase(this));
|
this.phaseQueue.push(new TurnInitPhase(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
addModifier(modifier: Modifier, playSound?: boolean, virtual?: boolean): Promise<void> {
|
addModifier(modifier: Modifier, playSound?: boolean, virtual?: boolean): Promise<void> {
|
||||||
@ -828,7 +844,9 @@ export default class BattleScene extends Phaser.Scene {
|
|||||||
}
|
}
|
||||||
if (isBoss)
|
if (isBoss)
|
||||||
count = Math.max(count, Math.floor(chances / 2));
|
count = Math.max(count, Math.floor(chances / 2));
|
||||||
getEnemyModifierTypesForWave(waveIndex, count, this.getEnemyParty()).map(mt => mt.newModifier(this.getEnemyPokemon()).add(this.enemyModifiers, false));
|
const enemyField = this.getEnemyField();
|
||||||
|
getEnemyModifierTypesForWave(waveIndex, count, this.getEnemyField())
|
||||||
|
.map(mt => mt.newModifier(enemyField[enemyField.length === 1 ? 0 : Utils.randInt(enemyField.length)]).add(this.enemyModifiers, false));
|
||||||
|
|
||||||
this.updateModifiers(false).then(() => resolve());
|
this.updateModifiers(false).then(() => resolve());
|
||||||
});
|
});
|
||||||
@ -855,7 +873,7 @@ export default class BattleScene extends Phaser.Scene {
|
|||||||
modifiers.splice(modifiers.indexOf(modifier), 1);
|
modifiers.splice(modifiers.indexOf(modifier), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyParty()).then(() => {
|
this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyField()).then(() => {
|
||||||
(player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers);
|
(player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers);
|
||||||
if (!player)
|
if (!player)
|
||||||
this.updateWaveCountPosition();
|
this.updateWaveCountPosition();
|
||||||
|
@ -1,18 +1,44 @@
|
|||||||
import { EnemyPokemon, PlayerPokemon } from "./pokemon";
|
import { EnemyPokemon, PlayerPokemon, QueuedMove } from "./pokemon";
|
||||||
|
import { Command } from "./ui/command-ui-handler";
|
||||||
import * as Utils from "./utils";
|
import * as Utils from "./utils";
|
||||||
|
|
||||||
export class Battle {
|
export enum BattleTarget {
|
||||||
|
PLAYER,
|
||||||
|
PLAYER_2,
|
||||||
|
ENEMY,
|
||||||
|
ENEMY_2
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TurnCommand {
|
||||||
|
command: Command;
|
||||||
|
cursor?: integer;
|
||||||
|
move?: QueuedMove;
|
||||||
|
targetIndex?: integer;
|
||||||
|
args?: any[];
|
||||||
|
};
|
||||||
|
|
||||||
|
interface TurnCommands {
|
||||||
|
[key: integer]: TurnCommand
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Battle {
|
||||||
public waveIndex: integer;
|
public waveIndex: integer;
|
||||||
public enemyLevel: integer;
|
public enemyLevels: integer[];
|
||||||
public enemyPokemon: EnemyPokemon;
|
public enemyField: EnemyPokemon[];
|
||||||
|
public double: boolean;
|
||||||
public turn: integer;
|
public turn: integer;
|
||||||
|
public turnCommands: TurnCommands;
|
||||||
public playerParticipantIds: Set<integer> = new Set<integer>();
|
public playerParticipantIds: Set<integer> = new Set<integer>();
|
||||||
public escapeAttempts: integer = 0;
|
public escapeAttempts: integer = 0;
|
||||||
|
|
||||||
constructor(waveIndex: integer) {
|
constructor(waveIndex: integer, double: boolean) {
|
||||||
this.waveIndex = waveIndex;
|
this.waveIndex = waveIndex;
|
||||||
this.enemyLevel = this.getLevelForWave();
|
this.enemyLevels = new Array(double ? 2 : 1).fill(null).map(() => this.getLevelForWave());
|
||||||
this.turn = 1;
|
this.enemyField = [];
|
||||||
|
this.double = double;
|
||||||
|
this.turn = 0;
|
||||||
|
|
||||||
|
this.incrementTurn();
|
||||||
}
|
}
|
||||||
|
|
||||||
private getLevelForWave(): number {
|
private getLevelForWave(): number {
|
||||||
@ -31,6 +57,7 @@ export class Battle {
|
|||||||
|
|
||||||
incrementTurn() {
|
incrementTurn() {
|
||||||
this.turn++;
|
this.turn++;
|
||||||
|
this.turnCommands = Object.fromEntries(Utils.getEnumValues(BattleTarget).map(bt => [ bt, null ]));
|
||||||
}
|
}
|
||||||
|
|
||||||
addParticipant(playerPokemon: PlayerPokemon): void {
|
addParticipant(playerPokemon: PlayerPokemon): void {
|
||||||
|
@ -157,7 +157,7 @@ export class TypeImmunityHealAbAttr extends TypeImmunityAbAttr {
|
|||||||
|
|
||||||
if (ret && pokemon.getHpRatio() < 1) {
|
if (ret && pokemon.getHpRatio() < 1) {
|
||||||
const scene = pokemon.scene;
|
const scene = pokemon.scene;
|
||||||
scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.isPlayer(), Math.max(Math.floor(pokemon.getMaxHp() / 4), 1), getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nrestored its HP a little!`), true));
|
scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.isPlayer(), pokemon.getFieldIndex(), Math.max(Math.floor(pokemon.getMaxHp() / 4), 1), getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nrestored its HP a little!`), true));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ class TypeImmunityStatChangeAbAttr extends TypeImmunityAbAttr {
|
|||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
cancelled.value = true;
|
cancelled.value = true;
|
||||||
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.isPlayer(), true, [ this.stat ], this.levels));
|
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(), true, [ this.stat ], this.levels));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -406,9 +406,9 @@ export class PostSummonStatChangeAbAttr extends PostSummonAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
applyPostSummon(pokemon: Pokemon, args: any[]): boolean {
|
applyPostSummon(pokemon: Pokemon, args: any[]): boolean {
|
||||||
const statChangePhase = new StatChangePhase(pokemon.scene, pokemon.isPlayer() === this.selfTarget, this.selfTarget, this.stats, this.levels);
|
const statChangePhase = new StatChangePhase(pokemon.scene, pokemon.isPlayer() === this.selfTarget, pokemon.getFieldIndex(), this.selfTarget, this.stats, this.levels);
|
||||||
|
|
||||||
if (!this.selfTarget && !pokemon.getOpponent()?.summonData)
|
if (!this.selfTarget && !pokemon.getOpponent(0)?.summonData)
|
||||||
pokemon.scene.pushPhase(statChangePhase); // TODO: This causes the ability bar to be shown at the wrong time
|
pokemon.scene.pushPhase(statChangePhase); // TODO: This causes the ability bar to be shown at the wrong time
|
||||||
else
|
else
|
||||||
pokemon.scene.unshiftPhase(statChangePhase);
|
pokemon.scene.unshiftPhase(statChangePhase);
|
||||||
@ -576,7 +576,7 @@ export class PostTurnAbAttr extends AbAttr {
|
|||||||
|
|
||||||
export class PostTurnSpeedBoostAbAttr extends PostTurnAbAttr {
|
export class PostTurnSpeedBoostAbAttr extends PostTurnAbAttr {
|
||||||
applyPostTurn(pokemon: Pokemon, args: any[]): boolean {
|
applyPostTurn(pokemon: Pokemon, args: any[]): boolean {
|
||||||
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.isPlayer(), true, [ BattleStat.SPD ], 1));
|
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(), true, [ BattleStat.SPD ], 1));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -594,7 +594,8 @@ export class PostTurnHealAbAttr extends PostTurnAbAttr {
|
|||||||
applyPostTurn(pokemon: Pokemon, args: any[]): boolean {
|
applyPostTurn(pokemon: Pokemon, args: any[]): boolean {
|
||||||
if (pokemon.getHpRatio() < 1) {
|
if (pokemon.getHpRatio() < 1) {
|
||||||
const scene = pokemon.scene;
|
const scene = pokemon.scene;
|
||||||
scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.isPlayer(), Math.max(Math.floor(pokemon.getMaxHp() / 16), 1), getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nrestored its HP a little!`), true));
|
scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.isPlayer(), pokemon.getFieldIndex(),
|
||||||
|
Math.max(Math.floor(pokemon.getMaxHp() / 16), 1), getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nrestored its HP a little!`), true));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,7 +633,7 @@ export class PostWeatherLapseHealAbAttr extends PostWeatherLapseAbAttr {
|
|||||||
applyPostWeatherLapse(pokemon: Pokemon, weather: Weather, args: any[]): boolean {
|
applyPostWeatherLapse(pokemon: Pokemon, weather: Weather, args: any[]): boolean {
|
||||||
if (pokemon.getHpRatio() < 1) {
|
if (pokemon.getHpRatio() < 1) {
|
||||||
const scene = pokemon.scene;
|
const scene = pokemon.scene;
|
||||||
scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.isPlayer(), Math.max(Math.floor(pokemon.getMaxHp() / (16 / this.healFactor)), 1), getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nrestored its HP a little!`), true));
|
scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.isPlayer(), pokemon.getFieldIndex(), Math.max(Math.floor(pokemon.getMaxHp() / (16 / this.healFactor)), 1), getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nrestored its HP a little!`), true));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -988,7 +989,7 @@ function canApplyAttr(pokemon: Pokemon, attr: AbAttr): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function queueShowAbility(pokemon: Pokemon): void {
|
function queueShowAbility(pokemon: Pokemon): void {
|
||||||
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.isPlayer()));
|
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex()));
|
||||||
pokemon.scene.clearPhaseQueueSplice();
|
pokemon.scene.clearPhaseQueueSplice();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1232,8 +1233,8 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.MAGMA_ARMOR, "Magma Armor", "Prevents the POKéMON from becoming frozen.", 3)
|
new Ability(Abilities.MAGMA_ARMOR, "Magma Armor", "Prevents the POKéMON from becoming frozen.", 3)
|
||||||
.attr(StatusEffectImmunityAbAttr, StatusEffect.FREEZE),
|
.attr(StatusEffectImmunityAbAttr, StatusEffect.FREEZE),
|
||||||
new Ability(Abilities.MAGNET_PULL, "Magnet Pull", "Prevents STEEL-type POKéMON from escaping.", 3)
|
new Ability(Abilities.MAGNET_PULL, "Magnet Pull", "Prevents STEEL-type POKéMON from escaping.", 3)
|
||||||
.attr(ArenaTrapAbAttr)
|
/*.attr(ArenaTrapAbAttr)
|
||||||
.condition((pokemon: Pokemon) => pokemon.getOpponent()?.isOfType(Type.STEEL)),
|
.condition((pokemon: Pokemon) => pokemon.getOpponent()?.isOfType(Type.STEEL))*/, // TODO: Rework
|
||||||
new Ability(Abilities.MARVEL_SCALE, "Marvel Scale (N)", "Ups DEFENSE if there is a status problem.", 3),
|
new Ability(Abilities.MARVEL_SCALE, "Marvel Scale (N)", "Ups DEFENSE if there is a status problem.", 3),
|
||||||
new Ability(Abilities.MINUS, "Minus (N)", "Ups SP. ATK if another POKéMON has PLUS or MINUS.", 3),
|
new Ability(Abilities.MINUS, "Minus (N)", "Ups SP. ATK if another POKéMON has PLUS or MINUS.", 3),
|
||||||
new Ability(Abilities.NATURAL_CURE, "Natural Cure (N)", "All status problems heal when it switches out.", 3),
|
new Ability(Abilities.NATURAL_CURE, "Natural Cure (N)", "All status problems heal when it switches out.", 3),
|
||||||
|
@ -143,8 +143,7 @@ class SpikesTag extends ArenaTrapTag {
|
|||||||
super.onAdd(arena);
|
super.onAdd(arena);
|
||||||
|
|
||||||
const source = arena.scene.getPokemonById(this.sourceId);
|
const source = arena.scene.getPokemonById(this.sourceId);
|
||||||
const target = source.getOpponent();
|
arena.scene.queueMessage(`${this.getMoveName()} were scattered\nall around ${source.getOpponentDescriptor()}'s feet!`);
|
||||||
arena.scene.queueMessage(`${this.getMoveName()} were scattered\nall around ${target.name}'s feet!`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
activateTrap(pokemon: Pokemon): boolean {
|
activateTrap(pokemon: Pokemon): boolean {
|
||||||
@ -170,15 +169,14 @@ class ToxicSpikesTag extends ArenaTrapTag {
|
|||||||
super.onAdd(arena);
|
super.onAdd(arena);
|
||||||
|
|
||||||
const source = arena.scene.getPokemonById(this.sourceId);
|
const source = arena.scene.getPokemonById(this.sourceId);
|
||||||
const target = source.getOpponent();
|
arena.scene.queueMessage(`${this.getMoveName()} were scattered\nall around ${source.getOpponentDescriptor()}'s feet!`);
|
||||||
arena.scene.queueMessage(`${this.getMoveName()} were scattered\nall around ${target.name}'s feet!`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
activateTrap(pokemon: Pokemon): boolean {
|
activateTrap(pokemon: Pokemon): boolean {
|
||||||
if (!pokemon.status && (!pokemon.isOfType(Type.FLYING) || pokemon.getTag(BattlerTagType.IGNORE_FLYING) || pokemon.scene.arena.getTag(ArenaTagType.GRAVITY))) {
|
if (!pokemon.status && (!pokemon.isOfType(Type.FLYING) || pokemon.getTag(BattlerTagType.IGNORE_FLYING) || pokemon.scene.arena.getTag(ArenaTagType.GRAVITY))) {
|
||||||
const toxic = this.layers > 1;
|
const toxic = this.layers > 1;
|
||||||
|
|
||||||
pokemon.scene.unshiftPhase(new ObtainStatusEffectPhase(pokemon.scene, pokemon.isPlayer(),
|
pokemon.scene.unshiftPhase(new ObtainStatusEffectPhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(),
|
||||||
!toxic ? StatusEffect.POISON : StatusEffect.TOXIC, null, `the ${this.getMoveName()}`));
|
!toxic ? StatusEffect.POISON : StatusEffect.TOXIC, null, `the ${this.getMoveName()}`));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -196,8 +194,7 @@ class StealthRockTag extends ArenaTrapTag {
|
|||||||
super.onAdd(arena);
|
super.onAdd(arena);
|
||||||
|
|
||||||
const source = arena.scene.getPokemonById(this.sourceId);
|
const source = arena.scene.getPokemonById(this.sourceId);
|
||||||
const target = source.getOpponent();
|
arena.scene.queueMessage(`Pointed stones float in the air\naround ${source.getOpponentDescriptor()}!`);
|
||||||
arena.scene.queueMessage(`Pointed stones float in the air\naround ${target.name}!`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
activateTrap(pokemon: Pokemon): boolean {
|
activateTrap(pokemon: Pokemon): boolean {
|
||||||
@ -242,8 +239,8 @@ export class TrickRoomTag extends ArenaTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply(args: any[]): boolean {
|
apply(args: any[]): boolean {
|
||||||
const speedDelayed = args[0] as Utils.BooleanHolder;
|
const speedReversed = args[0] as Utils.BooleanHolder;
|
||||||
speedDelayed.value = !speedDelayed.value;
|
speedReversed.value = !speedReversed.value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -831,8 +831,8 @@ export class CommonBattleAnim extends BattleAnim {
|
|||||||
export class MoveAnim extends BattleAnim {
|
export class MoveAnim extends BattleAnim {
|
||||||
public move: Moves;
|
public move: Moves;
|
||||||
|
|
||||||
constructor(move: Moves, user: Pokemon) {
|
constructor(move: Moves, user: Pokemon, targetIndex: integer) {
|
||||||
super(user, getMoveTarget(user, move));
|
super(user, getMoveTarget(user, targetIndex, move));
|
||||||
|
|
||||||
this.move = move;
|
this.move = move;
|
||||||
}
|
}
|
||||||
@ -852,7 +852,7 @@ export class MoveChargeAnim extends MoveAnim {
|
|||||||
private chargeAnim: ChargeAnim;
|
private chargeAnim: ChargeAnim;
|
||||||
|
|
||||||
constructor(chargeAnim: ChargeAnim, move: Moves, user: Pokemon) {
|
constructor(chargeAnim: ChargeAnim, move: Moves, user: Pokemon) {
|
||||||
super(move, user);
|
super(move, user, 0);
|
||||||
|
|
||||||
this.chargeAnim = chargeAnim;
|
this.chargeAnim = chargeAnim;
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ export class ConfusedTag extends BattlerTag {
|
|||||||
onAdd(pokemon: Pokemon): void {
|
onAdd(pokemon: Pokemon): void {
|
||||||
super.onAdd(pokemon);
|
super.onAdd(pokemon);
|
||||||
|
|
||||||
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.isPlayer(), CommonAnim.CONFUSION));
|
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(), 0, CommonAnim.CONFUSION));
|
||||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' became\nconfused!'));
|
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' became\nconfused!'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,14 +198,14 @@ export class ConfusedTag extends BattlerTag {
|
|||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nconfused!'));
|
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nconfused!'));
|
||||||
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.isPlayer(), CommonAnim.CONFUSION));
|
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(), 0, CommonAnim.CONFUSION));
|
||||||
|
|
||||||
if (Utils.randInt(2)) {
|
if (Utils.randInt(2)) {
|
||||||
const atk = pokemon.getBattleStat(Stat.ATK);
|
const atk = pokemon.getBattleStat(Stat.ATK);
|
||||||
const def = pokemon.getBattleStat(Stat.DEF);
|
const def = pokemon.getBattleStat(Stat.DEF);
|
||||||
const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * ((Utils.randInt(15) + 85) / 100));
|
const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * ((Utils.randInt(15) + 85) / 100));
|
||||||
pokemon.scene.queueMessage('It hurt itself in its\nconfusion!');
|
pokemon.scene.queueMessage('It hurt itself in its\nconfusion!');
|
||||||
pokemon.scene.unshiftPhase(new DamagePhase(pokemon.scene, pokemon.isPlayer()));
|
pokemon.scene.unshiftPhase(new DamagePhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex()));
|
||||||
pokemon.damage(damage);
|
pokemon.damage(damage);
|
||||||
(pokemon.scene.getCurrentPhase() as MovePhase).cancel();
|
(pokemon.scene.getCurrentPhase() as MovePhase).cancel();
|
||||||
}
|
}
|
||||||
@ -245,7 +245,7 @@ export class InfatuatedTag extends BattlerTag {
|
|||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` is in love\nwith ${pokemon.scene.getPokemonById(this.sourceId).name}!`));
|
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` is in love\nwith ${pokemon.scene.getPokemonById(this.sourceId).name}!`));
|
||||||
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.isPlayer(), CommonAnim.ATTRACT));
|
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(), 0, CommonAnim.ATTRACT));
|
||||||
|
|
||||||
if (Utils.randInt(2)) {
|
if (Utils.randInt(2)) {
|
||||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nimmobilized by love!'));
|
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nimmobilized by love!'));
|
||||||
@ -282,12 +282,13 @@ export class SeedTag extends BattlerTag {
|
|||||||
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, !pokemon.isPlayer(), CommonAnim.LEECH_SEED));
|
const source = pokemon.scene.getPokemonById(this.sourceId);
|
||||||
|
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, source.isPlayer(), source.getFieldIndex(), pokemon.getFieldIndex(), CommonAnim.LEECH_SEED));
|
||||||
|
|
||||||
const damage = Math.max(Math.floor(pokemon.getMaxHp() / 8), 1);
|
const damage = Math.max(Math.floor(pokemon.getMaxHp() / 8), 1);
|
||||||
pokemon.scene.unshiftPhase(new DamagePhase(pokemon.scene, pokemon.isPlayer()));
|
pokemon.scene.unshiftPhase(new DamagePhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex()));
|
||||||
pokemon.damage(damage);
|
pokemon.damage(damage);
|
||||||
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, !pokemon.isPlayer(), damage, getPokemonMessage(pokemon, '\'s health is\nsapped by LEECH SEED!'), false, true));
|
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, !source.isPlayer(), source.getFieldIndex(), damage, getPokemonMessage(pokemon, '\'s health is\nsapped by LEECH SEED!'), false, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -320,10 +321,10 @@ export class NightmareTag extends BattlerTag {
|
|||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is locked\nin a NIGHTMARE!'));
|
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is locked\nin a NIGHTMARE!'));
|
||||||
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.isPlayer(), CommonAnim.CURSE)); // TODO: Update animation type
|
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(), 0, CommonAnim.CURSE)); // TODO: Update animation type
|
||||||
|
|
||||||
const damage = Math.ceil(pokemon.getMaxHp() / 4);
|
const damage = Math.ceil(pokemon.getMaxHp() / 4);
|
||||||
pokemon.scene.unshiftPhase(new DamagePhase(pokemon.scene, pokemon.isPlayer()));
|
pokemon.scene.unshiftPhase(new DamagePhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex()));
|
||||||
pokemon.damage(damage);
|
pokemon.damage(damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +345,7 @@ export class IngrainTag extends TrappedTag {
|
|||||||
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.isPlayer(), Math.floor(pokemon.getMaxHp() / 16),
|
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(), Math.floor(pokemon.getMaxHp() / 16),
|
||||||
getPokemonMessage(pokemon, ` absorbed\nnutrients with its roots!`), true));
|
getPokemonMessage(pokemon, ` absorbed\nnutrients with its roots!`), true));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -374,7 +375,8 @@ export class AquaRingTag extends BattlerTag {
|
|||||||
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.isPlayer(), Math.floor(pokemon.getMaxHp() / 16), `${this.getMoveName()} restored\n${pokemon.name}\'s HP!`, true));
|
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(),
|
||||||
|
Math.floor(pokemon.getMaxHp() / 16), `${this.getMoveName()} restored\n${pokemon.name}\'s HP!`, true));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -393,7 +395,7 @@ export class DrowsyTag extends BattlerTag {
|
|||||||
|
|
||||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
if (!super.lapse(pokemon, lapseType)) {
|
if (!super.lapse(pokemon, lapseType)) {
|
||||||
pokemon.scene.unshiftPhase(new ObtainStatusEffectPhase(pokemon.scene, pokemon.isPlayer(), StatusEffect.SLEEP));
|
pokemon.scene.unshiftPhase(new ObtainStatusEffectPhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(), StatusEffect.SLEEP));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,10 +425,10 @@ export abstract class DamagingTrapTag extends TrappedTag {
|
|||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` is hurt\nby ${this.getMoveName()}!`));
|
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` is hurt\nby ${this.getMoveName()}!`));
|
||||||
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.isPlayer(), this.commonAnim));
|
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(), 0, this.commonAnim));
|
||||||
|
|
||||||
const damage = Math.ceil(pokemon.getMaxHp() / 16);
|
const damage = Math.ceil(pokemon.getMaxHp() / 16);
|
||||||
pokemon.scene.unshiftPhase(new DamagePhase(pokemon.scene, pokemon.isPlayer()));
|
pokemon.scene.unshiftPhase(new DamagePhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex()));
|
||||||
pokemon.damage(damage);
|
pokemon.damage(damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,7 +543,7 @@ export class TruantTag extends BattlerTag {
|
|||||||
|
|
||||||
if (lastMove && lastMove.move !== Moves.NONE) {
|
if (lastMove && lastMove.move !== Moves.NONE) {
|
||||||
(pokemon.scene.getCurrentPhase() as MovePhase).cancel();
|
(pokemon.scene.getCurrentPhase() as MovePhase).cancel();
|
||||||
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.isPlayer()));
|
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex()));
|
||||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nloafing around!'));
|
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nloafing around!'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +54,7 @@ export function getBerryPredicate(berryType: BerryType): BerryPredicate {
|
|||||||
case BerryType.LUM:
|
case BerryType.LUM:
|
||||||
return (pokemon: Pokemon) => !!pokemon.status || !!pokemon.getTag(BattlerTagType.CONFUSED);
|
return (pokemon: Pokemon) => !!pokemon.status || !!pokemon.getTag(BattlerTagType.CONFUSED);
|
||||||
case BerryType.ENIGMA:
|
case BerryType.ENIGMA:
|
||||||
return (pokemon: Pokemon) => {
|
return (pokemon: Pokemon) => !!pokemon.turnData.attacksReceived.filter(a => a.result === MoveResult.SUPER_EFFECTIVE).length;
|
||||||
const opponent = pokemon.getOpponent();
|
|
||||||
const opponentLastMove = opponent ? opponent.getLastXMoves(1).find(() => true) : null; // TODO: Update so this works even if opponent has fainted
|
|
||||||
|
|
||||||
return opponentLastMove && opponentLastMove.turn === pokemon.scene.currentBattle?.turn - 1 && opponentLastMove.result === MoveResult.SUPER_EFFECTIVE;
|
|
||||||
};
|
|
||||||
case BerryType.LIECHI:
|
case BerryType.LIECHI:
|
||||||
case BerryType.GANLON:
|
case BerryType.GANLON:
|
||||||
case BerryType.SALAC:
|
case BerryType.SALAC:
|
||||||
@ -83,7 +78,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
|
|||||||
case BerryType.SITRUS:
|
case BerryType.SITRUS:
|
||||||
case BerryType.ENIGMA:
|
case BerryType.ENIGMA:
|
||||||
return (pokemon: Pokemon) => {
|
return (pokemon: Pokemon) => {
|
||||||
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.isPlayer(), Math.floor(pokemon.getMaxHp() / 4), getPokemonMessage(pokemon, `'s ${getBerryName(berryType)}\nrestored its HP!`), true));
|
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(), Math.floor(pokemon.getMaxHp() / 4), getPokemonMessage(pokemon, `'s ${getBerryName(berryType)}\nrestored its HP!`), true));
|
||||||
};
|
};
|
||||||
case BerryType.LUM:
|
case BerryType.LUM:
|
||||||
return (pokemon: Pokemon) => {
|
return (pokemon: Pokemon) => {
|
||||||
@ -101,13 +96,13 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
|
|||||||
case BerryType.APICOT:
|
case BerryType.APICOT:
|
||||||
return (pokemon: Pokemon) => {
|
return (pokemon: Pokemon) => {
|
||||||
const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
|
const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
|
||||||
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.isPlayer(), true, [ battleStat ], 1));
|
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(), true, [ battleStat ], 1));
|
||||||
};
|
};
|
||||||
case BerryType.LANSAT:
|
case BerryType.LANSAT:
|
||||||
return (pokemon: Pokemon) => {
|
return (pokemon: Pokemon) => {
|
||||||
pokemon.addTag(BattlerTagType.CRIT_BOOST);
|
pokemon.addTag(BattlerTagType.CRIT_BOOST);
|
||||||
};
|
};
|
||||||
case BerryType.STARF:
|
case BerryType.STARF:
|
||||||
return (pokemon: Pokemon) => pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.isPlayer(), true, [ BattleStat.RAND ], 2));
|
return (pokemon: Pokemon) => pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.isPlayer(), pokemon.getFieldIndex(), true, [ BattleStat.RAND ], 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -936,7 +936,8 @@ export class HealAttr extends MoveEffectAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addHealPhase(user: Pokemon, healRatio: number) {
|
addHealPhase(user: Pokemon, healRatio: number) {
|
||||||
user.scene.unshiftPhase(new PokemonHealPhase(user.scene, user.isPlayer(), Math.max(Math.floor(user.getMaxHp() * healRatio), 1), getPokemonMessage(user, ' regained\nhealth!'), true, !this.showAnim));
|
user.scene.unshiftPhase(new PokemonHealPhase(user.scene, user.isPlayer(), user.getFieldIndex(),
|
||||||
|
Math.max(Math.floor(user.getMaxHp() * healRatio), 1), getPokemonMessage(user, ' regained\nhealth!'), true, !this.showAnim));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -977,7 +978,8 @@ export class HitHealAttr extends MoveHitEffectAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
user.scene.unshiftPhase(new PokemonHealPhase(user.scene, user.isPlayer(), Math.max(Math.floor(user.turnData.damageDealt * this.healRatio), 1), getPokemonMessage(target, ` had its\nenergy drained!`), false, true));
|
user.scene.unshiftPhase(new PokemonHealPhase(user.scene, user.isPlayer(), user.getFieldIndex(),
|
||||||
|
Math.max(Math.floor(user.turnData.damageDealt * this.healRatio), 1), getPokemonMessage(target, ` had its\nenergy drained!`), false, true));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1214,7 +1216,7 @@ export class StatChangeAttr extends MoveEffectAttr {
|
|||||||
|
|
||||||
if (move.chance < 0 || move.chance === 100 || Utils.randInt(100) < move.chance) {
|
if (move.chance < 0 || move.chance === 100 || Utils.randInt(100) < move.chance) {
|
||||||
const levels = this.getLevels(user);
|
const levels = this.getLevels(user);
|
||||||
user.scene.unshiftPhase(new StatChangePhase(user.scene, user.isPlayer() === this.selfTarget, this.selfTarget, this.stats, levels));
|
user.scene.unshiftPhase(new StatChangePhase(user.scene, user.isPlayer() === this.selfTarget, user.getFieldIndex(), this.selfTarget, this.stats, levels));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1770,8 +1772,8 @@ export class RandomMovesetMoveAttr extends OverrideMoveEffectAttr {
|
|||||||
const moveIndex = moveset.findIndex(m => m.moveId === move.moveId);
|
const moveIndex = moveset.findIndex(m => m.moveId === move.moveId);
|
||||||
user.getMoveQueue().push({ move: move.moveId, ignorePP: this.enemyMoveset });
|
user.getMoveQueue().push({ move: move.moveId, ignorePP: this.enemyMoveset });
|
||||||
user.scene.unshiftPhase(user.isPlayer()
|
user.scene.unshiftPhase(user.isPlayer()
|
||||||
? new PlayerMovePhase(user.scene, user as PlayerPokemon, moveset[moveIndex], true)
|
? new PlayerMovePhase(user.scene, user as PlayerPokemon, target.getFieldIndex(), moveset[moveIndex], true)
|
||||||
: new EnemyMovePhase(user.scene, user as EnemyPokemon, moveset[moveIndex], true));
|
: new EnemyMovePhase(user.scene, user as EnemyPokemon, target.getFieldIndex(), moveset[moveIndex], true));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1786,8 +1788,8 @@ export class RandomMoveAttr extends OverrideMoveEffectAttr {
|
|||||||
const moveId = moveIds[Utils.randInt(moveIds.length)];
|
const moveId = moveIds[Utils.randInt(moveIds.length)];
|
||||||
user.getMoveQueue().push({ move: moveId, ignorePP: true });
|
user.getMoveQueue().push({ move: moveId, ignorePP: true });
|
||||||
user.scene.unshiftPhase(user.isPlayer()
|
user.scene.unshiftPhase(user.isPlayer()
|
||||||
? new PlayerMovePhase(user.scene, user as PlayerPokemon, new PokemonMove(moveId, 0, 0, true), true)
|
? new PlayerMovePhase(user.scene, user as PlayerPokemon, target.getFieldIndex(), new PokemonMove(moveId, 0, 0, true), true)
|
||||||
: new EnemyMovePhase(user.scene, user as EnemyPokemon, new PokemonMove(moveId, 0, 0, true), true));
|
: new EnemyMovePhase(user.scene, user as EnemyPokemon, target.getFieldIndex(), new PokemonMove(moveId, 0, 0, true), true));
|
||||||
initMoveAnim(moveId).then(() => {
|
initMoveAnim(moveId).then(() => {
|
||||||
loadMoveAnimAssets(user.scene, [ moveId ], true)
|
loadMoveAnimAssets(user.scene, [ moveId ], true)
|
||||||
.then(() => resolve(true));
|
.then(() => resolve(true));
|
||||||
@ -1824,8 +1826,8 @@ export class CopyMoveAttr extends OverrideMoveEffectAttr {
|
|||||||
|
|
||||||
user.getMoveQueue().push({ move: copiedMove.move, ignorePP: true });
|
user.getMoveQueue().push({ move: copiedMove.move, ignorePP: true });
|
||||||
user.scene.unshiftPhase(user.isPlayer()
|
user.scene.unshiftPhase(user.isPlayer()
|
||||||
? new PlayerMovePhase(user.scene, user as PlayerPokemon, new PokemonMove(copiedMove.move, 0, 0, true), true)
|
? new PlayerMovePhase(user.scene, user as PlayerPokemon, target.getFieldIndex(), new PokemonMove(copiedMove.move, 0, 0, true), true)
|
||||||
: new EnemyMovePhase(user.scene, user as EnemyPokemon, new PokemonMove(copiedMove.move, 0, 0, true), true));
|
: new EnemyMovePhase(user.scene, user as EnemyPokemon, target.getFieldIndex(), new PokemonMove(copiedMove.move, 0, 0, true), true));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1932,10 +1934,10 @@ export function applyFilteredMoveAttrs(attrFilter: MoveAttrFilter, user: Pokemon
|
|||||||
return applyMoveAttrsInternal(attrFilter, user, target, move, args);
|
return applyMoveAttrsInternal(attrFilter, user, target, move, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getMoveTarget(user: Pokemon, move: Moves): Pokemon {
|
export function getMoveTarget(user: Pokemon, targetIndex: integer, move: Moves): Pokemon {
|
||||||
const moveTarget = allMoves[move].moveTarget;
|
const moveTarget = allMoves[move].moveTarget;
|
||||||
|
|
||||||
const other = user.getOpponent();
|
const other = user.getOpponent(targetIndex);
|
||||||
|
|
||||||
switch (moveTarget) {
|
switch (moveTarget) {
|
||||||
case MoveTarget.USER:
|
case MoveTarget.USER:
|
||||||
|
@ -100,17 +100,10 @@ export class Weather {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isEffectSuppressed(scene: BattleScene): boolean {
|
isEffectSuppressed(scene: BattleScene): boolean {
|
||||||
const playerPokemon = scene.getPlayerPokemon();
|
const field = scene.getField().filter(p => p);
|
||||||
const enemyPokemon = scene.getEnemyPokemon();
|
|
||||||
|
|
||||||
if (playerPokemon) {
|
for (let pokemon of field) {
|
||||||
const suppressWeatherEffectAbAttr = playerPokemon.getAbility().getAttrs(SuppressWeatherEffectAbAttr).find(() => true) as SuppressWeatherEffectAbAttr;
|
const suppressWeatherEffectAbAttr = pokemon.getAbility().getAttrs(SuppressWeatherEffectAbAttr).find(() => true) as SuppressWeatherEffectAbAttr;
|
||||||
if (suppressWeatherEffectAbAttr && (!this.isImmutable() || suppressWeatherEffectAbAttr.affectsImmutable))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enemyPokemon) {
|
|
||||||
const suppressWeatherEffectAbAttr = enemyPokemon.getAbility().getAttrs(SuppressWeatherEffectAbAttr).find(() => true) as SuppressWeatherEffectAbAttr;
|
|
||||||
if (suppressWeatherEffectAbAttr && (!this.isImmutable() || suppressWeatherEffectAbAttr.affectsImmutable))
|
if (suppressWeatherEffectAbAttr && (!this.isImmutable() || suppressWeatherEffectAbAttr.affectsImmutable))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -179,6 +179,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
abstract isPlayer(): boolean;
|
abstract isPlayer(): boolean;
|
||||||
|
|
||||||
|
abstract getFieldIndex(): integer;
|
||||||
|
|
||||||
loadAssets(): Promise<void> {
|
loadAssets(): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const moveIds = this.getMoveset().map(m => m.getMove().id);
|
const moveIds = this.getMoveset().map(m => m.getMove().id);
|
||||||
@ -496,13 +498,24 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
this.levelExp = this.exp - getLevelTotalExp(this.level, this.getSpeciesForm().growthRate);
|
this.levelExp = this.exp - getLevelTotalExp(this.level, this.getSpeciesForm().growthRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
getOpponent(): Pokemon {
|
getOpponent(targetIndex: integer): Pokemon {
|
||||||
const ret = this.isPlayer() ? this.scene.getEnemyPokemon() : this.scene.getPlayerPokemon();
|
const ret = this.getOpponents()[targetIndex];
|
||||||
if (ret.summonData)
|
if (ret.summonData)
|
||||||
return ret;
|
return ret;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getOpponents(): Pokemon[] {
|
||||||
|
return this.isPlayer() ? this.scene.getEnemyField() : this.scene.getPlayerField();
|
||||||
|
}
|
||||||
|
|
||||||
|
getOpponentDescriptor(): string {
|
||||||
|
const opponents = this.getOpponents();
|
||||||
|
if (opponents.length === 1)
|
||||||
|
return opponents[0].name;
|
||||||
|
return this.isPlayer() ? 'the opposing team' : 'your team';
|
||||||
|
}
|
||||||
|
|
||||||
apply(source: Pokemon, battlerMove: PokemonMove): MoveResult {
|
apply(source: Pokemon, battlerMove: PokemonMove): MoveResult {
|
||||||
let result: MoveResult;
|
let result: MoveResult;
|
||||||
const move = battlerMove.getMove();
|
const move = battlerMove.getMove();
|
||||||
@ -626,9 +639,8 @@ 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.getFieldIndex()));
|
||||||
this.resetSummonData();
|
this.resetSummonData();
|
||||||
this.getOpponent()?.resetBattleSummonData();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -946,6 +958,10 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFieldIndex(): integer {
|
||||||
|
return this.scene.getPlayerField().indexOf(this);
|
||||||
|
}
|
||||||
|
|
||||||
generateCompatibleTms(): void {
|
generateCompatibleTms(): void {
|
||||||
this.compatibleTms = [];
|
this.compatibleTms = [];
|
||||||
|
|
||||||
@ -1127,6 +1143,10 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFieldIndex(): integer {
|
||||||
|
return this.scene.getEnemyField().indexOf(this);
|
||||||
|
}
|
||||||
|
|
||||||
addToParty() {
|
addToParty() {
|
||||||
const party = this.scene.getParty();
|
const party = this.scene.getParty();
|
||||||
let ret: PlayerPokemon = null;
|
let ret: PlayerPokemon = null;
|
||||||
|
@ -21,7 +21,7 @@ interface SystemSaveData {
|
|||||||
|
|
||||||
interface SessionSaveData {
|
interface SessionSaveData {
|
||||||
party: PokemonData[];
|
party: PokemonData[];
|
||||||
enemyParty: PokemonData[];
|
enemyField: PokemonData[];
|
||||||
modifiers: PersistentModifierData[];
|
modifiers: PersistentModifierData[];
|
||||||
enemyModifiers: PersistentModifierData[];
|
enemyModifiers: PersistentModifierData[];
|
||||||
arena: ArenaData;
|
arena: ArenaData;
|
||||||
@ -126,7 +126,7 @@ export class GameData {
|
|||||||
saveSession(scene: BattleScene): boolean {
|
saveSession(scene: BattleScene): boolean {
|
||||||
const sessionData = {
|
const sessionData = {
|
||||||
party: scene.getParty().map(p => new PokemonData(p)),
|
party: scene.getParty().map(p => new PokemonData(p)),
|
||||||
enemyParty: scene.getEnemyParty().map(p => new PokemonData(p)),
|
enemyField: scene.getEnemyField().map(p => new PokemonData(p)),
|
||||||
modifiers: scene.findModifiers(m => true).map(m => new PersistentModifierData(m, true)),
|
modifiers: scene.findModifiers(m => true).map(m => new PersistentModifierData(m, true)),
|
||||||
enemyModifiers: scene.findModifiers(m => true, false).map(m => new PersistentModifierData(m, false)),
|
enemyModifiers: scene.findModifiers(m => true, false).map(m => new PersistentModifierData(m, false)),
|
||||||
arena: new ArenaData(scene.arena),
|
arena: new ArenaData(scene.arena),
|
||||||
@ -188,16 +188,19 @@ export class GameData {
|
|||||||
party.push(pokemon);
|
party.push(pokemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
const enemyPokemon = sessionData.enemyParty[0].toPokemon(scene) as EnemyPokemon;
|
|
||||||
|
|
||||||
Object.keys(scene.pokeballCounts).forEach((key: string) => {
|
Object.keys(scene.pokeballCounts).forEach((key: string) => {
|
||||||
scene.pokeballCounts[key] = sessionData.pokeballCounts[key] || 0;
|
scene.pokeballCounts[key] = sessionData.pokeballCounts[key] || 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
scene.newArena(sessionData.arena.biome, true);
|
scene.newArena(sessionData.arena.biome, sessionData.enemyField.length > 1);
|
||||||
scene.newBattle(sessionData.waveIndex).enemyPokemon = enemyPokemon;
|
const battle = scene.newBattle(sessionData.waveIndex, sessionData.enemyField.length > 1);
|
||||||
|
|
||||||
loadPokemonAssets.push(enemyPokemon.loadAssets());
|
sessionData.enemyField.forEach((enemyData, e) => {
|
||||||
|
const enemyPokemon = enemyData.toPokemon(scene) as EnemyPokemon;
|
||||||
|
battle.enemyField[e] = enemyPokemon;
|
||||||
|
|
||||||
|
loadPokemonAssets.push(enemyPokemon.loadAssets());
|
||||||
|
});
|
||||||
|
|
||||||
scene.arena.weather = sessionData.arena.weather;
|
scene.arena.weather = sessionData.arena.weather;
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -37,7 +37,7 @@ export default class ModifierData {
|
|||||||
type.generatorId = this.typeGeneratorId;
|
type.generatorId = this.typeGeneratorId;
|
||||||
|
|
||||||
if (type instanceof ModifierTypeGenerator)
|
if (type instanceof ModifierTypeGenerator)
|
||||||
type = (type as ModifierTypeGenerator).generateType(this.player ? scene.getParty() : scene.getEnemyParty(), this.typePregenArgs);
|
type = (type as ModifierTypeGenerator).generateType(this.player ? scene.getParty() : scene.getEnemyField(), this.typePregenArgs);
|
||||||
|
|
||||||
const ret = Reflect.construct(constructor, ([ type ] as any[]).concat(this.args).concat(this.stackCount)) as PersistentModifier
|
const ret = Reflect.construct(constructor, ([ type ] as any[]).concat(this.args).concat(this.stackCount)) as PersistentModifier
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ export default class CommandUiHandler extends UiHandler {
|
|||||||
const messageHandler = this.getUi().getMessageHandler();
|
const messageHandler = this.getUi().getMessageHandler();
|
||||||
messageHandler.bg.setTexture('bg_command');
|
messageHandler.bg.setTexture('bg_command');
|
||||||
messageHandler.message.setWordWrapWidth(1110);
|
messageHandler.message.setWordWrapWidth(1110);
|
||||||
messageHandler.showText(`What will\n${this.scene.getPlayerPokemon().name} do?`, 0);
|
messageHandler.showText(`What will\n${(this.scene.getCurrentPhase() as CommandPhase).getPokemon().name} do?`, 0);
|
||||||
this.setCursor(this.cursor);
|
this.setCursor(this.cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ export default class CommandUiHandler extends UiHandler {
|
|||||||
success = true;
|
success = true;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ui.setMode(Mode.PARTY, PartyUiMode.SWITCH);
|
ui.setMode(Mode.PARTY, PartyUiMode.SWITCH, (this.scene.getCurrentPhase() as CommandPhase).getPokemon().getFieldIndex());
|
||||||
success = true;
|
success = true;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
@ -91,7 +91,7 @@ export default class FightUiHandler extends UiHandler {
|
|||||||
ui.add(this.cursorObj);
|
ui.add(this.cursorObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
const moveset = this.scene.getPlayerPokemon().getMoveset();
|
const moveset = (this.scene.getCurrentPhase() as CommandPhase).getPokemon().getMoveset();
|
||||||
|
|
||||||
const hasMove = cursor < moveset.length;
|
const hasMove = cursor < moveset.length;
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ export default class FightUiHandler extends UiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
displayMoves() {
|
displayMoves() {
|
||||||
const moveset = this.scene.getPlayerPokemon().getMoveset();
|
const moveset = (this.scene.getCurrentPhase() as CommandPhase).getPokemon().getMoveset();
|
||||||
for (let m = 0; m < 4; m++) {
|
for (let m = 0; m < 4; m++) {
|
||||||
const moveText = addTextObject(this.scene, m % 2 === 0 ? 0 : 100, m < 2 ? 0 : 16, '-', TextStyle.WINDOW);
|
const moveText = addTextObject(this.scene, m % 2 === 0 ? 0 : 100, m < 2 ? 0 : 16, '-', TextStyle.WINDOW);
|
||||||
if (m < moveset.length)
|
if (m < moveset.length)
|
||||||
|
@ -42,6 +42,7 @@ export type PokemonMoveSelectFilter = (pokemonMove: PokemonMove) => string;
|
|||||||
|
|
||||||
export default class PartyUiHandler extends MessageUiHandler {
|
export default class PartyUiHandler extends MessageUiHandler {
|
||||||
private partyUiMode: PartyUiMode;
|
private partyUiMode: PartyUiMode;
|
||||||
|
private fieldIndex: integer;
|
||||||
|
|
||||||
private partyContainer: Phaser.GameObjects.Container;
|
private partyContainer: Phaser.GameObjects.Container;
|
||||||
private partySlotsContainer: Phaser.GameObjects.Container;
|
private partySlotsContainer: Phaser.GameObjects.Container;
|
||||||
@ -143,17 +144,19 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||||||
|
|
||||||
this.partyUiMode = args[0] as PartyUiMode;
|
this.partyUiMode = args[0] as PartyUiMode;
|
||||||
|
|
||||||
|
this.fieldIndex = args.length > 1 ? args[1] as integer : -1;
|
||||||
|
|
||||||
this.partyContainer.setVisible(true);
|
this.partyContainer.setVisible(true);
|
||||||
this.populatePartySlots();
|
this.populatePartySlots();
|
||||||
this.setCursor(this.cursor < 6 ? this.cursor : 0);
|
this.setCursor(this.cursor < 6 ? this.cursor : 0);
|
||||||
|
|
||||||
if (args.length > 1 && args[1] instanceof Function)
|
if (args.length > 2 && args[2] instanceof Function)
|
||||||
this.selectCallback = args[1];
|
this.selectCallback = args[2];
|
||||||
this.selectFilter = args.length > 2 && args[2] instanceof Function
|
this.selectFilter = args.length > 3 && args[3] instanceof Function
|
||||||
? args[2] as PokemonSelectFilter
|
? args[3] as PokemonSelectFilter
|
||||||
: PartyUiHandler.FilterAll;
|
: PartyUiHandler.FilterAll;
|
||||||
this.moveSelectFilter = args.length > 3 && args[3] instanceof Function
|
this.moveSelectFilter = args.length > 4 && args[4] instanceof Function
|
||||||
? args[3] as PokemonMoveSelectFilter
|
? args[4] as PokemonMoveSelectFilter
|
||||||
: PartyUiHandler.FilterAllMoves;
|
: PartyUiHandler.FilterAllMoves;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,7 +417,8 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||||||
if (this.cursor) {
|
if (this.cursor) {
|
||||||
this.options.push(PartyOption.SEND_OUT);
|
this.options.push(PartyOption.SEND_OUT);
|
||||||
if (this.partyUiMode !== PartyUiMode.FAINT_SWITCH
|
if (this.partyUiMode !== PartyUiMode.FAINT_SWITCH
|
||||||
&& this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === this.scene.getPlayerPokemon().id))
|
&& this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier
|
||||||
|
&& (m as SwitchEffectTransferModifier).pokemonId === this.scene.getPlayerField()[this.fieldIndex].id))
|
||||||
this.options.push(PartyOption.PASS_BATON);
|
this.options.push(PartyOption.PASS_BATON);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user