Add switch out preventing to traps
parent
f13302e28f
commit
2ac0a3645f
|
@ -5,7 +5,7 @@ import * as Utils from "./utils";
|
|||
import PokemonSpecies, { getPokemonSpecies } from "./data/pokemon-species";
|
||||
import { Species } from "./data/species";
|
||||
import { Weather, WeatherType, getWeatherClearMessage, getWeatherStartMessage } from "./data/weather";
|
||||
import { CommonAnimPhase, MessagePhase } from "./battle-phases";
|
||||
import { CommonAnimPhase } from "./battle-phases";
|
||||
import { CommonAnim } from "./data/battle-anims";
|
||||
import { Type } from "./data/type";
|
||||
import Move from "./data/move";
|
||||
|
|
|
@ -18,7 +18,7 @@ import { BattleStat, getBattleStatLevelChangeDescription, getBattleStatName } fr
|
|||
import { Biome, biomeLinks } from "./data/biome";
|
||||
import { ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, getPlayerModifierTypeOptionsForWave, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
|
||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||
import { BattlerTagLapseType, BattlerTagType, HideSpriteTag as HiddenTag } from "./data/battler-tag";
|
||||
import { BattlerTagLapseType, BattlerTagType, HideSpriteTag as HiddenTag, DamagingTrapTag, TrappedTag as TrapTag } from "./data/battler-tag";
|
||||
import { getPokemonMessage } from "./messages";
|
||||
import { Starter } from "./ui/starter-select-ui-handler";
|
||||
import { Gender } from "./data/gender";
|
||||
|
@ -370,6 +370,8 @@ export class SwitchSummonPhase extends SummonPhase {
|
|||
|
||||
const playerPokemon = this.scene.getPlayerPokemon();
|
||||
|
||||
this.scene.getEnemyPokemon()?.removeTagsBySourceId(playerPokemon.id);
|
||||
|
||||
this.scene.ui.showText(`Come back, ${this.scene.getPlayerPokemon().name}!`);
|
||||
this.scene.sound.play('pb_rel');
|
||||
playerPokemon.hideInfo();
|
||||
|
@ -542,8 +544,14 @@ export class CommandPhase extends BattlePhase {
|
|||
}
|
||||
break;
|
||||
case Command.POKEMON:
|
||||
this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, cursor, true));
|
||||
success = true;
|
||||
const trapTag = playerPokemon.findTag(t => t instanceof TrapTag) as TrapTag;
|
||||
if (!trapTag) {
|
||||
this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, cursor, true));
|
||||
success = true;
|
||||
} else
|
||||
this.scene.ui.showText(`${this.scene.getPokemonById(trapTag.sourceId).name}'s ${trapTag.getMoveName()}\nprevents switching!`, null, () => {
|
||||
this.scene.ui.showText(null, 0);
|
||||
}, null, true);
|
||||
break;
|
||||
case Command.RUN:
|
||||
//this.scene.unshiftPhase(new MoveAnimTestPhase(this.scene, [ Moves.TELEPORT ]));
|
||||
|
@ -1299,6 +1307,10 @@ export class FaintPhase extends PokemonPhase {
|
|||
const pokemon = this.getPokemon();
|
||||
|
||||
pokemon.lapseTags(BattlerTagLapseType.FAINT);
|
||||
if (pokemon.isPlayer())
|
||||
this.scene.getEnemyPokemon()?.removeTagsBySourceId(pokemon.id);
|
||||
else
|
||||
this.scene.getPlayerPokemon()?.removeTagsBySourceId(pokemon.id);
|
||||
|
||||
pokemon.faintCry(() => {
|
||||
pokemon.hideInfo();
|
||||
|
@ -1793,6 +1805,7 @@ export class AttemptCapturePhase extends BattlePhase {
|
|||
const newPokemon = pokemon.addToParty();
|
||||
const modifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier, false);
|
||||
Promise.all(modifiers.map(m => this.scene.addModifier(m))).then(() => {
|
||||
this.scene.getPlayerPokemon().removeTagsBySourceId(pokemon.id);
|
||||
pokemon.hp = 0;
|
||||
this.scene.clearEnemyModifiers();
|
||||
this.scene.field.remove(pokemon, true);
|
||||
|
|
|
@ -433,6 +433,11 @@ export default class BattleScene extends Phaser.Scene {
|
|||
return this.currentBattle?.enemyPokemon;
|
||||
}
|
||||
|
||||
getPokemonById(pokemonId: integer): Pokemon {
|
||||
const findInParty = (party: Pokemon[]) => party.find(p => p.id === pokemonId);
|
||||
return findInParty(this.getParty()) || findInParty(this.getEnemyParty());
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this.pokeballCounts = Object.fromEntries(Utils.getEnumValues(PokeballType).filter(p => p <= PokeballType.MASTER_BALL).map(t => [ t, 0 ]));
|
||||
|
||||
|
|
|
@ -619,7 +619,7 @@ export abstract class BattleAnim {
|
|||
const setSpritePriority = (priority: integer) => {
|
||||
switch (priority) {
|
||||
case 0:
|
||||
scene.field.moveBelow(moveSprite, scene.getEnemyPokemon());
|
||||
scene.field.moveBelow(moveSprite, scene.getEnemyPokemon() || scene.getPlayerPokemon());
|
||||
break;
|
||||
case 1:
|
||||
scene.field.moveTo(moveSprite, scene.field.getAll().length - 1);
|
||||
|
|
|
@ -5,7 +5,8 @@ import Pokemon from "../pokemon";
|
|||
import { Stat } from "./pokemon-stat";
|
||||
import { StatusEffect } from "./status-effect";
|
||||
import * as Utils from "../utils";
|
||||
import { Moves } from "./move";
|
||||
import { Moves, allMoves } from "./move";
|
||||
import { Type } from "./type";
|
||||
|
||||
export enum BattlerTagType {
|
||||
NONE,
|
||||
|
@ -18,6 +19,7 @@ export enum BattlerTagType {
|
|||
INGRAIN,
|
||||
AQUA_RING,
|
||||
DROWSY,
|
||||
TRAPPED,
|
||||
BIND,
|
||||
WRAP,
|
||||
FIRE_SPIN,
|
||||
|
@ -46,11 +48,19 @@ export class BattlerTag {
|
|||
public tagType: BattlerTagType;
|
||||
public lapseType: BattlerTagLapseType;
|
||||
public turnCount: integer;
|
||||
public sourceId: integer;
|
||||
public sourceMove: Moves;
|
||||
|
||||
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: integer) {
|
||||
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: integer, sourceId?: integer, sourceMove?: Moves) {
|
||||
this.tagType = tagType;
|
||||
this.lapseType = lapseType;
|
||||
this.turnCount = turnCount;
|
||||
this.sourceId = sourceId;
|
||||
this.sourceMove = sourceMove;
|
||||
}
|
||||
|
||||
canAdd(pokemon: Pokemon): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
onAdd(pokemon: Pokemon): void { }
|
||||
|
@ -62,6 +72,12 @@ export class BattlerTag {
|
|||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
return --this.turnCount > 0;
|
||||
}
|
||||
|
||||
getMoveName(): string {
|
||||
return this.sourceMove
|
||||
? allMoves[this.sourceMove].name
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
export class RechargingTag extends BattlerTag {
|
||||
|
@ -85,6 +101,32 @@ export class RechargingTag extends BattlerTag {
|
|||
}
|
||||
}
|
||||
|
||||
export class TrappedTag extends BattlerTag {
|
||||
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: integer, sourceId: integer, sourceMove: Moves) {
|
||||
super(tagType, lapseType, turnCount, sourceId, sourceMove);
|
||||
}
|
||||
|
||||
canAdd(pokemon: Pokemon): boolean {
|
||||
return !pokemon.isOfType(Type.GHOST) && !pokemon.getTag(BattlerTagType.TRAPPED);
|
||||
}
|
||||
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
pokemon.scene.queueMessage(this.getTrapMessage(pokemon));
|
||||
}
|
||||
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` was freed\nfrom ${this.getMoveName()}!`));
|
||||
}
|
||||
|
||||
getTrapMessage(pokemon: Pokemon): string {
|
||||
return getPokemonMessage(pokemon, ' can no\nlonger escape!');
|
||||
}
|
||||
}
|
||||
|
||||
export class FlinchedTag extends BattlerTag {
|
||||
constructor() {
|
||||
super(BattlerTagType.FLINCHED, BattlerTagLapseType.MOVE, 0);
|
||||
|
@ -100,13 +142,7 @@ export class FlinchedTag extends BattlerTag {
|
|||
}
|
||||
}
|
||||
|
||||
export class PseudoStatusTag extends BattlerTag {
|
||||
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: integer) {
|
||||
super(tagType, lapseType, turnCount);
|
||||
}
|
||||
}
|
||||
|
||||
export class ConfusedTag extends PseudoStatusTag {
|
||||
export class ConfusedTag extends BattlerTag {
|
||||
constructor(turnCount: integer) {
|
||||
super(BattlerTagType.CONFUSED, BattlerTagLapseType.MOVE, turnCount);
|
||||
}
|
||||
|
@ -152,7 +188,7 @@ export class ConfusedTag extends PseudoStatusTag {
|
|||
}
|
||||
}
|
||||
|
||||
export class SeedTag extends PseudoStatusTag {
|
||||
export class SeedTag extends BattlerTag {
|
||||
constructor() {
|
||||
super(BattlerTagType.SEEDED, BattlerTagLapseType.AFTER_MOVE, 1);
|
||||
}
|
||||
|
@ -179,7 +215,7 @@ export class SeedTag extends PseudoStatusTag {
|
|||
}
|
||||
}
|
||||
|
||||
export class NightmareTag extends PseudoStatusTag {
|
||||
export class NightmareTag extends BattlerTag {
|
||||
constructor() {
|
||||
super(BattlerTagType.NIGHTMARE, BattlerTagLapseType.AFTER_MOVE, 1);
|
||||
}
|
||||
|
@ -212,15 +248,9 @@ export class NightmareTag extends PseudoStatusTag {
|
|||
}
|
||||
}
|
||||
|
||||
export class IngrainTag extends PseudoStatusTag {
|
||||
constructor() {
|
||||
super(BattlerTagType.INGRAIN, BattlerTagLapseType.TURN_END, 1);
|
||||
}
|
||||
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' planted its roots!'));
|
||||
export class IngrainTag extends TrappedTag {
|
||||
constructor(sourceId: integer) {
|
||||
super(BattlerTagType.INGRAIN, BattlerTagLapseType.TURN_END, 1, sourceId, Moves.INGRAIN);
|
||||
}
|
||||
|
||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
|
@ -232,11 +262,15 @@ export class IngrainTag extends PseudoStatusTag {
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
getTrapMessage(pokemon: Pokemon): string {
|
||||
return getPokemonMessage(pokemon, ' planted its roots!');
|
||||
}
|
||||
}
|
||||
|
||||
export class AquaRingTag extends PseudoStatusTag {
|
||||
export class AquaRingTag extends BattlerTag {
|
||||
constructor() {
|
||||
super(BattlerTagType.AQUA_RING, BattlerTagLapseType.TURN_END, 1);
|
||||
super(BattlerTagType.AQUA_RING, BattlerTagLapseType.TURN_END, 1, undefined, Moves.AQUA_RING);
|
||||
}
|
||||
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
|
@ -249,7 +283,7 @@ export class AquaRingTag extends PseudoStatusTag {
|
|||
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||
|
||||
if (ret)
|
||||
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.isPlayer(), Math.floor(pokemon.getMaxHp() / 16), `AQUA RING restored\n${pokemon.name}\'s HP!`, true));
|
||||
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.isPlayer(), Math.floor(pokemon.getMaxHp() / 16), `${this.getMoveName()} restored\n${pokemon.name}\'s HP!`, true));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -276,30 +310,24 @@ export class DrowsyTag extends BattlerTag {
|
|||
}
|
||||
}
|
||||
|
||||
export abstract class TrapTag extends BattlerTag {
|
||||
export abstract class DamagingTrapTag extends TrappedTag {
|
||||
private commonAnim: CommonAnim;
|
||||
|
||||
constructor(tagType: BattlerTagType, commonAnim: CommonAnim, turnCount: integer) {
|
||||
super(tagType, BattlerTagLapseType.TURN_END, turnCount);
|
||||
constructor(tagType: BattlerTagType, commonAnim: CommonAnim, turnCount: integer, sourceId: integer, sourceMove: Moves) {
|
||||
super(tagType, BattlerTagLapseType.TURN_END, turnCount, sourceId, sourceMove);
|
||||
|
||||
this.commonAnim = commonAnim;
|
||||
}
|
||||
|
||||
getTrapName(): string {
|
||||
return BattlerTagType[this.tagType].toUpperCase().replace(/\_/g, ' ');
|
||||
}
|
||||
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
pokemon.scene.queueMessage(this.getTrapMessage(pokemon));
|
||||
canAdd(pokemon: Pokemon): boolean {
|
||||
return !pokemon.isOfType(Type.GHOST) && !pokemon.findTag(t => t instanceof DamagingTrapTag);
|
||||
}
|
||||
|
||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
const ret = lapseType !== BattlerTagLapseType.CUSTOM && super.lapse(pokemon, lapseType);
|
||||
const ret = super.lapse(pokemon, lapseType);
|
||||
|
||||
if (ret) {
|
||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` is hurt\nby ${this.getTrapName()}!`));
|
||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` is hurt\nby ${this.getMoveName()}!`));
|
||||
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.isPlayer(), this.commonAnim));
|
||||
|
||||
const damage = Math.ceil(pokemon.getMaxHp() / 16);
|
||||
|
@ -309,39 +337,31 @@ export abstract class TrapTag extends BattlerTag {
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` was freed\nfrom ${this.getTrapName()}!`));
|
||||
}
|
||||
|
||||
abstract getTrapMessage(pokemon: Pokemon): string;
|
||||
}
|
||||
|
||||
export class BindTag extends TrapTag {
|
||||
constructor(turnCount: integer) {
|
||||
super(BattlerTagType.BIND, CommonAnim.BIND, turnCount);
|
||||
export class BindTag extends DamagingTrapTag {
|
||||
constructor(turnCount: integer, sourceId: integer) {
|
||||
super(BattlerTagType.BIND, CommonAnim.BIND, turnCount, sourceId, Moves.BIND);
|
||||
}
|
||||
|
||||
getTrapMessage(pokemon: Pokemon): string {
|
||||
return getPokemonMessage(pokemon, ` was squeezed\nby ${this.getTrapName}!`);
|
||||
return getPokemonMessage(pokemon, ` was squeezed by\n${pokemon.scene.getPokemonById(this.sourceId)}'s ${this.getMoveName()}!`);
|
||||
}
|
||||
}
|
||||
|
||||
export class WrapTag extends TrapTag {
|
||||
constructor(turnCount: integer) {
|
||||
super(BattlerTagType.WRAP, CommonAnim.WRAP, turnCount);
|
||||
export class WrapTag extends DamagingTrapTag {
|
||||
constructor(turnCount: integer, sourceId: integer) {
|
||||
super(BattlerTagType.WRAP, CommonAnim.WRAP, turnCount, sourceId, Moves.WRAP);
|
||||
}
|
||||
|
||||
getTrapMessage(pokemon: Pokemon): string {
|
||||
return getPokemonMessage(pokemon, ' was WRAPPED!');
|
||||
return getPokemonMessage(pokemon, ` was WRAPPED\nby ${pokemon.scene.getPokemonById(this.sourceId)}!`);
|
||||
}
|
||||
}
|
||||
|
||||
export class FireSpinTag extends TrapTag {
|
||||
constructor(turnCount: integer) {
|
||||
super(BattlerTagType.FIRE_SPIN, CommonAnim.FIRE_SPIN, turnCount);
|
||||
export abstract class VortexTrapTag extends DamagingTrapTag {
|
||||
constructor(tagType: BattlerTagType, commonAnim: CommonAnim, turnCount: integer, sourceId: integer, sourceMove: Moves) {
|
||||
super(tagType, commonAnim, turnCount, sourceId, sourceMove);
|
||||
}
|
||||
|
||||
getTrapMessage(pokemon: Pokemon): string {
|
||||
|
@ -349,39 +369,41 @@ export class FireSpinTag extends TrapTag {
|
|||
}
|
||||
}
|
||||
|
||||
export class WhirlpoolTag extends TrapTag {
|
||||
constructor(turnCount: integer) {
|
||||
super(BattlerTagType.WHIRLPOOL, CommonAnim.WHIRLPOOL, turnCount);
|
||||
}
|
||||
|
||||
getTrapMessage(pokemon: Pokemon): string {
|
||||
return getPokemonMessage(pokemon, ' was trapped\nin the vortex!');
|
||||
export class FireSpinTag extends VortexTrapTag {
|
||||
constructor(turnCount: integer, sourceId: integer) {
|
||||
super(BattlerTagType.FIRE_SPIN, CommonAnim.FIRE_SPIN, turnCount, sourceId, Moves.FIRE_SPIN);
|
||||
}
|
||||
}
|
||||
|
||||
export class ClampTag extends TrapTag {
|
||||
constructor(turnCount: integer) {
|
||||
super(BattlerTagType.CLAMP, CommonAnim.CLAMP, turnCount);
|
||||
}
|
||||
|
||||
getTrapMessage(pokemon: Pokemon): string {
|
||||
return getPokemonMessage(pokemon, ' was CLAMPED!');
|
||||
export class WhirlpoolTag extends VortexTrapTag {
|
||||
constructor(turnCount: integer, sourceId: integer) {
|
||||
super(BattlerTagType.WHIRLPOOL, CommonAnim.WHIRLPOOL, turnCount, sourceId, Moves.WHIRLPOOL);
|
||||
}
|
||||
}
|
||||
|
||||
export class SandTombTag extends TrapTag {
|
||||
constructor(turnCount: integer) {
|
||||
super(BattlerTagType.SAND_TOMB, CommonAnim.SAND_TOMB, turnCount);
|
||||
export class ClampTag extends DamagingTrapTag {
|
||||
constructor(turnCount: integer, sourceId: integer) {
|
||||
super(BattlerTagType.CLAMP, CommonAnim.CLAMP, turnCount, sourceId, Moves.CLAMP);
|
||||
}
|
||||
|
||||
getTrapMessage(pokemon: Pokemon): string {
|
||||
return getPokemonMessage(pokemon, ` was trapped\nby ${this.getTrapName()}!`);
|
||||
return getPokemonMessage(pokemon.scene.getPokemonById(this.sourceId), ` CLAMPED\n${pokemon.name}!`);
|
||||
}
|
||||
}
|
||||
|
||||
export class MagmaStormTag extends TrapTag {
|
||||
constructor(turnCount: integer) {
|
||||
super(BattlerTagType.MAGMA_STORM, CommonAnim.MAGMA_STORM, turnCount);
|
||||
export class SandTombTag extends DamagingTrapTag {
|
||||
constructor(turnCount: integer, sourceId: integer) {
|
||||
super(BattlerTagType.SAND_TOMB, CommonAnim.SAND_TOMB, turnCount, sourceId, Moves.SAND_TOMB);
|
||||
}
|
||||
|
||||
getTrapMessage(pokemon: Pokemon): string {
|
||||
return getPokemonMessage(pokemon.scene.getPokemonById(this.sourceId), ` became trapped\nby ${this.getMoveName()}!`);
|
||||
}
|
||||
}
|
||||
|
||||
export class MagmaStormTag extends DamagingTrapTag {
|
||||
constructor(turnCount: integer, sourceId: integer) {
|
||||
super(BattlerTagType.MAGMA_STORM, CommonAnim.MAGMA_STORM, turnCount, sourceId, Moves.MAGMA_STORM);
|
||||
}
|
||||
|
||||
getTrapMessage(pokemon: Pokemon): string {
|
||||
|
@ -432,7 +454,7 @@ export class HideSpriteTag extends BattlerTag {
|
|||
}
|
||||
}
|
||||
|
||||
export function getBattlerTag(tagType: BattlerTagType, turnCount: integer): BattlerTag {
|
||||
export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourceId: integer, sourceMove: Moves): BattlerTag {
|
||||
switch (tagType) {
|
||||
case BattlerTagType.RECHARGING:
|
||||
return new RechargingTag();
|
||||
|
@ -445,25 +467,27 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer): Batt
|
|||
case BattlerTagType.NIGHTMARE:
|
||||
return new NightmareTag();
|
||||
case BattlerTagType.INGRAIN:
|
||||
return new IngrainTag();
|
||||
return new IngrainTag(sourceId);
|
||||
case BattlerTagType.AQUA_RING:
|
||||
return new AquaRingTag();
|
||||
case BattlerTagType.DROWSY:
|
||||
return new DrowsyTag();
|
||||
case BattlerTagType.TRAPPED:
|
||||
return new TrappedTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceId, sourceMove);
|
||||
case BattlerTagType.BIND:
|
||||
return new BindTag(turnCount);
|
||||
return new BindTag(turnCount, sourceId);
|
||||
case BattlerTagType.WRAP:
|
||||
return new WrapTag(turnCount);
|
||||
return new WrapTag(turnCount, sourceId);
|
||||
case BattlerTagType.FIRE_SPIN:
|
||||
return new FireSpinTag(turnCount);
|
||||
return new FireSpinTag(turnCount, sourceId);
|
||||
case BattlerTagType.WHIRLPOOL:
|
||||
return new WhirlpoolTag(turnCount);
|
||||
return new WhirlpoolTag(turnCount, sourceId);
|
||||
case BattlerTagType.CLAMP:
|
||||
return new ClampTag(turnCount);
|
||||
return new ClampTag(turnCount, sourceId);
|
||||
case BattlerTagType.SAND_TOMB:
|
||||
return new SandTombTag(turnCount);
|
||||
return new SandTombTag(turnCount, sourceId);
|
||||
case BattlerTagType.MAGMA_STORM:
|
||||
return new MagmaStormTag(turnCount);
|
||||
return new MagmaStormTag(turnCount, sourceId);
|
||||
case BattlerTagType.PROTECTED:
|
||||
return new ProtectedTag();
|
||||
case BattlerTagType.FLYING:
|
||||
|
|
|
@ -1410,7 +1410,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
|
|||
return false;
|
||||
|
||||
if (move.chance < 0 || move.chance === 100 || Utils.randInt(100) < move.chance) {
|
||||
(this.selfTarget ? user : target).addTag(this.tagType, this.turnCount);
|
||||
(this.selfTarget ? user : target).addTag(this.tagType, this.turnCount, user.id, move.id);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1738,7 +1738,7 @@ export const allMoves = [
|
|||
new AttackMove(Moves.ABSORB, "Absorb", Type.GRASS, MoveCategory.SPECIAL, 20, 100, 25, -1, "User recovers half the HP inflicted on opponent.", -1, 0, 1, new HitHealAttr()),
|
||||
new AttackMove(Moves.MEGA_DRAIN, "Mega Drain", Type.GRASS, MoveCategory.SPECIAL, 40, 100, 15, -1, "User recovers half the HP inflicted on opponent.", -1, 0, 1, new HitHealAttr()),
|
||||
new StatusMove(Moves.LEECH_SEED, "Leech Seed", Type.GRASS, 90, 10, -1, "Drains HP from opponent each turn.", -1, 0, 1,
|
||||
new ConditionalMoveAttr((user: Pokemon, target: Pokemon, move: Move) => !target.getTag(BattlerTagType.SEEDED) && !target.species.isOfType(Type.GRASS)), new AddBattlerTagAttr(BattlerTagType.SEEDED)),
|
||||
new ConditionalMoveAttr((user: Pokemon, target: Pokemon, move: Move) => !target.getTag(BattlerTagType.SEEDED) && !target.isOfType(Type.GRASS)), new AddBattlerTagAttr(BattlerTagType.SEEDED)),
|
||||
new SelfStatusMove(Moves.GROWTH, "Growth", Type.NORMAL, -1, 20, -1, "Raises user's Attack and Special Attack.", -1, 0, 1, new GrowthStatChangeAttr()),
|
||||
new AttackMove(Moves.RAZOR_LEAF, "Razor Leaf", Type.GRASS, MoveCategory.PHYSICAL, 55, 95, 25, -1, "High critical hit ratio.", -1, 0, 1, new HighCritAttr()),
|
||||
new AttackMove(Moves.SOLAR_BEAM, "Solar Beam", Type.GRASS, MoveCategory.SPECIAL, 120, 100, 10, 168, "Charges on first turn, attacks on second.", -1, 0, 1,
|
||||
|
@ -1896,7 +1896,8 @@ export const allMoves = [
|
|||
new AttackMove(Moves.SPARK, "Spark", Type.ELECTRIC, MoveCategory.PHYSICAL, 65, 100, 20, -1, "May paralyze opponent.", 30, 0, 2, new StatusEffectAttr(StatusEffect.PARALYSIS)),
|
||||
new AttackMove(Moves.FURY_CUTTER, "Fury Cutter", Type.BUG, MoveCategory.PHYSICAL, 40, 95, 20, -1, "Power increases each turn.", -1, 0, 2, new ConsecutiveUseDoublePowerAttr(3, true)),
|
||||
new AttackMove(Moves.STEEL_WING, "Steel Wing", Type.STEEL, MoveCategory.PHYSICAL, 70, 90, 25, -1, "May raise user's Defense.", 10, 0, 2, new StatChangeAttr(BattleStat.DEF, 1, true)),
|
||||
new StatusMove(Moves.MEAN_LOOK, "Mean Look (N)", Type.NORMAL, -1, 5, -1, "Opponent cannot flee or switch.", -1, 0, 2),
|
||||
new StatusMove(Moves.MEAN_LOOK, "Mean Look", Type.NORMAL, -1, 5, -1, "Opponent cannot flee or switch.", -1, 0, 2,
|
||||
new ConditionalMoveAttr((user: Pokemon, target: Pokemon, move: Move) => !target.getTag(BattlerTagType.TRAPPED)), new AddBattlerTagAttr(BattlerTagType.TRAPPED, false, 1)),
|
||||
new StatusMove(Moves.ATTRACT, "Attract (N)", Type.NORMAL, 100, 15, -1, "If opponent is the opposite gender, it's less likely to attack.", -1, 0, 2),
|
||||
new SelfStatusMove(Moves.SLEEP_TALK, "Sleep Talk", Type.NORMAL, -1, 10, 70, "User performs one of its own moves while sleeping.", -1, 0, 2,
|
||||
new BypassSleepAttr(), new ConditionalMoveAttr((user: Pokemon, target: Pokemon, move: Move) => user.status?.effect === StatusEffect.SLEEP), new RandomMovesetMoveAttr()),
|
||||
|
@ -1967,7 +1968,7 @@ export const allMoves = [
|
|||
new SelfStatusMove(Moves.WISH, "Wish (N)", Type.NORMAL, -1, 10, -1, "The user recovers HP in the following turn.", -1, 0, 3),
|
||||
new SelfStatusMove(Moves.ASSIST, "Assist (N)", Type.NORMAL, -1, 20, -1, "User performs a move known by its allies at random.", -1, 0, 3),
|
||||
new SelfStatusMove(Moves.INGRAIN, "Ingrain", Type.GRASS, -1, 20, -1, "User restores HP each turn. User cannot escape/switch.", -1, 0, 3,
|
||||
new NoTagOverlapConditionalAttr(BattlerTagType.INGRAIN, true), new AddBattlerTagAttr(BattlerTagType.INGRAIN, true)), // TODO
|
||||
new NoTagOverlapConditionalAttr(BattlerTagType.INGRAIN, true), new AddBattlerTagAttr(BattlerTagType.INGRAIN, true)),
|
||||
new AttackMove(Moves.SUPERPOWER, "Superpower", Type.FIGHTING, MoveCategory.PHYSICAL, 120, 100, 5, -1, "Lowers user's Attack and Defense.", 100, 0, 3,
|
||||
new StatChangeAttr([ BattleStat.ATK, BattleStat.DEF ], -1, true)),
|
||||
new SelfStatusMove(Moves.MAGIC_COAT, "Magic Coat (N)", Type.PSYCHIC, -1, 15, -1, "Reflects moves that cause status conditions back to the attacker.", -1, 4, 3),
|
||||
|
@ -2035,7 +2036,8 @@ export const allMoves = [
|
|||
new AttackMove(Moves.AERIAL_ACE, "Aerial Ace", Type.FLYING, MoveCategory.PHYSICAL, 60, -1, 20, 27, "Ignores Accuracy and Evasiveness.", -1, 0, 3),
|
||||
new AttackMove(Moves.ICICLE_SPEAR, "Icicle Spear", Type.ICE, MoveCategory.PHYSICAL, 25, 100, 30, -1, "Hits 2-5 times in one turn.", -1, 0, 3, new MultiHitAttr()),
|
||||
new SelfStatusMove(Moves.IRON_DEFENSE, "Iron Defense", Type.STEEL, -1, 15, 104, "Sharply raises user's Defense.", -1, 0, 3, new StatChangeAttr(BattleStat.DEF, 2, true)),
|
||||
new StatusMove(Moves.BLOCK, "Block (N)", 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 ConditionalMoveAttr((user: Pokemon, target: Pokemon, move: Move) => !target.getTag(BattlerTagType.TRAPPED)), new AddBattlerTagAttr(BattlerTagType.TRAPPED, false, 1)),
|
||||
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.FRENZY_PLANT, "Frenzy Plant", Type.GRASS, MoveCategory.SPECIAL, 150, 90, 5, 155, "User must recharge next turn.", -1, 0, 3, new AddBattlerTagAttr(BattlerTagType.RECHARGING, true)),
|
||||
|
|
|
@ -272,13 +272,13 @@ export class PokemonBaseStatBoosterModifierType extends PokemonHeldItemModifierT
|
|||
|
||||
class AllPokemonFullHpRestoreModifierType extends ModifierType {
|
||||
constructor(name: string, description?: string, newModifierFunc?: NewModifierFunc, iconImage?: string) {
|
||||
super(name, description || `Restore 100% HP for all POKéMON`, newModifierFunc || ((_type, _args) => new Modifiers.PokemonHpRestoreModifier(this, -1, 100, false)), iconImage);
|
||||
super(name, description || `Restore 100% HP for all POKéMON`, newModifierFunc || ((_type, _args) => new Modifiers.PokemonHpRestoreModifier(this, -1, 100, true)), iconImage);
|
||||
}
|
||||
}
|
||||
|
||||
class AllPokemonFullReviveModifierType extends AllPokemonFullHpRestoreModifierType {
|
||||
constructor(name: string, iconImage?: string) {
|
||||
super(name, `Revives all fainted POKéMON, restoring 100% HP`, (_type, _args) => new Modifiers.PokemonHpRestoreModifier(this, -1, 100, true), iconImage);
|
||||
super(name, `Revives all fainted POKéMON, restoring 100% HP`, (_type, _args) => new Modifiers.PokemonHpRestoreModifier(this, -1, 100, true, true), iconImage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -279,9 +279,8 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
|
|||
return container;
|
||||
}
|
||||
|
||||
getPokemon(scene: BattleScene) {
|
||||
const findInParty = (party: Pokemon[]) => party.find(p => p.id === this.pokemonId);
|
||||
return findInParty(scene.getParty()) || findInParty(scene.getEnemyParty());
|
||||
getPokemon(scene: BattleScene): Pokemon {
|
||||
return scene.getPokemonById(this.pokemonId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import { BattlerTag, BattlerTagLapseType, BattlerTagType, getBattlerTag } from '
|
|||
import { Species } from './data/species';
|
||||
import { WeatherType } from './data/weather';
|
||||
import { TempBattleStat } from './data/temp-battle-stat';
|
||||
import { ArenaTagType, WeakenTypeTag as WeakenMoveTypeTag } from './data/arena-tag';
|
||||
import { WeakenTypeTag as WeakenMoveTypeTag } from './data/arena-tag';
|
||||
|
||||
export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
public id: integer;
|
||||
|
@ -341,6 +341,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
return types;
|
||||
}
|
||||
|
||||
isOfType(type: Type) {
|
||||
return this.getTypes().indexOf(type) > -1;
|
||||
}
|
||||
|
||||
getEvolution(): SpeciesEvolution {
|
||||
if (!pokemonEvolutions.hasOwnProperty(this.species.speciesId))
|
||||
return null;
|
||||
|
@ -554,18 +558,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
}
|
||||
}
|
||||
|
||||
addTag(tagType: BattlerTagType, turnCount?: integer): boolean {
|
||||
addTag(tagType: BattlerTagType, turnCount?: integer, sourceId?: integer, sourceMove?: Moves): boolean {
|
||||
const existingTag = this.getTag(tagType);
|
||||
if (existingTag) {
|
||||
existingTag.onOverlap(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
const newTag = getBattlerTag(tagType, turnCount || 0);
|
||||
this.summonData.tags.push(newTag);
|
||||
newTag.onAdd(this);
|
||||
const newTag = getBattlerTag(tagType, turnCount || 0, sourceId, sourceMove);
|
||||
|
||||
return true;
|
||||
if (newTag.canAdd(this)) {
|
||||
this.summonData.tags.push(newTag);
|
||||
newTag.onAdd(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
getTag(tagType: BattlerTagType | { new(...args: any[]): BattlerTag }): BattlerTag {
|
||||
|
@ -606,6 +615,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
});
|
||||
}
|
||||
|
||||
removeTagsBySourceId(sourceId: integer): void {
|
||||
const tags = this.summonData.tags;
|
||||
tags.filter(t => t.sourceId === sourceId).forEach(t => {
|
||||
t.onRemove(this);
|
||||
tags.splice(tags.indexOf(t), 1);
|
||||
});
|
||||
}
|
||||
|
||||
getMoveHistory(): TurnMove[] {
|
||||
return this.summonData.moveHistory;
|
||||
}
|
||||
|
@ -686,19 +703,18 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
trySetStatus(effect: StatusEffect): boolean {
|
||||
if (this.status)
|
||||
return false;
|
||||
const speciesForm = this.getSpeciesForm();
|
||||
switch (effect) {
|
||||
case StatusEffect.POISON:
|
||||
case StatusEffect.TOXIC:
|
||||
if (speciesForm.isOfType(Type.POISON) || speciesForm.isOfType(Type.STEEL))
|
||||
if (this.isOfType(Type.POISON) || this.isOfType(Type.STEEL))
|
||||
return false;
|
||||
break;
|
||||
case StatusEffect.FREEZE:
|
||||
if (speciesForm.isOfType(Type.ICE))
|
||||
if (this.isOfType(Type.ICE))
|
||||
return false;
|
||||
break;
|
||||
case StatusEffect.BURN:
|
||||
if (speciesForm.isOfType(Type.FIRE))
|
||||
if (this.isOfType(Type.FIRE))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -218,13 +218,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||
return;
|
||||
} else {
|
||||
this.clearOptions();
|
||||
this.partyMessageBox.setTexture('party_message_large');
|
||||
this.message.y -= 15;
|
||||
this.showText(filterResult as string, null, () => {
|
||||
this.partyMessageBox.setTexture('party_message');
|
||||
this.message.setText(defaultMessage);
|
||||
this.message.y += 15;
|
||||
}, null, true);
|
||||
this.showText(filterResult as string, null, () => this.showText(null, 0), null, true);
|
||||
}
|
||||
} else if (option === PartyOption.SUMMARY) {
|
||||
ui.playSelect();
|
||||
|
@ -239,11 +233,11 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||
this.doRelease(this.cursor);
|
||||
}, () => {
|
||||
ui.setMode(Mode.PARTY);
|
||||
this.message.setText(defaultMessage);
|
||||
this.showText(null, 0);
|
||||
});
|
||||
});
|
||||
} else
|
||||
this.showText('You can\'t release a POKéMON that\'s in battle!', null, () => this.message.setText(defaultMessage), null, true);
|
||||
this.showText('You can\'t release a POKéMON that\'s in battle!', null, () => this.showText(null, 0), null, true);
|
||||
} else if (option === PartyOption.CANCEL)
|
||||
this.processInput(Button.CANCEL);
|
||||
} else if (button === Button.CANCEL) {
|
||||
|
@ -363,6 +357,21 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||
return changed;
|
||||
}
|
||||
|
||||
showText(text: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer) {
|
||||
if (text === null)
|
||||
text = defaultMessage;
|
||||
|
||||
if (text?.indexOf('\n') === -1) {
|
||||
this.partyMessageBox.setTexture('party_message');
|
||||
this.message.setY(10);
|
||||
} else {
|
||||
this.partyMessageBox.setTexture('party_message_large');
|
||||
this.message.setY(-5);
|
||||
}
|
||||
|
||||
super.showText(text, delay, callback, callbackDelay, prompt, promptDelay);
|
||||
}
|
||||
|
||||
showOptions() {
|
||||
if (this.cursor === 6)
|
||||
return;
|
||||
|
@ -385,7 +394,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||
break;
|
||||
}
|
||||
|
||||
this.message.setText(optionsMessage);
|
||||
this.showText(optionsMessage, 0);
|
||||
|
||||
const optionsBottom = this.scene.add.image(0, 0, `party_options${wideOptions ? '_wide' : ''}_bottom`);
|
||||
optionsBottom.setOrigin(1, 1);
|
||||
|
@ -500,7 +509,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||
this.selectCallback = null;
|
||||
selectCallback(this.cursor, PartyOption.RELEASE);
|
||||
} else
|
||||
this.message.setText(defaultMessage);
|
||||
this.showText(null, 0);
|
||||
}, null, true);
|
||||
}
|
||||
|
||||
|
@ -535,7 +544,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||
this.eraseOptionsCursor();
|
||||
|
||||
this.partyMessageBox.setTexture('party_message');
|
||||
this.message.setText(defaultMessage);
|
||||
this.showText(null, 0);
|
||||
}
|
||||
|
||||
eraseOptionsCursor() {
|
||||
|
|
Loading…
Reference in New Issue