package forge.card.cardFactory;
import com.esotericsoftware.minlog.Log;
import forge.*;
import forge.card.abilityFactory.AbilityFactory;
import forge.card.spellability.*;
import forge.card.trigger.Trigger;
import forge.card.trigger.TriggerHandler;
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.List;
import java.util.Stack;
/**
* <p>CardFactory_Creatures class.</p>
*
* @author Forge
* @version $Id: $
*/
public class CardFactory_Creatures {
/**
* <p>hasKeyword.</p>
*
* @param c a {@link forge.Card} object.
* @param k a {@link java.lang.String} object.
* @return a int.
*/
private static final int hasKeyword(Card c, String k) {
ArrayList<String> a = c.getKeyword();
for (int i = 0; i < a.size(); i++)
if (a.get(i).toString().startsWith(k)) return i;
return -1;
}
/**
* <p>shouldCycle.</p>
*
* @param c a {@link forge.Card} object.
* @return a int.
*/
public static int shouldCycle(Card c) {
ArrayList<String> a = c.getKeyword();
for (int i = 0; i < a.size(); i++)
if (a.get(i).toString().startsWith("Cycling")) return i;
return -1;
}
/**
* <p>shouldTypeCycle.</p>
*
* @param c a {@link forge.Card} object.
* @return a int.
*/
public static int shouldTypeCycle(Card c) {
ArrayList<String> a = c.getKeyword();
for (int i = 0; i < a.size(); i++)
if (a.get(i).toString().startsWith("TypeCycling")) return i;
return -1;
}
/**
* <p>shouldTransmute.</p>
*
* @param c a {@link forge.Card} object.
* @return a int.
*/
public static int shouldTransmute(Card c) {
ArrayList<String> a = c.getKeyword();
for (int i = 0; i < a.size(); i++)
if (a.get(i).toString().startsWith("Transmute")) return i;
return -1;
}
/**
* <p>shouldSoulshift.</p>
*
* @param c a {@link forge.Card} object.
* @return a int.
*/
public static int shouldSoulshift(Card c) {
ArrayList<String> a = c.getKeyword();
for (int i = 0; i < a.size(); i++)
if (a.get(i).toString().startsWith("Soulshift")) return i;
return -1;
}
/**
* <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.
* @param cf a {@link forge.card.cardFactory.CardFactory} object.
* @return a {@link forge.Card} object.
*/
public static Card getCard(final Card card, final String cardName, Player owner, CardFactory cf) {
//*************** START *********** START **************************
if (cardName.equals("Force of Savagery")) {
SpellAbility spell = new Spell_Permanent(card) {
private static final long serialVersionUID = 1603238129819160467L;
@Override
public boolean canPlayAI() {
CardList list = AllZoneUtil.getPlayerCardsInPlay(AllZone.getComputerPlayer());
return list.containsName("Glorious Anthem") || list.containsName("Gaea's Anthem");
}
};
// Do not remove SpellAbilities created by AbilityFactory or Keywords.
card.clearFirstSpell();
card.addSpellAbility(spell);
}
//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Gilder Bairn")) {
Cost abCost = new Cost("2 GU Untap", cardName, true);
Target tgt = new Target(card, "Select target permanent.", new String[]{"Permanent"});
final Ability_Activated a1 = new Ability_Activated(card, abCost, tgt) {
private static final long serialVersionUID = -1847685865277129366L;
@Override
public void resolve() {
Card c = getTargetCard();
if (c.sumAllCounters() == 0) return;
else if (AllZoneUtil.isCardInPlay(c) && CardFactoryUtil.canTarget(card, c)) {
//zerker clean up:
for (Counters c_1 : Counters.values())
if (c.getCounters(c_1) > 0) c.addCounter(c_1, c.getCounters(c_1));
}
}
@Override
public void chooseTargetAI() {
CardList perms = AllZoneUtil.getPlayerCardsInPlay(AllZone.getComputerPlayer());
perms = perms.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.sumAllCounters() > 0 && CardFactoryUtil.canTarget(card, c);
}
});
perms.shuffle();
setTargetCard(perms.get(0)); //TODO: improve this.
}
@Override
public boolean canPlayAI() {
CardList perms = AllZoneUtil.getPlayerCardsInPlay(AllZone.getComputerPlayer());
perms = perms.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.sumAllCounters() > 0 && CardFactoryUtil.canTarget(card, c);
}
});
return perms.size() > 0;
}
};//SpellAbility
card.addSpellAbility(a1);
a1.setDescription(abCost + "For each counter on target permanent, put another of those counters on that permanent.");
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Primal Plasma") || cardName.equals("Primal Clay")) {
card.setBaseAttack(3);
card.setBaseDefense(3);
final SpellAbility ability = new Ability(card, "0") {
@Override
public void resolve() {
String choice = "";
String choices[] = {"3/3", "2/2 with flying", "1/6 with defender"};
if (card.getController().isHuman()) {
choice = GuiUtils.getChoice("Choose one", choices);
} else choice = choices[MyRandom.random.nextInt(3)];
if (choice.equals("2/2 with flying")) {
card.setBaseAttack(2);
card.setBaseDefense(2);
card.addIntrinsicKeyword("Flying");
}
if (choice.equals("1/6 with defender")) {
card.setBaseAttack(1);
card.setBaseDefense(6);
card.addIntrinsicKeyword("Defender");
card.addType("Wall");
}
}//resolve()
};//SpellAbility
Command intoPlay = new Command() {
private static final long serialVersionUID = 8957338395786245312L;
public void execute() {
StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - choose: 3/3, 2/2 flying, 1/6 defender");
ability.setStackDescription(sb.toString());
AllZone.getStack().addSimultaneousStackEntry(ability);
}
};
card.addComesIntoPlayCommand(intoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Oracle of Mul Daya")) {
final SpellAbility ability = new Ability(card, "0") {
private static final long serialVersionUID = 2902408812353813L;
@Override
public void resolve() {
// TODO: change to static ability?
CardList library = AllZoneUtil.getPlayerCardsInLibrary(card.getController());
if (library.size() == 0)
return;
Card top = library.get(0);
if (top.isLand())
card.getController().playLand(top);
}//resolve()
@Override
public boolean canPlay() {
CardList library = AllZoneUtil.getPlayerCardsInLibrary(card.getController());
if (library.size() == 0) return false;
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, card.getController());
boolean canPlayLand = card.getController().canPlayLand();
return (AllZoneUtil.isCardInZone(play, card) && library.get(0).isLand() && canPlayLand);
}
};//SpellAbility
StringBuilder sb = new StringBuilder();
sb.append(card.getController()).append(" - plays land from top of library.");
ability.setStackDescription(sb.toString());
card.addSpellAbility(ability);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Drekavac")) {
final Input discard = new Input() {
private static final long serialVersionUID = -6392468000100283596L;
@Override
public void showMessage() {
AllZone.getDisplay().showMessage("Select a noncreature card to discard");
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectCard(Card c, PlayerZone zone) {
if (zone.is(Constant.Zone.Hand) && !c.isCreature()) {
c.getController().discard(c, null);
stop();
}
}
@Override
public void selectButtonCancel() {
AllZone.getGameAction().sacrifice(card);
stop();
}
};//Input
final SpellAbility ability = new Ability(card, "0") {
@Override
public void resolve() {
if (card.getController().isHuman()) {
if (AllZoneUtil.getPlayerHand(AllZone.getHumanPlayer()).size() == 0)
AllZone.getGameAction().sacrifice(card);
else AllZone.getInputControl().setInput(discard);
} else {
CardList list = AllZoneUtil.getPlayerHand(AllZone.getComputerPlayer());
list = list.filter(new CardListFilter() {
public boolean addCard(Card c) {
return (!c.isCreature());
}
});
list.get(0).getController().discard(list.get(0), this);
}//else
}//resolve()
};//SpellAbility
Command intoPlay = new Command() {
private static final long serialVersionUID = 9202753910259054021L;
public void execute() {
StringBuilder sb = new StringBuilder();
sb.append(card.getController()).append(" sacrifices Drekavac unless he discards a noncreature card");
ability.setStackDescription(sb.toString());
AllZone.getStack().addSimultaneousStackEntry(ability);
}
};
SpellAbility spell = new Spell_Permanent(card) {
private static final long serialVersionUID = -2940969025405788931L;
//could never get the AI to work correctly
//it always played the same card 2 or 3 times
@Override
public boolean canPlayAI() {
return false;
}
@Override
public boolean canPlay() {
CardList list = AllZoneUtil.getPlayerHand(card.getController());
list.remove(card);
list = list.filter(new CardListFilter() {
public boolean addCard(Card c) {
return (!c.isCreature());
}
});
return list.size() != 0;
}//canPlay()
};
card.addComesIntoPlayCommand(intoPlay);
// Do not remove SpellAbilities created by AbilityFactory or Keywords.
card.clearFirstSpell();
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Minotaur Explorer") || cardName.equals("Balduvian Horde") ||
cardName.equals("Pillaging Horde")) {
final SpellAbility creature = new Spell_Permanent(card) {
private static final long serialVersionUID = -7326018877172328480L;
@Override
public boolean canPlayAI() {
int reqHand = 1;
if (AllZone.getZone(card).is(Constant.Zone.Hand))
reqHand++;
// Don't play if it would sacrifice as soon as it comes into play
return AllZoneUtil.getCardsInZone(Constant.Zone.Hand, AllZone.getComputerPlayer()).size() > reqHand;
}
};
card.clearFirstSpell();
card.addFirstSpellAbility(creature);
final SpellAbility ability = new Ability(card, "0") {
@Override
public void resolve() {
CardList hand = AllZoneUtil.getPlayerHand(card.getController());
if (hand.size() == 0)
AllZone.getGameAction().sacrifice(card);
else
card.getController().discardRandom(this);
}
};//SpellAbility
Command intoPlay = new Command() {
private static final long serialVersionUID = 4986114285467649619L;
public void execute() {
StringBuilder sb = new StringBuilder();
sb.append(card.getController()).append(" - discards at random or sacrifices ").append(cardName);
ability.setStackDescription(sb.toString());
AllZone.getStack().addSimultaneousStackEntry(ability);
}
};
card.addComesIntoPlayCommand(intoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Sleeper Agent")) {
final SpellAbility ability = new Ability(card, "0") {
@Override
public void resolve() {
// TODO: this need to be targeted
AllZone.getGameAction().changeController(new CardList(card), card.getController(), card.getController().getOpponent());
}
};
ability.setStackDescription("When Sleeper Agent enters the battlefield, target opponent gains control of it.");
Command intoPlay = new Command() {
private static final long serialVersionUID = -3934471871041458847L;
public void execute() {
AllZone.getStack().addSimultaneousStackEntry(ability);
}//execute()
};
card.addComesIntoPlayCommand(intoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Phylactery Lich")) {
final CommandReturn getArt = new CommandReturn() {
//get target card, may be null
public Object execute() {
CardList art = AllZoneUtil.getPlayerCardsInPlay(AllZone.getComputerPlayer());
art = art.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.isArtifact();
}
});
CardList list = new CardList(art.toArray());
list = list.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.getIntrinsicKeyword().contains("Indestructible");
}
});
Card target = null;
if (!list.isEmpty())
target = list.get(0);
else if (!art.isEmpty())
target = art.get(0);
return target;
}//execute()
};//CommandReturn
final SpellAbility ability = new Ability(card, "0") {
@Override
public void resolve() {
Card c = getTargetCard();
if (AllZoneUtil.isCardInPlay(c) && c.isArtifact()) {
c.addCounter(Counters.PHYLACTERY, 1);
card.setFinishedEnteringBF(true);
}
}//resolve()
};//SpellAbility
Command intoPlay = new Command() {
private static final long serialVersionUID = -1601957445498569156L;
public void execute() {
Input target = new Input() {
private static final long serialVersionUID = -806140334868210520L;
@Override
public void showMessage() {
AllZone.getDisplay().showMessage("Select target artifact you control");
ButtonUtil.disableAll();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if (card.isArtifact() && zone.is(Constant.Zone.Battlefield) && card.getController().isHuman()) {
ability.setTargetCard(card);
AllZone.getStack().add(ability);
stop();
}
}
};//Input target
if (card.getController().isHuman()) {
CardList artifacts = AllZoneUtil.getPlayerTypeInPlay(AllZone.getHumanPlayer(), "Artifact");
if (artifacts.size() != 0) AllZone.getInputControl().setInput(target);
} else { //computer
Object o = getArt.execute();
if (o != null)//should never happen, but just in case
{
ability.setTargetCard((Card) o);
AllZone.getStack().addSimultaneousStackEntry(ability);
}
}//else
}//execute()
};
// Do not remove SpellAbilities created by AbilityFactory or Keywords.
card.clearFirstSpell();
card.addSpellAbility(new Spell_Permanent(card) {
private static final long serialVersionUID = -1506199222879057809L;
@Override
public boolean canPlayAI() {
Object o = getArt.execute();
return (o != null) && AllZone.getZone(getSourceCard()).is(Constant.Zone.Hand);
}
});
card.addComesIntoPlayCommand(intoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Sky Swallower")) {
final SpellAbility ability = new Ability(card, "0") {
@Override
public void resolve() {
//TODO - this needs to be targeted
Player opp = card.getController().getOpponent();
CardList list = AllZoneUtil.getCardsInPlay();
list = list.getValidCards("Card.Other+YouCtrl".split(","), card.getController(), card);
AllZone.getGameAction().changeController(list, card.getController(), opp);
}//resolve()
};//SpellAbility
Command intoPlay = new Command() {
private static final long serialVersionUID = -453410206437839334L;
public void execute() {
StringBuilder sb = new StringBuilder();
sb.append(card.getController().getOpponent());
sb.append(" gains control of all other permanents you control");
ability.setStackDescription(sb.toString());
AllZone.getStack().addSimultaneousStackEntry(ability);
}
};
card.addComesIntoPlayCommand(intoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Jhoira of the Ghitu")) {
final Stack<Card> chosen = new Stack<Card>();
final SpellAbility ability = new Ability(card, "2") {
private static final long serialVersionUID = 4414609319033894302L;
@Override
public boolean canPlay() {
CardList possible = AllZoneUtil.getPlayerHand(card.getController());
possible = possible.filter(AllZoneUtil.nonlands);
return !possible.isEmpty() && super.canPlay();
}
public boolean canPlayAI() {
return false;
}
@Override
public void resolve() {
Card c = chosen.pop();
c.addCounter(Counters.TIME, 4);
c.setSuspend(true);
}
};
ability.setAfterPayMana(new Input() {
private static final long serialVersionUID = -1647181037510967127L;
@Override
public void showMessage() {
ButtonUtil.disableAll();
AllZone.getDisplay().showMessage("Exile a nonland card from your hand.");
}
@Override
public void selectCard(Card c, PlayerZone zone) {
if (zone.is(Constant.Zone.Hand) && !c.isLand()) {
AllZone.getGameAction().exile(c);
chosen.push(c);
ability.setStackDescription(card.toString() + " - Suspending " + c.toString());
AllZone.getStack().add(ability);
stop();
}
}
});
card.addSpellAbility(ability);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Hermit Druid")) {
Cost abCost = new Cost("G T", cardName, true);
final Ability_Activated ability = new Ability_Activated(card, abCost, null) {
private static final long serialVersionUID = 5884624727757154056L;
@Override
public boolean canPlayAI() {
//Use the ability if there is still a forest in the library
CardList library = AllZoneUtil.getPlayerCardsInLibrary(card.getController());
return !library.getName("Forest").isEmpty();
}
@Override
public void resolve() {
CardList library = AllZoneUtil.getPlayerCardsInLibrary(card.getController());
if (library.size() == 0) return; // maybe provide some notification that library is empty?
CardList revealed = new CardList();
Card basicGrab = null;
int count = 0;
// reveal top card until library runs out or hit a basic land
while (basicGrab == null) {
Card top = library.get(count);
count++;
revealed.add(top);
if (top.isBasicLand())
basicGrab = top;
if (count == library.size())
break;
}//while
GuiUtils.getChoiceOptional("Revealed cards:", revealed.toArray());
if (basicGrab != null) {
// put basic in hand
AllZone.getGameAction().moveToHand(basicGrab);
revealed.remove(basicGrab);
}
// place revealed cards in graveyard (TODO: player should choose order)
for (Card c : revealed) {
AllZone.getGameAction().moveToGraveyard(c);
}
}
};
ability.setStackDescription(abCost + "Reveal cards from the top of your library until you reveal a basic land card." +
" Put that card into your hand and all other cards revealed this way into your graveyard.");
card.addSpellAbility(ability);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Vedalken Plotter")) {
final Card[] target = new Card[2];
final int[] index = new int[1];
final Ability ability = new Ability(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 = -7143706716256752987L;
@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)) {
//System.out.println("c is: " +c);
target[index[0]] = c;
index[0]++;
showMessage();
if (index[0] == target.length) {
AllZone.getStack().add(ability);
stop();
}
}
}//selectCard()
};//Input
Command comesIntoPlay = new Command() {
private static final long serialVersionUID = 6513203926272187582L;
public void execute() {
index[0] = 0;
if (card.getController().isHuman()) AllZone.getInputControl().setInput(input);
}
};
StringBuilder sb = new StringBuilder();
sb.append(cardName).append(" - Exchange control of target land you control and target land an opponent controls.");
ability.setStackDescription(sb.toString());
card.addComesIntoPlayCommand(comesIntoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Wojek Embermage")) {
Cost abCost = new Cost("T", cardName, true);
Target tgt = new Target(card, "TgtC");
final Ability_Activated ability = new Ability_Activated(card, abCost, tgt) {
private static final long serialVersionUID = -1208482961653326721L;
@Override
public boolean canPlayAI() {
return (CardFactoryUtil.AI_getHumanCreature(1, card, true).size() != 0)
&& (AllZone.getPhase().getPhase().equals(Constant.Phase.Main2));
}
@Override
public void chooseTargetAI() {
CardList list = CardFactoryUtil.AI_getHumanCreature(1, card, true);
list.shuffle();
setTargetCard(list.get(0));
}
@Override
public void resolve() {
if (AllZoneUtil.isCardInPlay(getTargetCard())
&& CardFactoryUtil.canTarget(card, getTargetCard())) {
CardList list = getRadiance(getTargetCard());
for (int i = 0; i < list.size(); i++) {
list.get(i).addDamage(1, card);
}
}
}//resolve()
//parameter Card c, is included in CardList
//no multi-colored cards
CardList getRadiance(Card c) {
if (CardUtil.getColors(c).contains(Constant.Color.Colorless)) {
CardList list = new CardList();
list.add(c);
return list;
}
CardList sameColor = new CardList();
CardList list = AllZoneUtil.getCreaturesInPlay();
for (int i = 0; i < list.size(); i++)
if (list.get(i).sharesColorWith(c)) sameColor.add(list.get(i));
return sameColor;
}
};//SpellAbility
card.addSpellAbility(ability);
ability.setDescription("Radiance - " + abCost + cardName + " deals 1 damage to target creature and each other creature that shares a color with it.");
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Adarkar Valkyrie")) {
//tap ability - no cost - target creature - EOT
final Card[] target = new Card[1];
final Command destroy = new Command() {
private static final long serialVersionUID = -2433442359225521472L;
public void execute() {
AllZone.getStack().addSimultaneousStackEntry(new Ability(card, "0", "Adarkar Valkyrie - Return " + target[0] + " from graveyard to the battlefield") {
@Override
public void resolve() {
PlayerZone grave = AllZone.getZone(target[0]);
//checks to see if card is still in the graveyard
if (grave != null && AllZoneUtil.isCardInZone(grave, target[0])) {
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, card.getController());
target[0].setController(card.getController());
AllZone.getGameAction().moveTo(play, target[0]);
}
}
});
}//execute()
};
final Command untilEOT = new Command() {
private static final long serialVersionUID = 2777978927867867610L;
public void execute() {
//resets the Card destroy Command
target[0].removeDestroyCommand(destroy);
}
};
Cost abCost = new Cost("T", cardName, true);
Target tgt = new Target(card, "Target creature other than " + cardName, "Creature.Other".split(","));
final Ability_Activated ability = new Ability_Activated(card, abCost, tgt) {
private static final long serialVersionUID = -8454685126878522607L;
@Override
public void resolve() {
if (AllZoneUtil.isCardInPlay(getTargetCard())) {
target[0] = getTargetCard();
if (!target[0].isToken()) { // not necessary, but will help speed up stack resolution
AllZone.getEndOfTurn().addUntil(untilEOT);
target[0].addDestroyCommand(destroy);
}
}//if
}//resolve()
@Override
public boolean canPlayAI() {
return false;
}
};//SpellAbility
card.addSpellAbility(ability);
StringBuilder sb = new StringBuilder();
sb.append("tap: When target creature other than Adarkar Valkyrie is put into a ");
sb.append("graveyard this turn, return that card to the battlefield under your control.");
ability.setDescription(sb.toString());
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Painter's Servant")) {
final long[] timeStamp = new long[1];
final String[] color = new String[1];
Command comesIntoPlay = new Command() {
private static final long serialVersionUID = 333134223161L;
public void execute() {
if (card.getController().isHuman()) {
String[] colors = Constant.Color.onlyColors;
Object o = GuiUtils.getChoice("Choose color", colors);
color[0] = (String) o;
card.setChosenColor(color[0]);
} else {
// AI chooses the color that appears in the keywords of the most cards in its deck, hand and on battlefield
CardList list = new CardList();
list.addAll(AllZoneUtil.getPlayerCardsInLibrary(AllZone.getComputerPlayer()));
list.addAll(AllZoneUtil.getPlayerHand(AllZone.getComputerPlayer()));
list.addAll(AllZoneUtil.getPlayerCardsInPlay(AllZone.getComputerPlayer()));
color[0] = Constant.Color.White;
int max = list.getKeywordsContain(color[0]).size();
String[] colors = {Constant.Color.Blue, Constant.Color.Black, Constant.Color.Red, Constant.Color.Green};
for (String c : colors) {
int cmp = list.getKeywordsContain(c).size();
if (cmp > max) {
max = cmp;
color[0] = c;
}
}
card.setChosenColor(color[0]);
}
String s = CardUtil.getShortColor(color[0]);
timeStamp[0] = AllZone.getGameInfo().addColorChanges(s, card, true, true);
}
};//Command
Command leavesBattlefield = new Command() {
private static final long serialVersionUID = 2559212590399132459L;
public void execute() {
String s = CardUtil.getShortColor(color[0]);
AllZone.getGameInfo().removeColorChanges(s, card, true, timeStamp[0]);
}
};
card.addComesIntoPlayCommand(comesIntoPlay);
card.addLeavesPlayCommand(leavesBattlefield);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Stangg")) {
final Ability ability = new Ability(card, "0") {
@Override
public void resolve() {
CardList cl = CardFactoryUtil.makeToken("Stangg Twin", "RG 3 4 Stangg Twin", card.getController(), "R G",
new String[]{"Legendary", "Creature", "Human", "Warrior"}, 3, 4, new String[]{""});
cl.get(0).addLeavesPlayCommand(new Command() {
private static final long serialVersionUID = 3367390368512271319L;
public void execute() {
if (AllZoneUtil.isCardInPlay(card)) AllZone.getGameAction().sacrifice(card);
}
});
}
};
ability.setStackDescription("When Stangg enters the battlefield, if Stangg is on the battlefield, put a legendary 3/4 red and green Human Warrior creature token named Stangg Twin onto the battlefield.");
card.addComesIntoPlayCommand(new Command() {
private static final long serialVersionUID = 6667896040611028600L;
public void execute() {
AllZone.getStack().addSimultaneousStackEntry(ability);
}
});
card.addLeavesPlayCommand(new Command() {
private static final long serialVersionUID = 1786900359843939456L;
public void execute() {
CardList list = AllZoneUtil.getCardsInPlay("Stangg Twin");
if (list.size() == 1) AllZone.getGameAction().exile(list.get(0));
}
});
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Horde of Notions")) {
final Ability ability = new Ability(card, "W U B R G") {
@Override
public void resolve() {
Card c = null;
if (card.getController().isHuman()) {
Object o = GuiUtils.getChoiceOptional("Select Elemental", getCreatures());
c = (Card) o;
} else {
c = getAIElemental();
}
if (AllZoneUtil.isCardInPlayerGraveyard(card.getController(), c)) {
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, c.getController());
AllZone.getGameAction().moveTo(play, c);
}
}//resolve()
@Override
public boolean canPlay() {
return getCreatures().size() != 0 && AllZoneUtil.isCardInPlay(card) && super.canPlay();
}
public CardList getCreatures() {
CardList creatures = AllZoneUtil.getPlayerTypeInGraveyard(card.getController(), "Elemental");
return creatures;
}
public Card getAIElemental() {
CardList c = getCreatures();
Card biggest = c.get(0);
for (int i = 0; i < c.size(); i++)
if (biggest.getNetAttack() < c.get(i).getNetAttack()) biggest = c.get(i);
return biggest;
}
};//SpellAbility
card.addSpellAbility(ability);
ability.setDescription("W U B R G: You may play target Elemental card from your graveyard without paying its mana cost.");
ability.setStackDescription("Horde of Notions - play Elemental card from graveyard without paying its mana cost.");
ability.setBeforePayMana(new Input_PayManaCost(ability));
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Rhys the Redeemed")) {
Cost abCost = new Cost("4 GW GW T", card.getName(), true);
final Ability_Activated copyTokens1 = new Ability_Activated(card, abCost, null) {
private static final long serialVersionUID = 6297992502069547478L;
@Override
public void resolve() {
CardList allTokens = AllZoneUtil.getCreaturesInPlay(card.getController());
allTokens = allTokens.filter(AllZoneUtil.token);
int multiplier = AllZoneUtil.getDoublingSeasonMagnitude(card.getController());
for (int i = 0; i < allTokens.size(); i++) {
Card c = allTokens.get(i);
for (int j = 0; j < multiplier; j++)
copyToken(c);
}
}
public void copyToken(Card token) {
Card copy = new Card();
copy.setName(token.getName());
copy.setImageName(token.getImageName());
copy.setOwner(token.getController());
copy.setController(token.getController());
copy.setManaCost(token.getManaCost());
copy.setColor(token.getColor());
copy.setToken(true);
copy.setType(token.getType());
copy.setBaseAttack(token.getBaseAttack());
copy.setBaseDefense(token.getBaseDefense());
AllZone.getGameAction().moveToPlay(copy);
}
@Override
public boolean canPlayAI() {
CardList allTokens = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer());
allTokens = allTokens.filter(AllZoneUtil.token);
return allTokens.size() >= 2;
}
};
card.addSpellAbility(copyTokens1);
copyTokens1.setDescription(abCost + "For each creature token you control, put a token that's a copy of that creature onto the battlefield.");
StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - For each creature token you control, put a token that's a copy of that creature onto the battlefield.");
copyTokens1.setStackDescription(sb.toString());
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Treva, the Renewer")) {
final Player player = card.getController();
final Ability ability2 = new Ability(card, "2 W") {
@Override
public void resolve() {
int lifeGain = 0;
if (card.getController().isHuman()) {
String choices[] = {"white", "blue", "black", "red", "green"};
Object o = GuiUtils.getChoiceOptional("Select Color: ", choices);
Log.debug("Treva, the Renewer", "Color:" + o);
lifeGain = CardFactoryUtil.getNumberOfPermanentsByColor((String) o);
} else {
CardList list = AllZoneUtil.getCardsInPlay();
String color = CardFactoryUtil.getMostProminentColor(list);
lifeGain = CardFactoryUtil.getNumberOfPermanentsByColor(color);
}
card.getController().gainLife(lifeGain, card);
}
@Override
public boolean canPlay() {
//this is set to false, since it should only TRIGGER
return false;
}
};// ability2
//card.clearSpellAbility();
card.addSpellAbility(ability2);
StringBuilder sb2 = new StringBuilder();
sb2.append(card.getName()).append(" - ").append(player);
sb2.append(" gains life equal to permanents of the chosen color.");
ability2.setStackDescription(sb2.toString());
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Rith, the Awakener")) {
final Player player = card.getController();
final Ability ability2 = new Ability(card, "2 G") {
@Override
public void resolve() {
int numberTokens = 0;
if (card.getController().isHuman()) {
String choices[] = {"white", "blue", "black", "red", "green"};
Object o = GuiUtils.getChoiceOptional("Select Color: ", choices);
//System.out.println("Color:" + o);
numberTokens = CardFactoryUtil.getNumberOfPermanentsByColor((String) o);
} else {
CardList list = AllZoneUtil.getCardsInPlay();
String color = CardFactoryUtil.getMostProminentColor(list);
numberTokens = CardFactoryUtil.getNumberOfPermanentsByColor(color);
}
for (int i = 0; i < numberTokens; i++) {
CardFactoryUtil.makeTokenSaproling(card.getController());
}
}
@Override
public boolean canPlay() {
//this is set to false, since it should only TRIGGER
return false;
}
};// ability2
//card.clearSpellAbility();
card.addSpellAbility(ability2);
StringBuilder sb2 = new StringBuilder();
sb2.append(card.getName()).append(" - ").append(player);
sb2.append(" puts a 1/1 green Saproling creature token onto the battlefield for each permanent of the chosen color");
ability2.setStackDescription(sb2.toString());
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Sphinx of Jwar Isle")) {
final SpellAbility ability1 = new Ability(card, "0") {
@Override
public void resolve() {
Player player = card.getController();
PlayerZone lib = AllZone.getZone(Constant.Zone.Library, player);
if (lib.size() < 1) return;
CardList cl = new CardList();
cl.add(lib.get(0));
GuiUtils.getChoiceOptional("Top card", cl.toArray());
}
@Override
public boolean canPlayAI() {
return false;
}
};//SpellAbility
StringBuilder sb1 = new StringBuilder();
sb1.append(card.getName()).append(" - look at top card of library.");
ability1.setStackDescription(sb1.toString());
ability1.setDescription("You may look at the top card of your library.");
card.addSpellAbility(ability1);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Master of the Wild Hunt")) {
final Cost abCost = new Cost("T", cardName, true);
final Target abTgt = new Target(card, "Target a creature to Hunt", "Creature".split(","));
final Ability_Activated ability = new Ability_Activated(card, abCost, abTgt) {
private static final long serialVersionUID = 35050145102566898L;
@Override
public boolean canPlayAI() {
CardList wolves = AllZoneUtil.getPlayerCardsInPlay(AllZone.getComputerPlayer());
wolves = wolves.getType("Wolf");
wolves = wolves.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.isUntapped() && c.isCreature();
}
});
int power = 0;
for (int i = 0; i < wolves.size(); i++)
power += wolves.get(i).getNetAttack();
if (power == 0)
return false;
final int totalPower = power;
CardList targetables = AllZoneUtil.getPlayerCardsInPlay(AllZone.getHumanPlayer());
targetables = targetables.filter(new CardListFilter() {
public boolean addCard(Card c) {
return CardFactoryUtil.canTarget(card, c) && c.isCreature() && c.getNetDefense() <= totalPower;
}
});
if (targetables.size() == 0)
return false;
getTarget().resetTargets();
setTargetCard(CardFactoryUtil.AI_getBestCreature(targetables));
return true;
}
@Override
public void resolve() {
CardList wolves = AllZoneUtil.getPlayerCardsInPlay(card.getController());
wolves = wolves.getType("Wolf");
wolves = wolves.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.isUntapped() && c.isCreature();
}
});
final Card target = getTargetCard();
if (wolves.size() == 0)
return;
if (!(CardFactoryUtil.canTarget(card, target) && AllZoneUtil.isCardInPlay(target)))
return;
for (Card c : wolves) {
c.tap();
target.addDamage(c.getNetAttack(), c);
}
if (target.getController().isHuman()) { // Human choose spread damage
for (int x = 0; x < target.getNetAttack(); x++) {
AllZone.getInputControl().setInput(CardFactoryUtil.MasteroftheWildHunt_input_targetCreature(this, wolves, new Command() {
private static final long serialVersionUID = -328305150127775L;
public void execute() {
getTargetCard().addDamage(1, target);
AllZone.getGameAction().checkStateEffects();
}
}));
}
} else { // AI Choose spread Damage
CardList damageableWolves = wolves.filter(new CardListFilter() {
public boolean addCard(Card c) {
return (c.predictDamage(target.getNetAttack(), target, false) > 0);
}
});
if (damageableWolves.size() == 0) // don't bother if I can't damage anything
return;
CardList wolvesLeft = damageableWolves.filter(new CardListFilter() {
public boolean addCard(Card c) {
return !c.hasKeyword("Indestructible");
}
});
for (int i = 0; i < target.getNetAttack(); i++) {
wolvesLeft = wolvesLeft.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.getKillDamage() > 0 && (c.getKillDamage() <= target.getNetAttack()
|| target.hasKeyword("Deathtouch"));
}
});
// Kill Wolves that can be killed first
if (wolvesLeft.size() > 0) {
Card best = CardFactoryUtil.AI_getBestCreature(wolvesLeft);
best.addDamage(1, target);
if (best.getKillDamage() <= 0 || target.hasKeyword("Deathtouch")) {
wolvesLeft.remove(best);
}
} else {
// Add -1/-1s to Random Indestructibles
if (target.hasKeyword("Infect") || target.hasKeyword("Wither")) {
CardList indestructibles = damageableWolves.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.hasKeyword("Indestructible");
}
});
indestructibles.shuffle();
indestructibles.get(0).addDamage(1, target);
}
// Then just add Damage randomnly
else {
damageableWolves.shuffle();
wolves.get(0).addDamage(1, target);
}
}
}
}
}//resolve()
};//SpellAbility
StringBuilder sb = new StringBuilder();
sb.append("Tap: Tap all untapped Wolf creatures you control. Each Wolf tapped ");
sb.append("this way deals damage equal to its power to target creature. That creature deals ");
sb.append("damage equal to its power divided as its controller chooses among any number of those Wolves.");
ability.setDescription(sb.toString());
card.addSpellAbility(ability);
}//*************** END ************ END **************************
/*
//*************** START *********** START **************************
else if (cardName.equals("Figure of Destiny")) {
Ability ability1 = new Ability(card, "RW") {
@Override
public void resolve() {
boolean artifact = false;
card.setBaseAttack(2);
card.setBaseDefense(2);
card.removeIntrinsicKeyword("Flying");
card.removeIntrinsicKeyword("First Strike");
if (card.isArtifact()) artifact = true;
card.setType(new ArrayList<String>());
if (artifact) card.addType("Artifact");
card.addType("Creature");
card.addType("Kithkin");
card.addType("Spirit");
}
@Override
public boolean canPlayAI() {
return !card.isType("Spirit")
&& super.canPlayAI();
}
};// ability1
ability1.setDescription("RW: Figure of Destiny becomes a 2/2 Kithkin Spirit.");
ability1.setStackDescription("Figure of Destiny becomes a 2/2 Kithkin Spirit.");
card.addSpellAbility(ability1);
Ability ability2 = new Ability(card, "RW RW RW") {
@Override
public void resolve() {
if (card.isType("Spirit")) {
boolean artifact = false;
card.setBaseAttack(4);
card.setBaseDefense(4);
card.removeIntrinsicKeyword("Flying");
card.removeIntrinsicKeyword("First Strike");
if (card.isArtifact()) artifact = true;
card.setType(new ArrayList<String>());
if (artifact) card.addType("Artifact");
card.addType("Creature");
card.addType("Kithkin");
card.addType("Spirit");
card.addType("Warrior");
}
}
@Override
public boolean canPlay() {
return card.isType("Spirit")
&& super.canPlay();
}
@Override
public boolean canPlayAI() {
return !card.isType("Warrior")
&& super.canPlayAI();
}
};// ability2
ability2.setDescription("RW RW RW: If Figure of Destiny is a Spirit, it becomes a 4/4 Kithkin Spirit Warrior.");
ability2.setStackDescription("Figure of Destiny becomes a 4/4 Kithkin Spirit Warrior.");
card.addSpellAbility(ability2);
Ability ability3 = new Ability(card, "RW RW RW RW RW RW") {
@Override
public void resolve() {
if (card.isType("Warrior")) {
boolean artifact = false;
card.setBaseAttack(8);
card.setBaseDefense(8);
card.addIntrinsicKeyword("Flying");
card.addIntrinsicKeyword("First Strike");
if (card.isArtifact()) artifact = true;
card.setType(new ArrayList<String>());
if (artifact) card.addType("Artifact");
card.addType("Creature");
card.addType("Kithkin");
card.addType("Spirit");
card.addType("Warrior");
card.addType("Avatar");
}
}
@Override
public boolean canPlay() {
return card.isType("Warrior")
&& super.canPlay();
}
@Override
public boolean canPlayAI() {
return !card.isType("Avatar")
&& super.canPlayAI();
}
};// ability3
StringBuilder sbDesc = new StringBuilder();
sbDesc.append("RW RW RW RW RW RW: If Figure of Destiny is a Warrior, it becomes ");
sbDesc.append("an 8/8 Kithkin Spirit Warrior Avatar with flying and first strike.");
ability3.setDescription(sbDesc.toString());
ability3.setStackDescription("Figure of Destiny becomes an 8/8 Kithkin Spirit Warrior Avatar with flying and first strike.");
card.addSpellAbility(ability3);
}//*************** END ************ END **************************
*/
//*************** START *********** START **************************
else if (cardName.equals("Cantivore")) {
SpellAbility spell = new Spell_Permanent(card) {
private static final long serialVersionUID = 7254358703158629514L;
@Override
public boolean canPlayAI() {
CardList list = AllZoneUtil.getPlayerGraveyard(AllZone.getComputerPlayer());
list.addAll(AllZoneUtil.getPlayerGraveyard(AllZone.getHumanPlayer()));
list = list.getType("Enchantment");
return super.canPlayAI() && list.size() > 0;
}
};
// Do not remove SpellAbilities created by AbilityFactory or Keywords.
card.clearFirstSpell();
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Terravore")) {
SpellAbility spell = new Spell_Permanent(card) {
private static final long serialVersionUID = 7316190829288665283L;
@Override
public boolean canPlayAI() {
CardList list = AllZoneUtil.getPlayerGraveyard(AllZone.getComputerPlayer());
list.addAll(AllZoneUtil.getPlayerGraveyard(AllZone.getHumanPlayer()));
list = list.getType("Land");
return super.canPlayAI() && list.size() > 0;
}
};
// Do not remove SpellAbilities created by AbilityFactory or Keywords.
card.clearFirstSpell();
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Mortivore")) {
SpellAbility spell = new Spell_Permanent(card) {
private static final long serialVersionUID = -7118801410173525870L;
@Override
public boolean canPlayAI() {
CardList list = AllZoneUtil.getPlayerGraveyard(AllZone.getComputerPlayer());
list.addAll(AllZoneUtil.getPlayerGraveyard(AllZone.getHumanPlayer()));
list = list.getType("Creature");
return super.canPlayAI() && list.size() > 0;
}
};
// Do not remove SpellAbilities created by AbilityFactory or Keywords.
card.clearFirstSpell();
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Cognivore")) {
SpellAbility spell = new Spell_Permanent(card) {
private static final long serialVersionUID = -2216181341715046786L;
@Override
public boolean canPlayAI() {
CardList list = AllZoneUtil.getPlayerGraveyard(AllZone.getComputerPlayer());
list.addAll(AllZoneUtil.getPlayerGraveyard(AllZone.getHumanPlayer()));
list = list.getType("Instant");
return super.canPlayAI() && list.size() > 0;
}
};
// Do not remove SpellAbilities created by AbilityFactory or Keywords.
card.clearFirstSpell();
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Magnivore")) {
SpellAbility spell = new Spell_Permanent(card) {
private static final long serialVersionUID = -2252263708643462897L;
@Override
public boolean canPlayAI() {
CardList list = AllZoneUtil.getPlayerGraveyard(AllZone.getComputerPlayer());
list.addAll(AllZoneUtil.getPlayerGraveyard(AllZone.getHumanPlayer()));
list = list.getType("Sorcery");
return super.canPlayAI() && list.size() > 0;
}
};
// Do not remove SpellAbilities created by AbilityFactory or Keywords.
card.clearFirstSpell();
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Shifting Wall") || cardName.equals("Maga, Traitor to Mortals") || cardName.equals("Feral Hydra")
|| cardName.equals("Krakilin") || cardName.equals("Ivy Elemental") || cardName.equals("Lightning Serpent")) {
SpellAbility spell = new Spell_Permanent(card) {
private static final long serialVersionUID = 7708945715867177172L;
@Override
public boolean canPlayAI() {
return super.canPlay() && 4 <= ComputerUtil.getAvailableMana().size() - CardUtil.getConvertedManaCost(card.getManaCost());
}
};
card.clearFirstSpell();
card.addFirstSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Apocalypse Hydra")) {
SpellAbility spell = new Spell_Permanent(card) {
private static final long serialVersionUID = -11489323313L;
@Override
public boolean canPlayAI() {
return super.canPlay() && 5 <= ComputerUtil.getAvailableMana().size() - 2;
}
@Override
public void resolve() {
int XCounters = card.getXManaCostPaid();
Card c = AllZone.getGameAction().moveToPlay(getSourceCard());
if (XCounters >= 5) XCounters = 2 * XCounters;
c.addCounter(Counters.P1P1, XCounters);
}
};
// Do not remove SpellAbilities created by AbilityFactory or Keywords.
card.clearFirstSpell();
card.addSpellAbility(spell);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Molten Hydra")) {
Target target = new Target(card, "TgtCP");
Cost abCost = new Cost("T", cardName, true);
final Ability_Activated ability2 = new Ability_Activated(card, abCost, target) {
private static final long serialVersionUID = 2626619319289064289L;
@Override
public boolean canPlay() {
return card.getCounters(Counters.P1P1) > 0 && super.canPlay();
}
@Override
public boolean canPlayAI() {
return getCreature().size() != 0;
}
@Override
public void chooseTargetAI() {
if (AllZone.getHumanPlayer().getLife() < card.getCounters(Counters.P1P1))
setTargetPlayer(AllZone.getHumanPlayer());
else {
CardList list = getCreature();
list.shuffle();
setTargetCard(list.get(0));
}
}//chooseTargetAI()
CardList getCreature() {
//toughness of 1
CardList list = CardFactoryUtil.AI_getHumanCreature(card.getCounters(Counters.P1P1), card, true);
list = list.filter(new CardListFilter() {
public boolean addCard(Card c) {
int total = card.getCounters(Counters.P1P1);
return (total >= c.getKillDamage());
}
});
return list;
}//getCreature()
@Override
public void resolve() {
int total = card.getCounters(Counters.P1P1);
if (getTargetCard() != null) {
if (AllZoneUtil.isCardInPlay(getTargetCard())
&& CardFactoryUtil.canTarget(card, getTargetCard())) getTargetCard().addDamage(total,
card);
} else getTargetPlayer().addDamage(total, card);
card.subtractCounter(Counters.P1P1, total);
}//resolve()
};//SpellAbility
card.addSpellAbility(ability2);
StringBuilder sb = new StringBuilder();
sb.append(abCost + "Remove all +1/+1 counters from " + cardName + ": " + cardName);
sb.append(" deals damage to target creature or player equal to the number of +1/+1 counters removed this way.");
ability2.setDescription(sb.toString());
ability2.setStackDescription("Molten Hydra deals damage to number of +1/+1 counters on it to target creature or player.");
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Academy Rector") || cardName.equals("Lost Auramancers")) {
final SpellAbility ability = new Ability(card, "0") {
@Override
public void resolve() {
if (card.getController().isHuman()) {
StringBuilder question = new StringBuilder();
if (card.getName().equals("Academy Rector")) {
question.append("Exile ").append(card.getName()).append(" and place ");
} else {
question.append("Place ");
}
question.append("an enchantment from your library onto the battlefield?");
if (GameActionUtil.showYesNoDialog(card, question.toString())) {
if (card.getName().equals("Academy Rector")) {
AllZone.getGameAction().exile(card);
}
CardList list = AllZoneUtil.getPlayerCardsInLibrary(AllZone.getHumanPlayer());
list = list.getType("Enchantment");
if (list.size() > 0) {
Object objectSelected = GuiUtils.getChoiceOptional("Choose an enchantment", list.toArray());
if (objectSelected != null) {
final Card c = (Card) objectSelected;
AllZone.getGameAction().moveToPlay(c);
if (c.isAura()) {
String enchantThisType[] = {""};
String message[] = {""};
// The type following "Enchant" maybe upercase or lowercase, cardsfolder has both
// Note that I am being overly cautious.
if (c.hasKeyword("Enchant creature without flying")
|| c.hasKeyword("Enchant Creature without flying")) {
enchantThisType[0] = "Creature.withoutFlying";
message[0] = "Select a creature without flying";
} else if (c.hasKeyword("Enchant creature with converted mana cost 2 or less")
|| c.hasKeyword("Enchant Creature with converted mana cost 2 or less")) {
enchantThisType[0] = "Creature.cmcLE2";
message[0] = "Select a creature with converted mana cost 2 or less";
} else if (c.hasKeyword("Enchant red or green creature")) {
enchantThisType[0] = "Creature.Red,Creature.Green";
message[0] = "Select a red or green creature";
} else if (c.hasKeyword("Enchant tapped creature")) {
enchantThisType[0] = "Creature.tapped";
message[0] = "Select a tapped creature";
} else if (c.hasKeyword("Enchant creature")
|| c.hasKeyword("Enchant Creature")) {
enchantThisType[0] = "Creature";
message[0] = "Select a creature";
} else if (c.hasKeyword("Enchant wall")
|| c.hasKeyword("Enchant Wall")) {
enchantThisType[0] = "Wall";
message[0] = "Select a Wall";
} else if (c.hasKeyword("Enchant land you control")
|| c.hasKeyword("Enchant Land you control")) {
enchantThisType[0] = "Land.YouCtrl";
message[0] = "Select a land you control";
} else if (c.hasKeyword("Enchant land")
|| c.hasKeyword("Enchant Land")) {
enchantThisType[0] = "Land";
message[0] = "Select a land";
} else if (c.hasKeyword("Enchant artifact")
|| c.hasKeyword("Enchant Artifact")) {
enchantThisType[0] = "Artifact";
message[0] = "Select an artifact";
} else if (c.hasKeyword("Enchant enchantment")
|| c.hasKeyword("Enchant Enchantment")) {
enchantThisType[0] = "Enchantment";
message[0] = "Select an enchantment";
}
CardList allCards = AllZoneUtil.getCardsInPlay();
// Make sure that we were able to match the selected aura with our list of criteria
if (enchantThisType[0] != "" && message[0] != "") {
final CardList choices = allCards.getValidCards(enchantThisType[0], card.getController(), card);
final String msg = message[0];
AllZone.getInputControl().setInput(new Input() {
private static final long serialVersionUID = -6271957194091955059L;
@Override
public void showMessage() {
AllZone.getDisplay().showMessage(msg);
ButtonUtil.enableOnlyOK();
}
@Override
public void selectButtonOK() {
stop();
}
@Override
public void selectCard(Card card, PlayerZone zone) {
if (choices.contains(card)) {
if (AllZoneUtil.isCardInPlay(card)) {
c.enchantCard(card);
stop();
}
}
}//selectCard()
});// Input()
}// if we were able to match the selected aura with our list of criteria
}// If enchantment selected is an aura
}// If an enchantment is selected
}// If there are enchantments in library
card.getController().shuffle();
}// If answered yes to may exile
}// If player is human
// player is the computer
else {
CardList list = AllZoneUtil.getPlayerCardsInLibrary(AllZone.getComputerPlayer());
list = list.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.isEnchantment() && !c.isAura();
}
});
if (list.size() > 0) {
Card c = CardFactoryUtil.AI_getBestEnchantment(list, card, false);
AllZone.getGameAction().moveToPlay(c);
if (card.getName().equals("Academy Rector")) {
AllZone.getGameAction().exile(card);
}
card.getController().shuffle();
}
}// player is the computer
}// resolve()
};// ability
StringBuilder sb = new StringBuilder();
if (card.getName().equals("Academy Rector")) {
sb.append("Academy Rector - ").append(card.getController());
sb.append(" may exile this card and place an enchantment from his library onto the battlefield.");
} else {
sb.append("Lost Auramancers - ").append(card.getController());
sb.append(" may place an enchantment from his library onto the battlefield.");
}
ability.setStackDescription(sb.toString());
final Command destroy = new Command() {
private static final long serialVersionUID = -4352349741511065318L;
public void execute() {
if (card.getName().equals("Lost Auramancers")
&& card.getCounters(Counters.TIME) <= 0) {
AllZone.getStack().addSimultaneousStackEntry(ability);
} else if (card.getName().equals("Academy Rector")) {
AllZone.getStack().addSimultaneousStackEntry(ability);
}
}// execute()
};// Command destroy
card.addDestroyCommand(destroy);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Deadly Grub")) {
final Command destroy = new Command() {
private static final long serialVersionUID = -4352349741511065318L;
public void execute() {
if (card.getCounters(Counters.TIME) <= 0) CardFactoryUtil.makeToken("Insect", "G 6 1 Insect",
card.getController(), "G", new String[]{"Creature", "Insect"}, 6, 1, new String[]{"Shroud"});
}
};
card.addDestroyCommand(destroy);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Meddling Mage")) {
final String[] input = new String[1];
final Ability ability = new Ability(card, "0") {
@Override
public void resolve() {
if (card.getController().isHuman()) {
input[0] = JOptionPane.showInputDialog(null, "Which card?", "Pick card",
JOptionPane.QUESTION_MESSAGE);
card.setNamedCard(input[0]);
} else {
String s = "Ancestral Recall";
CardList list = new CardList();
list.addAll(AllZoneUtil.getPlayerHand(AllZone.getHumanPlayer()));
list.addAll(AllZoneUtil.getPlayerCardsInLibrary(AllZone.getHumanPlayer()));
list = list.filter(new CardListFilter() {
public boolean addCard(Card c) {
return !c.isLand() && !c.isUnCastable();
}
});
if (list.size() > 0) {
CardList rare;
rare = list;
rare = rare.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.getRarity().equals("Rare");
}
});
if (rare.size() > 0) {
s = rare.get(CardUtil.getRandomIndex(rare)).getName();
} else {
Card c = list.get(CardUtil.getRandomIndex(list));
//System.out.println(c + " - " + c.getRarity());
s = c.getName();
}
}
card.setNamedCard(s);
}
}
};
Command comesIntoPlay = new Command() {
private static final long serialVersionUID = 8485080996453793968L;
public void execute() {
AllZone.getStack().addSimultaneousStackEntry(ability);
}
};//Command
ability.setStackDescription("As Meddling Mage enters the battlefield, name a nonland card.");
card.addComesIntoPlayCommand(comesIntoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Iona, Shield of Emeria")) {
Command comesIntoPlay = new Command() {
private static final long serialVersionUID = 3331342605626623161L;
public void execute() {
if (card.getController().isHuman()) {
String color = "";
String[] colors = Constant.Color.Colors;
colors[colors.length - 1] = null;
Object o = GuiUtils.getChoice("Choose color", colors);
color = (String) o;
card.setChosenColor(color);
} else {
CardList list = new CardList();
list.addAll(AllZoneUtil.getPlayerCardsInLibrary(AllZone.getHumanPlayer()));
list.addAll(AllZoneUtil.getPlayerHand(AllZone.getHumanPlayer()));
if (list.size() > 0) {
String color = CardFactoryUtil.getMostProminentColor(list);
if (!color.equals("")) card.setChosenColor(color);
else card.setChosenColor("black");
} else {
card.setChosenColor("black");
}
}
}
};//Command
card.addComesIntoPlayCommand(comesIntoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Singe-Mind Ogre")) {
final SpellAbility ability = new Ability(card, "0") {
@Override
public void resolve() {
Player opponent = card.getController().getOpponent();
CardList handChoices = AllZoneUtil.getPlayerHand(opponent);
if (handChoices.size() > 0) {
Card random = CardUtil.getRandom(handChoices.toArray());
CardList reveal = new CardList(random);
GuiUtils.getChoice("Random card", reveal);
opponent.loseLife(CardUtil.getConvertedManaCost(random.getManaCost()), card);
}
}//resolve()
};
Command intoPlay = new Command() {
private static final long serialVersionUID = -4833144157620224716L;
public void execute() {
ability.setStackDescription("When CARDNAME enters the battlefield, target player reveals a card at random from his or her hand, then loses life equal to that card's converted mana cost.");
AllZone.getStack().addSimultaneousStackEntry(ability);
}
};
card.addComesIntoPlayCommand(intoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Kinsbaile Borderguard")) {
final SpellAbility ability = new Ability(card, "0") {
@Override
public void resolve() {
card.addCounter(Counters.P1P1, countKithkin());
//System.out.println("all counters: " +card.sumAllCounters());
}//resolve()
public int countKithkin() {
CardList kithkin = AllZoneUtil.getPlayerCardsInPlay(card.getController());
kithkin = kithkin.filter(new CardListFilter() {
public boolean addCard(Card c) {
return (c.isType("Kithkin") || c.hasKeyword("Changeling"))
&& !c.equals(card);
}
});
return kithkin.size();
}
};
Command intoPlay = new Command() {
private static final long serialVersionUID = -7067218066522935060L;
public void execute() {
ability.setStackDescription("Kinsbaile Borderguard enters the battlefield with a +1/+1 counter on it for each other Kithkin you control.");
AllZone.getStack().addSimultaneousStackEntry(ability);
}
};
final SpellAbility ability2 = new Ability(card, "0") {
@Override
public void resolve() {
for (int i = 0; i < card.sumAllCounters(); i++) {
makeToken();
}
}//resolve()
public void makeToken() {
CardFactoryUtil.makeToken("Kithkin Soldier", "W 1 1 Kithkin Soldier", card.getController(), "W", new String[]{
"Creature", "Kithkin", "Soldier"}, 1, 1, new String[]{""});
}
};
Command destroy = new Command() {
private static final long serialVersionUID = 304026662487997331L;
public void execute() {
ability2.setStackDescription("When Kinsbaile Borderguard is put into a graveyard from play, put a 1/1 white " +
"Kithkin Soldier creature token onto the battlefield for each counter on it.");
AllZone.getStack().addSimultaneousStackEntry(ability2);
}
};
card.addComesIntoPlayCommand(intoPlay);
card.addDestroyCommand(destroy);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Arctic Nishoba")) {
final Ability ability = new Ability(card, "0") {
@Override
public void resolve() {
int lifeGain = card.getCounters(Counters.AGE) * 2;
card.getController().gainLife(lifeGain, card);
}
};
Command destroy = new Command() {
private static final long serialVersionUID = 1863551466234257411L;
public void execute() {
StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - gain 2 life for each age counter on it.");
ability.setStackDescription(sb.toString());
AllZone.getStack().addSimultaneousStackEntry(ability);
}
};//command
card.addDestroyCommand(destroy);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Kavu Titan")) {
final SpellAbility kicker = new Spell(card) {
private static final long serialVersionUID = -1598664196463358630L;
@Override
public void resolve() {
card.setKicked(true);
AllZone.getGameAction().moveToPlay(card);
}
@Override
public boolean canPlay() {
return super.canPlay() && AllZone.getPhase().getPlayerTurn().equals(card.getController())
&& !AllZone.getPhase().getPhase().equals("End of Turn")
&& !AllZoneUtil.isCardInPlay(card);
}
};
kicker.setKickerAbility(true);
kicker.setManaCost("3 G G");
kicker.setAdditionalManaCost("2 G");
kicker.setDescription("Kicker 2 G");
StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - Creature 5/5 (Kicked)");
kicker.setStackDescription(sb.toString());
card.addSpellAbility(kicker);
final Ability ability = new Ability(card, "0") {
@Override
public void resolve() {
card.addCounter(Counters.P1P1, 3);
card.addIntrinsicKeyword("Trample");
card.setKicked(false);
}
};
Command commandComes = new Command() {
private static final long serialVersionUID = -2622859088591798773L;
public void execute() {
if (card.isKicked()) {
ability.setStackDescription("Kavu Titan gets 3 +1/+1 counters and gains trample.");
AllZone.getStack().addSimultaneousStackEntry(ability);
}
}//execute()
};//CommandComes
card.addComesIntoPlayCommand(commandComes);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Gnarlid Pack") || cardName.equals("Apex Hawks") || cardName.equals("Enclave Elite") ||
cardName.equals("Quag Vampires") || cardName.equals("Skitter of Lizards") ||
cardName.equals("Joraga Warcaller")) {
final Ability_Static ability = new Ability_Static(card, "0") {
@Override
public void resolve() {
card.addCounter(Counters.P1P1, card.getMultiKickerMagnitude());
card.setMultiKickerMagnitude(0);
}
};
StringBuilder sb = new StringBuilder();
sb.append(cardName);
sb.append(" enters the battlefield with a +1/+1 counter on it for each time it was kicked.");
ability.setStackDescription(sb.toString());
final Command comesIntoPlay = new Command() {
private static final long serialVersionUID = 4245563898487609274L;
public void execute() {
AllZone.getStack().addSimultaneousStackEntry(ability);
}
};
card.addComesIntoPlayCommand(comesIntoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Storm Entity")) {
final SpellAbility intoPlay = new Ability(card, "0") {
@Override
public boolean canPlayAI() {
CardList human = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer());
CardListUtil.sortAttack(human);
return (human.get(0).getNetAttack() < Phase.getStormCount() && Phase.getStormCount() > 1);
}
@Override
public void resolve() {
for (int i = 0; i < Phase.getStormCount() - 1; i++) {
card.addCounter(Counters.P1P1, 1);
}
}
};//SpellAbility
Command comesIntoPlay = new Command() {
private static final long serialVersionUID = -3734151854295L;
public void execute() {
AllZone.getStack().addSimultaneousStackEntry(intoPlay);
}
};
StringBuilder sb = new StringBuilder();
sb.append(cardName).append(" - enters the battlefield with a +1/+1 counter on it for each other spell played this turn.");
intoPlay.setStackDescription(sb.toString());
card.addComesIntoPlayCommand(comesIntoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Vampire Hexmage")) {
/*
* Sacrifice Vampire Hexmage: Remove all counters from target permanent.
*/
Cost cost = new Cost("Sac<1/CARDNAME>", cardName, true);
final Target tgt = new Target(card, "Select a permanent", "Permanent".split(","));
final SpellAbility ability = new Ability_Activated(card, cost, tgt) {
private static final long serialVersionUID = -5084369399105353155L;
@Override
public boolean canPlayAI() {
//Dark Depths:
CardList list = AllZoneUtil.getPlayerCardsInPlay(AllZone.getComputerPlayer(), "Dark Depths");
list = list.filter(new CardListFilter() {
public boolean addCard(Card crd) {
return crd.getCounters(Counters.ICE) >= 3;
}
});
if (list.size() > 0) {
tgt.addTarget(list.get(0));
return true;
}
//Get rid of Planeswalkers:
list = AllZoneUtil.getPlayerCardsInPlay(AllZone.getHumanPlayer());
list = list.filter(new CardListFilter() {
public boolean addCard(Card crd) {
return crd.isPlaneswalker() && crd.getCounters(Counters.LOYALTY) >= 5;
}
});
if (list.size() > 0) {
tgt.addTarget(list.get(0));
return true;
}
return false;
}
@Override
public void resolve() {
final Card c = getTargetCard();
for (Counters counter : Counters.values()) {
if (c.getCounters(counter) > 0) {
c.setCounter(counter, 0, false);
}
}
}
};
card.addSpellAbility(ability);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Sutured Ghoul")) {
final int[] numCreatures = new int[1];
final int[] sumPower = new int[1];
final int[] sumToughness = new int[1];
Command intoPlay = new Command() {
private static final long serialVersionUID = -75234586897814L;
public void execute() {
int intermSumPower, intermSumToughness;
intermSumPower = intermSumToughness = 0;
CardList creats = AllZoneUtil.getPlayerGraveyard(card.getController());
creats = creats.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.isCreature() && !c.equals(card);
}
});
if (card.getController().isHuman()) {
if (creats.size() > 0) {
List<Card> selection = GuiUtils.getChoicesOptional("Select creatures to sacrifice", creats.toArray());
numCreatures[0] = selection.size();
for (int m = 0; m < selection.size(); m++) {
intermSumPower += selection.get(m).getBaseAttack();
intermSumToughness += selection.get(m).getBaseDefense();
AllZone.getGameAction().exile(selection.get(m));
}
}
}//human
else {
int count = 0;
for (int i = 0; i < creats.size(); i++) {
Card c = creats.get(i);
if (c.getNetAttack() <= 2 && c.getNetDefense() <= 3) {
intermSumPower += c.getBaseAttack();
intermSumToughness += c.getBaseDefense();
AllZone.getGameAction().exile(c);
count++;
}
//is this needed?
AllZone.getComputerBattlefield().updateObservers();
}
numCreatures[0] = count;
}
sumPower[0] = intermSumPower;
sumToughness[0] = intermSumToughness;
card.setBaseAttack(sumPower[0]);
card.setBaseDefense(sumToughness[0]);
}
};
// Do not remove SpellAbilities created by AbilityFactory or Keywords.
card.clearFirstSpell();
card.addComesIntoPlayCommand(intoPlay);
card.addSpellAbility(new Spell_Permanent(card) {
private static final long serialVersionUID = 304885517082977723L;
@Override
public boolean canPlayAI() {
//get all creatures
CardList list = AllZoneUtil.getPlayerGraveyard(AllZone.getComputerPlayer());
list = list.filter(AllZoneUtil.creatures);
return 0 < list.size();
}
});
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Nameless Race")) {
/*
* As Nameless Race enters the battlefield, pay any amount of life.
* The amount you pay can't be more than the total number of white
* nontoken permanents your opponents control plus the total number
* of white cards in their graveyards.
* Nameless Race's power and toughness are each equal to the life
* paid as it entered the battlefield.
*/
final SpellAbility ability = new Ability(card, "0") {
@Override
public void resolve() {
Player player = card.getController();
Player opp = player.getOpponent();
int max = 0;
CardList play = AllZoneUtil.getPlayerCardsInPlay(opp);
play = play.filter(AllZoneUtil.nonToken);
play = play.filter(AllZoneUtil.white);
max += play.size();
CardList grave = AllZoneUtil.getPlayerGraveyard(opp);
grave = grave.filter(AllZoneUtil.white);
max += grave.size();
String[] life = new String[max + 1];
for (int i = 0; i <= max; i++) {
life[i] = String.valueOf(i);
}
Object o = GuiUtils.getChoice("Nameless Race - pay X life", life);
String answer = (String) o;
int loseLife = 0;
try {
loseLife = Integer.parseInt(answer.trim());
} catch (NumberFormatException nfe) {
System.out.println(card.getName() + " - NumberFormatException: " + nfe.getMessage());
}
card.setBaseAttack(loseLife);
card.setBaseDefense(loseLife);
player.loseLife(loseLife, card);
}//resolve()
};//SpellAbility
Command intoPlay = new Command() {
private static final long serialVersionUID = 931101364538995898L;
public void execute() {
AllZone.getStack().addSimultaneousStackEntry(ability);
}
};
StringBuilder sb = new StringBuilder();
sb.append(cardName).append(" - pay any amount of life.");
ability.setStackDescription(sb.toString());
card.addComesIntoPlayCommand(intoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Banshee")) {
/*
* X, Tap: Banshee deals half X damage, rounded down, to target creature or
* player, and half X damage, rounded up, to you.
*/
Cost abCost = new Cost("X T", cardName, true);
Target tgt = new Target(card, "TgtCP");
final Ability_Activated ability = new Ability_Activated(card, abCost, tgt) {
private static final long serialVersionUID = 2755743211116192949L;
@Override
public void resolve() {
int x = card.getXManaCostPaid();
if (getTargetPlayer() == null) {
getTargetCard().addDamage((int) Math.floor(x / 2.0), card);
} else {
getTargetPlayer().addDamage((int) Math.floor(x / 2.0), card);
}
card.getController().addDamage((int) Math.ceil(x / 2.0), card);
card.setXManaCostPaid(0);
}//resolve()
@Override
public boolean canPlayAI() {
return false;
}
};//SpellAbility
ability.setDescription("X, tap: " + "Banshee deals half X damage, rounded down, to target creature or player, and half X damage, rounded up, to you.");
ability.setStackDescription(card.getName() + " - Banshee deals half X damage, rounded down, to target creature or player, and half X damage, rounded up, to you.");
card.addSpellAbility(ability);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Shapeshifter")) {
Command intoPlay = new Command() {
private static final long serialVersionUID = 5447692676152380940L;
public void execute() {
if (!card.isToken()) { //ugly hack to get around tokens created by Crib Swap
int num = 0;
if (card.getController().isHuman()) {
String[] choices = new String[7];
for (int j = 0; j < 7; j++) {
choices[j] = "" + j;
}
String answer = (String) (GuiUtils.getChoiceOptional(
card.getName() + " - Choose a number", choices));
num = Integer.parseInt(answer);
} else {
num = 3;
}
card.setBaseAttack(num);
card.setBaseDefense(7 - num);
}
}
};
card.addComesIntoPlayCommand(intoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Metalworker")) {
final Cost abCost = new Cost("T", card.getName(), true);
final SpellAbility ability = new Ability_Activated(card, abCost, null) {
private static final long serialVersionUID = 6661308920885136284L;
@Override
public boolean canPlayAI() {
//compy doesn't have a manapool
return false;
}//canPlayAI()
@Override
public void resolve() {
AllZone.getInputControl().setInput(new Input() {
private static final long serialVersionUID = 6150236529653275947L;
CardList revealed = new CardList();
@Override
public void showMessage() {
//in case hand is empty, don't do anything
if (AllZoneUtil.getPlayerHand(card.getController()).size() == 0) stop();
AllZone.getDisplay().showMessage(card.getName() + " - Reveal an artifact. Revealed " + revealed.size() + " so far. Click OK when done.");
ButtonUtil.enableOnlyOK();
}
@Override
public void selectCard(Card c, PlayerZone zone) {
if (zone.is(Constant.Zone.Hand) && c.isArtifact() && !revealed.contains(c)) {
revealed.add(c);
//in case no more cards in hand to reveal
if (revealed.size() == AllZoneUtil.getPlayerHand(card.getController()).size()) done();
else
showMessage();
}
}
@Override
public void selectButtonOK() {
done();
}
void done() {
StringBuilder sb = new StringBuilder();
for (Card reveal : revealed) sb.append(reveal.getName() + "\n");
JOptionPane.showMessageDialog(null, "Revealed Cards:\n" + sb.toString(), card.getName(), JOptionPane.PLAIN_MESSAGE);
//adding mana
Ability_Mana abMana = new Ability_Mana(card, "0", "1", 2 * revealed.size()) {
private static final long serialVersionUID = -2182129023960978132L;
};
abMana.setUndoable(false);
abMana.produceMana();
stop();
}
});
}//resolve()
};//SpellAbility
ability.setDescription(abCost + "Reveal any number of artifact cards in your hand. Add 2 to your mana pool for each card revealed this way.");
ability.setStackDescription(cardName + " - Reveal any number of artifact cards in your hand.");
card.addSpellAbility(ability);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Necratog")) {
final Command untilEOT = new Command() {
private static final long serialVersionUID = 6743592637334556854L;
public void execute() {
if (AllZoneUtil.isCardInPlay(card)) {
card.addTempAttackBoost(-2);
card.addTempDefenseBoost(-2);
}
}
};
final SpellAbility ability = new Ability(card, "0") {
@Override
public boolean canPlayAI() {
return false;
}
@Override
public boolean canPlay() {
CardList grave = AllZoneUtil.getPlayerGraveyard(card.getController());
grave = grave.filter(AllZoneUtil.creatures);
return super.canPlay() && grave.size() > 0;
}
@Override
public void resolve() {
if (AllZoneUtil.isCardInPlay(card)) {
card.addTempAttackBoost(2);
card.addTempDefenseBoost(2);
AllZone.getEndOfTurn().addUntil(untilEOT);
}
}
};
Input runtime = new Input() {
private static final long serialVersionUID = 63327418012595048L;
Card topCreature = null;
public void showMessage() {
PlayerZone grave = AllZone.getZone(Constant.Zone.Graveyard, card.getController());
for (int i = grave.size() - 1; i >= 0; i--) {
Card c = grave.get(i);
if (c.isCreature()) {
topCreature = c;
break;
}
}
AllZone.getDisplay().showMessage(card.getName() + " - Select OK to exile " + topCreature + ".");
ButtonUtil.enableAll();
}
public void selectButtonOK() {
AllZone.getGameAction().exile(topCreature);
AllZone.getStack().add(ability);
stop();
}
public void selectButtonCancel() {
stop();
}
};
ability.setDescription("Exile the top creature card of your graveyard: CARDNAME gets +2/+2 until end of turn.");
StringBuilder sb = new StringBuilder();
sb.append(card).append(" gets +2/+2 until end of turn.");
ability.setStackDescription(sb.toString());
ability.setBeforePayMana(runtime);
card.addSpellAbility(ability);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Phyrexian Scuta")) {
Cost abCost = new Cost("3 B PayLife<3>", cardName, false);
final SpellAbility kicker = new Spell(card, abCost, null) {
private static final long serialVersionUID = -6420757044982294960L;
@Override
public void resolve() {
card.setKicked(true);
AllZone.getGameAction().moveToPlay(card);
card.addCounterFromNonEffect(Counters.P1P1, 2);
}
@Override
public boolean canPlay() {
return super.canPlay() && card.getController().getLife() >= 3;
}
};
kicker.setKickerAbility(true);
kicker.setManaCost("3 B");
kicker.setDescription("Kicker - Pay 3 life.");
StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - Creature 3/3 (Kicked)");
kicker.setStackDescription(sb.toString());
card.addSpellAbility(kicker);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Yosei, the Morning Star")) {
final CardList targetPerms = new CardList();
final SpellAbility ability = new Ability(card, "0") {
@Override
public void resolve() {
Player p = getTargetPlayer();
if (p.canTarget(card)) {
p.setSkipNextUntap(true);
for (Card c : targetPerms) {
if (AllZoneUtil.isCardInPlay(c) && CardFactoryUtil.canTarget(card, c)) {
c.tap();
}
}
}
targetPerms.clear();
}//resolve()
};
final Input targetInput = new Input() {
private static final long serialVersionUID = -8727869672234802473L;
@Override
public void showMessage() {
if (targetPerms.size() == 5) done();
AllZone.getDisplay().showMessage("Select up to 5 target permanents. Selected (" + targetPerms.size() + ") so far. Click OK when done.");
ButtonUtil.enableOnlyOK();
}
@Override
public void selectButtonOK() {
done();
}
private void done() {
//here, we add the ability to the stack since it's triggered.
StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - tap up to 5 permanents target player controls. Target player skips his or her next untap step.");
ability.setStackDescription(sb.toString());
AllZone.getStack().add(ability);
stop();
}
@Override
public void selectCard(Card c, PlayerZone zone) {
if (zone.is(Constant.Zone.Battlefield, ability.getTargetPlayer()) && !targetPerms.contains(c)) {
if (CardFactoryUtil.canTarget(card, c)) {
targetPerms.add(c);
}
}
showMessage();
}
};//Input
final Input playerInput = new Input() {
private static final long serialVersionUID = 4765535692144126496L;
@Override
public void showMessage() {
AllZone.getDisplay().showMessage(card.getName() + " - Select target player");
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectPlayer(Player p) {
if (p.canTarget(card)) {
ability.setTargetPlayer(p);
stopSetNext(targetInput);
}
}
@Override
public void selectButtonCancel() {
stop();
}
};
Command destroy = new Command() {
private static final long serialVersionUID = -3868616119471172026L;
public void execute() {
Player player = card.getController();
CardList list = CardFactoryUtil.AI_getHumanCreature(card, true);
if (player.isHuman()) AllZone.getInputControl().setInput(playerInput);
else if (list.size() != 0) {
Card target = CardFactoryUtil.AI_getBestCreature(list);
ability.setTargetCard(target);
AllZone.getStack().addSimultaneousStackEntry(ability);
}
}//execute()
};
card.addDestroyCommand(destroy);
}
//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Phyrexian Dreadnought")) {
final Player player = card.getController();
final CardList toSac = new CardList();
final Ability sacOrSac = new Ability(card, "") {
@Override
public void resolve() {
if (player.isHuman()) {
Input target = new Input() {
private static final long serialVersionUID = 2698036349873486664L;
@Override
public void showMessage() {
String toDisplay = cardName + " - Select any number of creatures to sacrifice. ";
toDisplay += "Currently, (" + toSac.size() + ") selected with a total power of: " + getTotalPower();
toDisplay += " Click OK when Done.";
AllZone.getDisplay().showMessage(toDisplay);
ButtonUtil.enableAll();
}
@Override
public void selectButtonOK() {
done();
}
@Override
public void selectButtonCancel() {
toSac.clear();
AllZone.getGameAction().sacrifice(card);
stop();
}
@Override
public void selectCard(Card c, PlayerZone zone) {
if (c.isCreature() && zone.is(Constant.Zone.Battlefield, AllZone.getHumanPlayer())
&& !toSac.contains(c)) {
toSac.add(c);
}
showMessage();
}//selectCard()
private void done() {
if (getTotalPower() >= 12) {
for (Card sac : toSac) AllZone.getGameAction().sacrifice(sac);
} else {
AllZone.getGameAction().sacrifice(card);
}
toSac.clear();
stop();
}
};//Input
AllZone.getInputControl().setInput(target);
}
}//end resolve
private int getTotalPower() {
int sum = 0;
for (Card c : toSac) {
sum += c.getNetAttack();
}
return sum;
}
};// end sacOrSac
final Command comesIntoPlay = new Command() {
private static final long serialVersionUID = 7680692311339496770L;
public void execute() {
sacOrSac.setStackDescription("When " + cardName + " enters the battlefield, sacrifice it unless you sacrifice any number of creatures with total power 12 or greater.");
AllZone.getStack().addSimultaneousStackEntry(sacOrSac);
}
};
card.addComesIntoPlayCommand(comesIntoPlay);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Clone") || cardName.equals("Vesuvan Doppelganger")
|| cardName.equals("Quicksilver Gargantuan")
|| cardName.equals("Jwari Shapeshifter")
|| cardName.equals("Phyrexian Metamorph")) {
final CardFactory cfact = cf;
final Card[] copyTarget = new Card[1];
final Card[] cloned = new Card[1];
final Command leaves = new Command() {
private static final long serialVersionUID = 8590474793502538215L;
public void execute() {
//Slight hack if the cloner copies a card with triggers
AllZone.getTriggerHandler().removeAllFromCard(cloned[0]);
Card orig = cfact.getCard(card.getName(), card.getController());
PlayerZone dest = AllZone.getZone(card.getCurrentlyCloningCard());
AllZone.getGameAction().moveTo(dest, orig);
dest.remove(card.getCurrentlyCloningCard());
}
};
final SpellAbility copy = new Spell(card) {
private static final long serialVersionUID = 4496978456522751302L;
@Override
public void resolve() {
if (card.getController().isComputer()) {
CardList creatures = AllZoneUtil.getCreaturesInPlay();
if (!creatures.isEmpty()) {
copyTarget[0] = CardFactoryUtil.AI_getBestCreature(creatures);
}
}
if (copyTarget[0] != null) {
/*
* This cannot just be copyStats with an addSpellAbility loop from copyTarget[0].
* Unless we get a copySpellAbility. Adding the SpellAbility from the
* source card causes many weird and Bad Things to happen.
*/
try {
cloned[0] = cfact.getCard(copyTarget[0].getName(), card.getController());
}
catch(RuntimeException re) {
//the copyTarget was not found in CardFactory
cloned[0] = CardFactory.copyStats(copyTarget[0]);
}
cloned[0].setOwner(card.getController());
cloned[0].setController(card.getController());
if (cardName.equals("Phyrexian Metamorph")) cloned[0].addType("Artifact");
cloned[0].setCloneOrigin(card);
cloned[0].addLeavesPlayCommand(leaves);
cloned[0].setCloneLeavesPlayCommand(leaves);
cloned[0].setCurSetCode(copyTarget[0].getCurSetCode());
cloned[0].setImageFilename(copyTarget[0].getImageFilename());
if (cardName.equals("Vesuvan Doppelganger")) {
cloned[0].addExtrinsicKeyword("At the beginning of your upkeep, you may have this creature become a copy of target creature except it doesn't copy that creature's color. If you do, this creature gains this ability.");
cloned[0].addColor("U", cloned[0], false, true);
} else if (cardName.equals("Quicksilver Gargantuan")) {
cloned[0].setBaseDefense(7);
cloned[0].setBaseAttack(7);
}
//Slight hack in case the cloner copies a card with triggers
for (Trigger t : cloned[0].getTriggers()) {
AllZone.getTriggerHandler().registerTrigger(t);
}
AllZone.getGameAction().moveToPlayFromHand(cloned[0]);
card.setCurrentlyCloningCard(cloned[0]);
}
}
};//SpellAbility
Input runtime = new Input() {
private static final long serialVersionUID = 7615038074569687330L;
@Override
public void showMessage() {
String message = "Select a creature ";
if (cardName.equals("Phyrexian Metamorph")) message += "or artifact ";
message += "on the battlefield";
AllZone.getDisplay().showMessage(cardName + " - " + message);
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
stop();
}
@Override
public void selectCard(Card c, PlayerZone z) {
if (z.is(Constant.Zone.Battlefield) &&
(c.isCreature() || (cardName.equals("Phyrexian Metamorph") && c.isArtifact()))) {
if (cardName.equals("Jwari Shapeshifter") && !c.isType("Ally")) {
return;
}
copyTarget[0] = c;
stopSetNext(new Input_PayManaCost(copy));
}
}
};
// Do not remove SpellAbilities created by AbilityFactory or Keywords.
card.clearFirstSpell();
card.addSpellAbility(copy);
copy.setStackDescription(cardName + " - enters the battlefield as a copy of selected card.");
copy.setBeforePayMana(runtime);
}//*************** END ************ END **************************
//*************** START ************ START **************************
else if (cardName.equals("Nebuchadnezzar")) {
/*
* X, T: Name a card. Target opponent reveals X cards at random from his or her hand.
* Then that player discards all cards with that name revealed this way.
* Activate this ability only during your turn.
*/
Cost abCost = new Cost("X T", cardName, true);
Target target = new Target(card, "Select target opponent", "Opponent".split(","));
Ability_Activated discard = new Ability_Activated(card, abCost, target) {
private static final long serialVersionUID = 4839778470534392198L;
@Override
public void resolve() {
//name a card
String choice = JOptionPane.showInputDialog(null, "Name a card", cardName, JOptionPane.QUESTION_MESSAGE);
CardList hand = AllZoneUtil.getPlayerHand(getTargetPlayer());
int numCards = card.getXManaCostPaid();
numCards = Math.min(hand.size(), numCards);
CardList revealed = new CardList();
for (int i = 0; i < numCards; i++) {
Card random = CardUtil.getRandom(hand.toArray());
revealed.add(random);
hand.remove(random);
}
if (!revealed.isEmpty()) {
GuiUtils.getChoice("Revealed at random", revealed.toArray());
} else {
GuiUtils.getChoice("Revealed at random", new String[]{"Nothing to reveal"});
}
for (Card c : revealed) {
if (c.getName().equals(choice)) c.getController().discard(c, this);
}
}
@Override
public boolean canPlayAI() {
return false;
}
};
discard.getRestrictions().setPlayerTurn(true);
StringBuilder sbDesc = new StringBuilder();
sbDesc.append(abCost).append("Name a card. Target opponent reveals X cards at random from his or her hand. ");
sbDesc.append("Then that player discards all cards with that name revealed this way. ");
sbDesc.append("Activate this ability only during your turn.");
discard.setDescription(sbDesc.toString());
StringBuilder sbStack = new StringBuilder();
sbStack.append(cardName).append(" - name a card.");
discard.setStackDescription(sbStack.toString());
card.addSpellAbility(discard);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Brass Squire")) {
Target t2 = new Target(card, "Select target creature you control", "Creature.YouCtrl".split(","));
final Ability_Sub sub = new Ability_Sub(card, t2) {
private static final long serialVersionUID = -8926850792424930054L;
@Override
public boolean chkAI_Drawback() {
return false;
}
@Override
public void resolve() {
Card equipment = this.getParent().getTargetCard();
Card creature = getTargetCard();
if (AllZoneUtil.isCardInPlay(equipment) && AllZoneUtil.isCardInPlay(creature)) {
if (CardFactoryUtil.canTarget(card, equipment) && CardFactoryUtil.canTarget(card, creature)) {
if (equipment.isEquipping()) {
Card equipped = equipment.getEquipping().get(0);
if (!equipped.equals(creature)) {
equipment.unEquipCard(equipped);
equipment.equipCard(creature);
}
} else {
equipment.equipCard(getTargetCard());
}
}
}
}
@Override
public boolean doTrigger(boolean b) {
return false;
}
};
Cost abCost = new Cost("T", cardName, true);
Target t1 = new Target(card, "Select target equipment you control", "Equipment.YouCtrl".split(","));
final Ability_Activated ability = new Ability_Activated(card, abCost, t1) {
private static final long serialVersionUID = 3818559481920103914L;
@Override
public boolean canPlayAI() {
return false;
}
@Override
public void resolve() {
sub.resolve();
}
};
ability.setSubAbility(sub);
ability.setStackDescription(cardName + " - Attach target Equipment you control to target creature you control.");
card.addSpellAbility(ability);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Gore Vassal")) {
Cost abCost = new Cost("Sac<1/CARDNAME>", cardName, true);
final Ability_Activated ability = new Ability_Activated(card, abCost, new Target(card, "TgtC")) {
private static final long serialVersionUID = 3689290210743241201L;
@Override
public boolean canPlayAI() {
return false;
}
@Override
public void resolve() {
final Card target = getTargetCard();
if (AllZoneUtil.isCardInPlay(target) && CardFactoryUtil.canTarget(card, target)) {
target.addCounter(Counters.M1M1, 1);
if (target.getNetDefense() >= 1) {
target.addShield();
AllZone.getEndOfTurn().addUntil(new Command() {
private static final long serialVersionUID = -3332692040606224591L;
public void execute() {
target.resetShield();
}
});
}
}
}//resolve()
};//SpellAbility
card.addSpellAbility(ability);
ability.setDescription(abCost + "Put a -1/-1 counter on target creature. Then if that creature's toughness is 1 or greater, regenerate it.");
StringBuilder sb = new StringBuilder();
sb.append(cardName).append(" put a -1/-1 counter on target creature.");
ability.setStackDescription(sb.toString());
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Orcish Captain")) {
Cost abCost = new Cost("1", cardName, true);
Target target = new Target(card, "Select target Orc creature", "Creature.Orc".split(","));
final Ability_Activated ability = new Ability_Activated(card, abCost, target) {
private static final long serialVersionUID = 6724781940648179318L;
@Override
public boolean canPlayAI() {
return false;
}
@Override
public void resolve() {
final Card tgt = getTargetCard();
final boolean[] win = new boolean[1];
if (AllZoneUtil.isCardInPlay(tgt) && CardFactoryUtil.canTarget(card, tgt)) {
if (GameActionUtil.flipACoin(card.getController(), card)) {
tgt.addTempAttackBoost(2);
win[0] = true;
} else {
tgt.addTempDefenseBoost(-2);
win[0] = false;
}
final Command EOT = new Command() {
private static final long serialVersionUID = -7905540871887278236L;
public void execute() {
if (AllZoneUtil.isCardInPlay(tgt)) {
if (win[0]) {
tgt.addTempAttackBoost(-2);
} else {
tgt.addTempDefenseBoost(2);
}
}
}
};
AllZone.getEndOfTurn().addUntil(EOT);
}//if (card is in play)
}//resolve()
};//SpellAbility
card.addSpellAbility(ability);
ability.setDescription(abCost + "Flip a coin. If you win the flip, target Orc creature gets +2/+0 until end of turn. If you lose the flip, it gets -0/-2 until end of turn.");
}//*************** END ************ END **************************
/*
//*************** START *********** START **************************
else if (cardName.equals("Orcish Spy")) {
Target target = new Target(card, "Select target player", new String[]{"Player"});
Cost abCost = new Cost("T", cardName, true);
final Ability_Activated ability = new Ability_Activated(card, abCost, target) {
private static final long serialVersionUID = -7781215422160018196L;
@Override
public void resolve() {
final Player player = getTargetPlayer();
CardList lib = AllZoneUtil.getPlayerCardsInLibrary(player);
CardList toDisplay = new CardList();
for (int i = 0; i < 3 && i < lib.size(); i++) {
toDisplay.add(lib.get(i));
}
if (lib.size() > 0) {
GuiUtils.getChoice("Top three cards of " + player + "'s library", toDisplay.toArray());
} else {
StringBuilder sb = new StringBuilder();
sb.append(getTargetPlayer()).append("'s library is empty!");
javax.swing.JOptionPane.showMessageDialog(null, sb.toString(), "Target player's library", JOptionPane.INFORMATION_MESSAGE);
}
}//resolve()
@Override
public boolean canPlayAI() {
return false;
}
};//SpellAbility
ability.setDescription(abCost + "Look at the top three cards of target player's library.");
card.addSpellAbility(ability);
}//*************** END ************ END **************************
*/
//*************** START *********** START **************************
else if (cardName.equals("Awakener Druid")) {
final long[] timeStamp = {0};
Trigger myTrig = TriggerHandler.parseTrigger("Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | TriggerDescription$ When CARDNAME enters the battlefield, target Forest becomes a 4/5 green Treefolk creature for as long as CARDNAME is on the battlefield. It's still a land.", card);
Target myTarget = new Target(card, "Choose target forest.", "Land.Forest".split(","), "1", "1");
final SpellAbility awaken = new Ability(card, "0") {
@Override
public void resolve() {
if (!AllZone.getZone(card).is("Battlefield") || getTarget().getTargetCards().size() == 0)
return;
final Card c = getTarget().getTargetCards().get(0);
String[] types = {"Creature", "Treefolk"};
String[] keywords = {};
timeStamp[0] = CardFactoryUtil.activateManland(c, 4, 5, types, keywords, "G");
final Command onleave = new Command() {
private static final long serialVersionUID = -6004932214386L;
long stamp = timeStamp[0];
Card tgt = c;
public void execute() {
String[] types = {"Creature", "Treefolk"};
String[] keywords = {""};
CardFactoryUtil.revertManland(tgt, types, keywords, "G", stamp);
}
};
card.addLeavesPlayCommand(onleave);
}
};//SpellAbility
awaken.setTarget(myTarget);
myTrig.setOverridingAbility(awaken);
card.addTrigger(myTrig);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Duct Crawler") || cardName.equals("Shrewd Hatchling") || cardName.equals("Spin Engine")) {
String theCost = "0";
if (cardName.equals("Duct Crawler"))
theCost = "1 R";
else if (cardName.equals("Shrewd Hatchling"))
theCost = "UR";
else if (cardName.equals("Spin Engine"))
theCost = "R";
StringBuilder keywordBuilder = new StringBuilder("HIDDEN CARDNAME can't block ");
keywordBuilder.append(card.getName()).append(" (").append(card.getUniqueNumber()).append(")");
AbilityFactory createAb = new AbilityFactory();
StringBuilder abilityBuilder = new StringBuilder("AB$Pump | Cost$ ");
abilityBuilder.append(theCost);
abilityBuilder.append(" | Tgt$ TgtC | IsCurse$ True | KW$ ");
abilityBuilder.append(keywordBuilder.toString());
abilityBuilder.append(" | SpellDescription$ Target creature can't block CARDNAME this turn.");
SpellAbility myAb = createAb.getAbility(abilityBuilder.toString(), card);
card.addSpellAbility(myAb);
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Krovikan Sorcerer")) {
Cost abCost = new Cost("T Discard<1/Card.Black>", cardName, true);
final Ability_Activated ability = new Ability_Activated(card, abCost, null) {
private static final long serialVersionUID = 3689290210743241201L;
@Override
public boolean canPlayAI() {
return false;
}
@Override
public void resolve() {
final Player player = card.getController();
if (player.isHuman()) {
final CardList n = player.drawCards(2);
AllZone.getInputControl().setInput(new Input() {
private static final long serialVersionUID = -1411038851955251074L;
@Override
public void showMessage() {
if(n.isEmpty()) stop();
AllZone.getDisplay().showMessage(card+" - discard one of the cards drawn.");
ButtonUtil.disableAll();
}
@Override
public void selectCard(Card c, PlayerZone zone) {
if (zone.is(Constant.Zone.Hand) && n.contains(c)) {
player.discard(c, null);
stop();
}
}
});//end Input
}
}//resolve()
};//SpellAbility
card.addSpellAbility(ability);
ability.setDescription("Tap, Discard a black card: " + "Draw two cards, then discard one of them.");
StringBuilder sb = new StringBuilder();
sb.append(card).append(" - Draw two cards, then discard one of them.");
ability.setStackDescription(sb.toString());
}//*************** END ************ END **************************
//***************************************************
// end of card specific code
//***************************************************
if (hasKeyword(card, "Level up") != -1 && hasKeyword(card, "maxLevel") != -1) {
int n = hasKeyword(card, "Level up");
int m = hasKeyword(card, "maxLevel");
if (n != -1) {
String parse = card.getKeyword().get(n).toString();
String parseMax = card.getKeyword().get(m).toString();
card.removeIntrinsicKeyword(parse);
card.removeIntrinsicKeyword(parseMax);
String k[] = parse.split(":");
final String manacost = k[1];
String l[] = parseMax.split(":");
final int maxLevel = Integer.parseInt(l[1]);
final SpellAbility levelUp = new Ability_Activated(card, manacost) {
private static final long serialVersionUID = 3998280279949548652L;
public void resolve() {
card.addCounter(Counters.LEVEL, 1);
}
public boolean canPlayAI() {
// Todo: Improve Level up code
return card.getCounters(Counters.LEVEL) < maxLevel;
}
};
levelUp.getRestrictions().setSorcerySpeed(true);
card.addSpellAbility(levelUp);
StringBuilder sbDesc = new StringBuilder();
sbDesc.append("Level up ").append(manacost).append(" (").append(manacost);
sbDesc.append(": Put a level counter on this. Level up only as a sorcery.)");
levelUp.setDescription(sbDesc.toString());
StringBuilder sbStack = new StringBuilder();
sbStack.append(card).append(" - put a level counter on this.");
levelUp.setStackDescription(sbStack.toString());
card.setLevelUp(true);
}
}//level up
return card;
}
}