diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 0fea80c3759..ecf401e1dda 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -68,6 +68,17 @@ export class BattlerTag { ? allMoves[this.sourceMove].name : null; } + + /** + * When given a battler tag or json representing one, load the data for it. + * This is meant to be inherited from by any battler tag with custom attributes + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + this.turnCount = source.turnCount; + this.sourceMove = source.sourceMove; + this.sourceId = source.sourceId; + } } export interface WeatherBattlerTag { @@ -299,6 +310,15 @@ export class SeedTag extends BattlerTag { super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId); } + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.sourceIndex = source.sourceIndex; + } + canAdd(pokemon: Pokemon): boolean { return !pokemon.isOfType(Type.GRASS); } @@ -404,6 +424,15 @@ export class EncoreTag extends BattlerTag { super(BattlerTagType.ENCORE, BattlerTagLapseType.AFTER_MOVE, 3, Moves.ENCORE, sourceId); } + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.moveId = source.moveId as Moves; + } + canAdd(pokemon: Pokemon): boolean { if (pokemon.isMax()) return false; @@ -553,6 +582,15 @@ export abstract class DamagingTrapTag extends TrappedTag { this.commonAnim = commonAnim; } + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.commonAnim = source.commonAnim as CommonAnim; + } + canAdd(pokemon: Pokemon): boolean { return !pokemon.isOfType(Type.GHOST) && !pokemon.findTag(t => t instanceof DamagingTrapTag); } @@ -709,6 +747,15 @@ export class ContactDamageProtectedTag extends ProtectedTag { this.damageRatio = damageRatio; } + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.damageRatio = source.damageRatio; + } + lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { const ret = super.lapse(pokemon, lapseType); @@ -735,6 +782,16 @@ export class ContactStatChangeProtectedTag extends ProtectedTag { this.levels = levels; } + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.stat = source.stat as BattleStat; + this.levels = source.levels; + } + lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { const ret = super.lapse(pokemon, lapseType); @@ -855,6 +912,15 @@ export class AbilityBattlerTag extends BattlerTag { this.ability = ability; } + + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.ability = source.ability as Abilities; + } } export class TruantTag extends AbilityBattlerTag { @@ -912,6 +978,16 @@ export class HighestStatBoostTag extends AbilityBattlerTag { super(tagType, ability, BattlerTagLapseType.CUSTOM, 1); } + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.stat = source.stat as Stat; + this.multiplier = this.multiplier; + } + onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); @@ -953,6 +1029,15 @@ export class WeatherHighestStatBoostTag extends HighestStatBoostTag implements W super(tagType, ability); this.weatherTypes = weatherTypes; } + + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.weatherTypes = source.weatherTypes.map(w => w as WeatherType); + } } export class TerrainHighestStatBoostTag extends HighestStatBoostTag implements TerrainBattlerTag { @@ -962,6 +1047,15 @@ export class TerrainHighestStatBoostTag extends HighestStatBoostTag implements T super(tagType, ability); this.terrainTypes = terrainTypes; } + + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.terrainTypes = source.terrainTypes.map(w => w as TerrainType); + } } export class HideSpriteTag extends BattlerTag { @@ -989,6 +1083,15 @@ export class TypeImmuneTag extends BattlerTag { constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number) { super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove); } + + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.immuneType = source.immuneType as Type; + } } export class MagnetRisenTag extends TypeImmuneTag { @@ -1010,6 +1113,17 @@ export class TypeBoostTag extends BattlerTag { this.oneUse = oneUse; } + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.boostedType = source.boostedType as Type; + this.boostValue = source.boostValue; + this.oneUse = source.oneUse; + } + lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); } @@ -1056,6 +1170,15 @@ export class SaltCuredTag extends BattlerTag { super(BattlerTagType.SALT_CURED, BattlerTagLapseType.TURN_END, 1, Moves.SALT_CURE, sourceId); } + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.sourceIndex = source.sourceIndex; + } + onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); @@ -1091,6 +1214,15 @@ export class CursedTag extends BattlerTag { super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId); } + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.sourceIndex = source.sourceIndex; + } + onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); @@ -1231,4 +1363,15 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); } } - \ No newline at end of file + +/** +* When given a battler tag or json representing one, creates an actual BattlerTag object with the same data. +* @param {BattlerTag | any} source A battler tag +* @return {BattlerTag} The valid battler tag +*/ +export function loadBattlerTag(source: BattlerTag | any): BattlerTag { + const tag = getBattlerTag(source.tagType, source.turnCount, source.sourceMove, source.sourceId); + tag.loadTag(source); + return tag; +} + diff --git a/src/data/move.ts b/src/data/move.ts index 49865a9e51d..99c4457a5db 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -5753,79 +5753,116 @@ export function initMoves() { .ignoresProtect(), /* Unused */ new AttackMove(Moves.BREAKNECK_BLITZ__PHYSICAL, Type.NORMAL, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.BREAKNECK_BLITZ__SPECIAL, Type.NORMAL, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.ALL_OUT_PUMMELING__PHYSICAL, Type.FIGHTING, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.ALL_OUT_PUMMELING__SPECIAL, Type.FIGHTING, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.SUPERSONIC_SKYSTRIKE__PHYSICAL, Type.FLYING, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.SUPERSONIC_SKYSTRIKE__SPECIAL, Type.FLYING, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.ACID_DOWNPOUR__PHYSICAL, Type.POISON, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.ACID_DOWNPOUR__SPECIAL, Type.POISON, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.TECTONIC_RAGE__PHYSICAL, Type.GROUND, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.TECTONIC_RAGE__SPECIAL, Type.GROUND, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.CONTINENTAL_CRUSH__PHYSICAL, Type.ROCK, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.CONTINENTAL_CRUSH__SPECIAL, Type.ROCK, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.SAVAGE_SPIN_OUT__PHYSICAL, Type.BUG, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.SAVAGE_SPIN_OUT__SPECIAL, Type.BUG, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.NEVER_ENDING_NIGHTMARE__PHYSICAL, Type.GHOST, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.NEVER_ENDING_NIGHTMARE__SPECIAL, Type.GHOST, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.CORKSCREW_CRASH__PHYSICAL, Type.STEEL, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.CORKSCREW_CRASH__SPECIAL, Type.STEEL, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.INFERNO_OVERDRIVE__PHYSICAL, Type.FIRE, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.INFERNO_OVERDRIVE__SPECIAL, Type.FIRE, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.HYDRO_VORTEX__PHYSICAL, Type.WATER, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.HYDRO_VORTEX__SPECIAL, Type.WATER, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.BLOOM_DOOM__PHYSICAL, Type.GRASS, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.BLOOM_DOOM__SPECIAL, Type.GRASS, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.GIGAVOLT_HAVOC__PHYSICAL, Type.ELECTRIC, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.GIGAVOLT_HAVOC__SPECIAL, Type.ELECTRIC, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.SHATTERED_PSYCHE__PHYSICAL, Type.PSYCHIC, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.SHATTERED_PSYCHE__SPECIAL, Type.PSYCHIC, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.SUBZERO_SLAMMER__PHYSICAL, Type.ICE, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.SUBZERO_SLAMMER__SPECIAL, Type.ICE, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.DEVASTATING_DRAKE__PHYSICAL, Type.DRAGON, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.DEVASTATING_DRAKE__SPECIAL, Type.DRAGON, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.BLACK_HOLE_ECLIPSE__PHYSICAL, Type.DARK, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.BLACK_HOLE_ECLIPSE__SPECIAL, Type.DARK, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.TWINKLE_TACKLE__PHYSICAL, Type.FAIRY, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.TWINKLE_TACKLE__SPECIAL, Type.FAIRY, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.CATASTROPIKA, Type.ELECTRIC, MoveCategory.PHYSICAL, 210, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), /* End Unused */ new SelfStatusMove(Moves.SHORE_UP, Type.GROUND, -1, 5, -1, 0, 7) .attr(SandHealAttr) @@ -5933,23 +5970,32 @@ export function initMoves() { /* Unused */ new AttackMove(Moves.SINISTER_ARROW_RAID, Type.GHOST, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7) .makesContact(false) - .partial(), + .partial() + .ignoresVirtual(), new AttackMove(Moves.MALICIOUS_MOONSAULT, Type.DARK, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7) - .partial(), + .partial() + .ignoresVirtual(), new AttackMove(Moves.OCEANIC_OPERETTA, Type.WATER, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7) - .partial(), + .partial() + .ignoresVirtual(), new AttackMove(Moves.GUARDIAN_OF_ALOLA, Type.FAIRY, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.SOUL_STEALING_7_STAR_STRIKE, Type.GHOST, MoveCategory.PHYSICAL, 195, -1, 1, -1, 0, 7) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.STOKED_SPARKSURFER, Type.ELECTRIC, MoveCategory.SPECIAL, 175, -1, 1, 100, 0, 7) - .partial(), + .partial() + .ignoresVirtual(), new AttackMove(Moves.PULVERIZING_PANCAKE, Type.NORMAL, MoveCategory.PHYSICAL, 210, -1, 1, -1, 0, 7) - .partial(), + .partial() + .ignoresVirtual(), new SelfStatusMove(Moves.EXTREME_EVOBOOST, Type.NORMAL, -1, 1, 100, 0, 7) - .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 2, true), + .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 2, true) + .ignoresVirtual(), new AttackMove(Moves.GENESIS_SUPERNOVA, Type.PSYCHIC, MoveCategory.SPECIAL, 185, -1, 1, -1, 0, 7) - .attr(TerrainChangeAttr, TerrainType.PSYCHIC), + .attr(TerrainChangeAttr, TerrainType.PSYCHIC) + .ignoresVirtual(), /* End Unused */ new AttackMove(Moves.SHELL_TRAP, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, -3, 7) .target(MoveTarget.ALL_NEAR_ENEMIES) @@ -5987,7 +6033,8 @@ export function initMoves() { .partial(), /* Unused */ new AttackMove(Moves.TEN_MILLION_VOLT_THUNDERBOLT, Type.ELECTRIC, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7) - .partial(), + .partial() + .ignoresVirtual(), /* End Unused */ new AttackMove(Moves.MIND_BLOWN, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, 0, 7) .condition(failIfDampCondition) @@ -6003,21 +6050,27 @@ export function initMoves() { /* Unused */ new AttackMove(Moves.LIGHT_THAT_BURNS_THE_SKY, Type.PSYCHIC, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7) .attr(PhotonGeyserCategoryAttr) - .ignoresAbilities(), + .ignoresAbilities() + .ignoresVirtual(), new AttackMove(Moves.SEARING_SUNRAZE_SMASH, Type.STEEL, MoveCategory.PHYSICAL, 200, -1, 1, -1, 0, 7) - .ignoresAbilities(), + .ignoresAbilities() + .ignoresVirtual(), new AttackMove(Moves.MENACING_MOONRAZE_MAELSTROM, Type.GHOST, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7) - .ignoresAbilities(), + .ignoresAbilities() + .ignoresVirtual(), new AttackMove(Moves.LETS_SNUGGLE_FOREVER, Type.FAIRY, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7) - .partial(), + .partial() + .ignoresVirtual(), new AttackMove(Moves.SPLINTERED_STORMSHARDS, Type.ROCK, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7) .attr(ClearTerrainAttr) - .makesContact(false), + .makesContact(false) + .ignoresVirtual(), new AttackMove(Moves.CLANGOROUS_SOULBLAZE, Type.DRAGON, MoveCategory.SPECIAL, 185, -1, 1, 100, 0, 7) .attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 1, true) .soundBased() .target(MoveTarget.ALL_NEAR_ENEMIES) - .partial(), + .partial() + .ignoresVirtual(), /* End Unused */ new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 100, 2, 7) .attr(CritOnlyAttr), @@ -6054,7 +6107,8 @@ export function initMoves() { .punchingMove(), /* Unused */ new SelfStatusMove(Moves.MAX_GUARD, Type.NORMAL, -1, 10, -1, 4, 8) - .attr(ProtectAttr), + .attr(ProtectAttr) + .ignoresVirtual(), /* End Unused */ new AttackMove(Moves.DYNAMAX_CANNON, Type.DRAGON, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 8) .attr(MovePowerMultiplierAttr, (user, target, move) => target.level > 200 ? 2 : 1) @@ -6098,58 +6152,76 @@ export function initMoves() { /* Unused */ new AttackMove(Moves.MAX_FLARE, Type.FIRE, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_FLUTTERBY, Type.BUG, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_LIGHTNING, Type.ELECTRIC, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_STRIKE, Type.NORMAL, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_KNUCKLE, Type.FIGHTING, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_PHANTASM, Type.GHOST, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_HAILSTORM, Type.ICE, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_OOZE, Type.POISON, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_GEYSER, Type.WATER, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_AIRSTREAM, Type.FLYING, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_STARFALL, Type.FAIRY, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_WYRMWIND, Type.DRAGON, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_MINDSTORM, Type.PSYCHIC, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_ROCKFALL, Type.ROCK, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_QUAKE, Type.GROUND, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_DARKNESS, Type.DARK, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_OVERGROWTH, Type.GRASS, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), new AttackMove(Moves.MAX_STEELSPIKE, Type.STEEL, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8) .target(MoveTarget.NEAR_ENEMY) - .unimplemented(), + .unimplemented() + .ignoresVirtual(), /* End Unused */ new SelfStatusMove(Moves.CLANGOROUS_SOUL, Type.DRAGON, 100, 5, 100, 0, 8) .attr(CutHpStatBoostAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 1, 3) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 758e25246af..88329a2c219 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -3232,4 +3232,13 @@ export class PokemonMove { getName(): string { return this.getMove().name; } + + /** + * Copies an existing move or creates a valid PokemonMove object from json representing one + * @param {PokemonMove | any} source The data for the move to copy + * @return {PokemonMove} A valid pokemonmove object + */ + static loadMove(source: PokemonMove | any): PokemonMove { + return new PokemonMove(source.moveId, source.ppUsed, source.ppUp, source.virtual); + } } diff --git a/src/field/trainer.ts b/src/field/trainer.ts index d52085b65a0..4a7458652c4 100644 --- a/src/field/trainer.ts +++ b/src/field/trainer.ts @@ -147,6 +147,9 @@ export default class Trainer extends Phaser.GameObjects.Container { const difficultyWaveIndex = this.scene.gameMode.getWaveForDifficulty(waveIndex); let baseLevel = 1 + difficultyWaveIndex / 2 + Math.pow(difficultyWaveIndex / 25, 2); + if (this.isDouble() && partyTemplate.size < 2) + partyTemplate.size = 2; + for (let i = 0; i < partyTemplate.size; i++) { let multiplier = 1; diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index b9589020e9b..dfbb9be570b 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -11,6 +11,7 @@ import Pokemon, { EnemyPokemon, PokemonMove, PokemonSummonData } from "../field/ import { TrainerSlot } from "../data/trainer-config"; import { Moves } from "../data/enums/moves"; import { Variant } from "#app/data/variant"; +import { loadBattlerTag } from '../data/battler-tags'; export default class PokemonData { public id: integer; @@ -112,9 +113,18 @@ export default class PokemonData { if (!forHistory && source.summonData) { this.summonData.battleStats = source.summonData.battleStats; this.summonData.moveQueue = source.summonData.moveQueue; - this.summonData.tags = []; // TODO - this.summonData.moveset = source.summonData.moveset; + this.summonData.disabledMove = source.summonData.disabledMove; + this.summonData.disabledTurns = source.summonData.disabledTurns; + this.summonData.abilitySuppressed = source.summonData.abilitySuppressed; + + this.summonData.ability = source.summonData.ability; + this.summonData.moveset = source.summonData.moveset?.map(m => PokemonMove.loadMove(m)); this.summonData.types = source.summonData.types; + + if (source.summonData.tags) + this.summonData.tags = source.summonData.tags?.map(t => loadBattlerTag(t)); + else + this.summonData.tags = []; } } } diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 087f24362ed..514bb173a5c 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -1098,7 +1098,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { // starterMoveData doesn't have base form moves or is using the single form format if (!this.scene.gameData.starterData[speciesId].moveset || Array.isArray(this.scene.gameData.starterData[speciesId].moveset)) this.scene.gameData.starterData[speciesId].moveset = { [props.formIndex]: this.starterMoveset.slice(0) as StarterMoveset }; - const starterMoveData = this.scene.gameData.starterData[speciesId].moveset[props.formIndex]; + const starterMoveData = this.scene.gameData.starterData[speciesId].moveset; // starterMoveData doesn't have active form moves if (!starterMoveData.hasOwnProperty(props.formIndex))