Update move.ts

This commit is contained in:
Alvin Zou 2024-05-04 22:54:19 -07:00
parent a45da8a382
commit 18a6b7ffeb

View File

@ -201,7 +201,7 @@ export default class Move implements Localizable {
return this; return this;
} }
partial(): this { partial(): this {
this.nameAppend += ' (P)'; this.nameAppend += ' (P)';
return this; return this;
@ -468,7 +468,7 @@ export class MoveEffectAttr extends MoveAttr {
} }
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise<boolean> { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise<boolean> {
return this.canApply(user, target, move, args); return this.canApply(user, target, move, args);
} }
} }
@ -587,16 +587,16 @@ export class MatchHpAttr extends FixedDamageAttr {
super(0); super(0);
} }
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
(args[0] as Utils.IntegerHolder).value = target.hp - user.hp; (args[0] as Utils.IntegerHolder).value = target.hp - user.hp;
return true; return true;
} }
getCondition(): MoveConditionFunc { getCondition(): MoveConditionFunc {
return (user, target, move) => user.hp <= target.hp; return (user, target, move) => user.hp <= target.hp;
} }
// TODO // TODO
/*getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { /*getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
return 0; return 0;
@ -669,7 +669,7 @@ export class SurviveDamageAttr extends ModifiedDamageAttr {
getCondition(): MoveConditionFunc { getCondition(): MoveConditionFunc {
return (user, target, move) => target.hp > 1; return (user, target, move) => target.hp > 1;
} }
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
return target.hp > 1 ? 0 : -20; return target.hp > 1 ? 0 : -20;
} }
@ -707,7 +707,7 @@ export class RecoilAttr extends MoveEffectAttr {
applyAbAttrs(BlockNonDirectDamageAbAttr, user, cancelled); applyAbAttrs(BlockNonDirectDamageAbAttr, user, cancelled);
if (cancelled.value) if (cancelled.value)
return false; return false;
user.damageAndUpdate(recoilDamage, HitResult.OTHER, false, true, true); user.damageAndUpdate(recoilDamage, HitResult.OTHER, false, true, true);
user.scene.queueMessage(getPokemonMessage(user, ' is hit\nwith recoil!')); user.scene.queueMessage(getPokemonMessage(user, ' is hit\nwith recoil!'));
user.turnData.damageTaken += recoilDamage; user.turnData.damageTaken += recoilDamage;
@ -1096,7 +1096,7 @@ export class PsychoShiftEffectAttr extends MoveEffectAttr {
} }
return statusAfflictResult; return statusAfflictResult;
} }
return false; return false;
} }
@ -1217,7 +1217,7 @@ export class HealStatusEffectAttr extends MoveEffectAttr {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status.effect))); pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status.effect)));
pokemon.resetStatus(); pokemon.resetStatus();
pokemon.updateInfo(); pokemon.updateInfo();
return true; return true;
} }
@ -1246,7 +1246,7 @@ export class BypassSleepAttr extends MoveAttr {
export class WeatherChangeAttr extends MoveEffectAttr { export class WeatherChangeAttr extends MoveEffectAttr {
private weatherType: WeatherType; private weatherType: WeatherType;
constructor(weatherType: WeatherType) { constructor(weatherType: WeatherType) {
super(); super();
@ -1264,7 +1264,7 @@ export class WeatherChangeAttr extends MoveEffectAttr {
export class ClearWeatherAttr extends MoveEffectAttr { export class ClearWeatherAttr extends MoveEffectAttr {
private weatherType: WeatherType; private weatherType: WeatherType;
constructor(weatherType: WeatherType) { constructor(weatherType: WeatherType) {
super(); super();
@ -1281,7 +1281,7 @@ export class ClearWeatherAttr extends MoveEffectAttr {
export class TerrainChangeAttr extends MoveEffectAttr { export class TerrainChangeAttr extends MoveEffectAttr {
private terrainType: TerrainType; private terrainType: TerrainType;
constructor(terrainType: TerrainType) { constructor(terrainType: TerrainType) {
super(); super();
@ -1318,7 +1318,7 @@ export class OneHitKOAttr extends MoveAttr {
return false; return false;
(args[0] as Utils.BooleanHolder).value = true; (args[0] as Utils.BooleanHolder).value = true;
return true; return true;
} }
@ -1558,7 +1558,7 @@ export class AcupressureStatChangeAttr extends MoveEffectAttr {
return true; return true;
} }
return false; return false;
} }
} }
export class GrowthStatChangeAttr extends StatChangeAttr { export class GrowthStatChangeAttr extends StatChangeAttr {
@ -1686,7 +1686,7 @@ export class HpSplitAttr extends MoveEffectAttr {
return resolve(false); return resolve(false);
const infoUpdates = []; const infoUpdates = [];
const hpValue = Math.floor((target.hp + user.hp) / 2); const hpValue = Math.floor((target.hp + user.hp) / 2);
if (user.hp < hpValue) { if (user.hp < hpValue) {
const healing = user.heal(hpValue - user.hp); const healing = user.heal(hpValue - user.hp);
@ -1843,7 +1843,7 @@ export class BattleStatRatioPowerAttr extends VariablePowerAttr {
// Gen 6+ always have 1 base power // Gen 6+ always have 1 base power
power.value = 1; power.value = 1;
return true; return true;
} }
let bp = Math.floor(Math.min(150, 25 * target.getBattleStat(this.stat) / userSpeed + 1)); let bp = Math.floor(Math.min(150, 25 * target.getBattleStat(this.stat) / userSpeed + 1));
power.value = bp; power.value = bp;
return true; return true;
@ -1899,7 +1899,7 @@ export class CompareWeightPowerAttr extends VariablePowerAttr {
if (!userWeight || userWeight === 0) if (!userWeight || userWeight === 0)
return false; return false;
const relativeWeight = (targetWeight / userWeight) * 100; const relativeWeight = (targetWeight / userWeight) * 100;
switch (true) { switch (true) {
@ -1990,7 +1990,7 @@ export class MagnitudePowerAttr extends VariablePowerAttr {
const magnitudePowers = [ 10, 30, 50, 70, 90, 100, 110, 150 ]; const magnitudePowers = [ 10, 30, 50, 70, 90, 100, 110, 150 ];
let rand: integer; let rand: integer;
user.scene.executeWithSeedOffset(() => rand = Utils.randSeedInt(100), user.scene.currentBattle.turn << 6, user.scene.waveSeed); user.scene.executeWithSeedOffset(() => rand = Utils.randSeedInt(100), user.scene.currentBattle.turn << 6, user.scene.waveSeed);
let m = 0; let m = 0;
@ -2054,7 +2054,7 @@ export class HitCountPowerAttr extends VariablePowerAttr {
} }
} }
export class StatChangeCountPowerAttr extends VariablePowerAttr { export class UserStatChangeCountPowerAttr extends VariablePowerAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const positiveStats: number = user.summonData.battleStats.reduce((total, stat) => stat > 0 && stat ? total + stat : total, 0); const positiveStats: number = user.summonData.battleStats.reduce((total, stat) => stat > 0 && stat ? total + stat : total, 0);
@ -2064,6 +2064,16 @@ export class StatChangeCountPowerAttr extends VariablePowerAttr {
} }
} }
export class OppStatChangeCountPowerAttr extends VariablePowerAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const positiveStats: number = target.summonData.battleStats.reduce((total, stat) => stat > 0 && stat ? total + stat : total, 0);
(args[0] as Utils.NumberHolder).value += Math.min(140, positiveStats * 20);
return true;
}
}
export class PresentPowerAttr extends VariablePowerAttr { export class PresentPowerAttr extends VariablePowerAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
@ -2090,9 +2100,9 @@ export class KnockOffPowerAttr extends VariablePowerAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
if(target.getHeldItems().length > 0){ if(target.getHeldItems().length > 0){
(args[0] as Utils.NumberHolder).value *= 1.5; (args[0] as Utils.NumberHolder).value *= 1.5;
return true; return true;
} }
return false; return false;
} }
} }
@ -2429,7 +2439,7 @@ export class HiddenPowerTypeAttr extends VariableMoveTypeAttr {
+(user.ivs[Stat.SPD] & 1) * 8 +(user.ivs[Stat.SPD] & 1) * 8
+(user.ivs[Stat.SPATK] & 1) * 16 +(user.ivs[Stat.SPATK] & 1) * 16
+(user.ivs[Stat.SPDEF] & 1) * 32) * 15/63); +(user.ivs[Stat.SPDEF] & 1) * 32) * 15/63);
type.value = [ type.value = [
Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND, Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND,
Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL, Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL,
@ -2527,11 +2537,11 @@ const crashDamageFunc = (user: Pokemon, move: Move) => {
applyAbAttrs(BlockNonDirectDamageAbAttr, user, cancelled); applyAbAttrs(BlockNonDirectDamageAbAttr, user, cancelled);
if (cancelled.value) if (cancelled.value)
return false; return false;
user.damageAndUpdate(Math.floor(user.getMaxHp() / 2), HitResult.OTHER, false, true); user.damageAndUpdate(Math.floor(user.getMaxHp() / 2), HitResult.OTHER, false, true);
user.scene.queueMessage(getPokemonMessage(user, ' kept going\nand crashed!')); user.scene.queueMessage(getPokemonMessage(user, ' kept going\nand crashed!'));
user.turnData.damageTaken += Math.floor(user.getMaxHp() / 2); user.turnData.damageTaken += Math.floor(user.getMaxHp() / 2);
return true; return true;
}; };
@ -2552,23 +2562,23 @@ export class DisableMoveAttr extends MoveEffectAttr {
turnMove = moveQueue.shift(); turnMove = moveQueue.shift();
if (turnMove.virtual) if (turnMove.virtual)
continue; continue;
const moveIndex = target.getMoveset().findIndex(m => m.moveId === turnMove.move); const moveIndex = target.getMoveset().findIndex(m => m.moveId === turnMove.move);
if (moveIndex === -1) if (moveIndex === -1)
return false; return false;
const disabledMove = target.getMoveset()[moveIndex]; const disabledMove = target.getMoveset()[moveIndex];
target.summonData.disabledMove = disabledMove.moveId; target.summonData.disabledMove = disabledMove.moveId;
target.summonData.disabledTurns = 4; target.summonData.disabledTurns = 4;
user.scene.queueMessage(getPokemonMessage(target, `'s ${disabledMove.getName()}\nwas disabled!`)); user.scene.queueMessage(getPokemonMessage(target, `'s ${disabledMove.getName()}\nwas disabled!`));
return true; return true;
} }
return false; return false;
} }
getCondition(): MoveConditionFunc { getCondition(): MoveConditionFunc {
return (user, target, move) => { return (user, target, move) => {
if (target.summonData.disabledMove || target.isMax()) if (target.summonData.disabledMove || target.isMax())
@ -2580,7 +2590,7 @@ export class DisableMoveAttr extends MoveEffectAttr {
turnMove = moveQueue.shift(); turnMove = moveQueue.shift();
if (turnMove.virtual) if (turnMove.virtual)
continue; continue;
const move = target.getMoveset().find(m => m.moveId === turnMove.move); const move = target.getMoveset().find(m => m.moveId === turnMove.move);
if (!move) if (!move)
continue; continue;
@ -2719,7 +2729,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
} }
export class CurseAttr extends MoveEffectAttr { export class CurseAttr extends MoveEffectAttr {
apply(user: Pokemon, target: Pokemon, move:Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move:Move, args: any[]): boolean {
if (user.getTypes(true).includes(Type.GHOST)) { if (user.getTypes(true).includes(Type.GHOST)) {
if (target.getTag(BattlerTagType.CURSED)) { if (target.getTag(BattlerTagType.CURSED)) {
@ -2754,7 +2764,7 @@ export class LapseBattlerTagAttr extends MoveEffectAttr {
for (let tagType of this.tagTypes) for (let tagType of this.tagTypes)
(this.selfTarget ? user : target).lapseTag(tagType); (this.selfTarget ? user : target).lapseTag(tagType);
return true; return true;
} }
} }
@ -2774,7 +2784,7 @@ export class RemoveBattlerTagAttr extends MoveEffectAttr {
for (let tagType of this.tagTypes) for (let tagType of this.tagTypes)
(this.selfTarget ? user : target).removeTag(tagType); (this.selfTarget ? user : target).removeTag(tagType);
return true; return true;
} }
} }
@ -2977,13 +2987,13 @@ export class RemoveScreensAttr extends MoveEffectAttr {
export class ForceSwitchOutAttr extends MoveEffectAttr { export class ForceSwitchOutAttr extends MoveEffectAttr {
private user: boolean; private user: boolean;
private batonPass: boolean; private batonPass: boolean;
constructor(user?: boolean, batonPass?: boolean) { constructor(user?: boolean, batonPass?: boolean) {
super(false, MoveEffectTrigger.POST_APPLY, true); super(false, MoveEffectTrigger.POST_APPLY, true);
this.user = !!user; this.user = !!user;
this.batonPass = !!batonPass; this.batonPass = !!batonPass;
} }
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
return new Promise(resolve => { return new Promise(resolve => {
@ -2997,7 +3007,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
// Move the switch out logic inside the conditional block // Move the switch out logic inside the conditional block
// This ensures that the switch out only happens when the conditions are met // This ensures that the switch out only happens when the conditions are met
const switchOutTarget = this.user ? user : target; const switchOutTarget = this.user ? user : target;
if (switchOutTarget instanceof PlayerPokemon) { if (switchOutTarget instanceof PlayerPokemon) {
if (switchOutTarget.hp) { if (switchOutTarget.hp) {
applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, switchOutTarget); applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, switchOutTarget);
(switchOutTarget as PlayerPokemon).switchOut(this.batonPass, true).then(() => resolve(true)); (switchOutTarget as PlayerPokemon).switchOut(this.batonPass, true).then(() => resolve(true));
@ -3013,30 +3023,30 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
switchOutTarget.setVisible(false); switchOutTarget.setVisible(false);
switchOutTarget.scene.field.remove(switchOutTarget); switchOutTarget.scene.field.remove(switchOutTarget);
user.scene.triggerPokemonFormChange(switchOutTarget, SpeciesFormChangeActiveTrigger, true); user.scene.triggerPokemonFormChange(switchOutTarget, SpeciesFormChangeActiveTrigger, true);
if (switchOutTarget.hp) if (switchOutTarget.hp)
user.scene.unshiftPhase(new SwitchSummonPhase(user.scene, switchOutTarget.getFieldIndex(), user.scene.currentBattle.trainer.getNextSummonIndex((switchOutTarget as EnemyPokemon).trainerSlot), false, this.batonPass, false)); user.scene.unshiftPhase(new SwitchSummonPhase(user.scene, switchOutTarget.getFieldIndex(), user.scene.currentBattle.trainer.getNextSummonIndex((switchOutTarget as EnemyPokemon).trainerSlot), false, this.batonPass, false));
} }
else { else {
// Switch out logic for everything else // Switch out logic for everything else
switchOutTarget.setVisible(false); switchOutTarget.setVisible(false);
if (switchOutTarget.hp) { if (switchOutTarget.hp) {
switchOutTarget.hideInfo().then(() => switchOutTarget.destroy()); switchOutTarget.hideInfo().then(() => switchOutTarget.destroy());
switchOutTarget.scene.field.remove(switchOutTarget); switchOutTarget.scene.field.remove(switchOutTarget);
user.scene.queueMessage(getPokemonMessage(switchOutTarget, ' fled!'), null, true, 500); user.scene.queueMessage(getPokemonMessage(switchOutTarget, ' fled!'), null, true, 500);
} }
if (!switchOutTarget.getAlly()?.isActive(true)) { if (!switchOutTarget.getAlly()?.isActive(true)) {
user.scene.clearEnemyHeldItemModifiers(); user.scene.clearEnemyHeldItemModifiers();
if (switchOutTarget.hp) { if (switchOutTarget.hp) {
user.scene.pushPhase(new BattleEndPhase(user.scene)); user.scene.pushPhase(new BattleEndPhase(user.scene));
user.scene.pushPhase(new NewBattlePhase(user.scene)); user.scene.pushPhase(new NewBattlePhase(user.scene));
} }
} }
} }
resolve(true); resolve(true);
}); });
} }
@ -3217,7 +3227,7 @@ export class FirstMoveTypeAttr extends MoveEffectAttr {
return false; return false;
const firstMoveType = target.getMoveset()[0].getMove().type const firstMoveType = target.getMoveset()[0].getMove().type
user.summonData.types = [ firstMoveType ]; user.summonData.types = [ firstMoveType ];
user.scene.queueMessage(getPokemonMessage(user, ` transformed\ninto to the ${Utils.toReadableString(Type[firstMoveType])} type!`)); user.scene.queueMessage(getPokemonMessage(user, ` transformed\ninto to the ${Utils.toReadableString(Type[firstMoveType])} type!`));
@ -3259,8 +3269,8 @@ export class RandomMovesetMoveAttr extends OverrideMoveEffectAttr {
selectTargets = [ moveTargets.targets[user.randSeedInt(moveTargets.targets.length)] ]; selectTargets = [ moveTargets.targets[user.randSeedInt(moveTargets.targets.length)] ];
break; break;
} }
} }
const targets = selectTargets; const targets = selectTargets;
user.getMoveQueue().push({ move: move.moveId, targets: targets, ignorePP: true }); user.getMoveQueue().push({ move: move.moveId, targets: targets, ignorePP: true });
user.scene.unshiftPhase(new MovePhase(user.scene, user, targets, moveset[moveIndex], true)); user.scene.unshiftPhase(new MovePhase(user.scene, user, targets, moveset[moveIndex], true));
return true; return true;
@ -3275,7 +3285,7 @@ export class RandomMoveAttr extends OverrideMoveEffectAttr {
return new Promise(resolve => { return new Promise(resolve => {
const moveIds = Utils.getEnumValues(Moves).filter(m => !allMoves[m].hasFlag(MoveFlags.IGNORE_VIRTUAL) && !allMoves[m].name.endsWith(' (N)')); const moveIds = Utils.getEnumValues(Moves).filter(m => !allMoves[m].hasFlag(MoveFlags.IGNORE_VIRTUAL) && !allMoves[m].name.endsWith(' (N)'));
const moveId = moveIds[user.randSeedInt(moveIds.length)]; const moveId = moveIds[user.randSeedInt(moveIds.length)];
const moveTargets = getMoveTargets(user, moveId); const moveTargets = getMoveTargets(user, moveId);
if (!moveTargets.targets.length) { if (!moveTargets.targets.length) {
resolve(false); resolve(false);
@ -3428,7 +3438,7 @@ export class NaturePowerAttr extends OverrideMoveEffectAttr {
moveId = Moves.TRI_ATTACK; moveId = Moves.TRI_ATTACK;
break; break;
} }
user.getMoveQueue().push({ move: moveId, targets: [target.getBattlerIndex()], ignorePP: true }); user.getMoveQueue().push({ move: moveId, targets: [target.getBattlerIndex()], ignorePP: true });
user.scene.unshiftPhase(new MovePhase(user.scene, user, [target.getBattlerIndex()], new PokemonMove(moveId, 0, 0, true), true)); user.scene.unshiftPhase(new MovePhase(user.scene, user, [target.getBattlerIndex()], new PokemonMove(moveId, 0, 0, true), true));
initMoveAnim(user.scene, moveId).then(() => { initMoveAnim(user.scene, moveId).then(() => {
@ -3595,16 +3605,16 @@ export class SketchAttr extends MoveEffectAttr {
return (user, target, move) => { return (user, target, move) => {
if (!targetMoveCopiableCondition(user, target, move)) if (!targetMoveCopiableCondition(user, target, move))
return false; return false;
const targetMoves = target.getMoveHistory().filter(m => !m.virtual); const targetMoves = target.getMoveHistory().filter(m => !m.virtual);
if (!targetMoves.length) if (!targetMoves.length)
return false; return false;
const sketchableMove = targetMoves[0]; const sketchableMove = targetMoves[0];
if (user.getMoveset().find(m => m.moveId === sketchableMove.move)) if (user.getMoveset().find(m => m.moveId === sketchableMove.move))
return false; return false;
return true; return true;
}; };
} }
@ -3651,7 +3661,7 @@ export class AbilityCopyAttr extends MoveEffectAttr {
user.summonData.ability = target.getAbility().id; user.summonData.ability = target.getAbility().id;
user.scene.queueMessage(getPokemonMessage(user, ` copied the `) + getPokemonMessage(target, `'s\n${allAbilities[target.getAbility().id].name}!`)); user.scene.queueMessage(getPokemonMessage(user, ` copied the `) + getPokemonMessage(target, `'s\n${allAbilities[target.getAbility().id].name}!`));
if (this.copyToPartner && user.scene.currentBattle?.double && user.getAlly().hp) { if (this.copyToPartner && user.scene.currentBattle?.double && user.getAlly().hp) {
user.getAlly().summonData.ability = target.getAbility().id; user.getAlly().summonData.ability = target.getAbility().id;
user.getAlly().scene.queueMessage(getPokemonMessage(user.getAlly(), ` copied the `) + getPokemonMessage(target, `'s\n${allAbilities[target.getAbility().id].name}!`)); user.getAlly().scene.queueMessage(getPokemonMessage(user.getAlly(), ` copied the `) + getPokemonMessage(target, `'s\n${allAbilities[target.getAbility().id].name}!`));
@ -3900,7 +3910,7 @@ export function getMoveTargets(user: Pokemon, move: Moves): MoveTargetSet {
const moveTarget = allMoves[move].getAttrs(VariableTargetAttr).length ? variableTarget.value : move ? allMoves[move].moveTarget : move === undefined ? MoveTarget.NEAR_ENEMY : []; const moveTarget = allMoves[move].getAttrs(VariableTargetAttr).length ? variableTarget.value : move ? allMoves[move].moveTarget : move === undefined ? MoveTarget.NEAR_ENEMY : [];
const opponents = user.getOpponents(); const opponents = user.getOpponents();
let set: Pokemon[] = []; let set: Pokemon[] = [];
let multiple = false; let multiple = false;
@ -4568,7 +4578,7 @@ export function initMoves() {
.partial(), .partial(),
new AttackMove(Moves.RAPID_SPIN, Type.NORMAL, MoveCategory.PHYSICAL, 50, 100, 40, 100, 0, 2) new AttackMove(Moves.RAPID_SPIN, Type.NORMAL, MoveCategory.PHYSICAL, 50, 100, 40, 100, 0, 2)
.attr(StatChangeAttr, BattleStat.SPD, 1, true) .attr(StatChangeAttr, BattleStat.SPD, 1, true)
.attr(RemoveBattlerTagAttr, [ .attr(RemoveBattlerTagAttr, [
BattlerTagType.BIND, BattlerTagType.BIND,
BattlerTagType.WRAP, BattlerTagType.WRAP,
BattlerTagType.FIRE_SPIN, BattlerTagType.FIRE_SPIN,
@ -4959,7 +4969,7 @@ export function initMoves() {
new AttackMove(Moves.CLOSE_COMBAT, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 100, 5, 100, 0, 4) new AttackMove(Moves.CLOSE_COMBAT, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 100, 5, 100, 0, 4)
.attr(StatChangeAttr, [ BattleStat.DEF, BattleStat.SPDEF ], -1, true), .attr(StatChangeAttr, [ BattleStat.DEF, BattleStat.SPDEF ], -1, true),
new AttackMove(Moves.PAYBACK, Type.DARK, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 4) new AttackMove(Moves.PAYBACK, Type.DARK, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 4)
.attr(MovePowerMultiplierAttr, (user, target, move) => target.getLastXMoves(1).find(m => m.turn === target.scene.currentBattle.turn) || user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command === Command.BALL ? 2 : 1), .attr(MovePowerMultiplierAttr, (user, target, move) => target.getLastXMoves(1).find(m => m.turn === target.scene.currentBattle.turn) || user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command === Command.BALL ? 2 : 1),
new AttackMove(Moves.ASSURANCE, Type.DARK, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 4) new AttackMove(Moves.ASSURANCE, Type.DARK, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 4)
.attr(MovePowerMultiplierAttr, (user, target, move) => target.turnData.damageTaken > 0 ? 2 : 1), .attr(MovePowerMultiplierAttr, (user, target, move) => target.turnData.damageTaken > 0 ? 2 : 1),
new StatusMove(Moves.EMBARGO, Type.DARK, 100, 15, -1, 0, 4) new StatusMove(Moves.EMBARGO, Type.DARK, 100, 15, -1, 0, 4)
@ -5004,9 +5014,9 @@ export function initMoves() {
.unimplemented(), .unimplemented(),
new StatusMove(Moves.GUARD_SWAP, Type.PSYCHIC, -1, 10, -1, 0, 4) new StatusMove(Moves.GUARD_SWAP, Type.PSYCHIC, -1, 10, -1, 0, 4)
.unimplemented(), .unimplemented(),
new AttackMove(Moves.PUNISHMENT, Type.DARK, MoveCategory.PHYSICAL, -1, 100, 5, -1, 0, 4) new AttackMove(Moves.PUNISHMENT, Type.DARK, MoveCategory.PHYSICAL, 60, 100, 5, -1, 0, 4)
.unimplemented(), .attr(OppStatChangeCountPowerAttr),
new AttackMove(Moves.LAST_RESORT, Type.NORMAL, MoveCategory.PHYSICAL, 140, 100, 5, -1, 0, 4) new AttackMove(Moves.LAST_RESORT, Type.NORMAL, MoveCategory.PHYSICAL, 60, 100, 5, -1, 0, 4)
.attr(LastResortAttr), .attr(LastResortAttr),
new StatusMove(Moves.WORRY_SEED, Type.GRASS, 100, 10, -1, 0, 4) new StatusMove(Moves.WORRY_SEED, Type.GRASS, 100, 10, -1, 0, 4)
.attr(AbilityChangeAttr, Abilities.INSOMNIA), .attr(AbilityChangeAttr, Abilities.INSOMNIA),
@ -5021,7 +5031,7 @@ export function initMoves() {
.attr(AddBattlerTagAttr, BattlerTagType.AQUA_RING, true, true), .attr(AddBattlerTagAttr, BattlerTagType.AQUA_RING, true, true),
new SelfStatusMove(Moves.MAGNET_RISE, Type.ELECTRIC, -1, 10, -1, 0, 4) new SelfStatusMove(Moves.MAGNET_RISE, Type.ELECTRIC, -1, 10, -1, 0, 4)
.attr(AddBattlerTagAttr, BattlerTagType.MAGNET_RISEN, true, true) .attr(AddBattlerTagAttr, BattlerTagType.MAGNET_RISEN, true, true)
.condition((user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY) && .condition((user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY) &&
!user.getTag(BattlerTagType.IGNORE_FLYING) && !user.getTag(BattlerTagType.INGRAIN) && !user.getTag(BattlerTagType.IGNORE_FLYING) && !user.getTag(BattlerTagType.INGRAIN) &&
!user.getTag(BattlerTagType.MAGNET_RISEN)) !user.getTag(BattlerTagType.MAGNET_RISEN))
.unimplemented(), .unimplemented(),
@ -5305,7 +5315,7 @@ export function initMoves() {
new AttackMove(Moves.CLEAR_SMOG, Type.POISON, MoveCategory.SPECIAL, 50, -1, 15, -1, 0, 5) new AttackMove(Moves.CLEAR_SMOG, Type.POISON, MoveCategory.SPECIAL, 50, -1, 15, -1, 0, 5)
.attr(ResetStatsAttr), .attr(ResetStatsAttr),
new AttackMove(Moves.STORED_POWER, Type.PSYCHIC, MoveCategory.SPECIAL, 20, 100, 10, -1, 0, 5) new AttackMove(Moves.STORED_POWER, Type.PSYCHIC, MoveCategory.SPECIAL, 20, 100, 10, -1, 0, 5)
.attr(StatChangeCountPowerAttr), .attr(UserStatChangeCountPowerAttr),
new StatusMove(Moves.QUICK_GUARD, Type.FIGHTING, -1, 15, -1, 3, 5) new StatusMove(Moves.QUICK_GUARD, Type.FIGHTING, -1, 15, -1, 3, 5)
.target(MoveTarget.USER_SIDE) .target(MoveTarget.USER_SIDE)
.unimplemented(), .unimplemented(),
@ -5328,7 +5338,7 @@ export function initMoves() {
new AttackMove(Moves.SKY_DROP, Type.FLYING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5) new AttackMove(Moves.SKY_DROP, Type.FLYING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5)
.attr(ChargeAttr, ChargeAnim.SKY_DROP_CHARGING, 'took {TARGET}\ninto the sky!', BattlerTagType.FLYING) // TODO: Add 2nd turn message .attr(ChargeAttr, ChargeAnim.SKY_DROP_CHARGING, 'took {TARGET}\ninto the sky!', BattlerTagType.FLYING) // TODO: Add 2nd turn message
.condition(failOnGravityCondition) .condition(failOnGravityCondition)
.ignoresVirtual(), .ignoresVirtual(),
new SelfStatusMove(Moves.SHIFT_GEAR, Type.STEEL, -1, 10, -1, 0, 5) new SelfStatusMove(Moves.SHIFT_GEAR, Type.STEEL, -1, 10, -1, 0, 5)
.attr(StatChangeAttr, BattleStat.ATK, 1, true) .attr(StatChangeAttr, BattleStat.ATK, 1, true)
.attr(StatChangeAttr, BattleStat.SPD, 2, true), .attr(StatChangeAttr, BattleStat.SPD, 2, true),
@ -5389,7 +5399,7 @@ export function initMoves() {
.attr(HitHealAttr) .attr(HitHealAttr)
.triageMove(), .triageMove(),
new AttackMove(Moves.SACRED_SWORD, Type.FIGHTING, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 5) new AttackMove(Moves.SACRED_SWORD, Type.FIGHTING, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 5)
.attr(IgnoreOpponentStatChangesAttr) .attr(IgnoreOpponentStatChangesAttr)
.slicingMove(), .slicingMove(),
new AttackMove(Moves.RAZOR_SHELL, Type.WATER, MoveCategory.PHYSICAL, 75, 95, 10, 50, 0, 5) new AttackMove(Moves.RAZOR_SHELL, Type.WATER, MoveCategory.PHYSICAL, 75, 95, 10, 50, 0, 5)
.attr(StatChangeAttr, BattleStat.DEF, -1) .attr(StatChangeAttr, BattleStat.DEF, -1)
@ -5778,7 +5788,7 @@ export function initMoves() {
new AttackMove(Moves.FIRE_LASH, Type.FIRE, MoveCategory.PHYSICAL, 80, 100, 15, 100, 0, 7) new AttackMove(Moves.FIRE_LASH, Type.FIRE, MoveCategory.PHYSICAL, 80, 100, 15, 100, 0, 7)
.attr(StatChangeAttr, BattleStat.DEF, -1), .attr(StatChangeAttr, BattleStat.DEF, -1),
new AttackMove(Moves.POWER_TRIP, Type.DARK, MoveCategory.PHYSICAL, 20, 100, 10, -1, 0, 7) new AttackMove(Moves.POWER_TRIP, Type.DARK, MoveCategory.PHYSICAL, 20, 100, 10, -1, 0, 7)
.attr(StatChangeCountPowerAttr), .attr(UserStatChangeCountPowerAttr),
new AttackMove(Moves.BURN_UP, Type.FIRE, MoveCategory.SPECIAL, 130, 100, 5, -1, 0, 7) new AttackMove(Moves.BURN_UP, Type.FIRE, MoveCategory.SPECIAL, 130, 100, 5, -1, 0, 7)
.condition((user) => { .condition((user) => {
const userTypes = user.getTypes(true); const userTypes = user.getTypes(true);
@ -6446,7 +6456,7 @@ export function initMoves() {
.attr(StatChangeAttr, BattleStat.SPATK, -1, true, null, true, true) .attr(StatChangeAttr, BattleStat.SPATK, -1, true, null, true, true)
.target(MoveTarget.ALL_NEAR_ENEMIES), .target(MoveTarget.ALL_NEAR_ENEMIES),
new AttackMove(Moves.PSYBLADE, Type.PSYCHIC, MoveCategory.PHYSICAL, 80, 100, 15, -1, 0, 9) new AttackMove(Moves.PSYBLADE, Type.PSYCHIC, MoveCategory.PHYSICAL, 80, 100, 15, -1, 0, 9)
.attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.ELECTRIC && user.isGrounded() ? 1.5 : 1) .attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.ELECTRIC && user.isGrounded() ? 1.5 : 1)
.slicingMove(), .slicingMove(),
new AttackMove(Moves.HYDRO_STEAM, Type.WATER, MoveCategory.SPECIAL, 80, 100, 15, -1, 0, 9) new AttackMove(Moves.HYDRO_STEAM, Type.WATER, MoveCategory.SPECIAL, 80, 100, 15, -1, 0, 9)
.partial(), .partial(),
@ -6584,4 +6594,4 @@ export function initMoves() {
new AttackMove(Moves.MALIGNANT_CHAIN, Type.POISON, MoveCategory.SPECIAL, 100, 100, 5, 50, 0, 9) new AttackMove(Moves.MALIGNANT_CHAIN, Type.POISON, MoveCategory.SPECIAL, 100, 100, 5, 50, 0, 9)
.attr(StatusEffectAttr, StatusEffect.TOXIC) .attr(StatusEffectAttr, StatusEffect.TOXIC)
); );
} }