PokemonMove healBell = new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 5) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
boolean sound = getMoveListEntry().getName().equals("Heal Bell");
Pokemon[] teammates = user.getTeammates();
for (int i = 0; i < teammates.length; ++i) {
Pokemon p = teammates[i];
if (p == null || p.isFainted() || (sound && p.hasAbility("Soundproof")))
continue;
p.removeStatus(StatusEffect.SPECIAL_EFFECT_LOCK);
}
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
};
PokemonMove aromatherapy = (PokemonMove)healBell.clone();
aromatherapy.setType(PokemonType.T_GRASS);
m_moves.add(new MoveListEntry("Aromatherapy", aromatherapy));
m_moves.add(new MoveListEntry("Heal Bell", healBell));
m_moves.add(new MoveListEntry("Assist",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 15) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
Pokemon[] teammates = user.getTeammates();
if (teammates.length < 2) {
user.getField().showMessage("But it failed!");
return 0;
}
Random random = mech.getRandom();
Pokemon teammate;
do {
teammate = teammates[random.nextInt(teammates.length)];
} while (teammate == user);
MoveListEntry move;
do {
move = teammate.getMove(random.nextInt(4));
} while (move == null);
if (move.getName().equals("Focus Punch")) {
user.getField().showMessage("But it failed!");
return 0;
}
return user.useMove(move, target);
}
}
));
m_moves.add(new MoveListEntry("Facade",
new PokemonMove(PokemonType.T_NORMAL, 70, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int power = getPower();
if (user.hasEffect(StatusEffect.SPECIAL_EFFECT_LOCK)) {
setPower(2 * power);
}
int damage = mech.calculateDamage(this, user, target);
setPower(power);
target.changeHealth(-damage);
return damage;
}
}
));
m_moves.add(new MoveListEntry("False Swipe",
new PokemonMove(PokemonType.T_NORMAL, 40, 1.0, 40) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int targetHealth = target.getHealth();
int damage = mech.calculateDamage(this, user, target);
if (damage >= targetHealth) {
damage = targetHealth - 1;
}
target.changeHealth(-damage);
return damage;
}
}
));
m_moves.add(new MoveListEntry("Psywave",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 0.8, 15) {
public boolean isAttack() {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
Random random = mech.getRandom();
int damage = user.getLevel() * (random.nextInt(11) * 10 + 50) / 100;
target.changeHealth(-damage);
return damage;
}
}
));
m_moves.add(new MoveListEntry("Jump Kick",
new JumpKickMove(PokemonType.T_FIGHTING, 70, 85, 0.95, 20)
));
m_moves.add(new MoveListEntry("Hi Jump Kick",
new JumpKickMove(PokemonType.T_FIGHTING, 85, 100, 0.90, 20)
));
m_moves.add(new MoveListEntry("Refresh",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.removeStatus(StatusEffect.SPECIAL_EFFECT_LOCK);
return 0;
}
}
));
m_moves.add(new MoveListEntry("Smellingsalt",
new PokemonMove(PokemonType.T_NORMAL, 60, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int power = getPower();
if (!target.hasSubstitute() && target.hasEffect(ParalysisEffect.class)) {
setPower(2 * power);
target.removeStatus(StatusEffect.SPECIAL_EFFECT_LOCK);
user.getField().showMessage(target.getName() + " was cured of paralysis!");
}
int damage = mech.calculateDamage(this, user, target);
setPower(power);
target.changeHealth(-damage);
return damage;
}
}
));
m_moves.add(new MoveListEntry("Splash",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 40) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.getField().showMessage("But nothing happened!");
return 0;
}
}
));
m_moves.add(new MoveListEntry("Teleport",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.getField().showMessage("But it failed!");
return 0;
}
}
));
m_moves.add(new MoveListEntry("Triple Kick",
new PokemonMove(PokemonType.T_FIGHTING, 60, 0.9, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int damage = 0;
PokemonMove move = new PokemonMove(PokemonType.T_FIGHTING, 0, 1.0, 1);
for (int i = 1; i < 4; ++i) {
move.setPower(i * 10);
damage += user.useMove(move, target);
}
user.getField().showMessage("Hit 3 time(s)!");
return damage;
}
}
));
m_moves.add(new MoveListEntry("Razor Wind", new StatusMove(
PokemonType.T_FLYING, 0, 1.0, 10, new StatusEffect[] {
new ChargeEffect(1, "created a whirlwind!", new MoveListEntry(
"Razor Wind",
new HighCriticalHitMove(
PokemonType.T_FLYING, 80, 1.0, 10
)
)
)
},
new boolean[] { true },
new double[] { 1.0 }
) {
public boolean isAttack() {
return true;
}
public boolean isDamaging() {
return true;
}
}
));
m_moves.add(new MoveListEntry("Skull Bash", new StatusMove(
PokemonType.T_NORMAL, 0, 1.0, 15, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_DEFENCE, true, 1),
new ChargeEffect(1, "lowered its head!", new MoveListEntry(
"Skull Bash",
new PokemonMove(
PokemonType.T_NORMAL, 100, 1.0, 15
)
)
)
},
new boolean[] { true, true },
new double[] { 1.0, 1.0 }
) {
public boolean isAttack() {
return true;
}
public boolean isDamaging() {
return true;
}
}
));
m_moves.add(new MoveListEntry("Sky Attack", new StatusMove(
PokemonType.T_FLYING, 0, 1.0, 5, new StatusEffect[] {
new ChargeEffect(1, "is glowing!", new MoveListEntry(
"Sky Attack",
new PokemonMove(
PokemonType.T_FLYING, 140, 0.9, 5
)
)
)
},
new boolean[] { true },
new double[] { 1.0 }
) {
public boolean isAttack() {
return true;
}
public boolean isDamaging() {
return true;
}
}
));
m_moves.add(new MoveListEntry("Pay Day",
new PokemonMove(PokemonType.T_NORMAL, 40, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.getField().showMessage("Coins scattered everywhere!");
return super.use(mech, user, target);
}
}
));
m_moves.add(new MoveListEntry("Present",
new PokemonMove(PokemonType.T_NORMAL, 0, 0.9, 15) {
public boolean isAttack() {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
double random = mech.getRandom().nextDouble();
int power;
if (random <= 0.4) {
power = 40;
} else if (random <= 0.7) {
power = 80;
} else if (random <= 0.8) {
power = 120;
} else {
double maximum = (double)target.getStat(Pokemon.S_HP);
int restore = (int)(maximum * 0.2);
target.changeHealth(restore);
return restore;
}
setPower(power);
int damage = mech.calculateDamage(this, user, target);
setPower(0);
target.changeHealth(-damage);
return damage;
}
}
));
m_moves.add(new MoveListEntry("Dream Eater",
new AbsorbMove(PokemonType.T_PSYCHIC, 100, 1.0, 15, 0.5) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.hasEffect(SleepEffect.class) && !target.hasSubstitute()) {
return super.use(mech, user, target);
}
user.getField().showMessage("But it failed!");
return 0;
}
}
));
m_moves.add(new MoveListEntry("Haze",
new PokemonMove(PokemonType.T_ICE, 0, 1.0, 30) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.removeStatus(StatChangeEffect.class);
target.removeStatus(StatChangeEffect.class);
return 0;
}
}
));
PokemonMove foresight = new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 40) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
List<StatusEffect> statuses = target.getNormalStatuses(0);
Iterator<StatusEffect> i = statuses.iterator();
while (i.hasNext()) {
StatusEffect effect = (StatusEffect)i.next();
if (!(effect instanceof StatChangeEffect)) continue;
StatChangeEffect eff = (StatChangeEffect)effect;
if (eff.getStat() == Pokemon.S_EVASION) {
target.removeStatus(eff);
}
}
statuses = user.getNormalStatuses(0);
i = statuses.iterator();
while (i.hasNext()) {
StatusEffect effect = (StatusEffect)i.next();
if (!(effect instanceof StatChangeEffect)) continue;
StatChangeEffect eff = (StatChangeEffect)effect;
if (eff.getStat() == Pokemon.S_ACCURACY) {
user.removeStatus(eff);
}
}
user.getAccuracy().setSecondaryMultiplier(1);
target.getEvasion().setSecondaryMultiplier(1);
return 0;
}
};
m_moves.add(new MoveListEntry("Foresight", (PokemonMove)foresight.clone()));
m_moves.add(new MoveListEntry("Odor Sleuth", (PokemonMove)foresight.clone()));
m_moves.add(new MoveListEntry("Fissure",
new OneHitKillMove(PokemonType.T_GROUND, 5)));
m_moves.add(new MoveListEntry("Horn Drill",
new OneHitKillMove(PokemonType.T_NORMAL, 5)));
m_moves.add(new MoveListEntry("Guillotine",
new OneHitKillMove(PokemonType.T_NORMAL, 5)));
m_moves.add(new MoveListEntry("Sheer Cold",
new OneHitKillMove(PokemonType.T_ICE, 5)));
m_moves.add(new MoveListEntry("Memento",
new StatusMove(PokemonType.T_DARK, 0, 1.0, 10, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_ATTACK, false, 2),
new StatChangeEffect(Pokemon.S_SPATTACK, false, 2)
},
new boolean[] { false, false },
new double[] { 1.0, 1.0 }
) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (mech.attemptHit(this, user, target)) {
super.use(mech, user, target);
}
user.faint();
return 0;
}
}
));
PokemonMove explosion = new PokemonMove(PokemonType.T_NORMAL, 250, 1.0, 5) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.hasAbility("Damp")) {
user.getField().showMessage(target.getName() + "'s Damp prevents explosions!");
return 0;
}
int damage = 0;
if (target.hasEffect(ProtectEffect.class)) {
List<StatusEffect> list = target.getNormalStatuses(0);
Iterator<StatusEffect> i = list.iterator();
while (i.hasNext()) {
Object o = i.next();
if (o instanceof ProtectEffect) {
ProtectEffect eff = (ProtectEffect)o;
user.getField().showMessage(target.getName() + eff.getDescription());
break;
}
}
} else if (mech.attemptHit(this, user, target)) {
StatMultiplier mul = target.getMultiplier(Pokemon.S_DEFENCE);
double value = mul.getSecondaryMultiplier();
mul.setSecondaryMultiplier(value / 2.0);
damage = mech.calculateDamage(this, user, target);
mul.setSecondaryMultiplier(value);
target.changeHealth(-damage);
}
user.faint();
return damage;
}
};
PokemonMove selfDestruct = (PokemonMove)explosion.clone();
selfDestruct.setPower(200);
m_moves.add(new MoveListEntry("Selfdestruct", selfDestruct));
m_moves.add(new MoveListEntry("Explosion", explosion));
m_moves.add(new MoveListEntry("Nightmare",
new StatusMove(PokemonType.T_GHOST, 0, 1.0, 15, new StatusEffect[] {
new StatusEffect() {
public String getName() {
return "Nightmare";
}
public boolean apply(Pokemon p) {
if (!p.hasEffect(SleepEffect.class)) {
p.getField().showMessage("But it failed!");
return false;
}
return true;
}
public String getDescription() {
return " fell into a nightmare!";
}
public int getTier() {
return 4;
}
public boolean tick(Pokemon p) {
if (!p.hasEffect(SleepEffect.class)) {
p.removeStatus(this);
return true;
}
double maximum = (double)p.getStat(Pokemon.S_HP);
int loss = (int)(maximum / 4.0);
if (loss < 1) loss = 1;
p.getField().showMessage(p.getName() + " is having a nightmare!");
p.changeHealth(-loss);
return false;
}
}
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Snore",
new PokemonMove(PokemonType.T_NORMAL, 40, 1.0, 15) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (!user.hasEffect(SleepEffect.class)) {
user.getField().showMessage("But it failed!");
return 0;
}
int damage = mech.calculateDamage(this, user, target);
target.changeHealth(-damage);
return damage;
}
public Class<?> getStatusException() {
return SleepEffect.class;
}
}
));
m_moves.add(new MoveListEntry("Sleep Talk",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (!user.hasEffect(SleepEffect.class)) {
user.getField().showMessage("But it failed!");
return 0;
}
Random random = mech.getRandom();
MoveListEntry move;
boolean hasOtherMoves = false;
for (int i = 0; i < 4; ++i) {
if ((move = user.getMove(i)) != null) {
if (!move.getName().equals("Sleep Talk")) {
hasOtherMoves = true;
break;
}
}
}
if (!hasOtherMoves) {
user.getField().showMessage("But it failed!");
return 0;
}
String name = null;
do {
move = user.getMove(random.nextInt(4));
if (move != null) {
if ((name = move.getName()) == null)
continue;
} else {
continue;
}
} while (name.equals("Sleep Talk"));
if (name.equals("Focus Punch")) {
user.getField().showMessage("But it failed!");
return 0;
}
return user.useMove(move, target);
}
public Class<?> getStatusException() {
return SleepEffect.class;
}
}
));
m_moves.add(new MoveListEntry("Hidden Power", new HiddenPowerMove()));
m_moves.add(new MoveListEntry("Endeavor",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 5) {
public boolean isAttack() {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (getEffectiveness(user, target) == 0.0) {
user.getField().showMessage("It doesn't affect "
+ target.getName() + "...");
return 0;
}
if (user.getHealth() >= target.getHealth()) {
user.getField().showMessage("But it failed!");
return 0;
}
int damage = target.getHealth() - user.getHealth();
target.changeHealth(-damage);
return damage;
}
}
));
m_moves.add(new MoveListEntry("Pain Split",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.hasSubstitute()) {
user.getField().showMessage("But it failed!");
return 0;
}
final int userHp = user.getHealth();
final int targetHp = target.getHealth();
final int newHealth = (userHp + targetHp) / 2;
user.changeHealth(newHealth - userHp, true);
target.changeHealth(newHealth - targetHp, true);
return 0;
}
}
));
m_moves.add(new MoveListEntry("Super Fang",
new PokemonMove(PokemonType.T_NORMAL, 0, 0.9, 10) {
public boolean isAttack() {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int damage = target.getHealth() / 2;
if (damage == 0) damage = 1;
target.changeHealth(-damage);
return damage;
}
}
));
m_moves.add(new MoveListEntry("Extremespeed",
new PriorityMove(PokemonType.T_NORMAL, 80, 1.0, 5, 1)));
m_moves.add(new MoveListEntry("Mach Punch",
new PriorityMove(PokemonType.T_FIGHTING, 40, 1.0, 30, 1)));
m_moves.add(new MoveListEntry("Quick Attack",
new PriorityMove(PokemonType.T_NORMAL, 40, 1.0, 30, 1)));
m_moves.add(new MoveListEntry("Vital Throw",
new PerfectAccuracyMove(PokemonType.T_FIGHTING, 70, 10) {
public int getPriority() {
return -1;
}
}
));
m_moves.add(new MoveListEntry("Leech Seed", new StatusMove(
PokemonType.T_GRASS, 0, 0.9, 10, new StatusEffect[] {
new LeechSeedEffect()
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Metronome", new PokemonMove(
PokemonType.T_NORMAL, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
ArrayList<MoveListEntry> moves = getMoveList();
int size = moves.size();
Random random = mech.getRandom();
MoveListEntry entry;
do {
entry = (MoveListEntry)moves.get(random.nextInt(size));
String name = entry.getName();
if (name.equals("Focus Punch") || (name.equals("Metronome"))) continue;
} while (false);
return user.useMove(entry, target);
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}
));
m_moves.add(new MoveListEntry("Perish Song", new StatusMove(
PokemonType.T_NORMAL, 0, 1.0, 5, new StatusEffect[] {
new PerishSongEffect(true),
new PerishSongEffect(true)
},
new boolean[] { true, false },
new double[] { 1.0, 1.0 }
) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.getField().showMessage("Both Pokemon will faint in 3 turn(s)");
return super.use(mech, user, target);
}
}
));
m_moves.add(new MoveListEntry("Beat Up",
new PokemonMove(PokemonType.T_NORMAL, 10, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
Pokemon[] team = user.getTeammates();
final int baseDefence = target.getBase(Pokemon.S_DEFENCE);
final int power = getPower();
int totalDamage = 0;
for (int i = 0; i < team.length; ++i) {
Pokemon pokemon = team[i];
if (pokemon.isFainted() || pokemon.hasEffect(StatusEffect.SPECIAL_EFFECT_LOCK)) {
continue;
}
final int baseAttack = pokemon.getBase(Pokemon.S_ATTACK);
boolean stab = pokemon.isType(getType());
int damage = (int)(((int)((int)(((int)((2 * pokemon.getLevel()) / 5.0 + 2.0)
* baseAttack
* power)
/ baseDefence)
/ 50.0)
+ 2)
* (stab ? 1.5 : 1.0));
user.getField().showMessage(pokemon.getName() + "'s attack!");
target.changeHealth(-damage);
totalDamage += damage;
}
return totalDamage;
}
}
));
m_moves.add(new MoveListEntry("Curse",
new PokemonMove(PokemonType.T_TYPELESS, 0, 1.0, 10) {
public boolean attemptHit(BattleMechanics mech, Pokemon source, Pokemon target) {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (user.isType(PokemonType.T_GHOST)) {
user.addStatus(user, new PercentEffect(-0.5, false, -1, null));
target.addStatus(user, new PercentEffect(-0.25, false, 3, " is afflicted by the curse!"));
user.getField().showMessage(user.getName() + " cut its health"
+ " and laid a curse on " + target.getName() + "!");
} else {
user.addStatus(user, new StatChangeEffect(Pokemon.S_SPEED, false, 1));
user.addStatus(user, new StatChangeEffect(Pokemon.S_ATTACK, true, 1));
user.addStatus(user, new StatChangeEffect(Pokemon.S_DEFENCE, true, 1));
}
return 0;
}
}
));
m_moves.add(new MoveListEntry("Conversion", new StatusMove(
PokemonType.T_NORMAL, 0, 1.0, 30, new StatusEffect[] {
new StatusEffect() {
private PokemonType[] m_types;
public String getName() {
return "Conversion";
}
public String getDescription() {
return null;
}
public int getTier() {
return -1;
}
public boolean tick(Pokemon p) {
return false;
}
public boolean apply(Pokemon p) {
m_types = p.getTypes();
Random random = p.getField().getRandom();
PokemonType moveType = null;
MoveListEntry move;
boolean fail = true;
for (int i = 0; i < 4; ++i) {
move = p.getMove(i);
if ((move != null)
&& !move.getMove().getType().equals(PokemonType.T_TYPELESS)
&& !move.getName().equals("Conversion")) {
fail = false;
break;
}
}
if (fail) {
return false;
}
do {
move = p.getMove(random.nextInt(4));
if ((move == null) || move.getName().equals("Conversion")) {
continue;
}
moveType = move.getMove().getType();
} while ((moveType == null) || moveType.equals(PokemonType.T_TYPELESS));
p.setType(new PokemonType[] { moveType });
p.getField().showMessage(p.getName() + " became the "
+ moveType + " type!");
return true;
}
public void unapply(Pokemon p) {
p.setType(m_types);
}
public boolean switchOut(Pokemon p) {
p.setType(m_types);
return true;
}
}
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Mud Sport", new TypeCutMove(
PokemonType.T_GROUND, 15, PokemonType.T_ELECTRIC, "Mud Sport"
)));
m_moves.add(new MoveListEntry("Water Sport", new TypeCutMove(
PokemonType.T_GROUND, 15, PokemonType.T_FIRE, "Water Sport"
)));
PokemonMove thief = new PokemonMove(PokemonType.T_DARK, 40, 1.0, 40) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.hasSubstitute()) {
return super.use(mech, user, target);
}
HoldItem enemyItem = target.getItem();
if ((enemyItem != null) && (user.getItem() == null) && !(target.hasAbility("Sticky Hold"))) {
user.setItem(enemyItem);
target.setItem(null);
user.getField().showMessage(user.getName() + " stole " + target.getName()
+ "'s " + enemyItem.getName() + "!");
} else if (target.hasAbility("Sticky Hold")) {
user.getField().showMessage(target.getName() + " held on with its Sticky Hold!");
}
return super.use(mech, user, target);
}
};
PokemonMove covet = (PokemonMove)thief.clone();
covet.setType(PokemonType.T_NORMAL);
m_moves.add(new MoveListEntry("Thief", thief));
m_moves.add(new MoveListEntry("Covet", covet));
m_moves.add(new MoveListEntry("Knock Off",
new PokemonMove(PokemonType.T_DARK, 20, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.hasSubstitute()) {
return super.use(mech, user, target);
}
HoldItem item = target.getItem();
if ((item != null) && !(target.hasAbility("Sticky Hold"))) {
target.setItem(null);
user.getField().showMessage(user.getName() + " knocked off foe "
+ target.getName() + "'s " + item.getName() + "!");
} else if (target.hasAbility("Sticky Hold")) {
user.getField().showMessage(target.getName() + " hung on with its Sticky Hold!");
}
return super.use(mech, user, target);
}
}
));
m_moves.add(new MoveListEntry("Trick",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.hasSubstitute()) {
user.getField().showMessage("But it failed!");
return 0;
}
if ((target.hasAbility("Sticky Hold")) || (user.hasAbility("Sticky Hold"))) {
if (user.hasAbility("Sticky Hold")) {
user.getField().showMessage(user.getName() + " hung on with its Sticky Hold!");
}
if (target.hasAbility("Sticky Hold")) {
user.getField().showMessage(target.getName() + " hung on with its Sticky Hold!");
}
return 0;
}
HoldItem targetItem = target.getItem();
HoldItem item = user.getItem();
/**if (item == null) {
user.getField().showMessage("But it failed!");
return 0;
}**/
HoldItem userItem = (item == null) ? null : (HoldItem)item.clone();
user.setItem(targetItem);
target.setItem(userItem);
if (targetItem != null) {
user.getField().showMessage(user.getName() + " obtained " + targetItem.getName() + "!");
}
if (userItem != null) {
user.getField().showMessage(target.getName() + " obtained " + userItem.getName() + "!");
}
return 0;
}
public boolean isAttack() {
return true;
}
public boolean isDamaging() {
return false;
}
}
));
m_moves.add(new MoveListEntry("Dig", new StatusMove(
PokemonType.T_GROUND, 0, 1.0, 10, new StatusEffect[] {
new InvulnerableStateEffect(new String[] { "Earthquake", "Fissure", "Magnitude" } ),
new ChargeEffect(1, "dug a hole!", new MoveListEntry(
"Dig",
new PokemonMove(
PokemonType.T_GROUND, 60, 1.0, 10
) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
setPower(mech instanceof JewelMechanics ? 80 : 60);
return super.use(mech, user, target);
}
}
)
)
},
new boolean[] { true, true },
new double[] { 1.0, 1.0 }
) {
public boolean isAttack() {
return true;
}
public boolean isDamaging() {
return true;
}
}
));
m_moves.add(new MoveListEntry("Fly", new StatusMove(
PokemonType.T_FLYING, 0, 0.95, 15, new StatusEffect[] {
new InvulnerableStateEffect(new String[] { "Thunder", "Twister", "Gust", "Sky Uppercut" } ),
new ChargeEffect(1, "flew up high!", new MoveListEntry(
"Fly",
new PokemonMove(
PokemonType.T_FLYING, 70, 0.95, 15
)
)
)
},
new boolean[] { true, true },
new double[] { 1.0, 1.0 }
) {
public boolean isAttack() {
return true;
}
public boolean isDamaging() {
return true;
}
}
));
m_moves.add(new MoveListEntry("Dive", new StatusMove(
PokemonType.T_WATER, 0, 1.0, 10, new StatusEffect[] {
new InvulnerableStateEffect(new String[] { "Surf" } ),
new ChargeEffect(1, "dove underwater!", new MoveListEntry(
"Dive",
new PokemonMove(
PokemonType.T_WATER, 60, 1.0, 10
)
)
)
},
new boolean[] { true, true },
new double[] { 1.0, 1.0 }
) {
public boolean isAttack() {
return true;
}
public boolean isDamaging() {
return true;
}
}
));
m_moves.add(new MoveListEntry("Bounce", new StatusMove(
PokemonType.T_FLYING, 0, 0.85, 5, new StatusEffect[] {
new InvulnerableStateEffect(new String[0]),
new ChargeEffect(1, "bounced up!", new MoveListEntry(
"Bounce",
new StatusMove(
PokemonType.T_FLYING, 85, 0.85, 5, new StatusEffect[] {
new ParalysisEffect()
},
new boolean[] { false },
new double[] { 0.3 }
)
)
)
},
new boolean[] { true, true },
new double[] { 1.0, 1.0 }
) {
public boolean isAttack() {
return true;
}
public boolean isDamaging() {
return true;
}
}
));
m_moves.add(new MoveListEntry("Ingrain", new StatusMove(
PokemonType.T_GRASS, 0, 1.0, 20, new StatusEffect[] {
new IngrainEffect()
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Magnitude",
new PokemonMove(PokemonType.T_GROUND, 0, 1.0, 30) {
public boolean isAttack() {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
double chance = mech.getRandom().nextDouble();
int power;
int magnitude;
if (chance <= 0.05) {
power = 10;
magnitude = 4;
} else if (chance <= 0.15) {
power = 30;
magnitude = 5;
} else if (chance <= 0.35) {
power = 50;
magnitude = 6;
} else if (chance <= 0.65) {
power = 70;
magnitude = 7;
} else if (chance <= 0.85) {
power = 90;
magnitude = 8;
} else if (chance <= 0.95) {
power = 110;
magnitude = 9;
} else {
power = 150;
magnitude = 10;
}
user.getField().showMessage("Magnitude " + magnitude + "!");
setPower(power);
int damage = mech.calculateDamage(this, user, target);
setPower(0);
target.changeHealth(-damage);
return damage;
}
}
));
m_moves.add(new MoveListEntry("Bind", new StatusMove(
PokemonType.T_NORMAL, 15, 0.75, 20, new StatusEffect[] {
new RestrainingEffect("Bind", "bound")
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Clamp", new StatusMove(
PokemonType.T_WATER, 35, 0.75, 10, new StatusEffect[] {
new RestrainingEffect("Clamp", "clamped")
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Fire Spin", new StatusMove(
PokemonType.T_FIRE, 15, 0.70, 15, new StatusEffect[] {
new RestrainingEffect("Fire Spin", "trapped in a vortex")
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Sand Tomb", new StatusMove(
PokemonType.T_GROUND, 15, 0.70, 10, new StatusEffect[] {
new RestrainingEffect("Sand Tomb", "trapped in a vortex")
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Whirlpool", new StatusMove(
PokemonType.T_WATER, 15, 0.70, 15, new StatusEffect[] {
new RestrainingEffect("Whirlpool", "trapped in a vortex")
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Wrap", new StatusMove(
PokemonType.T_NORMAL, 15, 0.85, 20, new StatusEffect[] {
new RestrainingEffect("Wrap", "wrapped")
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Block", new StatusMove(
PokemonType.T_NORMAL, 0, 1.0, 5, new StatusEffect[] {
new TrappingEffect("Block")
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Mean Look", new StatusMove(
PokemonType.T_NORMAL, 0, 1.0, 5, new StatusEffect[] {
new TrappingEffect("Mean Look")
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Spider Web", new StatusMove(
PokemonType.T_BUG, 0, 1.0, 5, new StatusEffect[] {
new TrappingEffect("Spider Web")
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Yawn", new StatusMove(
PokemonType.T_NORMAL, 0, 1.0, 10, new StatusEffect[] {
new StatusEffect() {
private int m_turns = 1;
public String getName() {
return "Yawn";
}
public String getDescription() {
return " became drowsy!";
}
public int getTier() {
return 5;
}
public boolean hitsThroughSubstitute() {
return false;
}
public boolean isPassable() {
/** According to the smogon research thread,
* this is not passed. This was also confirmed
* was an additional in game test.
*/
return false;
}
public boolean tick(Pokemon p) {
if (m_turns-- <= 0) {
p.addStatus(p.getOpponent(), new SleepEffect() {
public boolean hitsThroughSubstitute() {
return true;
}
});
p.removeStatus(this);
return false;
}
return true;
}
}
},
new boolean[] { false },
new double[] { 1.0 }
) {
public boolean attemptHit(BattleMechanics mech, Pokemon source, Pokemon target) {
return true;
}
}));
m_moves.add(new MoveListEntry("Skill Swap",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
IntrinsicAbility userAbility = (IntrinsicAbility)user.getAbility().clone();
IntrinsicAbility targetAbility = target.getAbility();
if (!userAbility.isSwappable() || !targetAbility.isSwappable()) {
user.getField().showMessage("But it failed!");
return 0;
}
user.setAbility(targetAbility, false);
target.setAbility(userAbility, false);
user.getField().showMessage(user.getName() + " swapped abilities with its opponent!");
return 0;
}
}
));
m_moves.add(new MoveListEntry("Role Play",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
IntrinsicAbility abl = target.getAbility();
if (!abl.isSwappable()) {
user.getField().showMessage("But it failed!");
return 0;
}
user.setAbility(abl, false);
user.getField().showMessage(user.getName() + " copied its opponent's ability!");
return 0;
}
}
));
m_moves.add(new MoveListEntry("Psych Up",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.removeStatus(StatChangeEffect.class);
List<?> statuses = target.getNormalStatuses(0);
Iterator<?> i = statuses.iterator();
while (i.hasNext()) {
StatusEffect effect = (StatusEffect)i.next();
if (effect instanceof StatChangeEffect) {
StatChangeEffect effectClone = (StatChangeEffect)effect.clone();
effectClone.setDescription(null);
// TODO: Open question: does Clear Body protect
// against lowering stats by using this move?
user.addStatus(target, effectClone);
}
}
user.getField().showMessage(user.getName() + " copied the opponent's stat changes!");
return 0;
}
}
));
m_moves.add(new MoveListEntry("Hyper Beam", new StatusMove(
PokemonType.T_NORMAL, 150, 0.9, 5, new StatusEffect[] {
new RechargeEffect(1)
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Frenzy Plant", new StatusMove(
PokemonType.T_GRASS, 150, 0.9, 5, new StatusEffect[] {
new RechargeEffect(1)
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Blast Burn", new StatusMove(
PokemonType.T_FIRE, 150, 0.9, 5, new StatusEffect[] {
new RechargeEffect(1)
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Hydro Cannon", new StatusMove(
PokemonType.T_WATER, 150, 0.9, 5, new StatusEffect[] {
new RechargeEffect(1)
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Spikes",
new PokemonMove(PokemonType.T_GROUND, 0, 1.0, 20) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
BattleField field = user.getField();
SpikesEffect spikes = SpikesEffect.getSpikes(field, SpikesEffect.class);
if (spikes == null) {
spikes = new SpikesEffect();
field.applyEffect(spikes);
}
spikes.addSpikes(target);
return 0;
}
}
));
m_moves.add(new MoveListEntry("Rapid Spin",
new PokemonMove(PokemonType.T_NORMAL, 20, 1.0, 40) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (getEffectiveness(user, target) == 0.0) {
user.getField().showMessage("It doesn't affect "
+ target.getName() + "...");
return 0;
}
if (user.hasEffect(RestrainingEffect.class) || user.hasEffect(LeechSeedEffect.class)) {
user.removeStatus(RestrainingEffect.class);
user.removeStatus(LeechSeedEffect.class);
user.getField().showMessage(user.getName() + " was released!");
}
ArrayList<FieldEffect> spikes = user.getField().getEffectsByType(SpikesEffect.class);
Iterator<FieldEffect> i = spikes.iterator();
boolean blewAway = false;
while (i.hasNext()) {
SpikesEffect eff = (SpikesEffect)i.next();
if (eff != null && eff.getLayers(user) >= 1) {
eff.removeSpikes(user);
blewAway = true;
}
}
if (blewAway) {
user.getField().showMessage(user.getName() + " blew away the spikes!");
}
return super.use(mech, user, target);
}
}
));
m_moves.add(new MoveListEntry("Charge", new StatusMove(
PokemonType.T_ELECTRIC, 0, 1.0, 20, new StatusEffect[] {
new StatusEffect() {
private int m_turns = 2;
public String getName() {
return "Charge";
}
public boolean apply(Pokemon p) {
if (p.getField().getMechanics() instanceof JewelMechanics) {
p.addStatus(p, new StatChangeEffect(Pokemon.S_SPDEFENCE, true, 1));
}
return true;
}
//tier is not very important
public int getTier() {
return 1;
}
public String getDescription() {
return " is charging power!";
}
public boolean tick(Pokemon p) {
if (--m_turns <= 0) {
p.removeStatus(this);
return true;
}
return false;
}
public boolean isMoveTransformer(boolean enemy) {
return !enemy;
}
public MoveListEntry getTransformedMove(Pokemon p, MoveListEntry entry) {
PokemonMove move = entry.getMove();
if (move.getType().equals(PokemonType.T_ELECTRIC)) {
int power = move.getPower();
move.setPower(power * 2);
}
return entry;
}
}
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Rest",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 10) {
public boolean attemptHit(BattleMechanics mech, Pokemon source, Pokemon target) {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (user.hasAbility("Insomnia")
|| user.hasAbility("Vital Spirit")
|| user.hasEffect(SleepEffect.class)
|| (user.getHealth() == user.getStat(Pokemon.S_HP))) {
user.getField().showMessage("But it failed!");
return 0;
}
user.removeStatus(StatusEffect.SPECIAL_EFFECT_LOCK);
// The turn it is applied still counts as a turn
user.addStatus(user, new SleepEffect(3));
int change = user.getStat(Pokemon.S_HP) - user.getHealth();
user.changeHealth(change);
return 0;
}
}
));
m_moves.add(new MoveListEntry("Reflect",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (!user.getField().applyEffect(new StatCutEffect(Pokemon.S_DEFENCE,
user.getParty(), "reflect"))) {
user.getField().showMessage("But it failed!");
}
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}
));
m_moves.add(new MoveListEntry("Light Screen",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (!user.getField().applyEffect(new StatCutEffect(Pokemon.S_SPDEFENCE,
user.getParty(), "light screen"))) {
user.getField().showMessage("But it failed!");
}
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}
));
m_moves.add(new MoveListEntry("Brick Break",
new PokemonMove(PokemonType.T_FIGHTING, 75, 1.0, 15) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
ArrayList<FieldEffect> effects = user.getField().getEffectsByType(StatCutEffect.class);
Iterator<FieldEffect> i = effects.iterator();
while (i.hasNext()) {
StatCutEffect eff = (StatCutEffect)i.next();
if (eff.getParty() == target.getParty()) {
user.getField().removeEffect(eff);
user.getField().showMessage("The wall shattered!");
}
}
return super.use(mech, user, target);
}
}
));
m_moves.add(new MoveListEntry("Camouflage", new StatusMove(
PokemonType.T_NORMAL, 0, 1.0, 20, new StatusEffect[] {
new StatusEffect() {
private PokemonType[] types;
public String getName() {
return "Camouflage";
}
public String getDescription() {
return null;
}
public int getTier() {
return -1;
}
public boolean tick(Pokemon p) {
return false;
}
public boolean apply(Pokemon p) {
types = p.getTypes();
//todo: this should be based on the terrain but it isn't implemented yet
PokemonType type = PokemonType.T_NORMAL;
p.setType(new PokemonType[] { type });
p.getField().showMessage(p.getName() + " became the "
+ type + " type!");
return true;
}
public boolean switchOut(Pokemon p) {
p.setType(types);
return true;
}
}
},
new boolean[] { true },
new double[] { 1.0 }
) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}));
m_moves.add(new MoveListEntry("Nature Power",
new PokemonMove(PokemonType.T_NORMAL, 0, 0.95, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
//todo: this should also be based on terrain
if (mech instanceof JewelMechanics) {
return user.useMove(getMove("Swift"), target);
} else {
return user.useMove(getMove("Tri Attack"), target);
}
}
public boolean isAttack() {
return false;
}
}
));
m_moves.add(new MoveListEntry("Secret Power",
new PokemonMove(PokemonType.T_NORMAL, 70, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int damage = mech.calculateDamage(this, user, target);
target.changeHealth(-damage);
double random = mech.getRandom().nextDouble();
//todo: this should also be based on terrain
if (random <= 0.3) {
target.addStatus(user, new ParalysisEffect());
}
return damage;
}
}
));
//Doesn't do anything in 1 vs 1
m_moves.add(new MoveListEntry("Follow Me",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.getField().showMessage(user.getName() + " became the centre of attention!");
return 0;
}
public int getPriority() {
return 4;
}
}
));
//Doesn't do anything in 1 vs 1
m_moves.add(new MoveListEntry("Helping Hand",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.getField().showMessage("But it failed!");
return 0;
}
public int getPriority() {
return 6;
}
}
));
m_moves.add(new MoveListEntry("Doom Desire",
new PokemonMove(PokemonType.T_STEEL, 120, 0.85, 5) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int damage;
if (!super.attemptHit(mech, user, target)) {
damage = 0;
} else {
PokemonMove move = new PokemonMove(PokemonType.T_TYPELESS, this.getPower(), 1.0, 1);
move.setMoveListEntry(getMoveListEntry());
damage = mech.calculateDamage(move, user, target);
}
user.getField().applyEffect(
new DelayedDamageEffect(damage, target.getParty(), 3));
return 0;
}
}
));
m_moves.add(new MoveListEntry("Future Sight",
new PokemonMove(PokemonType.T_PSYCHIC, 80, 0.9, 15) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int damage;
if (!super.attemptHit(mech, user, target)) {
damage = 0;
} else {
damage = mech.calculateDamage(
new PokemonMove(PokemonType.T_TYPELESS, this.getPower(), 1.0, 1), user, target);
}
user.getField().applyEffect(
new DelayedDamageEffect(damage, target.getParty(), 3));
return 0;
}
}
));
m_moves.add(new MoveListEntry("Focus Punch",
new DamageListenerMove(PokemonType.T_FIGHTING, 150, 1.0, 20) {
public void beginTurn(BattleTurn[] turn, int index, Pokemon source) {
if (!source.hasEffect(SleepEffect.class) && !source.hasEffect(FreezeEffect.class)) {
source.getField().showMessage(source.getName() + " is tightening its focus!");
}
super.beginTurn(turn, index, source);
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
DamageListenerEffect listener = getListener(user);
if (listener == null) return 0;
if (listener.getDamage() > 0) {
user.getField().showMessage(user.getName() + " lost its focus and couldn't move!");
return 0;
}
return super.use(mech, user, target);
}
public int getPriority() {
return -2;
}
}
));
m_moves.add(new MoveListEntry("Low Kick",
new MassBasedMove(PokemonType.T_FIGHTING, 1.0, 20)));
m_moves.add(new MoveListEntry("Baton Pass",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 40) {
@SuppressWarnings("unchecked")
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
BattleField field = user.getField();
int party = user.getParty();
if (field.getAliveCount(party) == 1) {
user.getField().showMessage("But it failed!");
return 0;
}
List<StatusEffect> list = user.getNormalStatuses(0);
List applied = new ArrayList();
Iterator<StatusEffect> i = list.iterator();
while (i.hasNext()) {
StatusEffect effect = (StatusEffect)i.next();
if (effect.getLock() != StatusEffect.SPECIAL_EFFECT_LOCK) {
if (effect.isPassable()) {
if (effect instanceof LeechSeedEffect) {
applied.add(new LeechSeedEffect(false));
} else if (effect instanceof PerishSongEffect) {
applied.add(new PerishSongEffect(false));
} else {
applied.add(effect.clone());
}
if (effect instanceof CoEffect) {
CoEffect coeffect = (CoEffect)effect;
if (!coeffect.getType().equals(AttractEffect.class)) {
effect.disable();
}
}
}
}
}
int substitute = user.getSubstitute();
field.requestAndWaitForSwitch(party);
target = field.getActivePokemon()[party];
target.setSubstitute(substitute);
i = applied.iterator();
field.setNarrationEnabled(false);
while (i.hasNext()) {
StatusEffect effect = (StatusEffect)i.next();
target.addStatus(target, effect);
}
field.setNarrationEnabled(true);
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon source, Pokemon target) {
return true;
}
}));
PokemonMove roar = new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.hasAbility("Suction Cups") || target.hasEffect(IngrainEffect.class)) {
user.getField().showMessage("But it failed!");
return 0;
}
if (target.isFainted())
return 0;
ArrayList<Pokemon> party = new ArrayList<Pokemon>(Arrays.asList(target.getTeammates()));
Iterator<Pokemon> i = party.iterator();
while (i.hasNext()) {
Pokemon p = (Pokemon)i.next();
if (p == null || p.isFainted() || (p == target)) {
i.remove();
}
}
if (party.size() == 0) {
user.getField().showMessage("But it failed!");
return 0;
}
Pokemon p = (Pokemon)party.get(mech.getRandom().nextInt(party.size()));
p.getField().switchInPokemon(p.getParty(), p.getId());
p.addStatus(user, new StatusEffect() {
public int getTier() {
return 1;
}
public boolean tick(Pokemon p) {
p.removeStatus(this);
return true;
}
public boolean isMoveTransformer(boolean enemy) {
return !enemy;
}
public MoveListEntry getTransformedMove(Pokemon p, MoveListEntry entry) {
return null;
}
public String getDescription() {
return null;
}
public String getName() {
return null;
}
});
return 0;
}
public int getPriority() {
return -5;
}
};
PokemonMove whirlwind = (PokemonMove)roar.clone();
m_moves.add(new MoveListEntry("Roar", roar));
m_moves.add(new MoveListEntry("Whirlwind", whirlwind));
m_moves.add(new MoveListEntry("Wish",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.getField().applyEffect(new DelayedStatusEffect(
new PercentEffect(0.5, false, -1, "The wish came true!"),
user.getParty(), 2, " made a wish!"));
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}
));
m_moves.add(new MoveListEntry("Counter",
new CounterMove(PokemonType.T_FIGHTING, 1.0, 20, 2)));
m_moves.add(new MoveListEntry("Mirror Coat",
new CounterMove(PokemonType.T_PSYCHIC, 1.0, 20, 1)));
m_moves.add(new MoveListEntry("Pursuit",
new PokemonMove(PokemonType.T_DARK, 40, 1.0, 20) {
public void beginTurn(BattleTurn[] turn, int index, Pokemon source) {
// Note: assumes two pokemon.
BattleTurn opp = turn[1 - index];
Pokemon target = source.getOpponent();
boolean damageNow = false;
if (!opp.isMoveTurn()) {
damageNow = true;
} else {
MoveListEntry entry = target.getMove(opp.getId());
if (entry.getName().equals("U-turn")) {
if (target.getStat(Pokemon.S_SPEED) > source.getStat(Pokemon.S_SPEED)) {
damageNow = true;
}
}
}
if (!damageNow)
return;
// Prevent this attack from occurring later in the turn.
turn[index] = null;
if (source.isImmobilised(null))
return;
int power = getPower();
setPower(power * 2);
source.useMove(new MoveListEntry("Pursuit", (PokemonMove)clone()), target);
setPower(power);
}
}
));
m_moves.add(new MoveListEntry("Revenge",
new DamageListenerMove(PokemonType.T_FIGHTING, 60, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
DamageListenerEffect listener = getListener(user);
if (listener == null) return 0;
if (listener.getDamage() <= 0) {
return super.use(mech, user, target);
}
int power = 60;
setPower(power * 2);
int damage = super.use(mech, user, target);
setPower(power);
return damage;
}
public int getPriority() {
return -3;
}
}
));
/********************************************************************
* DP moves start
********************************************************************/
m_moves.add(new MoveListEntry("U-turn",
new PokemonMove(PokemonType.T_BUG, 70, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int damage = mech.calculateDamage(this, user, target);
target.changeHealth(-damage);
int party = user.getParty();
BattleField field = user.getField();
if (field.getAliveCount(party) > 1) {
field.requestAndWaitForSwitch(party);
target = field.getActivePokemon()[party];
HoldItem item = target.getItem();
if (item instanceof ChoiceBandItem) {
for (int i = 0; i < 4; ++i) {
MoveListEntry entry = target.getMove(i);
if ((entry != null) && entry.getName().equals("U-turn")) {
((ChoiceBandItem)item).setChoice(target, mech, entry);
break;
}
}
}
}
return damage;
}
}));
m_moves.add(new MoveListEntry("Lunar Dance",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int party = user.getParty();
BattleField field = user.getField();
if (field.getAliveCount(party) == 1) {
user.getField().showMessage("But it failed!");
return 0;
}
user.faint();
field.requestAndWaitForSwitch(party);
target = field.getActivePokemon()[party];
target.changeHealth(target.getStat(Pokemon.S_HP));
for (int i = 0; i < 4; ++i) {
MoveListEntry entry = target.getMove(i);
if (entry != null) {
PokemonMove move = entry.getMove();
if (move != null) {
target.setPp(i, target.getMaxPp(i));
}
}
}
target.removeStatus(StatusEffect.SPECIAL_EFFECT_LOCK);
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon source, Pokemon target) {
return true;
}
}));
m_moves.add(new MoveListEntry("Worry Seed",
new PokemonMove(PokemonType.T_GRASS, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.hasAbility("Multitype") || target.hasSubstitute()) {
user.getField().showMessage("But it failed!");
return 0;
}
target.setAbility(IntrinsicAbility.getInstance("Insomnia"), false);
return 0;
}
}
));
m_moves.add(new MoveListEntry("Psycho Shift",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.hasSubstitute()) {
user.getField().showMessage("But it failed!");
return 0;
}
StatusEffect eff = user.getEffect(StatusEffect.SPECIAL_EFFECT_LOCK);
if (eff == null)
return 0;
StatusEffect clone = (StatusEffect)eff.clone();
if (!target.hasEffect(StatusEffect.SPECIAL_EFFECT_LOCK)) {
user.removeStatus(eff);
target.addStatus(user, clone);
}
return 0;
}
}
));
m_moves.add(new MoveListEntry("Trick Room",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 5) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
BattleField field = user.getField();
FieldEffect effect = field.getEffectByType(SpeedSwapEffect.class);
if (effect != null) {
field.removeEffect(effect);
} else {
field.showMessage(user.getName() + " twisted the dimensions!");
field.applyEffect(new SpeedSwapEffect());
}
return 0;
}
public int getPriority() {
return -5;
}
}
));
m_moves.add(new MoveListEntry("Gyro Ball",
new PokemonMove(PokemonType.T_STEEL, 100, 1.0, 5) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int power = 51 * target.getStat(Pokemon.S_SPEED) /
user.getStat(Pokemon.S_SPEED) / 2;
if (power > 150) power = 150;
setPower(getPower() * power / 100);
int damage = mech.calculateDamage(this, user, target);
target.changeHealth(-damage);
setPower(100);
return damage;
}
}
));
m_moves.add(new MoveListEntry("Wake-up Slap",
new PokemonMove(PokemonType.T_FIGHTING, 60, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int power = getPower();
if (!target.hasSubstitute() && target.hasEffect(SleepEffect.class)) {
setPower(2 * power);
target.removeStatus(StatusEffect.SPECIAL_EFFECT_LOCK);
user.getField().showMessage(target.getName() + " woke up!");
}
int damage = mech.calculateDamage(this, user, target);
setPower(power);
target.changeHealth(-damage);
return damage;
}
}
));
m_moves.add(new MoveListEntry("Hammer Arm", new StatusMove(
PokemonType.T_FIGHTING, 100, 0.9, 10, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPEED, false)
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Brine",
new PokemonMove(PokemonType.T_WATER, 65, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int power = getPower();
if (target.getHealth() < (target.getStat(Pokemon.S_HP) / 2)) {
setPower(power * 2);
}
int damage = super.use(mech, user, target);
setPower(power);
return damage;
}
}
));
m_moves.add(new MoveListEntry("Acupressure",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 30) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int random = mech.getRandom().nextInt(7) + 1;
user.addStatus(user, new StatChangeEffect(random, true, 2));
return 0;
}
}
));
m_moves.add(new MoveListEntry("Close Combat", new StatusMove(
PokemonType.T_FIGHTING, 120, 1.0, 5, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_DEFENCE, false),
new StatChangeEffect(Pokemon.S_SPDEFENCE, false)
},
new boolean[] { true, true },
new double[] { 1.0, 1.0 }
)));
//todo: get right tier
m_moves.add(new MoveListEntry("Aqua Ring", new StatusMove(
PokemonType.T_WATER, 0, 1.0, 20, new StatusEffect[] {
new PercentEffect(0.0625, false, 3, "'s Aqua Ring restored health!") {
public boolean isSingleton() {
return true;
}
}
},
new boolean[] { true },
new double[] { 1.0 }
)));
//todo: find correct rate for all of these
m_moves.add(new MoveListEntry("Flare Blitz",
new RecoilMove(PokemonType.T_FIRE, 120, 1.0, 15, 1.0/3.0)));
m_moves.add(new MoveListEntry("Brave Bird",
new RecoilMove(PokemonType.T_FLYING, 120, 1.0, 15, 1.0/3.0)));
m_moves.add(new MoveListEntry("Wood Hammer",
new RecoilMove(PokemonType.T_GRASS, 120, 1.0, 15, 1.0/3.0)));
m_moves.add(new MoveListEntry("Head Smash",
new RecoilMove(PokemonType.T_ROCK, 150, 0.8, 5, 0.5)));
m_moves.add(new MoveListEntry("Force Palm", new StatusMove(
PokemonType.T_FIGHTING, 60, 1.0, 10, new StatusEffect[] {
new ParalysisEffect()
},
new boolean[] { false },
new double[] { 0.3 }
)));
m_moves.add(new MoveListEntry("Aura Sphere",
new PerfectAccuracyMove(PokemonType.T_FIGHTING, 90, 20)));
m_moves.add(new MoveListEntry("Magnet Bomb",
new PerfectAccuracyMove(PokemonType.T_STEEL, 60, 20)));
m_moves.add(new MoveListEntry("Rock Polish", new StatusMove(
PokemonType.T_ROCK, 0, 1.0, 30, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPEED, true, 2)
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Poison Jab", new StatusMove(
PokemonType.T_POISON, 80, 1.0, 20, new StatusEffect[] {
new PoisonEffect()
},
new boolean[] { false },
new double[] { 0.3 }
)));
m_moves.add(new MoveListEntry("Dark Pulse", new StatusMove(
PokemonType.T_DARK, 80, 1.0, 15, new StatusEffect[] {
new FlinchEffect()
},
new boolean[] { false },
new double[] { 0.2 }
)));
m_moves.add(new MoveListEntry("Night Slash",
new HighCriticalHitMove(PokemonType.T_DARK, 70, 1.0, 15)));
m_moves.add(new MoveListEntry("Shadow Claw",
new HighCriticalHitMove(PokemonType.T_GHOST, 70, 1.0, 15)));
m_moves.add(new MoveListEntry("Psycho Cut",
new HighCriticalHitMove(PokemonType.T_PSYCHIC, 70, 1.0, 20)));
m_moves.add(new MoveListEntry("Stone Edge",
new HighCriticalHitMove(PokemonType.T_ROCK, 100, 0.8, 5)));
m_moves.add(new MoveListEntry("Attack Order",
new HighCriticalHitMove(PokemonType.T_BUG, 90, 1.0, 15)));
m_moves.add(new MoveListEntry("Spacial Rend",
new HighCriticalHitMove(PokemonType.T_DRAGON, 100, 0.95, 5)));
m_moves.add(new MoveListEntry("Aqua Tail",
new PokemonMove(PokemonType.T_WATER, 90, 0.9, 10)));
m_moves.add(new MoveListEntry("Seed Bomb",
new PokemonMove(PokemonType.T_GRASS, 80, 1.0, 15)));
m_moves.add(new MoveListEntry("X-Scissor",
new PokemonMove(PokemonType.T_BUG, 80, 1.0, 15)));
m_moves.add(new MoveListEntry("Dragon Pulse",
new PokemonMove(PokemonType.T_DRAGON, 90, 1.0, 10)));
m_moves.add(new MoveListEntry("Power Gem",
new PokemonMove(PokemonType.T_ROCK, 70, 1.0, 20)));
m_moves.add(new MoveListEntry("Power Whip",
new PokemonMove(PokemonType.T_GRASS, 120, 0.85, 10)));
m_moves.add(new MoveListEntry("Air Slash", new StatusMove(
PokemonType.T_FLYING, 75, 0.95, 20, new StatusEffect[] {
new FlinchEffect()
},
new boolean[] { false },
new double[] { 0.3 }
)));
m_moves.add(new MoveListEntry("Zen Headbutt", new StatusMove(
PokemonType.T_PSYCHIC, 80, 0.9, 15, new StatusEffect[] {
new FlinchEffect()
},
new boolean[] { false },
new double[] { 0.2 }
)));
m_moves.add(new MoveListEntry("Dragon Rush", new StatusMove(
PokemonType.T_DRAGON, 100, 0.75, 10, new StatusEffect[] {
new FlinchEffect()
},
new boolean[] { false },
new double[] { 0.2 }
)));
m_moves.add(new MoveListEntry("Iron Head", new StatusMove(
PokemonType.T_STEEL, 80, 1.0, 15, new StatusEffect[] {
new FlinchEffect()
},
new boolean[] { false },
new double[] { 0.3 }
)));
m_moves.add(new MoveListEntry("Bug Buzz", new StatusMove(
PokemonType.T_BUG, 90, 1.0, 10, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPDEFENCE, false)
},
new boolean[] { false },
new double[] { 0.1 }
)));
m_moves.add(new MoveListEntry("Drain Punch",
new AbsorbMove(PokemonType.T_FIGHTING, 60, 1.0, 5, 0.5)));
m_moves.add(new MoveListEntry("Vacuum Wave",
new PriorityMove(PokemonType.T_FIGHTING, 40, 1.0, 30, 1)));
m_moves.add(new MoveListEntry("Bullet Punch",
new PriorityMove(PokemonType.T_STEEL, 40, 1.0, 30, 1)));
m_moves.add(new MoveListEntry("Ice Shard",
new PriorityMove(PokemonType.T_ICE, 40, 1.0, 30, 1)));
m_moves.add(new MoveListEntry("Shadow Sneak",
new PriorityMove(PokemonType.T_GHOST, 40, 1.0, 30, 1)));
m_moves.add(new MoveListEntry("Aqua Jet",
new PriorityMove(PokemonType.T_WATER, 40, 1.0, 30, 1)));
m_moves.add(new MoveListEntry("Focus Blast", new StatusMove(
PokemonType.T_FIGHTING, 120, 0.7, 5, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPDEFENCE, false)
},
new boolean[] { false },
new double[] { 0.1 }
)));
m_moves.add(new MoveListEntry("Energy Ball", new StatusMove(
PokemonType.T_GRASS, 80, 1.0, 10, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPDEFENCE, false)
},
new boolean[] { false },
new double[] { 0.1 }
)));
m_moves.add(new MoveListEntry("Earth Power", new StatusMove(
PokemonType.T_GROUND, 90, 1.0, 10, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPDEFENCE, false)
},
new boolean[] { false },
new double[] { 0.1 }
)));
m_moves.add(new MoveListEntry("Mirror Shot", new StatusMove(
PokemonType.T_STEEL, 65, 0.85, 10, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_ACCURACY, false)
},
new boolean[] { false },
new double[] { 0.3 }
)));
m_moves.add(new MoveListEntry("Flash Cannon", new StatusMove(
PokemonType.T_STEEL, 80, 1.0, 10, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPATTACK, false)
},
new boolean[] { false },
new double[] { 0.1 }
)));
m_moves.add(new MoveListEntry("Rock Climb", new StatusMove(
PokemonType.T_NORMAL, 90, 0.85, 20, new StatusEffect[] {
new ConfuseEffect()
},
new boolean[] { false },
new double[] { 0.2 }
)));
m_moves.add(new MoveListEntry("Switcheroo",
new PokemonMove(PokemonType.T_DARK, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.hasSubstitute()) {
user.getField().showMessage("But it failed!");
return 0;
}
if ((target.hasAbility("Sticky Hold")) || (user.hasAbility("Sticky Hold"))) {
if (user.hasAbility("Sticky Hold")) {
user.getField().showMessage(user.getName() + " hung on with its Sticky Hold!");
}
if (target.hasAbility("Sticky Hold")) {
user.getField().showMessage(target.getName() + " hung on with its Sticky Hold!");
}
return 0;
}
HoldItem targetItem = target.getItem();
HoldItem item = user.getItem();
/**if (item == null) {
user.getField().showMessage("But it failed!");
return 0;
}**/
HoldItem userItem = (item == null) ? null : (HoldItem)item.clone();
user.setItem(targetItem);
target.setItem(userItem);
if (targetItem != null) {
user.getField().showMessage(user.getName() + " obtained " + targetItem.getName() + "!");
}
if (userItem != null) {
user.getField().showMessage(target.getName() + " obtained " + userItem.getName() + "!");
}
return 0;
}
public boolean isAttack() {
return true;
}
public boolean isDamaging() {
return false;
}
}
));
m_moves.add(new MoveListEntry("Giga Impact", new StatusMove(
PokemonType.T_NORMAL, 150, 0.9, 5, new StatusEffect[] {
new RechargeEffect(1)
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Rock Wrecker", new StatusMove(
PokemonType.T_ROCK, 150, 0.9, 5, new StatusEffect[] {
new RechargeEffect(1)
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Roar Of Time", new StatusMove(
PokemonType.T_DRAGON, 150, 0.9, 5, new StatusEffect[] {
new RechargeEffect(1)
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Nasty Plot", new StatusMove(
PokemonType.T_DARK, 0, 1.0, 20, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPATTACK, true, 2)
},
new boolean[] { true },
new double[] { 1.0 }
)));
//todo: correct probabilities?
m_moves.add(new MoveListEntry("Thunder Fang", new StatusMove(
PokemonType.T_ELECTRIC, 65, 0.95, 15, new StatusEffect[] {
new FlinchEffect(),
new ParalysisEffect()
},
new boolean[] { false, false },
new double[] { 0.1, 0.1 }
)));
m_moves.add(new MoveListEntry("Ice Fang", new StatusMove(
PokemonType.T_ICE, 65, 0.95, 15, new StatusEffect[] {
new FlinchEffect(),
new FreezeEffect()
},
new boolean[] { false, false },
new double[] { 0.1, 0.1 }
)));
m_moves.add(new MoveListEntry("Fire Fang", new StatusMove(
PokemonType.T_FIRE, 65, 0.95, 15, new StatusEffect[] {
new FlinchEffect(),
new BurnEffect()
},
new boolean[] { false, false },
new double[] { 0.1, 0.1 }
)));
m_moves.add(new MoveListEntry("Mud Bomb", new StatusMove(
PokemonType.T_GROUND, 65, 0.85, 10, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_ACCURACY, false)
},
new boolean[] { false },
new double[] { 0.3 }
)));
m_moves.add(new MoveListEntry("Defog", new StatusMove(
PokemonType.T_NORMAL, 0, 1.0, 15, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_EVASION, false)
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Draco Meteor", new StatusMove(
PokemonType.T_DRAGON, 140, 0.90, 5, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPATTACK, false, 2)
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Leaf Storm", new StatusMove(
PokemonType.T_GRASS, 140, 0.90, 5, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPATTACK, false, 2)
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Discharge", new StatusMove(
PokemonType.T_ELECTRIC, 80, 1.0, 15, new StatusEffect[] {
new ParalysisEffect()
},
new boolean[] { false },
new double[] { 0.3 }
)));
m_moves.add(new MoveListEntry("Lava Plume", new StatusMove(
PokemonType.T_FIRE, 80, 1.0, 15, new StatusEffect[] {
new BurnEffect()
},
new boolean[] { false },
new double[] { 0.3 }
)));
m_moves.add(new MoveListEntry("Cross Poison",
new StatusMove(PokemonType.T_POISON, 70, 1.0, 20, new StatusEffect[] {
new PoisonEffect()
},
new boolean[] { false },
new double[] { 0.1 }
) {
public boolean hasHighCriticalHitRate() { return true; }
}
));
m_moves.add(new MoveListEntry("Gunk Shot", new StatusMove(
PokemonType.T_POISON, 120, 0.7, 5, new StatusEffect[] {
new PoisonEffect()
},
new boolean[] { false },
new double[] { 0.3 }
)));
m_moves.add(new MoveListEntry("Captivate",
new StatusMove(PokemonType.T_NORMAL, 0, 1.0, 20, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPATTACK, false, 2)
},
new boolean[] { false },
new double[] { 1.0 }
) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int userGender = user.getGender();
int targetGender = target.getGender();
if ((userGender == targetGender) || (userGender == PokemonSpecies.GENDER_NONE)
|| (targetGender == PokemonSpecies.GENDER_NONE)) {
user.getField().showMessage("But it failed!");
return 0;
}
return super.use(mech, user, target);
}
}
));
m_moves.add(new MoveListEntry("Chatter", new StatusMove(
PokemonType.T_FLYING, 60, 1.0, 20, new StatusEffect[] {
new ConfuseEffect()
},
new boolean[] { false },
new double[] { 0.31 }
)));
m_moves.add(new MoveListEntry("Charge Beam", new StatusMove(
PokemonType.T_ELECTRIC, 50, 0.9, 10, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPATTACK, true)
},
new boolean[] { true },
new double[] { 0.7 }
)));
m_moves.add(new MoveListEntry("Defend Order", new StatusMove(
PokemonType.T_BUG, 0, 1.0, 10, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_DEFENCE, true),
new StatChangeEffect(Pokemon.S_SPDEFENCE, true)
},
new boolean[] { true, true },
new double[] { 1.0, 1.0 }
)));
m_moves.add(new MoveListEntry("Substitute",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (!user.createSubstitute()) {
user.getField().showMessage("But it failed!");
} else {
user.addStatus(user, new SubstituteEffect());
}
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}));
m_moves.add(new MoveListEntry("Heal Order", new StatusMove(
PokemonType.T_BUG, 0, 1.0, 10, new StatusEffect[] {
new PercentEffect(0.5, false, -1, null)
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Double Hit",
new PokemonMove(PokemonType.T_NORMAL, 35, 0.9, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int damage = 0;
for (int i = 0; i < 2; ++i) {
final int partial = mech.calculateDamage(this, user, target);
target.changeHealth(-partial);
damage += partial;
}
user.getField().showMessage("Hit 2 time(s)!");
return damage;
}
}
));
PokemonMove crushGrip = new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 5) {
//todo: this formula may not be exactly correct
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int power = (int)(110.0 *
(((double)target.getHealth())
/ ((double)target.getStat(Pokemon.S_HP))));
setPower(power);
int damage = mech.calculateDamage(this, user, target);
target.changeHealth(-damage);
return damage;
}
public boolean isAttack() {
return true;
}
};
PokemonMove wringOut = (PokemonMove)crushGrip.clone();
m_moves.add(new MoveListEntry("Crush Grip", crushGrip));
m_moves.add(new MoveListEntry("Wring Out", wringOut));
m_moves.add(new MoveListEntry("Feint",
new PokemonMove(PokemonType.T_NORMAL, 50, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (!target.hasEffect(CounterEffect.class)) {
user.getField().showMessage("But it failed!");
return 0;
}
return super.use(mech, user, target);
}
}
));
m_moves.add(new MoveListEntry("Trump Card",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 5) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
//todo: these are estimated values for the powers
int pp = 5;
for (int i = 0; i < 4; ++i) {
MoveListEntry entry = user.getMove(i);
if (entry == null) continue;
if (entry.getName().equals("Trump Card")) {
pp = user.getPp(i);
break;
}
}
if (pp > 4) {
setPower(35);
} else if (pp == 4) {
setPower(50);
} else if (pp == 3) {
setPower(60);
} else if (pp == 2) {
setPower(75);
} else {
setPower(190);
}
int damage = super.use(mech, user, target);
setPower(0);
return damage;
}
public boolean isAttack() {
return true;
}
}
));
m_moves.add(new MoveListEntry("Punishment",
new PokemonMove(PokemonType.T_DARK, 0, 1.0, 5) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int raises = 0;
List<StatusEffect> statuses = target.getNormalStatuses(0);
Iterator<StatusEffect> i = statuses.iterator();
while (i.hasNext()) {
StatusEffect effect = (StatusEffect)i.next();
if (!(effect instanceof StatChangeEffect)) continue;
if (((StatChangeEffect)effect).isRaise()) {
raises++;
}
}
setPower(60 + 20 * raises);
int damage = super.use(mech, user, target);
setPower(0);
return damage;
}
public boolean isAttack() {
return true;
}
}
));
m_moves.add(new MoveListEntry("Last Resort",
new PokemonMove(PokemonType.T_NORMAL, 130, 1.0, 5) {
class LastResortEffect extends StatusEffect {
int[] m_pp;
public LastResortEffect(int[] pp) {
m_pp = pp;
}
public int getPp(int i) {
return m_pp[i];
}
}
public void switchIn(Pokemon p) {
int[] pp = new int[4];
for (int i = 0; i < 4; ++i) {
pp[i] = p.getPp(i);
}
p.addStatus(p, new LastResortEffect(pp));
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
LastResortEffect effect = (LastResortEffect)
user.getEffect(LastResortEffect.class);
if (effect == null) {
user.getField().showMessage("But it failed!");
return 0;
}
boolean hasOtherMoves = false;
for (int i = 0; i < 4; ++i) {
MoveListEntry entry = user.getMove(i);
if (entry == null) continue;
if (!entry.getName().equals("Last Resort")) {
hasOtherMoves = true;
if (user.getPp(i) >= effect.getPp(i)) {
hasOtherMoves = false;
break;
}
}
}
if (!hasOtherMoves) {
user.getField().showMessage("But it failed!");
return 0;
}
return super.use(mech, user, target);
}
}
));
m_moves.add(new MoveListEntry("Magma Storm", new StatusMove(
PokemonType.T_FIRE, 120, 0.70, 5, new StatusEffect[] {
new RestrainingEffect("Magma Storm", "trapped in a vortex!")
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Dark Void", new StatusMove(
PokemonType.T_DARK, 0, 0.8, 10, new StatusEffect[] {
new SleepEffect()
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Seed Flare", new StatusMove(
PokemonType.T_GRASS, 120, 0.85, 5, new StatusEffect[] {
new StatChangeEffect(Pokemon.S_SPDEFENCE, false)
},
new boolean[] { false },
new double[] { 0.4 }
)));
m_moves.add(new MoveListEntry("Protect", new ProtectMove(
PokemonType.T_NORMAL, 10, new ProtectEffect() {
public String getDescription() {
return " protected itself!";
}
})));
m_moves.add(new MoveListEntry("Endure", new ProtectMove(
PokemonType.T_NORMAL, 10, new EndureEffect()
)));
m_moves.add(new MoveListEntry("Detect", new ProtectMove(
PokemonType.T_FIGHTING, 5, new ProtectEffect() {
public String getDescription() {
return " braced itself!";
}
})));
m_moves.add(new MoveListEntry("Taunt", new StatusMove(
PokemonType.T_DARK, 0, 1.0, 20, new StatusEffect[] {
new StatusEffect() {
private int m_turns;
public boolean apply(Pokemon p) {
Random r = p.getField().getMechanics().getRandom();
m_turns = r.nextInt(3) + 3;
return true;
}
public String getDescription() {
return " fell for the taunt!";
}
public String getName() {
return "Taunt";
}
public int getTier() {
return 1;
}
public boolean tick(Pokemon p) {
if (--m_turns == 0) {
p.removeStatus(this);
p.getField().showMessage(p.getName() + "'s taunt wore off!");
return true;
}
return false;
}
public boolean isMoveTransformer(boolean enemy) {
return !enemy;
}
public boolean hitsThroughSubstitute() {
// TODO: NOTE: Does not hit through in advance!
return true;
}
public boolean vetoesMove(Pokemon p, MoveListEntry entry) {
String name = entry.getName();
if (name.equals("Struggle")) {
return false;
}
HashSet<String> set = new HashSet<String>(Arrays.asList(new String[] {
"Nature Power", "Sleep Talk", "Assist", "Metronome"
}));
if (set.contains(name)) {
return true;
}
return !entry.getMove().isDamaging();
}
public MoveListEntry getTransformedMove(Pokemon p, MoveListEntry entry) {
if (vetoesMove(p, entry)) {
BattleField field = p.getField();
String move = entry.getName();
field.informUseMove(p, move);
field.showMessage(p.getName() + " can't use " + move + " after the taunt!");
return null;
}
return entry;
}
}
},
new boolean[] { false },
new double[] { 1.0 }
) {
public boolean attemptHit(BattleMechanics mech, Pokemon source, Pokemon target) {
return true;
}
}));
m_moves.add(new MoveListEntry("Shadow Force", new StatusMove(
PokemonType.T_GHOST, 0, 1.0, 5, new StatusEffect[] {
new InvulnerableStateEffect(new String[0]),
new ChargeEffect(1, "dissappeared from sight!", new MoveListEntry(
"Shadow Force",
new PokemonMove(PokemonType.T_GHOST, 120, 1.0, 5)
)
)
},
new boolean[] { true, true },
new double[] { 1.0, 1.0 }
) {
public boolean isAttack() {
return true;
}
public boolean isDamaging() {
return true;
}
}
));
m_moves.add(new MoveListEntry("Ominous Wind", new StatusMove(
PokemonType.T_GHOST, 60, 1.0, 5, new StatusEffect[] {
new MultipleStatChangeEffect(new int[] {
Pokemon.S_ATTACK,
Pokemon.S_DEFENCE,
Pokemon.S_SPEED,
Pokemon.S_SPATTACK,
Pokemon.S_SPDEFENCE
}
)
},
new boolean[] { true },
new double[] { 0.1 }
)));
m_moves.add(new MoveListEntry("Toxic Spikes",
new PokemonMove(PokemonType.T_POISON, 0, 1.0, 20) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
BattleField field = user.getField();
ToxicSpikesEffect spikes = (ToxicSpikesEffect)SpikesEffect.getSpikes(field, ToxicSpikesEffect.class);
if (spikes == null) {
spikes = new ToxicSpikesEffect();
field.applyEffect(spikes);
}
spikes.addSpikes(target);
return 0;
}
}
));
m_moves.add(new MoveListEntry("Stealth Rock",
new PokemonMove(PokemonType.T_ROCK, 0, 1.0, 20) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
BattleField field = user.getField();
StealthRockEffect spikes = (StealthRockEffect)SpikesEffect.getSpikes(field, StealthRockEffect.class);
if (spikes == null) {
spikes = new StealthRockEffect();
field.applyEffect(spikes);
}
spikes.addSpikes(target);
return 0;
}
}
));
class MeFirstEffect extends StatusEffect {
private MoveListEntry m_move;
public MeFirstEffect(MoveListEntry move) {
m_move = move;
}
public boolean isMoveTransformer(boolean enemy) {
return !enemy;
}
public MoveListEntry getTransformedMove(Pokemon p, MoveListEntry entry) {
p.getField().informUseMove(p, "Me First");
return m_move;
}
public int getTier() {
return 1;
}
public boolean tick(Pokemon p) {
p.removeStatus(this);
return true;
}
public String getName() {
return null;
}
public String getDescription() {
return null;
}
}
m_moves.add(new MoveListEntry("Me First",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 20) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
public void beginTurn(BattleTurn[] turn, int index, Pokemon source) {
// Assume two pokemon
/** Note: You cannot give PokemonMoves states
* outside of their nature as a move - there is only one
* copy for the whole program, not for each pokemon who
* has the move! The latter would be a massive waste of
* memory.
*/
if ((index == 1) || source.hasEffect(SleepEffect.class) || source.hasEffect(FreezeEffect.class)) {
return;
}
BattleTurn opp = turn[1 - index];
Pokemon target = source.getOpponent();
if (!opp.isMoveTurn()) return;
MoveListEntry entry = (MoveListEntry)target.getMove(opp.getId()).clone();
PokemonMove move = entry.getMove();
int power = move.getPower();
if (!move.isDamaging()) return;
move.setPower(power * 3 / 2);
source.addStatus(source, new MeFirstEffect(entry));
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.getField().showMessage("But it failed!");
return 0;
}
}
));
class SuckerPunchEffect extends StatusEffect {
public int getTier() {
return 1;
}
public boolean tick(Pokemon p) {
p.removeStatus(this);
return true;
}
public String getName() {
return null;
}
public String getDescription() {
return null;
}
}
m_moves.add(new MoveListEntry("Sucker Punch",
new PokemonMove(PokemonType.T_DARK, 80, 1.0, 5) {
public void beginTurn(BattleTurn[] turn, int index, Pokemon source) {
// Assume two pokemon
if (index == 1) {
// User must be going first.
return;
}
BattleTurn opp = turn[1 - index];
if (opp.isMoveTurn() && opp.getMove(source.getOpponent()).isDamaging()) {
source.addStatus(source, new SuckerPunchEffect());
}
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (!user.hasEffect(SuckerPunchEffect.class)) {
user.getField().showMessage("But it failed!");
return 0;
}
return super.use(mech, user, target);
}
public int getPriority() {
return 1;
}
}
));
class AssuranceEffect extends StatusEffect {
private int m_health;
public boolean apply(Pokemon p) {
m_health = p.getOpponent().getHealth();
return true;
}
public int getHealth() {
return m_health;
}
public int getTier() {
return 5;
}
public boolean tick(Pokemon p) {
p.removeStatus(this);
return true;
}
}
m_moves.add(new MoveListEntry("Assurance",
new PokemonMove(PokemonType.T_DARK, 50, 1.0, 10) {
public void beginTurn(BattleTurn[] turn, int index, Pokemon source) {
source.getOpponent().addStatus(source, new AssuranceEffect());
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int power = getPower();
if (!target.hasEffect(AssuranceEffect.class)) {
StatusEffect effect = target.getEffect(AssuranceEffect.class);
AssuranceEffect eff = (AssuranceEffect) effect;
if (target.getHealth() < eff.getHealth()) {
setPower(power * 2);
}
int damage = super.use(mech, user, target);
setPower(power);
return damage;
} else {
return super.use(mech, user, target);
}
}
}
));
m_moves.add(new MoveListEntry("Judgement",
new PokemonMove(PokemonType.T_NORMAL, 100, 1.0, 10)));
m_moves.add(new MoveListEntry("Metal Burst",
new CounterMove(PokemonType.T_STEEL, 1.0, 10, 3) {
public int getPriority() {
return 0;
}
}
));
DamageListenerMove payback = new DamageListenerMove(PokemonType.T_DARK, 50, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
DamageListenerEffect listener = getListener(user);
if ((listener == null) || (listener.getDamage() <= 0)) {
return super.use(mech, user, target);
}
int power = getPower();
setPower(power * 2);
int damage = super.use(mech, user, target);
setPower(power);
return damage;
}
};
DamageListenerMove avalanche = (DamageListenerMove)payback.clone();
avalanche.setType(PokemonType.T_ICE);
avalanche.setPower(60);
avalanche.setPriority(-3);
m_moves.add(new MoveListEntry("Payback", payback));
m_moves.add(new MoveListEntry("Avalanche", avalanche));
m_moves.add(new MoveListEntry("Roost", new StatusMove(
PokemonType.T_FLYING, 0, 1.0, 10, new StatusEffect[] {
new StatusEffect() {
private PokemonType[] m_types;
public boolean apply(Pokemon p) {
m_types = p.getTypes();
ArrayList<PokemonType> types = new ArrayList<PokemonType>(Arrays.asList(m_types));
Iterator<PokemonType> i = types.iterator();
while (i.hasNext()) {
PokemonType type = (PokemonType)i.next();
if (type.equals(PokemonType.T_FLYING)) {
i.remove();
}
}
p.setType((PokemonType[])types.toArray(new PokemonType[types.size()]));
return true;
}
public String getName() {
return "Roosting";
}
public int getTier() {
return 5;
}
public String getDescription() {
return null;
}
public void unapply(Pokemon p) {
p.setType(m_types);
}
public boolean tick(Pokemon p) {
p.removeStatus(this);
return true;
}
}, new PercentEffect(0.5, false, -1, null)
},
new boolean[] { true, true },
new double[] { 1.0, 1.0 }
)));
m_moves.add(new MoveListEntry("Grass Knot",
new MassBasedMove(PokemonType.T_GRASS, 1.0, 20)));
m_moves.add(new MoveListEntry("Guard Swap",
new StatChangeSwapMove(PokemonType.T_PSYCHIC, 10, new int[] {
Pokemon.S_DEFENCE,
Pokemon.S_SPDEFENCE
}
)));
m_moves.add(new MoveListEntry("Power Swap",
new StatChangeSwapMove(PokemonType.T_PSYCHIC, 10, new int[] {
Pokemon.S_ATTACK,
Pokemon.S_SPATTACK
}
)));
m_moves.add(new MoveListEntry("Heart Swap",
new StatChangeSwapMove(PokemonType.T_PSYCHIC, 10, new int[] {
Pokemon.S_DEFENCE,
Pokemon.S_SPDEFENCE,
Pokemon.S_ATTACK,
Pokemon.S_SPATTACK,
Pokemon.S_SPEED,
Pokemon.S_ACCURACY,
Pokemon.S_EVASION
}
)));
m_moves.add(new MoveListEntry("Outrage",
new RampageMove(PokemonType.T_DRAGON, 120, 1.0, 15) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
setPower((int)(((double)getPower()) / 120.0 * ((mech instanceof JewelMechanics) ? 120.0 : 90.0)));
return super.use(mech, user, target);
}
}));
m_moves.add(new MoveListEntry("Petal Dance",
new RampageMove(PokemonType.T_GRASS, 70, 1.0, 20)
));
m_moves.add(new MoveListEntry("Thrash",
new RampageMove(PokemonType.T_NORMAL, 90, 1.0, 20)
));
m_moves.add(new MoveListEntry("Fake Out",
new PokemonMove(PokemonType.T_NORMAL, 40, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (!user.isFirstTurn()) {
user.getField().showMessage("But it failed!");
return 0;
}
if ((getEffectiveness(user, target) != 0.0) && !target.hasSubstitute()) {
target.addStatus(user, new FlinchEffect());
}
return super.use(mech, user, target);
}
public int getPriority() {
return 1;
}
}
));
m_moves.add(new MoveListEntry("Magnet Rise",
new PokemonMove(PokemonType.T_ELECTRIC, 0, 0, 10) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
StatusEffect eff = user.addStatus(user, new MagnetRiseEffect());
if (eff == null) {
user.getField().showMessage("But it failed!");
}
return 0;
}
}
));
PokemonMove mirrorMove = new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.getLastMove() == null) {
user.getField().showMessage("But it failed!");
return 0;
}
return user.useMove(target.getLastMove(), target);
}
};
m_moves.add(new MoveListEntry("Mirror Move", (PokemonMove)mirrorMove.clone()));
m_moves.add(new MoveListEntry("Copycat", (PokemonMove)mirrorMove.clone()));
m_moves.add(new MoveListEntry("Spite",
new PokemonMove(PokemonType.T_GHOST, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
MoveListEntry move = target.getLastMove();
if (move == null) {
user.getField().showMessage("But it failed!");
return 0;
}
for (int i = 0; i < 4; ++i) {
if (move.equals(target.getMove(i))) {
int number = (mech instanceof JewelMechanics) ? 4 :
mech.getRandom().nextInt(3) + 2;
target.setPp(i, target.getPp(i) - number);
return 0;
}
}
return 0;
}
}
));
m_moves.add(new MoveListEntry("Destiny Bond", new StatusMove(
PokemonType.T_GHOST, 0, 1.0, 5, new StatusEffect[] {
new StatusEffect() {
public String getName() {
return "Destiny bond";
}
public String getDescription() {
return " is trying to take its foe with it!";
}
public int getTier() {
return -1;
}
public boolean tick(Pokemon p) {
return false;
}
public void executeTurn(Pokemon p, BattleTurn turn) {
p.removeStatus(this);
}
public boolean isListener() {
return true;
}
public boolean hitsThroughSubstitute() {
return true;
}
public void informDamaged(Pokemon source, Pokemon target, MoveListEntry move, int damage) {
if (target.getHealth() <= 0) {
target.getField().showMessage(target.getName() + " took " +
source.getName() + " with it!");
source.faint();
}
}
}
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Grudge", new StatusMove(
PokemonType.T_GHOST, 0, 1.0, 5, new StatusEffect[] {
new StatusEffect() {
public String getName() {
return "Grudge";
}
public String getDescription() {
return " is bearing a Grudge!";
}
public int getTier() {
return -1;
}
public boolean tick(Pokemon p) {
return false;
}
public boolean isListener() {
return true;
}
public boolean hitsThroughSubstitute() {
return true;
}
public void informDamaged(Pokemon source, Pokemon target, MoveListEntry move, int damage) {
if (target.getHealth() <= 0) {
for (int i = 0; i < 4; i++) {
if (move.equals(source.getMove(i))) {
source.getField().showMessage(
move.getName() + " lost its PP due to the Grudge!");
source.setPp(i, 0);
break;
}
}
}
}
}
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Miracle Eye", new StatusMove(
PokemonType.T_PSYCHIC, 0, 1.0, 40, new StatusEffect[] {
new StatusEffect() {
public String getName() {
return "Miracle";
}
public String getDescription() {
return " indentified the enemy Pokemon!";
}
public int getTier() {
return -1;
}
public boolean tick(Pokemon p) {
return false;
}
public boolean isEffectivenessTransformer(boolean enemy) {
return !enemy;
}
public double getTransformedEffectiveness(PokemonType move, PokemonType pokemon) {
if (move.equals(PokemonType.T_PSYCHIC) && pokemon.equals(PokemonType.T_DARK)) {
return 1.0;
}
return super.getTransformedEffectiveness(move, pokemon);
}
}
},
new boolean[] { false },
new double[] { 1.0 }
) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
List<StatusEffect> statuses = target.getNormalStatuses(0);
Iterator<StatusEffect> i = statuses.iterator();
while (i.hasNext()) {
StatusEffect effect = (StatusEffect)i.next();
if (!(effect instanceof StatChangeEffect)) continue;
StatChangeEffect eff = (StatChangeEffect)effect;
if (eff.getStat() == Pokemon.S_EVASION) {
target.removeStatus(eff);
}
}
target.getEvasion().setSecondaryMultiplier(1);
return super.use(mech, user, target);
}
}
));
m_moves.add(new MoveListEntry("Torment", new StatusMove(
PokemonType.T_DARK, 0, 1.0, 15, new StatusEffect[] {
new StatusEffect() {
private MoveListEntry m_entry;
public String getName() {
return "Torment";
}
public String getDescription() {
return " was subjected to Torment!";
}
public int getTier() {
return -1;
}
public boolean tick(Pokemon p) {
return false;
}
public boolean apply(Pokemon p) {
m_entry = p.getLastMove();
return super.apply(p);
}
public boolean isMoveTransformer(boolean enemy) {
return !enemy;
}
public MoveListEntry getTransformedMove(Pokemon p, MoveListEntry entry) {
if (entry.equals(m_entry)) {
p.getField().showMessage(p.getName() + " couldn't use the move after" +
" the torment!");
return null;
}
m_entry = entry;
return entry;
}
public boolean vetoesMove(Pokemon p, MoveListEntry entry) {
if (m_entry == null) {
return false;
}
return m_entry.equals(entry);
}
}
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Encore", new StatusMove(
PokemonType.T_NORMAL, 0, 1.0, 5, new StatusEffect[] {
new StatusEffect() {
private int m_turns;
private boolean m_transform = true;
private MoveListEntry m_entry;
public String getName() {
return "Encore";
}
public String getDescription() {
return " got an encore!";
}
public int getTier() {
return 5;
}
public boolean hitsThroughSubstitute() {
return true;
}
public boolean apply(Pokemon p) {
MoveListEntry entry = p.getLastMove();
if (entry == null) {
p.getField().showMessage("But it failed!");
return false;
}
m_entry = entry;
m_turns = p.getField().getRandom().nextInt(5) + 5;
return true;
}
public boolean tick(Pokemon p) {
if (--m_turns <= 0) {
p.getField().showMessage(p.getName() + "'s encore ended.");
p.removeStatus(this);
return true;
}
return false;
}
public boolean isMoveTransformer(boolean enemy) {
return !enemy;
}
public MoveListEntry getTransformedMove(Pokemon p, MoveListEntry entry) {
if (m_transform) {
m_transform = false;
return m_entry;
}
return entry;
}
public boolean vetoesMove(Pokemon p, MoveListEntry entry) {
return !entry.equals(m_entry);
}
}
},
new boolean[] { false },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Disable", new StatusMove(
PokemonType.T_NORMAL, 0, 0.55, 20, new StatusEffect[] {
new StatusEffect() {
private int m_turns;
private MoveListEntry m_entry;
public String getName() {
return "Disabled: " + m_entry.getName();
}
public String getDescription() {
return " was disabled!";
}
public int getTier() {
return 5;
}
public boolean apply(Pokemon p) {
MoveListEntry entry = p.getLastMove();
if (entry == null) {
p.getField().showMessage("But it failed!");
return false;
}
m_entry = entry;
m_turns = p.getField().getRandom().nextInt(3) + 2;
return true;
}
public boolean isMoveTransformer(boolean enemy) {
return !enemy;
}
public MoveListEntry getEnemyTransformedMove(Pokemon p, MoveListEntry entry) {
if (entry.equals(m_entry)) {
p.getField().showMessage(p.getName() + "'s " + entry.getName() +
" is disabled!");
return null;
}
return entry;
}
public boolean tick(Pokemon p) {
if (--m_turns <= 0) {
p.removeStatus(this);
return true;
}
return false;
}
public boolean vetoesMove(Pokemon p, MoveListEntry entry) {
return entry.equals(m_entry);
}
public boolean hitsThroughSubstitute() {
return true;
}
}
},
new boolean[] { false },
new double[] { 1.0 }
) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
setAccuracy(mech instanceof JewelMechanics ? 80 : 55);
return super.attemptHit(mech, user, target);
}
}
));
m_moves.add(new MoveListEntry("Imprison", new StatusMove(
PokemonType.T_PSYCHIC, 0, 1.0, 15, new StatusEffect[] {
new StatusEffect() {
public String getName() {
return "Imprison";
}
public String getDescription() {
return "'s moves were sealed!";
}
public int getTier() {
return -1;
}
public boolean tick(Pokemon p) {
return false;
}
public boolean vetoesMove(Pokemon p, MoveListEntry entry) {
Pokemon target = p.getOpponent();
for (int i = 0; i < 4; ++i) {
MoveListEntry move = target.getMove(i);
if ((move != null) && move.equals(entry)) {
return true;
}
}
return false;
}
public boolean hitsThroughSubstitute() {
return true;
}
}
},
new boolean[] { false },
new double[] { 1.0 }
) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}
));
m_moves.add(new MoveListEntry("Stockpile", new PokemonMove(
PokemonType.T_NORMAL, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
StockpileEffect eff = (StockpileEffect)(user.getEffect(StockpileEffect.class));
if (eff == null) {
eff = (StockpileEffect)user.addStatus(user, new StockpileEffect());
}
eff.incrementLevel(user);
return 0;
}
}
));
m_moves.add(new MoveListEntry("Spit Up",
new StockpileMove(PokemonType.T_NORMAL, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int levels = getLevels(user);
if (levels <= 0) {
user.getField().showMessage("But it failed to spit up anything!");
return 0;
}
setPower(100 * levels);
int damage = super.use(mech, user, target);
setPower(0);
user.removeStatus(getStockpileEffect(user));
return damage;
}
public boolean isAttack() {
return true;
}
}
));
m_moves.add(new MoveListEntry("Swallow",
new StockpileMove(PokemonType.T_NORMAL, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int levels = getLevels(user);
if (levels <= 0) {
user.getField().showMessage("But it failed to swallow anything!");
return 0;
}
double[] percents = new double[] {0.25, 0.5, 1.0};
double percent = percents[levels];
user.addStatus(user, new PercentEffect(percent, false, -1, null));
user.removeStatus(getStockpileEffect(user));
return 0;
}
}
));
m_moves.add(new MoveListEntry("Tailwind",
new PokemonMove(PokemonType.T_FLYING, 0, 1.0, 30) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.getField().applyEffect(new TailwindEffect(user.getParty()));
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}
));
m_moves.add(new MoveListEntry("Bide", new StatusMove(
PokemonType.T_NORMAL, 0, 1.0, 10, new StatusEffect[] {
new StatusEffect() {
private int m_damage = 0;
private int m_turns = 2;
public String getName() {
return "Bide";
}
public String getDescription() {
return " is storing energy!";
}
public int getTier() {
return -1;
}
public boolean deactivates(Pokemon p) {
return true;
}
public boolean isListener() {
return true;
}
public void informDamaged(Pokemon source, Pokemon target, MoveListEntry move, int damage) {
m_damage += damage;
}
public boolean immobilises(Pokemon p) {
if (--m_turns <= 0) {
p.getField().showMessage(p.getName() + " unleashed energy!");
p.useMove(new PokemonMove(PokemonType.T_TYPELESS, 0, 1.0, 1) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int change = 2 * m_damage;
target.changeHealth(-change);
return change;
}
}, p.getOpponent());
p.removeStatus(this);
}
return true;
}
}
},
new boolean[] { true },
new double[] { 1.0 }
) {
public int getPriority() {
// todo: This should also only be in D/P.
return 1;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}
));
class MimicEffect extends StatusEffect {
private MoveListEntry m_entry;
public MimicEffect(MoveListEntry entry) {
m_entry = entry;
}
public String getName() {
return "Mimicking " + m_entry.getName();
}
public String getDescription() {
return " mimicked the foe's move!";
}
public boolean isMoveTransformer(boolean enemy) {
return !enemy;
}
public MoveListEntry getTransformedMove(Pokemon p, MoveListEntry entry) {
if (entry.getName().equals("Mimic")) {
return m_entry;
}
return entry;
}
}
m_moves.add(new MoveListEntry("Mimic",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
MoveListEntry move = target.getLastMove();
if (move == null) {
user.getField().showMessage("But it failed!");
return 0;
}
user.addStatus(user, new MimicEffect(move));
return 0;
}
}
));
m_moves.add(new MoveListEntry("Mist",
new PokemonMove(PokemonType.T_ICE, 0, 1.0, 30) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
StatusEffect eff = user.getField().getEffectByType(MistEffect.class);
if (eff == null) {
user.getField().applyEffect(new MistEffect());
}
eff = user.getField().getEffectByType(MistEffect.class);
if (eff != null) {
MistEffect effect = (MistEffect)eff;
effect.activateParty(user);
}
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}
));
m_moves.add(new MoveListEntry("Safeguard",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 25) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
StatusEffect eff = user.getField().getEffectByType(SafeguardEffect.class);
if (eff == null) {
user.getField().applyEffect(new SafeguardEffect());
}
eff = user.getField().getEffectByType(SafeguardEffect.class);
if (eff != null) {
SafeguardEffect effect = (SafeguardEffect)eff;
effect.activateParty(user);
}
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}
));
m_moves.add(new MoveListEntry("Gastro Acid",
new PokemonMove(PokemonType.T_POISON, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.hasSubstitute()) {
user.getField().showMessage("But it failed!");
return 0;
}
IntrinsicAbility ability = target.getAbility();
if ((ability != null) && ability.isActive()) {
ability.unapply(target);
ability.deactivate();
}
user.getField().showMessage(target.getName() + "'s ability was nullified.");
target.addStatus(user, new StatusEffect() {
public String getName() {
return "Gastro Acid";
}
});
return 0;
}
}));
m_moves.add(new MoveListEntry("Gravity",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 5) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.getField().applyEffect(new FieldEffect() {
private int m_turns = 5;
public int getTier() {
return 1;
}
public boolean applyToField(BattleField field) {
// Completely made up message.
field.showMessage("Gravity intensified!");
return true;
}
public boolean apply(Pokemon p) {
if (p.hasAbility("Levitate")) {
p.getAbility().deactivate();
}
BattleField field = p.getField();
field.setNarrationEnabled(false);
p.removeStatus(MagnetRiseEffect.class);
field.setNarrationEnabled(true);
p.getMultiplier(Pokemon.S_ACCURACY).multiplyBy(1.7);
return true;
}
public void unapply(Pokemon p) {
/** This will interfere with mold breaker and gastro acid,
* but we will address that later. */
IntrinsicAbility ability = p.getAbility();
if ((ability != null) && ability.getName().equals("Levitate")) {
ability.activate();
}
p.getMultiplier(Pokemon.S_ACCURACY).divideBy(1.7);
}
public boolean tickPokemon(Pokemon p) {
return false;
}
public boolean isEffectivenessTransformer(boolean enemy) {
return !enemy;
}
public double getTransformedEffectiveness(PokemonType move, PokemonType defender) {
if (PokemonType.T_GROUND.equals(move) && PokemonType.T_FLYING.equals(defender)) {
// Ground is neutral aganist flying under the effects of gravity.
return 1.0;
}
return super.getTransformedEffectiveness(move, defender);
}
public boolean isMoveTransformer(boolean enemy) {
return !enemy;
}
public boolean vetoesMove(Pokemon p, MoveListEntry entry) {
return !canUseMove(entry.getName());
}
private boolean canUseMove(String move) {
// Moves that involve going up into the air are forbidden.
Set<String> forbidden = new HashSet<String>(Arrays.asList(new String[] {
"Fly", "Bounce", "Hi Jump Kick", "Jump Kick", "Magnet Rise"
}));
return !forbidden.contains(move);
}
public MoveListEntry getTransformedMove(Pokemon p, MoveListEntry entry) {
String name = entry.getName();
if (!canUseMove(name)) {
BattleField field = p.getField();
field.showMessage(p.getName() + " can't use " + name + " because of the Gravity.");
return null;
}
return entry;
}
public boolean tickField(BattleField field) {
if (--m_turns == 0) {
field.removeEffect(this);
return true;
}
return false;
}
public String getName() {
return "Gravity";
}
public void unapplyToField(BattleField field) {
field.showMessage("Gravity returned to normal!");
}
});
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}));
m_moves.add(new MoveListEntry("Embargo",
new PokemonMove(PokemonType.T_DARK, 0, 1.0, 15) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (target.hasSubstitute()) {
user.getField().showMessage("But it failed!");
return 0;
}
target.addStatus(user, new StatusEffect() {
public boolean apply(Pokemon p) {
HoldItem item = p.getItem();
if ((item != null) && item.isActive()) {
item.unapply(p);
item.deactivate();
}
return true;
}
public String getDescription() {
return "'s item was nullified.";
}
public void unapply(Pokemon p) {
HoldItem item = p.getItem();
if ((item != null) && !item.isRemovable()) {
item.activate();
item.apply(p);
}
}
public String getName() {
return "Embargo";
}
});
return 0;
}
}));
class SnatchEffect extends StatusEffect {
private StatusEffect[] m_effects;
public SnatchEffect(StatusEffect[] effects) {
m_effects = effects;
}
public String getName() {
return "Snatch";
}
public String getDescription() {
return null;
}
public boolean tick(Pokemon p) {
p.removeStatus(this);
return true;
}
public boolean isMoveTransformer(boolean enemy) {
return enemy;
}
public MoveListEntry getEnemyTransformedMove(Pokemon p, MoveListEntry entry) {
return null;
}
public StatusEffect[] getEffects() {
return m_effects;
}
}
m_moves.add(new MoveListEntry("Snatch",
new PokemonMove(PokemonType.T_DARK, 0, 1.0, 10) {
@SuppressWarnings("unused")
public void beginTurn(BattleTurn[] turn, Pokemon p, int index) {
if (p.hasEffect(SleepEffect.class) || p.hasEffect(FreezeEffect.class)) {
return;
}
BattleTurn opp = turn[1 - index];
if (!opp.isMoveTurn()) return;
MoveListEntry entry = p.getOpponent().getMove(opp.getId());
PokemonMove move = entry.getMove();
if (!(move instanceof StatusMove)) return;
StatusMove statusMove = (StatusMove)move;
if (statusMove.isAttack()) return;
StatusEffect[] effects = statusMove.getEffects();
p.addStatus(p, new SnatchEffect(effects));
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.getField().showMessage(user.getName() + " awaits the foe's move!");
SnatchEffect eff = (SnatchEffect)user.getEffect(SnatchEffect.class);
if (eff == null) {
return 0;
}
StatusEffect[] effects = eff.getEffects();
if (effects.length > 0) {
user.getField().showMessage(user.getName() + " snatched the foe's effects!");
for (int i = 0; i < effects.length; ++i) {
user.addStatus(user, effects[i]);
}
}
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
public int getPriority() {
return 3;
}
}
));
PokemonMove lockOn = new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 5) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.addStatus(user, new LockOnEffect());
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
};
m_moves.add(new MoveListEntry("Lock-on", (PokemonMove)lockOn.clone()));
m_moves.add(new MoveListEntry("Mind Reader", (PokemonMove)lockOn.clone()));
m_moves.add(new MoveListEntry("Conversion 2", new StatusMove(
PokemonType.T_NORMAL, 0, 1.0, 30, new StatusEffect[] {
new StatusEffect() {
private PokemonType[] m_types;
public String getName() {
return "Conversion 2";
}
public String getDescription() {
return null;
}
public int getTier() {
return -1;
}
public boolean tick(Pokemon p) {
return false;
}
public boolean apply(Pokemon p) {
m_types = p.getTypes();
MoveListEntry entry = p.getOpponent().getLastMove();
if (entry == null) {
p.getField().showMessage("But it failed!");
return false;
}
PokemonType moveType = entry.getMove().getType();
ArrayList<PokemonType> types = new ArrayList<PokemonType>(Arrays.asList(PokemonType.getTypes()));
Iterator<PokemonType> i = types.iterator();
while (i.hasNext()) {
PokemonType type = (PokemonType)i.next();
if (moveType.getMultiplier(type) >= 1) {
i.remove();
}
}
int random = p.getField().getRandom().nextInt(types.size());
p.setType(new PokemonType[] { (PokemonType)types.get(random) });
return true;
}
public void unapply(Pokemon p) {
p.setType(m_types);
}
public boolean switchOut(Pokemon p) {
p.setType(m_types);
return true;
}
}
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Rage", new StatusMove(
PokemonType.T_NORMAL, 20, 1.0, 20, new StatusEffect[] {
new StatusEffect() {
public String getName() {
return "Rage";
}
public String getDescription() {
return " went into a rage!";
}
public int getTier() {
return -1;
}
public boolean tick(Pokemon p) {
return false;
}
public void executeTurn(Pokemon p, BattleTurn turn) {
p.removeStatus(this);
}
public boolean isListener() {
return true;
}
public void informDamaged(Pokemon source, Pokemon target, MoveListEntry move, int damage) {
target.getField().showMessage(target.getName() + " is angry!");
target.addStatus(target, new StatChangeEffect(Pokemon.S_ATTACK, true));
}
}
},
new boolean[] { true },
new double[] { 1.0 }
)));
class FuryCutterEffect extends StatusEffect {
public int m_turns = 0;
public String getName() {
return "Fury cutter";
}
public String getDescription() {
return null;
}
public int getTier() {
return -1;
}
public boolean tick(Pokemon p) {
m_turns++;
return false;
}
public void executeTurn(Pokemon p, BattleTurn turn) {
if (p.getField().getMechanics() instanceof JewelMechanics) {
return;
}
if (!p.getMove(turn.getId()).getName().equals("Fury Cutter")) {
p.removeStatus(this);
}
}
public boolean isMoveTransformer(boolean enemy) {
return !enemy;
}
public MoveListEntry getTransformedMove(Pokemon p, MoveListEntry entry) {
if (!entry.getName().equals("Fury Cuttter")) return entry;
PokemonMove move = entry.getMove();
int power = move.getPower() * (1 << m_turns);
if (power > 160) power = 160;
move.setPower(power);
return entry;
}
public boolean isSingleton() {
return true;
}
public void informDuplicateEffect(Pokemon p) {
}
}
m_moves.add(new MoveListEntry("Fury Cutter", new StatusMove(
PokemonType.T_BUG, 10, 0.95, 20, new StatusEffect[] {
new FuryCutterEffect()
},
new boolean[] { true },
new double[] { 1.0 }
) {
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
if (!super.attemptHit(mech, user, target)) {
user.removeStatus(FuryCutterEffect.class);
}
return super.use(mech, user, target);
}
}
));
m_moves.add(new MoveListEntry("Power Trick", new StatusMove(
PokemonType.T_PSYCHIC, 0, 1.0, 10, new StatusEffect[] {
new StatusEffect() {
private int m_attack;
private int m_defence;
public String getName() {
return "Power Trick";
}
public String getDescription() {
return " swapped its stats!";
}
public int getTier() {
return -1;
}
public boolean tick(Pokemon p) {
return false;
}
public boolean apply(Pokemon p) {
m_attack = p.getRawStat(Pokemon.S_ATTACK);
m_defence = p.getRawStat(Pokemon.S_DEFENCE);
p.setRawStat(Pokemon.S_ATTACK, m_defence);
p.setRawStat(Pokemon.S_DEFENCE, m_attack);
return super.apply(p);
}
public void unapply(Pokemon p) {
p.setRawStat(Pokemon.S_ATTACK, m_attack);
p.setRawStat(Pokemon.S_DEFENCE, m_defence);
}
}
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Uproar", new FixedAttackMove(
PokemonType.T_NORMAL, 50, 1.0, 20, new FixedAttackEffect("Uproar",
" caused an uproar!", " calmed down."))));
m_moves.add(new MoveListEntry("Rollout", new FixedAttackMove(
PokemonType.T_ROCK, 30, 0.9, 20, new RolloutEffect("Rollout"))));
m_moves.add(new MoveListEntry("Ice Ball", new FixedAttackMove(
PokemonType.T_ICE, 30, 0.9, 20, new RolloutEffect("Ice Ball"))));
/** If you had bothered to read the Smogon analysis, you would have learned that
* this is actually nearly a clone of Lunar Dance (except that it does not heal
* PP); it is not at all like Destiny Bond. Fortunately the move is rare
* enough that it has yet to matter.
*/
m_moves.add(new MoveListEntry("Healing Wish",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 10) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int party = user.getParty();
BattleField field = user.getField();
if (field.getAliveCount(party) == 1) {
user.getField().showMessage("But it failed!");
return 0;
}
user.faint();
field.requestAndWaitForSwitch(party);
target = field.getActivePokemon()[party];
target.changeHealth(target.getStat(Pokemon.S_HP));
target.removeStatus(StatusEffect.SPECIAL_EFFECT_LOCK);
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon source, Pokemon target) {
return true;
}
}
));
m_moves.add(new MoveListEntry("Bug Bite",
new PokemonMove(PokemonType.T_BUG, 60, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
HoldItem item = target.getItem();
if (item instanceof Berry) {
Berry berry = (Berry)item;
berry.executeEffects(user);
target.setItem(null);
}
return super.use(mech, user, target);
}
}
));
m_moves.add(new MoveListEntry("Pluck",
new PokemonMove(PokemonType.T_FLYING, 60, 1.0, 20) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
int power = getPower();
HoldItem item = target.getItem();
if (item instanceof Berry) {
setPower(power * 2);
}
int damage = super.use(mech, user, target);
setPower(power);
return damage;
}
}
));
m_moves.add(new MoveListEntry("Lucky Chant",
new PokemonMove(PokemonType.T_NORMAL, 0, 1.0, 30) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
FieldEffect effect = user.getField().getEffectByType(LuckyChantEffect.class);
if (effect == null) {
user.getField().applyEffect(
new LuckyChantEffect(" is feeling lucky!", "'s luck wore off..."));
}
effect = user.getField().getEffectByType(LuckyChantEffect.class);
LuckyChantEffect eff = (LuckyChantEffect)effect;
eff.activateParty(user);
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}
));
m_moves.add(new MoveListEntry("Heal Block",
new PokemonMove(PokemonType.T_PSYCHIC, 0, 1.0, 15) {
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
target.addStatus(user, new HealBlockEffect());
return 0;
}
public boolean attemptHit(BattleMechanics mech, Pokemon user, Pokemon target) {
return true;
}
}
));
m_moves.add(new MoveListEntry("Focus Energy", new StatusMove(
PokemonType.T_NORMAL, 0, 1.0, 30, new StatusEffect[] {
new StatusEffect() {
public String getName() {
return "Focus energy";
}
public String getDescription() {
return " tightened its focus!";
}
public boolean switchOut(Pokemon p) {
return true;
}
}
},
new boolean[] { true },
new double[] { 1.0 }
)));
m_moves.add(new MoveListEntry("Magic Coat", new PokemonMove(
PokemonType.T_PSYCHIC, 0, 1.0, 15) {
public int getPriority() {
return 5;
}
public int use(BattleMechanics mech, Pokemon user, Pokemon target) {
user.getField().showMessage(user.getName() + " created a barrier!");
target.addStatus(user, new StatusEffect() {
public boolean isMoveTransformer(boolean enemy) {
return !enemy;
}
public MoveListEntry getTransformedMove(Pokemon p, MoveListEntry entry) {
PokemonMove move = entry.getMove();