package forge.card.cardFactory;
import com.esotericsoftware.minlog.Log;
import forge.*;
import forge.card.spellability.*;
import forge.gui.GuiUtils;
import forge.gui.input.Input;
import forge.gui.input.Input_PayManaCost;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Vector;
/**
* <p>CardFactory_Sorceries class.</p>
*
* @author Forge
* @version $Id: $
*/
public class CardFactory_Sorceries {
/**
* <p>getCard.</p>
*
* @param card a {@link forge.Card} object.
* @param cardName a {@link java.lang.String} object.
* @param owner a {@link forge.Player} object.
* @return a {@link forge.Card} object.
*/
public static Card getCard(final Card card, final String cardName, Player owner) {
//*************** START *********** START **************************
if (cardName.equals("Political Trickery")) {
final Card[] target = new Card[2];
final int[] index = new int[1];
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -3075569295823682336L;
@Override
public boolean canPlayAI() {
return false;
}
@Override
public void resolve() {
Card crd0 = target[0];
Card crd1 = target[1];
if (crd0 != null && crd1 != null) {
Player p0 = crd0.getController();
Player p1 = crd1.getController();
AllZone.getGameAction().changeController(new CardList(crd0), p0, p1);
AllZone.getGameAction().changeController(new CardList(crd1), p1, p0);
}
}//resolve()
};//SpellAbility
final Input input = new Input() {
private static final long serialVersionUID = -1017253686774265770L;
@Override
public void showMessage() {
if (index[0] == 0) AllZone.getDisplay().showMessage("Select target land you control.");
else AllZone.getDisplay().showMessage("Select target land opponent controls.");
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
stop();
}
@Override
public void selectCard(Card c, PlayerZone zone) {
//must target creature you control
if (index[0] == 0 && !c.getController().equals(card.getController())) return;
//must target creature you don't control
if (index[0] == 1 && c.getController().equals(card.getController())) return;
if (c.isLand() && zone.is(Constant.Zone.Battlefield) && CardFactoryUtil.canTarget(card, c)) {
target[index[0]] = c;
index[0]++;
showMessage();
if (index[0] == target.length) {
if (this.isFree()) {
this.setFree(false);
AllZone.getStack().add(spell);
stop();
} else stopSetNext(new Input_PayManaCost(spell));
}
}
}//selectCard()
};//Input
Input runtime = new Input() {
private static final long serialVersionUID = 4003351872990899418L;
@Override
public void showMessage() {
index[0] = 0;
stopSetNext(input);
}
};//Input
card.addSpellAbility(spell);
spell.setBeforePayMana(runtime);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Do or Die")) {
// TODO: Please please please, someone fix this card
Cost cost = new Cost("1 B", cardName, false);
Target tgt = new Target(card, "Select a Player", "Player");
final SpellAbility spell = new Spell(card, cost, tgt) {
private static final long serialVersionUID = 8241241003478388362L;
@Override
public boolean canPlayAI() {
return 4 <= CardFactoryUtil.AI_getHumanCreature(card, true).size();
}
@Override
public void resolve() {
CardList list = AllZoneUtil.getCreaturesInPlay(getTargetPlayer());
list.shuffle();
for (int i = 0; i < list.size() / 2; i++)
AllZone.getGameAction().destroyNoRegeneration(list.get(i));
}
};//SpellAbility
spell.setChooseTargetAI(CardFactoryUtil.AI_targetHuman());
card.setSVar("PlayMain1", "TRUE");
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Insurrection")) {
/*
* Untap all creatures and gain control of them until end of
* turn. They gain haste until end of turn.
*/
final ArrayList<PlayerZone> orig = new ArrayList<PlayerZone>();
final PlayerZone[] newZone = new PlayerZone[1];
final ArrayList<Player> controllerEOT = new ArrayList<Player>();
final ArrayList<Card> targets = new ArrayList<Card>();
final Command untilEOT = new Command() {
private static final long serialVersionUID = -5809548350739536763L;
public void execute() {
int i = 0;
for (Card target : targets) {
//if card isn't in play, do nothing
if (!AllZoneUtil.isCardInPlay(target)) continue;
AllZone.getGameAction().changeController(new CardList(target), card.getController(), controllerEOT.get(i));
target.removeExtrinsicKeyword("Haste");
i++;
}
}//execute()
};//Command
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -532862769235091780L;
@Override
public void resolve() {
CardList creatures = AllZoneUtil.getCreaturesInPlay();
newZone[0] = AllZone.getZone(Constant.Zone.Battlefield, card.getController());
;
int i = 0;
for (Card target : creatures) {
if (AllZoneUtil.isCardInPlay(target)) {
orig.add(i, AllZone.getZone(target));
controllerEOT.add(i, target.getController());
targets.add(i, target);
AllZone.getGameAction().changeController(new CardList(target), target.getController(), card.getController());
target.untap();
target.addExtrinsicKeyword("Haste");
}//is card in play?
}//end for
AllZone.getEndOfTurn().addUntil(untilEOT);
}//resolve()
@Override
public boolean canPlayAI() {
CardList creatures = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer());
return creatures.size() > 0 && AllZone.getPhase().getPhase().equals(Constant.Phase.Main1);
}//canPlayAI()
};//SpellAbility
card.addSpellAbility(spell);
card.setSVar("PlayMain1", "TRUE");
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Ignite Memories")) {
Target t = new Target(card, "Select target player", "Player");
Cost cost = new Cost("4 R", cardName, false);
SpellAbility spell = new Spell(card, cost, t) {
private static final long serialVersionUID = 143904782338241969L;
@Override
public boolean canPlayAI() {
return AllZone.getPhase().getPhase().equals(Constant.Phase.Main2);
}
@Override
public void resolve() {
Player player = getTargetPlayer();
CardList handChoices = AllZoneUtil.getPlayerHand(player);
if (handChoices.size() > 0) {
Card choice = CardUtil.getRandom(handChoices.toArray());
GuiUtils.getChoice("Random card", new CardList(choice));
player.addDamage(CardUtil.getConvertedManaCost(choice.getManaCost()), card);
}
}//resolve()
};
spell.setChooseTargetAI(CardFactoryUtil.AI_targetHuman());
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Mind's Desire")) {
final Spell PlayCreature = new Spell(card) {
private static final long serialVersionUID = 53838791023456795L;
@Override
public void resolve() {
Player player = card.getController();
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, player);
PlayerZone RFG = AllZone.getZone(Constant.Zone.Exile, player);
Card[] Attached = card.getAttachedCards();
RFG.remove(Attached[0]);
play.add(Attached[0]);
card.unattachCard(Attached[0]);
}//resolve()
};//SpellAbility
final Ability freeCast = new Ability(card, "0") {
private static final long serialVersionUID = 4455819149429678456L;
@Override
public void resolve() {
Card target = null;
Card c = null;
Player player = card.getController();
if (player.isHuman()) {
Card[] Attached = getSourceCard().getAttachedCards();
Card[] Choices = new Card[Attached.length];
boolean SystemsGo = true;
if (AllZone.getStack().size() > 0) {
CardList Config = new CardList();
for (int i = 0; i < Attached.length; i++) {
if (Attached[i].isInstant() == true || Attached[i].hasKeyword("Flash") == true)
Config.add(Attached[i]);
}
for (int i = 0; i < Config.size(); i++) {
Card crd = Config.get(i);
Choices[i] = crd;
}
if (Config.size() == 0) SystemsGo = false;
} else {
for (int i = 0; i < Attached.length; i++) {
Choices[i] = Attached[i];
}
}
Object check = null;
if (SystemsGo == true) {
check = GuiUtils.getChoiceOptional("Select Card to play for free", Choices);
if (check != null) {
target = ((Card) check);
}
if (target != null) c = AllZone.getCardFactory().copyCard(target);
if (c != null) {
if (c.isLand()) {
if (player.canPlayLand()) {
player.playLand(c);
} else {
JOptionPane.showMessageDialog(null, "You can't play any more lands this turn.", "", JOptionPane.INFORMATION_MESSAGE);
}
} else if (c.isPermanent() == true && c.isAura() == false) {
c.removeIntrinsicKeyword("Flash"); // Stops the player from re-casting the flash spell.
StringBuilder sb = new StringBuilder();
sb.append(c.getName()).append(" - Copied from Mind's Desire");
PlayCreature.setStackDescription(sb.toString());
Card[] ReAttach = new Card[Attached.length];
ReAttach[0] = c;
int ReAttach_Count = 0;
for (int i = 0; i < Attached.length; i++) {
if (Attached[i] != target) {
ReAttach_Count = ReAttach_Count + 1;
ReAttach[ReAttach_Count] = Attached[i];
}
}
// Clear Attached List
for (int i = 0; i < Attached.length; i++) {
card.unattachCard(Attached[i]);
}
// Re-add
for (int i = 0; i < ReAttach.length; i++) {
if (ReAttach[i] != null) card.attachCard(ReAttach[i]);
}
target.addSpellAbility(PlayCreature);
AllZone.getStack().add(PlayCreature);
} else {
AllZone.getGameAction().playCardNoCost(c);
card.unattachCard(c);
}
} else
JOptionPane.showMessageDialog(null, "Player cancelled or there is no more cards available on Mind's Desire.", "", JOptionPane.INFORMATION_MESSAGE);
} else
JOptionPane.showMessageDialog(null, "You can only play an instant at this point in time, but none are attached to Mind's Desire.", "", JOptionPane.INFORMATION_MESSAGE);
}
}
public boolean canPlayAI() {
return false;
}
};
freeCast.setStackDescription("Mind's Desire - play card without paying its mana cost.");
Command intoPlay = new Command() {
private static final long serialVersionUID = 920148510259054021L;
public void execute() {
Player player = AllZone.getPhase().getPlayerTurn();
PlayerZone Play = AllZone.getZone(Constant.Zone.Battlefield, player);
Card Minds_D = card;
if (player.isHuman()) card.getController().shuffle();
CardList MindsList = AllZoneUtil.getPlayerCardsInPlay(player);
MindsList = MindsList.getName("Mind's Desire");
MindsList.remove(card);
if (MindsList.size() > 0) {
Play.remove(card);
Minds_D = MindsList.get(0);
} else
JOptionPane.showMessageDialog(null, "Click Mind's Desire to see the available cards to play without paying its mana cost.", "", JOptionPane.INFORMATION_MESSAGE);
CardList libList = AllZoneUtil.getPlayerCardsInLibrary(player);
Card c = null;
if (libList.size() > 0) {
c = libList.get(0);
PlayerZone RFG = AllZone.getZone(Constant.Zone.Exile, player);
AllZone.getGameAction().moveTo(RFG, c);
Minds_D.attachCard(c);
}
final Card Minds = card;
// AllZone.getGameAction().exile(Minds);
Minds.setImmutable(true);
Command untilEOT = new Command() {
private static final long serialVersionUID = -28032591440730370L;
public void execute() {
Player player = AllZone.getPhase().getPlayerTurn();
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, player);
play.remove(Minds);
}
};
AllZone.getEndOfTurn().addUntil(untilEOT);
}
};
SpellAbility spell = new Spell_Permanent(card) {
private static final long serialVersionUID = -2940969025405788931L;
@Override
public boolean canPlayAI() {
return false;
}
};
card.addComesIntoPlayCommand(intoPlay);
card.addSpellAbility(spell);
card.addSpellAbility(freeCast);
spell.setDescription("");
}
//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Brilliant Ultimatum")) {
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 1481112451519L;
@Override
public void resolve() {
Card choice = null;
//check for no cards in hand on resolve
CardList lib = AllZoneUtil.getPlayerCardsInLibrary(card.getController());
CardList cards = new CardList();
CardList exiled = new CardList();
if (lib.size() == 0) {
JOptionPane.showMessageDialog(null, "No more cards in library.", "", JOptionPane.INFORMATION_MESSAGE);
return;
}
int Count = 5;
if (lib.size() < 5) Count = lib.size();
for (int i = 0; i < Count; i++) cards.add(lib.get(i));
for (int i = 0; i < Count; i++) {
exiled.add(lib.get(i));
AllZone.getGameAction().exile(lib.get(i));
}
CardList Pile1 = new CardList();
CardList Pile2 = new CardList();
boolean stop = false;
int Pile1CMC = 0;
int Pile2CMC = 0;
GuiUtils.getChoice("Revealing top " + Count + " cards of library: ", cards.toArray());
//Human chooses
if (card.getController().isComputer()) {
for (int i = 0; i < Count; i++) {
if (stop == false) {
choice = GuiUtils.getChoiceOptional("Choose cards to put into the first pile: ", cards.toArray());
if (choice != null) {
Pile1.add(choice);
cards.remove(choice);
Pile1CMC = Pile1CMC + CardUtil.getConvertedManaCost(choice);
} else stop = true;
}
}
for (int i = 0; i < Count; i++) {
if (!Pile1.contains(exiled.get(i))) {
Pile2.add(exiled.get(i));
Pile2CMC = Pile2CMC + CardUtil.getConvertedManaCost(exiled.get(i));
}
}
StringBuilder sb = new StringBuilder();
sb.append("You have spilt the cards into the following piles" + "\r\n" + "\r\n");
sb.append("Pile 1: " + "\r\n");
for (int i = 0; i < Pile1.size(); i++) sb.append(Pile1.get(i).getName() + "\r\n");
sb.append("\r\n" + "Pile 2: " + "\r\n");
for (int i = 0; i < Pile2.size(); i++) sb.append(Pile2.get(i).getName() + "\r\n");
JOptionPane.showMessageDialog(null, sb, "", JOptionPane.INFORMATION_MESSAGE);
if (Pile1CMC >= Pile2CMC) {
JOptionPane.showMessageDialog(null, "Computer chooses the Pile 1", "", JOptionPane.INFORMATION_MESSAGE);
for (int i = 0; i < Pile1.size(); i++) {
ArrayList<SpellAbility> choices = Pile1.get(i).getBasicSpells();
for (SpellAbility sa : choices) {
if (sa.canPlayAI()) {
ComputerUtil.playStackFree(sa);
if (Pile1.get(i).isPermanent()) exiled.remove(Pile1.get(i));
break;
}
}
}
} else {
JOptionPane.showMessageDialog(null, "Computer chooses the Pile 2", "", JOptionPane.INFORMATION_MESSAGE);
for (int i = 0; i < Pile2.size(); i++) {
ArrayList<SpellAbility> choices = Pile2.get(i).getBasicSpells();
for (SpellAbility sa : choices) {
if (sa.canPlayAI()) {
ComputerUtil.playStackFree(sa);
if (Pile2.get(i).isPermanent()) exiled.remove(Pile2.get(i));
break;
}
}
}
}
} else {//Computer chooses (It picks the highest converted mana cost card and 1 random card.)
Card biggest = exiled.get(0);
for (Card c : exiled)
if (CardUtil.getConvertedManaCost(biggest.getManaCost()) < CardUtil.getConvertedManaCost(c.getManaCost()))
biggest = c;
Pile1.add(biggest);
cards.remove(biggest);
if (cards.size() > 2) {
Card Random = CardUtil.getRandom(cards.toArray());
Pile1.add(Random);
}
for (int i = 0; i < Count; i++) if (!Pile1.contains(exiled.get(i))) Pile2.add(exiled.get(i));
StringBuilder sb = new StringBuilder();
sb.append("Choose a pile to add to your hand: " + "\r\n" + "\r\n");
sb.append("Pile 1: " + "\r\n");
for (int i = 0; i < Pile1.size(); i++) sb.append(Pile1.get(i).getName() + "\r\n");
sb.append("\r\n" + "Pile 2: " + "\r\n");
for (int i = 0; i < Pile2.size(); i++) sb.append(Pile2.get(i).getName() + "\r\n");
Object[] possibleValues = {"Pile 1", "Pile 2"};
Object q = JOptionPane.showOptionDialog(null, sb, "Brilliant Ultimatum",
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
null, possibleValues, possibleValues[0]);
CardList chosen;
if (q.equals(0))
chosen = Pile1;
else
chosen = Pile2;
int numChosen = chosen.size();
for (int i = 0; i < numChosen; i++) {
Object check = GuiUtils.getChoiceOptional("Select spells to play in reverse order: ", chosen.toArray());
if (check == null)
break;
Card playing = (Card) check;
if (playing.isLand()) {
if (card.getController().canPlayLand()) {
card.getController().playLand(playing);
} else {
JOptionPane.showMessageDialog(null, "You can't play any more lands this turn.", "", JOptionPane.INFORMATION_MESSAGE);
}
} else {
AllZone.getGameAction().playCardNoCost(playing);
}
chosen.remove(playing);
}
}
Pile1.clear();
Pile2.clear();
}//resolve()
@Override
public boolean canPlayAI() {
CardList cards = AllZoneUtil.getPlayerCardsInLibrary(AllZone.getComputerPlayer());
return cards.size() >= 8;
}
};//SpellAbility
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Cranial Extraction")) {
Cost cost = new Cost("3 B", cardName, false);
Target tgt = new Target(card, "Select a Player", "Player");
final SpellAbility spell = new Spell(card, cost, tgt) {
private static final long serialVersionUID = 8127696608769903507L;
@Override
public void resolve() {
Player target = getTargetPlayer();
String choice = null;
//human chooses
if (card.getController().isHuman()) {
choice = JOptionPane.showInputDialog(null, "Name a nonland card", cardName, JOptionPane.QUESTION_MESSAGE);
CardList showLibrary = AllZoneUtil.getPlayerCardsInLibrary(target);
GuiUtils.getChoiceOptional("Target Player's Library", showLibrary.toArray());
CardList showHand = AllZoneUtil.getPlayerHand(target);
GuiUtils.getChoiceOptional("Target Player's Hand", showHand.toArray());
}//if
else //computer chooses
{
//the computer cheats by choosing a creature in the human players library or hand
CardList all = AllZoneUtil.getPlayerHand(target);
all.addAll(AllZoneUtil.getPlayerCardsInLibrary(target));
CardList four = all.filter(new CardListFilter() {
public boolean addCard(Card c) {
if (c.isLand()) return false;
return 3 < CardUtil.getConvertedManaCost(c.getManaCost());
}
});
if (!four.isEmpty()) choice = CardUtil.getRandom(four.toArray()).getName();
else choice = CardUtil.getRandom(all.toArray()).getName();
}//else
remove(choice, target);
target.shuffle();
}//resolve()
void remove(String name, Player player) {
CardList all = AllZoneUtil.getPlayerHand(player);
all.addAll(AllZoneUtil.getPlayerGraveyard(player));
all.addAll(AllZoneUtil.getPlayerCardsInLibrary(player));
for (int i = 0; i < all.size(); i++) {
if (all.get(i).getName().equals(name)) {
if (!all.get(i).isLand()) AllZone.getGameAction().exile(all.get(i));
}
}
}//remove()
@Override
public boolean canPlayAI() {
CardList c = AllZoneUtil.getPlayerCardsInLibrary(AllZone.getHumanPlayer());
c = c.filter(AllZoneUtil.nonlands);
return c.size() > 0;
}
};//SpellAbility spell
spell.setChooseTargetAI(CardFactoryUtil.AI_targetHuman());
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Maelstrom Pulse")) {
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -4050843868789582138L;
@Override
public boolean canPlayAI() {
CardList c = getCreature();
if (c.isEmpty()) return false;
else {
setTargetCard(c.get(0));
return true;
}
}//canPlayAI()
CardList getCreature() {
CardList out = new CardList();
CardList list = CardFactoryUtil.AI_getHumanCreature("Flying", card, true);
list.shuffle();
for (int i = 0; i < list.size(); i++)
if ((list.get(i).getNetAttack() >= 2) && (list.get(i).getNetDefense() <= 2))
out.add(list.get(i));
//in case human player only has a few creatures in play, target anything
if (out.isEmpty() && 0 < CardFactoryUtil.AI_getHumanCreature(2, card, true).size()
&& 3 > CardFactoryUtil.AI_getHumanCreature(card, true).size()) {
out.addAll(CardFactoryUtil.AI_getHumanCreature(2, card, true));
CardListUtil.sortFlying(out);
}
return out;
}//getCreature()
@Override
public void resolve() {
if (AllZoneUtil.isCardInPlay(getTargetCard())
&& CardFactoryUtil.canTarget(card, getTargetCard())) {
AllZone.getGameAction().destroy(getTargetCard());
if (!getTargetCard().isFaceDown()) {
//get all creatures
CardList list = AllZoneUtil.getCardsInPlay();
list = list.getName(getTargetCard().getName());
list.remove(getTargetCard());
if (!getTargetCard().isFaceDown()) for (int i = 0; i < list.size(); i++)
AllZone.getGameAction().destroy(list.get(i));
}//is token?
}//in play?
}//resolve()
};//SpellAbility
card.addSpellAbility(spell);
Input target = new Input() {
private static final long serialVersionUID = -4947592326270275532L;
@Override
public void showMessage() {
AllZone.getDisplay().showMessage("Select target nonland permanent for " + spell.getSourceCard());
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
stop();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if (zone.is(Constant.Zone.Battlefield) && !card.isLand()) {
spell.setTargetCard(card);
if (this.isFree()) {
this.setFree(false);
AllZone.getStack().add(spell);
stop();
} else stopSetNext(new Input_PayManaCost(spell));
}
}
};//Input
spell.setBeforePayMana(target);
}//*************** END ************ END ***************************
//*************** START *********** START **************************
else if (cardName.equals("Erratic Explosion")) {
Cost cost = new Cost(card.getManaCost(), cardName, false);
Target tgt = new Target(card, "CP");
final SpellAbility spell = new Spell(card, cost, tgt) {
private static final long serialVersionUID = -6003403347798646257L;
int damage = 3;
Card check;
@Override
public boolean canPlayAI() {
if (AllZone.getHumanPlayer().getLife() <= damage) return true;
check = getFlying();
return check != null;
}
@Override
public void chooseTargetAI() {
if (AllZone.getHumanPlayer().getLife() <= damage) {
setTargetPlayer(AllZone.getHumanPlayer());
return;
}
Card c = getFlying();
if ((c == null) || (!check.equals(c))) throw new RuntimeException(card
+ " error in chooseTargetAI() - Card c is " + c + ", Card check is " + check);
setTargetCard(c);
}//chooseTargetAI()
//uses "damage" variable
Card getFlying() {
CardList flying = CardFactoryUtil.AI_getHumanCreature("Flying", card, true);
for (int i = 0; i < flying.size(); i++)
if (flying.get(i).getNetDefense() <= damage) return flying.get(i);
return null;
}
@Override
public void resolve() {
int damage = getDamage();
if (getTargetCard() != null) {
if (AllZoneUtil.isCardInPlay(getTargetCard())
&& CardFactoryUtil.canTarget(card, getTargetCard())) {
javax.swing.JOptionPane.showMessageDialog(null, "Erratic Explosion causes " + damage
+ " to " + getTargetCard());
Card c = getTargetCard();
c.addDamage(damage, card);
}
} else {
javax.swing.JOptionPane.showMessageDialog(null, "Erratic Explosion causes " + damage
+ " to " + getTargetPlayer());
getTargetPlayer().addDamage(damage, card);
}
}
//randomly choose a nonland card
int getDamage() {
CardList notLand = AllZoneUtil.getPlayerCardsInLibrary(card.getController());
notLand = notLand.filter(AllZoneUtil.nonlands);
notLand.shuffle();
if (notLand.isEmpty()) return 0;
Card card = notLand.get(0);
return CardUtil.getConvertedManaCost(card.getSpellAbility()[0]);
}
};//SpellAbility
card.addSpellAbility(spell);
card.setSVar("PlayMain1", "TRUE");
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Martial Coup")) {
Cost cost = new Cost(card.getManaCost(), cardName, false);
SpellAbility spell = new Spell(card, cost, null) {
private static final long serialVersionUID = -29101524966207L;
@Override
public void resolve() {
CardList all = AllZoneUtil.getCardsInPlay();
int Soldiers = card.getXManaCostPaid();
for (int i = 0; i < Soldiers; i++) {
CardFactoryUtil.makeToken("Soldier", "W 1 1 Soldier", card.getController(), "W", new String[]{
"Creature", "Soldier"}, 1, 1, new String[]{""});
}
if (Soldiers >= 5) {
for (int i = 0; i < all.size(); i++) {
Card c = all.get(i);
if (c.isCreature()) AllZone.getGameAction().destroy(c);
}
}
}// resolve()
@Override
public boolean canPlayAI() {
CardList human = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer());
CardList computer = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer());
// the computer will at least destroy 2 more human creatures
return (computer.size() < human.size() - 1
|| (AllZone.getComputerPlayer().getLife() < 7 && !human.isEmpty())) && ComputerUtil.getAvailableMana().size() >= 7;
}
};// SpellAbility
card.addSpellAbility(spell);
}// *************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Incendiary Command")) {
//not sure what to call variables, so I just made up something
final Player[] m_player = new Player[1];
final Card[] m_land = new Card[1];
final ArrayList<String> userChoice = new ArrayList<String>();
final String[] cardChoice = {
"Incendiary Command deals 4 damage to target player",
"Incendiary Command deals 2 damage to each creature", "Destroy target nonbasic land",
"Each player discards all cards in his or her hand, then draws that many cards"};
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 9178547049760990376L;
@Override
public void resolve() {
//System.out.println(userChoice);
//System.out.println(m_land[0]);
//System.out.println(m_player[0]);
//"Incendiary Command deals 4 damage to target player",
for (int i = 0; i < card.getChoices().size(); i++) {
if (card.getChoice(i).equals(cardChoice[0])) {
if (card.getChoiceTarget(0).equals(AllZone.getHumanPlayer().getName())) {
setTargetPlayer(AllZone.getHumanPlayer());
} else {
setTargetPlayer(AllZone.getComputerPlayer());
}
getTargetPlayer().addDamage(4, card);
}
}
//"Incendiary Command deals 2 damage to each creature",
if (userChoice.contains(cardChoice[1]) || card.getChoices().contains(cardChoice[1])) {
CardList list = AllZoneUtil.getCreaturesInPlay();
for (int i = 0; i < list.size(); i++) {
list.get(i).addDamage(2, card);
}
}
//"Destroy target nonbasic land",
for (int i = 0; i < card.getChoices().size(); i++) {
if (card.getChoice(i).equals(cardChoice[2])) {
CardList all = AllZoneUtil.getCardsInPlay();
for (int i2 = 0; i2 < all.size(); i2++) {
if (String.valueOf(all.get(i2).getUniqueNumber()).equals(card.getChoiceTarget(card.getChoices().size() - 1))) {
setTargetCard(all.get(i2));
AllZone.getGameAction().destroy(getTargetCard());
}
}
}
}
//"Each player discards all cards in his or her hand, then draws that many cards"
if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3])) {
discardDraw(AllZone.getComputerPlayer());
discardDraw(AllZone.getHumanPlayer());
}
}//resolve()
void discardDraw(Player player) {
CardList hand = AllZoneUtil.getPlayerHand(player);
int n = hand.size();
//technically should let the user discard one card at a time
//in case graveyard order matters
player.discard(n, this, true);
player.drawCards(n);
}
@Override
public boolean canPlayAI() {
return false;
}
};//SpellAbility
final Command setStackDescription = new Command() {
private static final long serialVersionUID = -4833850318955216009L;
public void execute() {
ArrayList<String> a = new ArrayList<String>();
if (userChoice.contains(cardChoice[0]) || card.getChoices().contains(cardChoice[0]))
a.add("deals 4 damage to " + m_player[0]);
if (userChoice.contains(cardChoice[1]) || card.getChoices().contains(cardChoice[1]))
a.add("deals 2 damage to each creature");
if (userChoice.contains(cardChoice[2]) || card.getChoices().contains(cardChoice[2]))
a.add("destroy " + m_land[0]);
if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3]))
a.add("each player discards all cards in his or her hand, then draws that many cards");
String s = a.get(0) + ", " + a.get(1);
spell.setStackDescription(card.getName() + " - " + s);
}
};//Command
final Input targetLand = new Input() {
private static final long serialVersionUID = 1485276539154359495L;
@Override
public void showMessage() {
AllZone.getDisplay().showMessage("Select target nonbasic land");
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
stop();
}
@Override
public void selectCard(Card c, PlayerZone zone) {
if (c.isLand()
&& zone.is(Constant.Zone.Battlefield)
&& !c.isBasicLand()) {
if (card.isCopiedSpell()) card.getChoiceTargets().remove(0);
m_land[0] = c;
spell.setTargetCard(c);
card.setSpellChoiceTarget(String.valueOf(c.getUniqueNumber()));
setStackDescription.execute();
stopSetNext(new Input_PayManaCost(spell));
}//if
}//selectCard()
};//Input targetLand
final Input targetPlayer = new Input() {
private static final long serialVersionUID = -2636869617248434242L;
@Override
public void showMessage() {
AllZone.getDisplay().showMessage("Select target player");
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
stop();
}
@Override
public void selectPlayer(Player player) {
if (card.isCopiedSpell()) card.getChoiceTargets().remove(0);
m_player[0] = player;
spell.setTargetPlayer(player);
card.setSpellChoiceTarget(player.toString());
setStackDescription.execute();
//if user needs to target nonbasic land
if (userChoice.contains(cardChoice[2]) || card.getChoices().contains(cardChoice[2]))
stopSetNext(targetLand);
else {
stopSetNext(new Input_PayManaCost(spell));
}
}//selectPlayer()
};//Input targetPlayer
Input chooseTwoInput = new Input() {
private static final long serialVersionUID = 5625588008756700226L;
@Override
public void showMessage() {
if (card.isCopiedSpell()) {
if (card.getChoices().contains(cardChoice[0])) stopSetNext(targetPlayer);
else if (card.getChoices().contains(cardChoice[2])) stopSetNext(targetLand);
else {
setStackDescription.execute();
stopSetNext(new Input_PayManaCost(spell));
}
} else {
//reset variables
m_player[0] = null;
m_land[0] = null;
card.getChoices().clear();
card.getChoiceTargets().clear();
userChoice.clear();
ArrayList<String> display = new ArrayList<String>();
//get all
CardList list = AllZoneUtil.getCardsInPlay();
CardList land = list.getType("Land");
CardList basicLand = list.getType("Basic");
display.add("Incendiary Command deals 4 damage to target player");
display.add("Incendiary Command deals 2 damage to each creature");
if (land.size() != basicLand.size()) display.add("Destroy target nonbasic land");
display.add("Each player discards all cards in his or her hand, then draws that many cards");
ArrayList<String> a = chooseTwo(display);
//everything stops here if user cancelled
if (a == null) {
stop();
return;
}
userChoice.addAll(a);
if (userChoice.contains(cardChoice[0])) stopSetNext(targetPlayer);
else if (userChoice.contains(cardChoice[2])) stopSetNext(targetLand);
else {
setStackDescription.execute();
stopSetNext(new Input_PayManaCost(spell));
}
}
}//showMessage()
ArrayList<String> chooseTwo(ArrayList<String> choices) {
ArrayList<String> out = new ArrayList<String>();
Object o = GuiUtils.getChoiceOptional("Choose Two", choices.toArray());
if (o == null) return null;
out.add((String) o);
card.addSpellChoice((String) o);
choices.remove(out.get(0));
o = GuiUtils.getChoiceOptional("Choose Two", choices.toArray());
if (o == null) return null;
out.add((String) o);
card.addSpellChoice((String) o);
return out;
}//chooseTwo()
};//Input chooseTwoInput
card.addSpellAbility(spell);
card.setSpellWithChoices(true);
spell.setBeforePayMana(chooseTwoInput);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Parallel Evolution")) {
SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 3456160935845779623L;
@Override
public boolean canPlayAI() {
CardList humTokenCreats = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer());
humTokenCreats = humTokenCreats.filter(AllZoneUtil.token);
CardList compTokenCreats = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer());
compTokenCreats = compTokenCreats.filter(AllZoneUtil.token);
return compTokenCreats.size() > humTokenCreats.size();
}//canPlayAI()
@Override
public void resolve() {
CardList tokens = AllZoneUtil.getCreaturesInPlay();
tokens = tokens.filter(AllZoneUtil.token);
CardFactoryUtil.copyTokens(tokens);
}//resolve()
};//SpellAbility
spell.setDescription("For each creature token on the battlefield, its controller puts a token that's a copy of that creature onto the battlefield.");
spell.setStackDescription("Parallel Evolution - For each creature token on the battlefield, its controller puts a token that's a copy of that creature onto the battlefield.");
card.setFlashback(true);
card.addSpellAbility(spell);
card.addSpellAbility(CardFactoryUtil.ability_Flashback(card, "4 G G G"));
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Global Ruin")) {
final CardList target = new CardList();
final CardList saveList = new CardList();
//need to use arrays so we can declare them final and still set the values in the input and runtime classes. This is a hack.
final int[] index = new int[1];
final int[] countBase = new int[1];
final Vector<String> humanBasic = new Vector<String>();
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 5739127258598357186L;
@Override
public boolean canPlayAI() {
return false;
//should check if computer has land in hand, or if computer has more basic land types than human.
}
@Override
public void resolve() {
//add computer's lands to target
//int computerCountBase = 0;
//Vector<?> computerBasic = new Vector();
//figure out which basic land types the computer has
CardList land = AllZoneUtil.getPlayerLandsInPlay(AllZone.getComputerPlayer());
String basic[] = {"Forest", "Plains", "Mountain", "Island", "Swamp"};
for (int i = 0; i < basic.length; i++) {
CardList cl = land.getType(basic[i]);
if (!cl.isEmpty()) {
//remove one land of this basic type from this list
//the computer AI should really jump in here and select the land which is the best.
//to determine the best look at which lands have enchantments, which lands are tapped
cl.remove(cl.get(0));
//add the rest of the lands of this basic type to the target list, this is the list which will be sacrificed.
target.addAll(cl);
}
}
//need to sacrifice the other non-basic land types
land = land.filter(new CardListFilter() {
public boolean addCard(Card c) {
if (c.getName().contains("Dryad Arbor")) return true;
else if (!(c.isType("Forest")
|| c.isType("Plains")
|| c.isType("Mountain")
|| c.isType("Island")
|| c.isType("Swamp"))) return true;
else return false;
}
});
target.addAll(land);
//when this spell resolves all basic lands which were not selected are sacrificed.
for (int i = 0; i < target.size(); i++)
if (AllZoneUtil.isCardInPlay(target.get(i)) && !saveList.contains(target.get(i)))
AllZone.getGameAction().sacrifice(target.get(i));
}//resolve()
};//SpellAbility
final Input input = new Input() {
private static final long serialVersionUID = 1739423591445361917L;
private int count;
@Override
public void showMessage() { //count is the current index we are on.
//countBase[0] is the total number of basic land types the human has
//index[0] is the number to offset the index by
count = countBase[0] - index[0] - 1; //subtract by one since humanBasic is 0 indexed.
if (count < 0) {
//need to reset the variables in case they cancel this spell and it stays in hand.
humanBasic.clear();
countBase[0] = 0;
index[0] = 0;
stop();
} else {
AllZone.getDisplay().showMessage("Select target " + humanBasic.get(count)
+ " land to not sacrifice");
ButtonUtil.enableOnlyCancel();
}
}
@Override
public void selectButtonCancel() {
stop();
}
@Override
public void selectCard(Card c, PlayerZone zone) {
if (c.isLand() && zone.is(Constant.Zone.Battlefield)
&& c.getController().isHuman()
/*&& c.getName().equals(humanBasic.get(count))*/
&& c.isType(humanBasic.get(count))
/*&& !saveList.contains(c) */) {
//get all other basic[count] lands human player controls and add them to target
CardList land = AllZoneUtil.getPlayerLandsInPlay(AllZone.getHumanPlayer());
CardList cl = land.getType(humanBasic.get(count));
cl = cl.filter(new CardListFilter() {
public boolean addCard(Card crd) {
return !saveList.contains(crd);
}
});
if (!c.getName().contains("Dryad Arbor")) {
cl.remove(c);
saveList.add(c);
}
target.addAll(cl);
index[0]++;
showMessage();
if (index[0] >= humanBasic.size()) stopSetNext(new Input_PayManaCost(spell));
//need to sacrifice the other non-basic land types
land = land.filter(new CardListFilter() {
public boolean addCard(Card c) {
if (c.getName().contains("Dryad Arbor")) return true;
else if (!(c.isType("Forest")
|| c.isType("Plains")
|| c.isType("Mountain")
|| c.isType("Island")
|| c.isType("Swamp"))) return true;
else return false;
}
});
target.addAll(land);
}
}//selectCard()
};//Input
Input runtime = new Input() {
private static final long serialVersionUID = -122635387376995855L;
@Override
public void showMessage() {
countBase[0] = 0;
//figure out which basic land types the human has
//put those in an set to use later
CardList land = AllZoneUtil.getPlayerCardsInPlay(AllZone.getHumanPlayer());
String basic[] = {"Forest", "Plains", "Mountain", "Island", "Swamp"};
for (int i = 0; i < basic.length; i++) {
CardList c = land.getType(basic[i]);
if (!c.isEmpty()) {
humanBasic.add(basic[i]);
countBase[0]++;
}
}
if (countBase[0] == 0) {
//human has no basic land, so don't prompt to select one.
stop();
} else {
index[0] = 0;
target.clear();
stopSetNext(input);
}
}
};//Input
card.addSpellAbility(spell);
spell.setBeforePayMana(runtime);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Gerrard's Verdict")) {
SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 4734024742326763385L;
@Override
public boolean canPlayAI() {
PlayerZone humanHand = AllZone.getZone(Constant.Zone.Hand, AllZone.getHumanPlayer());
if (humanHand.size() >= 2) return true;
else return false;
}
@Override
public void resolve() {
Player player = card.getController();
if (player.isHuman()) humanResolve();
else computerResolve();
}
public void humanResolve() {
CardList list = AllZoneUtil.getPlayerHand(AllZone.getComputerPlayer());
list.shuffle();
if (list.size() == 0) return;
Card c1 = list.get(0);
list.remove(c1);
c1.getController().discard(c1, null);
if (list.size() == 0) return;
Card c2 = list.get(0);
list.remove(c2);
c2.getController().discard(c2, null);
if (c1.isLand()) {
AllZone.getHumanPlayer().gainLife(3, card);
}
if (c2.isLand()) {
AllZone.getHumanPlayer().gainLife(3, card);
}
}//resolve()
public void computerResolve() {
CardList list = AllZoneUtil.getPlayerHand(AllZone.getHumanPlayer());
if (list.size() > 0) {
Object o = GuiUtils.getChoiceOptional("First card to discard", list.toArray());
Card c = (Card) o;
list.remove(c);
c.getController().discard(c, null);
if (c.isLand()) {
AllZone.getComputerPlayer().gainLife(3, card);
}
if (list.size() > 0) {
Object o2 = GuiUtils.getChoiceOptional("Second card to discard", list.toArray());
Card c2 = (Card) o2;
list.remove(c2);
c2.getController().discard(c2, null);
if (c2.isLand()) {
AllZone.getComputerPlayer().gainLife(3, card);
}
}
}
}
};
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Mind Funeral")) {
Cost cost = new Cost("1 U B", cardName, false);
Target tgt = new Target(card, "Select a Player", "Player");
final SpellAbility spell = new Spell(card, cost, tgt) {
private static final long serialVersionUID = 42470566751344693L;
@Override
public boolean canPlayAI() {
setTargetPlayer(AllZone.getHumanPlayer());
CardList libList = AllZoneUtil.getPlayerCardsInLibrary(AllZone.getHumanPlayer());
return libList.size() > 0;
}
@Override
public void resolve() {
Player player = getTargetPlayer();
CardList libList = AllZoneUtil.getPlayerCardsInLibrary(player);
int numLands = libList.getType("Land").size();
int total = 0;
if (numLands > 3) { // if only 3 or less lands in the deck everything is going
int landCount = 0;
for (Card c : libList) {
total++;
if (c.isLand()) {
landCount++;
if (landCount == 4)
break;
}
}
} else {
total = libList.size();
}
player.mill(total);
}
};//SpellAbility
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Haunting Echoes")) {
Cost cost = new Cost("3 B B", cardName, false);
Target tgt = new Target(card, "Select a Player", "Player");
final SpellAbility spell = new Spell(card, cost, tgt) {
private static final long serialVersionUID = 42470566751344693L;
@Override
public boolean canPlayAI() {
// Haunting Echoes shouldn't be cast if only basic land in graveyard or library is empty
CardList graveyard = AllZoneUtil.getPlayerGraveyard(AllZone.getHumanPlayer());
CardList library = AllZoneUtil.getPlayerCardsInLibrary(AllZone.getHumanPlayer());
int graveCount = graveyard.size();
graveyard = graveyard.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.isBasicLand();
}
});
setTargetPlayer(AllZone.getHumanPlayer());
return ((graveCount - graveyard.size() > 0) && library.size() > 0);
}
@Override
public void resolve() {
Player player = getTargetPlayer();
CardList grave = AllZoneUtil.getPlayerGraveyard(player);
grave = grave.getNotType("Basic");
CardList lib = AllZoneUtil.getPlayerCardsInLibrary(player);
for (Card c : grave) {
CardList remLib = lib.getName(c.getName());
for (Card rem : remLib) {
AllZone.getGameAction().exile(rem);
lib.remove(rem);
}
AllZone.getGameAction().exile(c);
}
}
};//SpellAbility
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Donate")) {
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 782912579034503349L;
@Override
public void resolve() {
Card c = getTargetCard();
if (c != null && AllZoneUtil.isCardInPlay(c) && CardFactoryUtil.canTarget(card, c)) {
// Donate should target both the player and the creature
if (!c.isAura()) {
AllZone.getGameAction().changeController(new CardList(c), c.getController(), c.getController().getOpponent());
} else //Aura
{
c.setController(card.getController().getOpponent());
}
}
}
@Override
public boolean canPlayAI() {
CardList list = AllZoneUtil.getPlayerCardsInPlay(AllZone.getComputerPlayer(), "Illusions of Grandeur");
if (list.size() > 0) {
setTargetCard(list.get(0));
return true;
}
return false;
}
};
Input runtime = new Input() {
private static final long serialVersionUID = -7823269301012427007L;
@Override
public void showMessage() {
CardList perms = AllZoneUtil.getPlayerCardsInPlay(AllZone.getHumanPlayer());
perms = perms.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.isPermanent() && !c.getName().equals("Mana Pool");
}
});
boolean free = false;
if (this.isFree()) free = true;
stopSetNext(CardFactoryUtil.input_targetSpecific(spell, perms,
"Select a permanent you control", true, free));
}//showMessage()
};//Input
spell.setBeforePayMana(runtime);
card.addSpellAbility(spell);
}//*************** END ************ END **************************
/*
//********************Start********Start***********************
else if(cardName.equals("Living Death"))
{
final SpellAbility spell = new Spell(card)
{
private static final long serialVersionUID = -7657135492744579098L;
public void resolve()
{ //grab make 4 creature lists: human_play, human_graveyard, computer_play, computer_graveyard
CardList human_play = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer());
CardList human_graveyard = AllZoneUtil.getPlayerGraveyard(AllZone.getHumanPlayer());
human_graveyard = human_graveyard.filter(AllZoneUtil.creatures);
CardList computer_play = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer());
CardList computer_graveyard = AllZoneUtil.getPlayerGraveyard(AllZone.getComputerPlayer());
computer_graveyard = computer_graveyard.filter(AllZoneUtil.creatures);
//TODO - the following code doesn't look like it's doing what it should to me...
Card c = new Card();
Iterator<Card> it = human_play.iterator();
while(it.hasNext())
{
c = it.next();
AllZone.getGameAction().moveTo(AllZone.getHumanBattlefield(),c);
AllZone.getGameAction().moveTo(AllZone.getHumanGraveyard(),c);
}
it = human_graveyard.iterator();
while(it.hasNext())
{
c = it.next();
AllZone.getGameAction().moveTo(AllZone.getHumanGraveyard(),c);
AllZone.getGameAction().moveTo(AllZone.getHumanBattlefield(),c);
}
it = computer_play.iterator();
while(it.hasNext())
{
c = it.next();
AllZone.getGameAction().moveTo(AllZone.getComputerBattlefield(),c);
AllZone.getGameAction().moveTo(AllZone.getComputerGraveyard(),c);
}
it = computer_graveyard.iterator();
while(it.hasNext())
{
c = it.next();
AllZone.getGameAction().moveTo(AllZone.getComputerGraveyard(),c);
AllZone.getGameAction().moveTo(AllZone.getComputerBattlefield(),c);
}
}//resolve
};//spellability
card.addSpellAbility(spell);
}//*********************END**********END***********************
*/
//*************** START *********** START **************************
else if (cardName.equals("Balance")) {
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -5941893280103164961L;
public void resolve() {
//Lands:
CardList humLand = AllZoneUtil.getPlayerLandsInPlay(AllZone.getHumanPlayer());
CardList compLand = AllZoneUtil.getPlayerLandsInPlay(AllZone.getComputerPlayer());
if (compLand.size() > humLand.size()) {
compLand.shuffle();
for (int i = 0; i < compLand.size() - humLand.size(); i++)
AllZone.getGameAction().sacrifice(compLand.get(i));
} else if (humLand.size() > compLand.size()) {
int diff = humLand.size() - compLand.size();
AllZone.getInputControl().setInput(PlayerUtil.input_sacrificePermanents(diff, "Land"));
}
//Hand
CardList humHand = AllZoneUtil.getPlayerHand(AllZone.getHumanPlayer());
CardList compHand = AllZoneUtil.getPlayerHand(AllZone.getComputerPlayer());
int handDiff = Math.abs(humHand.size() - compHand.size());
if (compHand.size() > humHand.size()) {
AllZone.getComputerPlayer().discard(handDiff, this, false);
} else if (humHand.size() > compHand.size()) {
AllZone.getHumanPlayer().discard(handDiff, this, false);
}
//Creatures:
CardList humCreats = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer());
CardList compCreats = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer());
if (compCreats.size() > humCreats.size()) {
CardListUtil.sortAttackLowFirst(compCreats);
CardListUtil.sortCMC(compCreats);
compCreats.reverse();
for (int i = 0; i < compCreats.size() - humCreats.size(); i++)
AllZone.getGameAction().sacrifice(compCreats.get(i));
} else if (humCreats.size() > compCreats.size()) {
int diff = humCreats.size() - compCreats.size();
AllZone.getInputControl().setInput(PlayerUtil.input_sacrificePermanents(diff, "Creature"));
}
}
public boolean canPlayAI() {
int diff = 0;
CardList humLand = AllZoneUtil.getPlayerLandsInPlay(AllZone.getHumanPlayer());
CardList compLand = AllZoneUtil.getPlayerLandsInPlay(AllZone.getComputerPlayer());
diff += humLand.size() - compLand.size();
CardList humCreats = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer());
CardList compCreats = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer());
compCreats = compCreats.getType("Creature");
diff += 1.5 * (humCreats.size() - compCreats.size());
CardList humHand = AllZoneUtil.getPlayerHand(AllZone.getHumanPlayer());
CardList compHand = AllZoneUtil.getPlayerHand(AllZone.getComputerPlayer());
diff += 0.5 * (humHand.size() - compHand.size());
return diff > 2;
}
};
card.addSpellAbility(spell);
}
//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Summer Bloom")) {
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 5559004016728325736L;
public boolean canPlayAI() {
// The computer should only play this card if it has at least
// one land in its hand. Because of the way the computer turn
// is structured, it will already have played land to it's limit
CardList hand = AllZoneUtil.getPlayerHand(AllZone.getComputerPlayer());
hand = hand.getType("Land");
return hand.size() > 0;
}
public void resolve() {
final Player thePlayer = card.getController();
thePlayer.addMaxLandsToPlay(3);
Command untilEOT = new Command() {
private static final long serialVersionUID = 1665720009691293263L;
public void execute() {
thePlayer.addMaxLandsToPlay(-3);
}
};
AllZone.getEndOfTurn().addUntil(untilEOT);
}
};
card.addSpellAbility(spell);
card.setSVar("PlayMain1", "TRUE");
} //*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Explore")) {
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 8377957584738695517L;
public boolean canPlayAI() {
// The computer should only play this card if it has at least
// one land in its hand. Because of the way the computer turn
// is structured, it will already have played its first land.
CardList list = AllZoneUtil.getPlayerHand(AllZone.getComputerPlayer());
list = list.getType("Land");
if (list.size() > 0)
return true;
else
return false;
}
public void resolve() {
final Player thePlayer = card.getController();
thePlayer.addMaxLandsToPlay(1);
Command untilEOT = new Command() {
private static final long serialVersionUID = -2618916698575607634L;
public void execute() {
thePlayer.addMaxLandsToPlay(-1);
}
};
AllZone.getEndOfTurn().addUntil(untilEOT);
thePlayer.drawCard();
}
};
card.addSpellAbility(spell);
card.setSVar("PlayMain1", "TRUE");
} //*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Haunting Misery")) {
Cost cost = new Cost("1 B B", cardName, false);
Target tgt = new Target(card, "Select a Player", "Player");
final SpellAbility spell = new Spell(card, cost, tgt) {
private static final long serialVersionUID = 6867051257656060195L;
@Override
public void resolve() {
Player player = card.getController();
Player tPlayer = getTargetPlayer();
CardList graveList = AllZoneUtil.getPlayerTypeInGraveyard(player, "Creature");
int size = graveList.size();
int damage = 0;
if (player.isHuman()) {
for (int i = 0; i < size; i++) {
Object o = GuiUtils.getChoice("Exile from graveyard", graveList.toArray());
if (o == null) break;
damage++; // tally up how many cards removed
Card c_1 = (Card) o;
graveList.remove(c_1); //remove from the display list
AllZone.getGameAction().exile(c_1);
}
} else { //Computer
// it would be nice if the computer chose vanilla creatures over
for (int j = 0; j < size; j++) {
AllZone.getGameAction().exile(graveList.get(j));
}
}
tPlayer.addDamage(damage, card);
}
@Override
public void chooseTargetAI() {
setTargetPlayer(AllZone.getHumanPlayer());
}//chooseTargetAI()
@Override
public boolean canPlayAI() {
CardList graveList = AllZoneUtil.getPlayerTypeInGraveyard(AllZone.getHumanPlayer(), "Creature");
int humanLife = AllZone.getHumanPlayer().getLife();
return (graveList.size() > 5 || graveList.size() > humanLife);
}
};
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Brood Birthing")) {
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -8303724057068847270L;
public void resolve() {
int times = 1;
CardList cl;
if (AllZoneUtil.getPlayerCardsInPlay(card.getController(), "Eldrazi Spawn").size() > 0)
times = 3;
for (int i = 0; i < times; i++) {
cl = CardFactoryUtil.makeToken("Eldrazi Spawn", "C 0 1 Eldrazi Spawn", card.getController(), "", new String[]{
"Creature", "Eldrazi", "Spawn"}, 0, 1, new String[]{});
for (Card crd : cl)
crd.addSpellAbility(CardFactoryUtil.getEldraziSpawnAbility(crd));
}
}
};
StringBuilder sb = new StringBuilder();
sb.append(cardName).append(" - ").append(card.getController());
sb.append(" puts one or three 0/1 Eldrazi Spawn creature tokens onto the battlefield.");
spell.setStackDescription(sb.toString());
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Explosive Revelation")) {
/*
* Choose target creature or player. Reveal cards from the top of
* your library until you reveal a nonland card. Explosive Revelation
* deals damage equal to that card's converted mana cost to that
* creature or player. Put the nonland card into your hand and the
* rest on the bottom of your library in any order.
*/
Cost cost = new Cost(card.getManaCost(), cardName, false);
Target tgt = new Target(card, "CP");
final SpellAbility spell = new Spell(card, cost, tgt) {
private static final long serialVersionUID = -3234630801871872940L;
int damage = 3;
Card check;
@Override
public boolean canPlayAI() {
if (AllZone.getHumanPlayer().getLife() <= damage) return true;
check = getFlying();
return check != null;
}
@Override
public void chooseTargetAI() {
if (AllZone.getHumanPlayer().getLife() <= damage) {
setTargetPlayer(AllZone.getHumanPlayer());
return;
}
Card c = getFlying();
if ((c == null) || (!check.equals(c))) throw new RuntimeException(card
+ " error in chooseTargetAI() - Card c is " + c + ", Card check is " + check);
setTargetCard(c);
}//chooseTargetAI()
//uses "damage" variable
Card getFlying() {
CardList flying = CardFactoryUtil.AI_getHumanCreature("Flying", card, true);
for (int i = 0; i < flying.size(); i++)
if (flying.get(i).getNetDefense() <= damage) return flying.get(i);
return null;
}
@Override
public void resolve() {
int damage = getDamage();
if (getTargetCard() != null) {
if (AllZoneUtil.isCardInPlay(getTargetCard())
&& CardFactoryUtil.canTarget(card, getTargetCard())) {
javax.swing.JOptionPane.showMessageDialog(null, cardName + " causes " + damage
+ " to " + getTargetCard());
Card c = getTargetCard();
c.addDamage(damage, card);
}
} else {
javax.swing.JOptionPane.showMessageDialog(null, cardName + " causes " + damage
+ " to " + getTargetPlayer());
getTargetPlayer().addDamage(damage, card);
}
//System.out.println("Library after: "+AllZoneUtil.getPlayerCardsInLibrary(card.getController()));
}
int getDamage() {
/*
* Reveal cards from the top of
* your library until you reveal a nonland card.
*/
CardList lib = AllZoneUtil.getPlayerCardsInLibrary(card.getController());
Log.debug("Explosive Revelation", "Library before: " + lib);
CardList revealed = new CardList();
if (lib.size() > 0) {
int index = 0;
Card top;
do {
top = lib.get(index);
//System.out.println("Got from top of library:"+top);
index += 1;
revealed.add(top);
} while (index < lib.size() && top.isLand());
//Display the revealed cards
GuiUtils.getChoice("Revealed cards:", revealed.toArray());
//non-land card into hand
AllZone.getGameAction().moveToHand(revealed.get(revealed.size() - 1));
//put the rest of the cards on the bottom of library
for (int j = 0; j < revealed.size() - 1; j++) {
AllZone.getGameAction().moveToBottomOfLibrary(revealed.get(j));
}
//return the damage
//System.out.println("Explosive Revelation does "+CardUtil.getConvertedManaCost(top)+" from: "+top);
return CardUtil.getConvertedManaCost(top);
}
return 0;
}
};//SpellAbility
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Fireball")) {
/*
* Fireball deals X damage divided evenly, rounded down, among
* any number of target creatures and/or players.
* Fireball costs 1 more to cast for each target beyond the first.
*/
final CardList targets = new CardList();
final ArrayList<Player> targetPlayers = new ArrayList<Player>();
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -6293612568525319357L;
@Override
public boolean canPlayAI() {
final int maxX = ComputerUtil.getAvailableMana().size() - 1;
int humanLife = AllZone.getHumanPlayer().getLife();
if (maxX >= humanLife) {
targetPlayers.add(AllZone.getHumanPlayer());
return true;
}
return false;
}
@Override
public void resolve() {
int damage = (card.getXManaCostPaid() - getNumTargets() + 1) / getNumTargets();
//add that much damage to each creature
//DEBUG
Log.debug("Fireball", "Fireball - damage to each target: " + damage);
Log.debug("Fireball", "Fireball - card targets: ");
printCardTargets();
Log.debug("Fireball", "Fireball - player targets: ");
printPlayerTargets();
if (card.getController().isComputer()) {
StringBuilder sb = new StringBuilder();
sb.append(cardName + " - Computer causes " + damage + " to:\n\n");
for (int i = 0; i < targets.size(); i++) {
Card target = targets.get(i);
if (AllZoneUtil.isCardInPlay(target) && CardFactoryUtil.canTarget(card, target)) {
sb.append(target + "\n");
}
}
for (int i = 0; i < targetPlayers.size(); i++) {
Player p = targetPlayers.get(i);
if (p.canTarget(card)) {
sb.append(p + "\n");
}
}
javax.swing.JOptionPane.showMessageDialog(null, sb.toString());
}
for (int i = 0; i < targets.size(); i++) {
Card target = targets.get(i);
if (AllZoneUtil.isCardInPlay(target) && CardFactoryUtil.canTarget(card, target)) {
//DEBUG
Log.debug("Fireball", "Fireball does " + damage + " to: " + target);
target.addDamage(damage, card);
}
}
for (int i = 0; i < targetPlayers.size(); i++) {
Player p = targetPlayers.get(i);
if (p.canTarget(card)) {
//DEBUG
Log.debug("Fireball", "Fireball does " + damage + " to: " + p);
p.addDamage(damage, card);
}
}
}//resolve()
//DEBUG
private void printCardTargets() {
StringBuilder sb = new StringBuilder("[");
for (Card target : targets) {
sb.append(target).append(",");
}
sb.append("]");
Log.debug("Fireball", sb.toString());
}
//DEBUG
private void printPlayerTargets() {
StringBuilder sb = new StringBuilder("[");
for (Player p : targetPlayers) {
sb.append(p).append(",");
}
sb.append("]");
Log.debug("Fireball", sb.toString());
}
private int getNumTargets() {
int numTargets = 0;
numTargets += targets.size();
numTargets += targetPlayers.size();
return numTargets;
}
};//SpellAbility
final Input input = new Input() {
private static final long serialVersionUID = 1099272655273322957L;
@Override
public void showMessage() {
AllZone.getDisplay().showMessage("Select target creatures and/or players. Currently, " + getNumTargets() + " targets. Click OK when done.");
}
private int getNumTargets() {
int numTargets = 0;
numTargets += targets.size();
numTargets += targetPlayers.size();
//DEBUG
Log.debug("Fireball", "Fireball - numTargets = " + numTargets);
return numTargets;
}
@Override
public void selectButtonCancel() {
targets.clear();
targetPlayers.clear();
stop();
}
@Override
public void selectButtonOK() {
spell.setStackDescription(cardName + " deals X damage to " + getNumTargets() + " target(s).");
stopSetNext(new Input_PayManaCost(spell));
}
@Override
public void selectCard(Card c, PlayerZone zone) {
if (!CardFactoryUtil.canTarget(card, c)) {
AllZone.getDisplay().showMessage("Cannot target this card.");
return; //cannot target
}
if (targets.contains(c)) {
AllZone.getDisplay().showMessage("You have already selected this target.");
return; //cannot target the same creature twice.
}
if (c.isCreature() && zone.is(Constant.Zone.Battlefield)) {
targets.add(c);
showMessage();
}
}//selectCard()
@Override
public void selectPlayer(Player player) {
if (!player.canTarget(card)) {
AllZone.getDisplay().showMessage("Cannot target this card.");
return; //cannot target
}
if (targetPlayers.contains(player)) {
AllZone.getDisplay().showMessage("You have already selected this player.");
return; //cannot target the same player twice.
}
targetPlayers.add(player);
showMessage();
}
};//Input
card.addSpellAbility(spell);
spell.setBeforePayMana(input);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Recall")) {
/*
* Discard X cards, then return a card from your graveyard to your
* hand for each card discarded this way. Exile Recall.
*/
Cost cost = new Cost(card.getManaCost(), cardName, false);
final SpellAbility spell = new Spell(card, cost, null) {
private static final long serialVersionUID = -3935814273439962834L;
@Override
public boolean canPlayAI() {
//for compy to play this wisely, it should check hand, and if there
//are no spells that canPlayAI(), then use recall. maybe.
return false;
}
@Override
public void resolve() {
int numCards = card.getXManaCostPaid();
final Player player = card.getController();
int maxCards = AllZoneUtil.getPlayerHand(player).size();
if (numCards != 0) {
numCards = Math.min(numCards, maxCards);
if (player.isHuman()) {
AllZone.getInputControl().setInput(CardFactoryUtil.input_discardRecall(numCards, card, this));
}
}
/*else { //computer
card.getControler().discardRandom(numCards);
AllZone.getGameAction().exile(card);
CardList grave = AllZoneUtil.getPlayerGraveyard(card.getController());
for(int i = 1; i <= numCards; i ++) {
Card t1 = CardFactoryUtil.AI_getBestCreature(grave);
if(null != t1) {
t1 = grave.get(0);
grave.remove(t1);
AllZone.getGameAction().moveToHand(t1);
}
}
}*/
}//resolve()
};//SpellAbility
StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - discard X cards and return X cards to your hand.");
spell.setStackDescription(sb.toString());
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Windfall")) {
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -7707012960887790709L;
@Override
public boolean canPlayAI() {
/*
* We want compy to have less cards in hand than the human
*/
CardList Hhand = AllZoneUtil.getPlayerHand(AllZone.getHumanPlayer());
CardList Chand = AllZoneUtil.getPlayerHand(AllZone.getComputerPlayer());
return Chand.size() < Hhand.size();
}
@Override
public void resolve() {
CardList Hhand = AllZoneUtil.getPlayerHand(AllZone.getHumanPlayer());
CardList Chand = AllZoneUtil.getPlayerHand(AllZone.getComputerPlayer());
int num = Math.max(Hhand.size(), Chand.size());
discardDraw(AllZone.getHumanPlayer(), num);
discardDraw(AllZone.getComputerPlayer(), num);
}//resolve()
void discardDraw(Player player, int num) {
player.discardHand(this);
player.drawCards(num);
}
};//SpellAbility
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Stitch Together")) {
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -57996914115026814L;
@Override
public void resolve() {
CardList threshold = AllZoneUtil.getPlayerGraveyard(card.getController());
Card c = getTargetCard();
if (threshold.size() >= 7) {
if (AllZoneUtil.isCardInPlayerGraveyard(card.getController(), c)) {
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, card.getController());
AllZone.getGameAction().moveTo(play, c);
}
} else {
if (AllZoneUtil.isCardInPlayerGraveyard(card.getController(), c)) {
PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, card.getController());
AllZone.getGameAction().moveTo(hand, c);
}
}
}//resolve()
@Override
public boolean canPlay() {
return getCreatures().length != 0;
}
public boolean canPlayAI() {
CardList check = AllZoneUtil.getPlayerGraveyard(card.getController());
return getCreaturesAI().length != 0 || check.size() >= 7;
}
public Card[] getCreatures() {
CardList creature = AllZoneUtil.getPlayerTypeInGraveyard(card.getController(), "Creature");
return creature.toArray();
}
public Card[] getCreaturesAI() {
CardList creature = AllZoneUtil.getPlayerTypeInGraveyard(card.getController(), "Creature");
creature = creature.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.getNetAttack() > 4;
}
});
return creature.toArray();
}
@Override
public void chooseTargetAI() {
Card c[] = getCreatures();
Card biggest = c[0];
for (int i = 0; i < c.length; i++)
if (biggest.getNetAttack() < c[i].getNetAttack()) biggest = c[i];
setTargetCard(biggest);
}
};//SpellAbility
card.addSpellAbility(spell);
Input target = new Input() {
private static final long serialVersionUID = -3717723884199321767L;
@Override
public void showMessage() {
CardList creature = AllZoneUtil.getPlayerTypeInGraveyard(card.getController(), "Creature");
Object check = GuiUtils.getChoiceOptional("Select creature", creature);
if (check != null) {
spell.setTargetCard((Card) check);
stopSetNext(new Input_PayManaCost(spell));
} else stop();
}//showMessage()
};//Input
spell.setBeforePayMana(target);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Patriarch's Bidding")) {
final String[] input = new String[2];
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -2182173662547136798L;
@Override
public void resolve() {
input[0] = "";
while (input[0] == "") {
input[0] = JOptionPane.showInputDialog(null, "Which creature type?", "Pick type",
JOptionPane.QUESTION_MESSAGE);
if (input[0] == null) break;
if (!CardUtil.isACreatureType(input[0])) input[0] = "";
//TODO: some more input validation, case-sensitivity, etc.
input[0] = input[0].trim(); //this is to prevent "cheating", and selecting multiple creature types,eg "Goblin Soldier"
}
if (input[0] == null) input[0] = "";
HashMap<String, Integer> countInGraveyard = new HashMap<String, Integer>();
CardList allGrave = AllZoneUtil.getPlayerGraveyard(AllZone.getComputerPlayer());
allGrave.getType("Creature");
for (Card c : allGrave) {
for (String type : c.getType()) {
if (CardUtil.isACreatureType(type)) {
if (countInGraveyard.containsKey(type)) {
countInGraveyard.put(type, countInGraveyard.get(type) + 1);
} else {
countInGraveyard.put(type, 1);
}
}
}
}
String maxKey = "";
int maxCount = -1;
for (Entry<String, Integer> entry : countInGraveyard.entrySet()) {
if (entry.getValue() > maxCount) {
maxKey = entry.getKey();
maxCount = entry.getValue();
}
}
if (!maxKey.equals("")) input[1] = maxKey;
else input[1] = "Sliver";
//Actually put everything on the battlefield
CardList bidded = AllZoneUtil.getCardsInGraveyard();
bidded = bidded.getType("Creature");
for (Card c : bidded) {
if (c.isType(input[1]) || (!input[0].equals("") && c.isType(input[0])))
AllZone.getGameAction().moveToPlay(c);
}
}//resolve()
};//SpellAbility
card.addSpellAbility(spell);
StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - choose a creature type.");
spell.setStackDescription(sb.toString());
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Leeches")) {
/*
* Target player loses all poison counters.
* Leeches deals that much damage to that player.
*/
final Target tgt = new Target(card, "Select target player", "Player");
Cost cost = new Cost("1 W W", cardName, false);
SpellAbility spell = new Spell(card, cost, tgt) {
private static final long serialVersionUID = 8555498267738686288L;
@Override
public void resolve() {
Player p = tgt.getTargetPlayers().get(0);
int counters = p.getPoisonCounters();
p.addDamage(counters, card);
p.subtractPoisonCounters(counters);
}// resolve()
@Override
public boolean canPlayAI() {
int humanPoison = AllZone.getHumanPlayer().getPoisonCounters();
int compPoison = AllZone.getComputerPlayer().getPoisonCounters();
if (AllZone.getHumanPlayer().getLife() <= humanPoison) {
tgt.addTarget(AllZone.getHumanPlayer());
return true;
}
if ((2 * (11 - compPoison) < AllZone.getComputerPlayer().getLife() || compPoison > 7) && compPoison < AllZone.getComputerPlayer().getLife() - 2) {
tgt.addTarget(AllZone.getComputerPlayer());
return true;
}
return false;
}
};// SpellAbility
card.addSpellAbility(spell);
}// *************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Cerebral Eruption")) {
/*
* Target opponent reveals the top card of his or her library.
* Cerebral Eruption deals damage equal to the revealed card's
* converted mana cost to that player and each creature he or
* she controls. If a land card is revealed this way, return
* Cerebral Eruption to its owner's hand.
*/
SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -1365692178841929046L;
@Override
public void resolve() {
Player player = card.getController();
Player opponent = player.getOpponent();
CardList lib = AllZoneUtil.getPlayerCardsInLibrary(opponent);
if (lib.size() > 0) {
final Card topCard = lib.get(0);
int damage = CardUtil.getConvertedManaCost(topCard);
GuiUtils.getChoiceOptional(card + " - Revealed card", new Card[]{topCard});
//deal damage to player
opponent.addDamage(damage, card);
//deal damage to all opponent's creatures
CardList creatures = AllZoneUtil.getCreaturesInPlay(opponent);
for (Card creature : creatures) {
creature.addDamage(damage, card);
}
card.addReplaceMoveToGraveyardCommand(new Command() {
private static final long serialVersionUID = -5912663572746146726L;
public void execute() {
if (null != topCard && topCard.isLand()) {
AllZone.getGameAction().moveToHand(card);
} else AllZone.getGameAction().moveToGraveyard(card);
}
});
}
}// resolve()
@Override
public boolean canPlayAI() {
return AllZoneUtil.getPlayerCardsInLibrary(AllZone.getHumanPlayer()).size() > 0;
}
};// SpellAbility
card.addSpellAbility(spell);
}// *************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Sanity Grinding")) {
/*
* Chroma - Reveal the top ten cards of your library. For each blue
* mana symbol in the mana costs of the revealed cards, target opponent
* puts the top card of his or her library into his or her graveyard.
* Then put the cards you revealed this way on the bottom of your
* library in any order.
*/
SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 4475834103787262421L;
@Override
public void resolve() {
Player player = card.getController();
Player opp = player.getOpponent();
PlayerZone lib = AllZone.getZone(Constant.Zone.Library, card.getController());
int maxCards = lib.size();
maxCards = Math.min(maxCards, 10);
if (maxCards == 0) return;
CardList topCards = new CardList();
//show top n cards:
for (int j = 0; j < maxCards; j++) {
topCards.add(lib.get(j));
}
final int num = CardFactoryUtil.getNumberOfManaSymbolsByColor("U", topCards);
GuiUtils.getChoiceOptional("Revealed cards - " + num + " U mana symbols", topCards.toArray());
//opponent moves this many cards to graveyard
opp.mill(num);
//then, move revealed cards to bottom of library
for (Card c : topCards) {
AllZone.getGameAction().moveToBottomOfLibrary(c);
}
}// resolve()
@Override
public boolean canPlayAI() {
return AllZoneUtil.getPlayerCardsInLibrary(AllZone.getComputerPlayer()).size() > 0;
}
};// SpellAbility
card.addSpellAbility(spell);
}// *************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Winds of Change")) {
/*
* Each player shuffles the cards from his or her hand into
* his or her library, then draws that many cards.
*/
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 1137557863607126794L;
@Override
public void resolve() {
discardDrawX(AllZone.getHumanPlayer());
discardDrawX(AllZone.getComputerPlayer());
}//resolve()
void discardDrawX(Player player) {
CardList hand = AllZoneUtil.getPlayerHand(player);
for (Card c : hand)
AllZone.getGameAction().moveToLibrary(c);
// Shuffle library
player.shuffle();
player.drawCards(hand.size());
}
// Simple, If computer has two or less playable cards remaining in hand play Winds of Change
@Override
public boolean canPlayAI() {
CardList c = AllZoneUtil.getPlayerCardsInPlay(AllZone.getComputerPlayer());
c = c.filter(AllZoneUtil.nonlands);
return 2 >= c.size();
}
};//SpellAbility
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Molten Psyche")) {
/*
* Each player shuffles the cards from his or her hand into his
* or her library, then draws that many cards.
* Metalcraft - If you control three or more artifacts, Molten
* Psyche deals damage to each opponent equal to the number of
* cards that player has drawn this turn.
*/
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -1276674329039279896L;
@Override
public void resolve() {
Player player = card.getController();
Player opp = player.getOpponent();
discardDraw(AllZone.getHumanPlayer());
discardDraw(AllZone.getComputerPlayer());
if (player.hasMetalcraft()) {
opp.addDamage(opp.getNumDrawnThisTurn(), card);
}
}//resolve()
void discardDraw(Player player) {
CardList hand = AllZoneUtil.getPlayerHand(player);
int numDraw = hand.size();
//move hand to library
for (Card c : hand) {
AllZone.getGameAction().moveToLibrary(c);
}
// Shuffle library
player.shuffle();
// Draw X cards
player.drawCards(numDraw);
}
// Simple, If computer has two or less playable cards remaining in hand play CARDNAME
@Override
public boolean canPlayAI() {
CardList c = AllZoneUtil.getPlayerHand(AllZone.getComputerPlayer());
c = c.filter(AllZoneUtil.nonlands);
return 2 >= c.size() ||
(AllZone.getComputerPlayer().hasMetalcraft() && AllZone.getHumanPlayer().getLife() <= 3);
}
};//SpellAbility
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Austere Command")) {
final ArrayList<String> userChoice = new ArrayList<String>();
final String[] cardChoices = {
"Destroy all artifacts",
"Destroy all enchantments",
"Destroy all creatures with converted mana cost 3 or less",
"Destroy all creatures with converted mana cost 4 or more"
};
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -8501457363981482513L;
@Override
public void resolve() {
//"Destroy all artifacts",
if (userChoice.contains(cardChoices[0])) {
CardList cards = AllZoneUtil.getCardsInPlay().filter(AllZoneUtil.artifacts);
for (Card c : cards) AllZone.getGameAction().destroy(c);
}
//"Destroy all enchantments",
if (userChoice.contains(cardChoices[1])) {
CardList cards = AllZoneUtil.getCardsInPlay().filter(AllZoneUtil.enchantments);
for (Card c : cards) AllZone.getGameAction().destroy(c);
}
//"Destroy all creatures with converted mana cost 3 or less",
if (userChoice.contains(cardChoices[2])) {
CardList cards = AllZoneUtil.getCreaturesInPlay();
cards = cards.filter(new CardListFilter() {
public boolean addCard(Card c) {
return CardUtil.getConvertedManaCost(c) <= 3;
}
});
for (Card c : cards) AllZone.getGameAction().destroy(c);
}
//"Destroy all creatures with converted mana cost 4 or more"};
if (userChoice.contains(cardChoices[3])) {
CardList cards = AllZoneUtil.getCreaturesInPlay();
cards = cards.filter(new CardListFilter() {
public boolean addCard(Card c) {
return CardUtil.getConvertedManaCost(c) >= 4;
}
});
for (Card c : cards) AllZone.getGameAction().destroy(c);
}
}//resolve()
@Override
public boolean canPlayAI() {
return false;
}
};//SpellAbility
final Command setStackDescription = new Command() {
private static final long serialVersionUID = -635710110379729475L;
public void execute() {
ArrayList<String> a = new ArrayList<String>();
if (userChoice.contains(cardChoices[0])) a.add("destroy all artifacts");
if (userChoice.contains(cardChoices[1])) a.add("destroy all enchantments");
if (userChoice.contains(cardChoices[2])) a.add("destroy all creatures with CMC <= 3");
if (userChoice.contains(cardChoices[3])) a.add("destroy all creatures with CMC >= 4");
String s = a.get(0) + ", " + a.get(1);
spell.setStackDescription(card.getName() + " - " + s);
}
};//Command
Input chooseTwoInput = new Input() {
private static final long serialVersionUID = 2352497236500922820L;
@Override
public void showMessage() {
if (card.isCopiedSpell()) {
setStackDescription.execute();
stopSetNext(new Input_PayManaCost(spell));
} else {
//reset variables
userChoice.clear();
ArrayList<String> display = new ArrayList<String>(Arrays.asList(cardChoices));
ArrayList<String> a = chooseTwo(display);
//everything stops here if user cancelled
if (a == null) {
stop();
return;
}
userChoice.addAll(a);
setStackDescription.execute();
stopSetNext(new Input_PayManaCost(spell));
}
}//showMessage()
ArrayList<String> chooseTwo(ArrayList<String> choices) {
ArrayList<String> out = new ArrayList<String>();
Object o = GuiUtils.getChoiceOptional("Choose Two", choices.toArray());
if (o == null) return null;
out.add((String) o);
choices.remove(out.get(0));
o = GuiUtils.getChoiceOptional("Choose Two", choices.toArray());
if (o == null) return null;
out.add((String) o);
return out;
}//chooseTwo()
};//Input chooseTwoInput
card.addSpellAbility(spell);
spell.setBeforePayMana(chooseTwoInput);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Praetor's Counsel")) {
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 2208683667850222369L;
@Override
public boolean canPlayAI() {
return false;
}
@Override
public void resolve() {
Player player = card.getController();
CardList grave = AllZoneUtil.getPlayerGraveyard(player);
for (Card c : grave) AllZone.getGameAction().moveToHand(c);
AllZone.getGameAction().exile(card);
card.setSVar("HSStamp", "" + Player.getHandSizeStamp());
player.addHandSizeOperation(new HandSizeOp("=", -1, Integer.parseInt(card.getSVar("HSStamp"))));
}
};//SpellAbility
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Profane Command")) {
//not sure what to call variables, so I just made up something
final Player[] ab0player = new Player[1];
final Card[] ab1card = new Card[1];
final Card[] ab2card = new Card[1];
final ArrayList<Card> ab3cards = new ArrayList<Card>();
final int x[] = new int[1];
final ArrayList<String> userChoice = new ArrayList<String>();
final String[] cardChoice = {
"Target player loses X life",
"Return target creature card with converted mana cost X or less from your graveyard to the battlefield",
"Target creature gets -X/-X until end of turn",
"Up to X target creatures gain fear until end of turn"
};
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = -2924301460675657126L;
@Override
public void resolve() {
//System.out.println(userChoice);
//System.out.println("0: "+ab0player[0]);
//System.out.println("1: "+ab1card[0]);
//System.out.println("2: "+ab2card[0]);
//System.out.println("3: "+ab3cards);
//"Target player loses X life",
for (int i = 0; i < card.getChoices().size(); i++) {
if (card.getChoice(i).equals(cardChoice[0])) {
if (ab0player[0] != null) {
setTargetPlayer(ab0player[0]);
if (getTargetPlayer().canTarget(card)) {
getTargetPlayer().addDamage(x[0], card);
}
}
}
}
//"Return target creature card with converted mana cost X or less from your graveyard to the battlefield",
if (userChoice.contains(cardChoice[1]) || card.getChoices().contains(cardChoice[1])) {
Card c = ab1card[0];
if (c != null) {
if (AllZoneUtil.isCardInPlayerGraveyard(card.getController(), c) && CardFactoryUtil.canTarget(card, c)) {
AllZone.getGameAction().moveToPlay(c);
}
}
}
//"Target creature gets -X/-X until end of turn",
for (int i = 0; i < card.getChoices().size(); i++) {
if (card.getChoice(i).equals(cardChoice[2])) {
final Card c = ab2card[0];
if (c != null) {
if (AllZoneUtil.isCardInPlay(c) && CardFactoryUtil.canTarget(card, c)) {
final int boost = x[0] * -1;
c.addTempAttackBoost(boost);
c.addTempDefenseBoost(boost);
final Command untilEOT = new Command() {
private static final long serialVersionUID = -6010783402521993651L;
public void execute() {
if (AllZoneUtil.isCardInPlay(c)) {
c.addTempAttackBoost(-1 * boost);
c.addTempDefenseBoost(-1 * boost);
}
}
};
AllZone.getEndOfTurn().addUntil(untilEOT);
}
}
}
}//end ab[2]
//"Up to X target creatures gain fear until end of turn"
if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3])) {
ArrayList<Card> cs = new ArrayList<Card>();
cs.addAll(ab3cards);
for (final Card c : cs) {
if (AllZoneUtil.isCardInPlay(c) && CardFactoryUtil.canTarget(card, c)) {
c.addExtrinsicKeyword("Fear");
final Command untilEOT = new Command() {
private static final long serialVersionUID = 986259855862338866L;
public void execute() {
if (AllZoneUtil.isCardInPlay(c)) {
c.removeExtrinsicKeyword("Fear");
}
}
};
AllZone.getEndOfTurn().addUntil(untilEOT);
}
}
}//end ab[3]
}//resolve()
@Override
public boolean canPlayAI() {
return false;
}
};//SpellAbility
final Command setStackDescription = new Command() {
private static final long serialVersionUID = 5840471361149632482L;
public void execute() {
ArrayList<String> a = new ArrayList<String>();
if (userChoice.contains(cardChoice[0]) || card.getChoices().contains(cardChoice[0]))
a.add(ab0player[0] + " loses X life");
if (userChoice.contains(cardChoice[1]) || card.getChoices().contains(cardChoice[1]))
a.add("return " + ab1card[0] + " from graveyard to play");
if (userChoice.contains(cardChoice[2]) || card.getChoices().contains(cardChoice[2]))
a.add(ab2card[0] + " gets -X/-X until end of turn");
if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3]))
a.add("up to X target creatures gain Fear until end of turn");
String s = a.get(0) + ", " + a.get(1);
spell.setStackDescription(card.getName() + " - " + s);
}
};//Command
//for ab[3] - X creatures gain fear until EOT
final Input targetXCreatures = new Input() {
private static final long serialVersionUID = 2584765431286321048L;
int stop = 0;
int count = 0;
@Override
public void showMessage() {
if (count == 0) stop = x[0];
AllZone.getDisplay().showMessage(cardName + " - Select a target creature to gain Fear (up to " + (stop - count) + " more)");
ButtonUtil.enableAll();
}
@Override
public void selectButtonCancel() {
stop();
}
@Override
public void selectButtonOK() {
done();
}
@Override
public void selectCard(Card c, PlayerZone zone) {
if (c.isCreature() && zone.is(Constant.Zone.Battlefield) && CardFactoryUtil.canTarget(card, c) &&
!ab3cards.contains(c)) {
ab3cards.add(c);
count++;
if (count == stop) done();
else showMessage();
}
}//selectCard()
private void done() {
setStackDescription.execute();
stopSetNext(new Input_PayManaCost(spell));
}
};
//for ab[2] target creature gets -X/-X
final Input targetCreature = new Input() {
private static final long serialVersionUID = -6879692803780014943L;
@Override
public void showMessage() {
AllZone.getDisplay().showMessage(cardName + " - Select target creature to get -X/-X");
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
stop();
}
@Override
public void selectCard(Card c, PlayerZone zone) {
if (c.isCreature() && zone.is(Constant.Zone.Battlefield) && CardFactoryUtil.canTarget(card, c)) {
if (card.isCopiedSpell()) card.getChoiceTargets().remove(0);
ab2card[0] = c;
//spell.setTargetCard(c);
card.setSpellChoiceTarget(String.valueOf(c.getUniqueNumber()));
setStackDescription.execute();
if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3]))
stopSetNext(targetXCreatures);
else {
System.out.println("Input_PayManaCost for spell is getting: " + spell.getManaCost());
stopSetNext(new Input_PayManaCost(spell));
}
}//if
}//selectCard()
};//Input targetCreature
//for ab[1] - return creature from grave to the battlefield
final Input targetGraveCreature = new Input() {
private static final long serialVersionUID = -7558252187229252725L;
@Override
public void showMessage() {
CardList grave = AllZoneUtil.getPlayerGraveyard(card.getController());
grave = grave.filter(AllZoneUtil.creatures);
grave = grave.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.getCMC() <= x[0];
}
});
Object check = GuiUtils.getChoiceOptional("Select target creature with CMC < X", grave.toArray());
if (check != null) {
Card c = (Card) check;
if (CardFactoryUtil.canTarget(card, c)) {
ab1card[0] = c;
}
} else
stop();
done();
}//showMessage()
public void done() {
if (userChoice.contains(cardChoice[2]) || card.getChoices().contains(cardChoice[2]))
stopSetNext(targetCreature);
else if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3]))
stopSetNext(targetXCreatures);
else {
stopSetNext(new Input_PayManaCost(spell));
}
}
};//Input
//for ab[0] - target player loses X life
final Input targetPlayer = new Input() {
private static final long serialVersionUID = 9101387253945650303L;
@Override
public void showMessage() {
AllZone.getDisplay().showMessage(cardName + " - Select target player to lose life");
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
stop();
}
@Override
public void selectPlayer(Player player) {
if (player.canTarget(card)) {
if (card.isCopiedSpell()) card.getChoiceTargets().remove(0);
ab0player[0] = player;
//spell.setTargetPlayer(player);
card.setSpellChoiceTarget(player.toString());
setStackDescription.execute();
if (userChoice.contains(cardChoice[1]) || card.getChoices().contains(cardChoice[1]))
stopSetNext(targetGraveCreature);
else if (userChoice.contains(cardChoice[2]) || card.getChoices().contains(cardChoice[2]))
stopSetNext(targetCreature);
else if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3]))
stopSetNext(targetXCreatures);
else {
stopSetNext(new Input_PayManaCost(spell));
}
}
}//selectPlayer()
};//Input targetPlayer
final Input chooseX = new Input() {
private static final long serialVersionUID = 5625588008756700226L;
@Override
public void showMessage() {
if (card.isCopiedSpell()) {
x[0] = 0;
if (userChoice.contains(cardChoice[0])) stopSetNext(targetPlayer);
else if (userChoice.contains(cardChoice[1])) stopSetNext(targetGraveCreature);
else if (userChoice.contains(cardChoice[2])) stopSetNext(targetCreature);
else if (userChoice.contains(cardChoice[3])) stopSetNext(targetXCreatures);
else {
throw new RuntimeException("Something in if(isCopiedSpell()) in Profane Command selection is FUBAR.");
}
} else {
ArrayList<String> choices = new ArrayList<String>();
for (int i = 0; i <= card.getController().getLife(); i++) {
choices.add("" + i);
}
Object o = GuiUtils.getChoice("Choose X", choices.toArray());
//everything stops here if user cancelled
if (o == null) {
stop();
return;
}
String answer = (String) o;
x[0] = Integer.parseInt(answer);
spell.setManaCost(x[0] + " B B");
spell.setIsXCost(false);
if (userChoice.contains(cardChoice[0])) stopSetNext(targetPlayer);
else if (userChoice.contains(cardChoice[1])) stopSetNext(targetGraveCreature);
else if (userChoice.contains(cardChoice[2])) stopSetNext(targetCreature);
else if (userChoice.contains(cardChoice[3])) stopSetNext(targetXCreatures);
else {
throw new RuntimeException("Something in Profane Command selection is FUBAR.");
}
}
}//showMessage()
};//Input chooseX
Input chooseTwoInput = new Input() {
private static final long serialVersionUID = 5625588008756700226L;
@Override
public void showMessage() {
if (card.isCopiedSpell()) {
if (userChoice.contains(cardChoice[0])) stopSetNext(targetPlayer);
else if (userChoice.contains(cardChoice[1])) stopSetNext(targetGraveCreature);
else if (userChoice.contains(cardChoice[2])) stopSetNext(targetCreature);
else if (userChoice.contains(cardChoice[3])) stopSetNext(targetXCreatures);
else {
throw new RuntimeException("Something in if(isCopiedSpell()) in Profane Command selection is FUBAR.");
}
} else {
//reset variables
ab0player[0] = null;
ab1card[0] = null;
ab2card[0] = null;
ab3cards.clear();
card.getChoices().clear();
card.getChoiceTargets().clear();
userChoice.clear();
ArrayList<String> display = new ArrayList<String>();
//get all
CardList creatures = AllZoneUtil.getCreaturesInPlay();
CardList grave = AllZoneUtil.getPlayerGraveyard(card.getController());
grave = grave.filter(AllZoneUtil.creatures);
if (AllZone.getHumanPlayer().canTarget(card) || AllZone.getComputerPlayer().canTarget(card))
display.add("Target player loses X life");
if (grave.size() > 0)
display.add("Return target creature card with converted mana cost X or less from your graveyard to the battlefield");
if (creatures.size() > 0) display.add("Target creature gets -X/-X until end of turn");
display.add("Up to X target creatures gain fear until end of turn");
ArrayList<String> a = chooseTwo(display);
//everything stops here if user cancelled
if (a == null) {
stop();
return;
}
userChoice.addAll(a);
stopSetNext(chooseX);
}
}//showMessage()
private ArrayList<String> chooseTwo(ArrayList<String> choices) {
ArrayList<String> out = new ArrayList<String>();
Object o = GuiUtils.getChoiceOptional("Choose Two", choices.toArray());
if (o == null) return null;
out.add((String) o);
card.addSpellChoice((String) o);
choices.remove(out.get(0));
o = GuiUtils.getChoiceOptional("Choose Two", choices.toArray());
if (o == null) return null;
out.add((String) o);
card.addSpellChoice((String) o);
return out;
}//chooseTwo()
};//Input chooseTwoInput
card.addSpellAbility(spell);
card.setSpellWithChoices(true);
spell.setBeforePayMana(chooseTwoInput);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Turn to Slag")) {
Cost abCost = new Cost("3 R R", cardName, false);
Target target = new Target(card, "Select target creature", "Creature".split(","));
final SpellAbility spell = new Spell(card, abCost, target) {
private static final long serialVersionUID = 3848014348910653252L;
@Override
public boolean canPlayAI() {
return false;
}
@Override
public void resolve() {
Card tgt = getTargetCard();
if (AllZoneUtil.isCardInPlay(tgt) && CardFactoryUtil.canTarget(card, tgt)) {
tgt.addDamage(5, card);
CardList equipment = new CardList(tgt.getEquippedBy());
for (Card eq : equipment) AllZone.getGameAction().destroy(eq);
}
}//resolve()
};//SpellAbility
spell.setDescription(cardName + " deals 5 damage to target creature. Destroy all Equipment attached to that creature.");
card.addSpellAbility(spell);
}//*************** END ************ END **************************
return card;
}//getCard
}