package forge.card.cardFactory; import forge.*; import forge.card.spellability.*; import forge.gui.GuiUtils; import forge.gui.input.Input; import forge.gui.input.Input_PayManaCost; import javax.swing.*; import java.util.ArrayList; /** * <p>CardFactory_Instants class.</p> * * @author Forge * @version $Id: $ */ public class CardFactory_Instants { /** * <p>getCard.</p> * * @param card a {@link forge.Card} object. * @param cardName a {@link java.lang.String} object. * @param owner a {@link forge.Player} object. * @return a {@link forge.Card} object. */ public static Card getCard(final Card card, final String cardName, Player owner) { //*************** START *********** START ************************** if (cardName.equals("Brave the Elements")) { /** * This card now works slightly better than it did before the spAllPump * keyword was created. The AI is too simple and needs some work. */ final SpellAbility spell = new Spell(card) { private static final long serialVersionUID = -7998437920995642451L; @Override public boolean canPlayAI() { return getAttacker() != null; } public Card getAttacker() { // target creatures that is going to attack Combat c = ComputerUtil.getAttackers(); Card[] att = c.getAttackers(); // Effect best used on at least a couple creatures if (att.length > 1) { return att[0]; } else return null; }//getAttacker() String getKeywordBoost() { String theColor = getChosenColor(); return "Protection from " + theColor; }//getKeywordBoost() String getChosenColor() { // Choose color for protection in Brave the Elements String color = ""; if (card.getController().isHuman()) { // String[] colors = Constant.Color.Colors; // colors[colors.length-1] = null; // You can no longer choose to gain "protection from null". String[] colors = Constant.Color.onlyColors; Object o = GuiUtils.getChoice("Choose color", colors); color = (String) o; } else { CardList list = new CardList(); list.addAll(AllZoneUtil.getPlayerCardsInLibrary(AllZone.getHumanPlayer())); list.addAll(AllZoneUtil.getPlayerHand(AllZone.getHumanPlayer())); if (list.size() > 0) { String mpcolor = CardFactoryUtil.getMostProminentColor(list); if (!mpcolor.equals("")) color = mpcolor; else color = "black"; } else { color = "black"; } } return color; } // getChosenColor @Override public void resolve() { final String kboost = getKeywordBoost(); CardList list = AllZoneUtil.getPlayerCardsInPlay(card.getController()); list = list.filter(AllZoneUtil.white); for (int i = 0; i < list.size(); i++) { final Card[] target = new Card[1]; target[0] = list.get(i); final Command untilEOT = new Command() { private static final long serialVersionUID = 6308754740309909072L; public void execute() { if (AllZoneUtil.isCardInPlay(target[0])) { target[0].removeExtrinsicKeyword(kboost); } } };//Command if (AllZoneUtil.isCardInPlay(target[0]) && !target[0].hasKeyword(kboost)) { target[0].addExtrinsicKeyword(kboost); AllZone.getEndOfTurn().addUntil(untilEOT); }//if }//for }//resolve };//SpellAbility card.setSVar("PlayMain1", "TRUE"); card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Sprout Swarm")) { final SpellAbility spell_one = new Spell(card) { private static final long serialVersionUID = -609007714604161377L; @Override public boolean canPlayAI() { return false; } @Override public void resolve() { CardFactoryUtil.makeTokenSaproling(card.getController()); } };//SpellAbility final SpellAbility spell_two = new Spell(card) { private static final long serialVersionUID = -1387385820860395676L; @Override public void resolve() { CardFactoryUtil.makeTokenSaproling(card.getController()); //return card to the hand PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, card.getController()); AllZone.getGameAction().moveTo(hand, card); } };//SpellAbility spell_one.setManaCost("1 G"); spell_two.setManaCost("4 G"); spell_two.setAdditionalManaCost("3"); spell_one.setDescription("Put a 1/1 green Saproling token onto the battlefield."); spell_two.setDescription("Buyback 3 (You may pay an additional 3 as you cast this spell. If you do, put this card into your hand as it resolves.)"); spell_one.setStackDescription("Sprout Swarm - Put a 1/1 green Saproling token onto the battlefield"); spell_two.setStackDescription("Sprout Swarm - Buyback, Put a 1/1 green Saproling token onto the battlefield"); spell_two.setIsBuyBackAbility(true); card.addSpellAbility(spell_one); card.addSpellAbility(spell_two); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Fact or Fiction")) { final SpellAbility spell = new Spell(card) { private static final long serialVersionUID = 1481112451519L; @Override public void resolve() { Card choice = null; //check for no cards in hand on resolve PlayerZone Library = AllZone.getZone(Constant.Zone.Library, card.getController()); PlayerZone Hand = AllZone.getZone(Constant.Zone.Hand, card.getController()); //PlayerZone Grave = AllZone.getZone(Constant.Zone.Graveyard, card.getController()); CardList cards = new CardList(); if (Library.size() == 0) { JOptionPane.showMessageDialog(null, "No more cards in library.", "", JOptionPane.INFORMATION_MESSAGE); return; } int Count = 5; if (Library.size() < 5) Count = Library.size(); for (int i = 0; i < Count; i++) cards.add(Library.get(i)); CardList Pile1 = new CardList(); CardList Pile2 = new CardList(); boolean stop = false; int Pile1CMC = 0; int Pile2CMC = 0; GuiUtils.getChoice("Revealing top " + Count + " cards of library: ", cards.toArray()); //Human chooses if (card.getController().isComputer()) { for (int i = 0; i < Count; i++) { if (stop == false) { choice = GuiUtils.getChoiceOptional("Choose cards to put into the first pile: ", cards.toArray()); if (choice != null) { Pile1.add(choice); cards.remove(choice); Pile1CMC = Pile1CMC + CardUtil.getConvertedManaCost(choice); } else stop = true; } } for (int i = 0; i < Count; i++) { if (!Pile1.contains(Library.get(i))) { Pile2.add(Library.get(i)); Pile2CMC = Pile2CMC + CardUtil.getConvertedManaCost(Library.get(i)); } } StringBuilder sb = new StringBuilder(); sb.append("You have spilt the cards into the following piles" + "\r\n" + "\r\n"); sb.append("Pile 1: " + "\r\n"); for (int i = 0; i < Pile1.size(); i++) sb.append(Pile1.get(i).getName() + "\r\n"); sb.append("\r\n" + "Pile 2: " + "\r\n"); for (int i = 0; i < Pile2.size(); i++) sb.append(Pile2.get(i).getName() + "\r\n"); JOptionPane.showMessageDialog(null, sb, "", JOptionPane.INFORMATION_MESSAGE); if (Pile1CMC >= Pile2CMC) { JOptionPane.showMessageDialog(null, "Computer adds the first pile to its hand and puts the second pile into the graveyard", "", JOptionPane.INFORMATION_MESSAGE); for (int i = 0; i < Pile1.size(); i++) AllZone.getGameAction().moveTo(Hand, Pile1.get(i)); for (int i = 0; i < Pile2.size(); i++) AllZone.getGameAction().moveToGraveyard(Pile2.get(i)); } else { JOptionPane.showMessageDialog(null, "Computer adds the second pile to its hand and puts the first pile into the graveyard", "", JOptionPane.INFORMATION_MESSAGE); for (int i = 0; i < Pile2.size(); i++) AllZone.getGameAction().moveTo(Hand, Pile2.get(i)); for (int i = 0; i < Pile1.size(); i++) AllZone.getGameAction().moveToGraveyard(Pile1.get(i)); } } else//Computer chooses (It picks the highest converted mana cost card and 1 random card.) { Card biggest = null; biggest = Library.get(0); for (int i = 0; i < Count; i++) { if (CardUtil.getConvertedManaCost(biggest.getManaCost()) >= CardUtil.getConvertedManaCost(biggest.getManaCost())) { biggest = cards.get(i); } } Pile1.add(biggest); cards.remove(biggest); if (cards.size() > 0) { Card Random = CardUtil.getRandom(cards.toArray()); Pile1.add(Random); } for (int i = 0; i < Count; i++) if (!Pile1.contains(Library.get(i))) Pile2.add(Library.get(i)); StringBuilder sb = new StringBuilder(); sb.append("Choose a pile to add to your hand: " + "\r\n" + "\r\n"); sb.append("Pile 1: " + "\r\n"); for (int i = 0; i < Pile1.size(); i++) sb.append(Pile1.get(i).getName() + "\r\n"); sb.append("\r\n" + "Pile 2: " + "\r\n"); for (int i = 0; i < Pile2.size(); i++) sb.append(Pile2.get(i).getName() + "\r\n"); Object[] possibleValues = {"Pile 1", "Pile 2"}; Object q = JOptionPane.showOptionDialog(null, sb, "Fact or Fiction", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]); if (q.equals(0)) { for (int i = 0; i < Pile1.size(); i++) AllZone.getGameAction().moveTo(Hand, Pile1.get(i)); for (int i = 0; i < Pile2.size(); i++) AllZone.getGameAction().moveToGraveyard(Pile2.get(i)); } else { for (int i = 0; i < Pile2.size(); i++) AllZone.getGameAction().moveTo(Hand, Pile2.get(i)); for (int i = 0; i < Pile1.size(); i++) AllZone.getGameAction().moveToGraveyard(Pile1.get(i)); } } Pile1.clear(); Pile2.clear(); }//resolve() @Override public boolean canPlayAI() { CardList cards = AllZoneUtil.getPlayerCardsInPlay(AllZone.getComputerPlayer()); return cards.size() >= 10; } };//SpellAbility card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Echoing Decay")) { Cost cost = new Cost(card.getManaCost(), cardName, false); Target tgt = new Target(card, "C"); final SpellAbility spell = new Spell(card, cost, tgt) { private static final long serialVersionUID = 3154935854257358023L; @Override public boolean canPlayAI() { CardList c = getCreature(); if (c.isEmpty()) return false; else { setTargetCard(c.get(0)); return true; } }//canPlayAI() CardList getCreature() { CardList out = new CardList(); CardList list = CardFactoryUtil.AI_getHumanCreature("Flying", card, true); list.shuffle(); for (int i = 0; i < list.size(); i++) if ((list.get(i).getNetAttack() >= 2) && (list.get(i).getNetDefense() <= 2)) out.add(list.get(i)); //in case human player only has a few creatures in play, target anything if (out.isEmpty() && 0 < CardFactoryUtil.AI_getHumanCreature(2, card, true).size() && 3 > CardFactoryUtil.AI_getHumanCreature(card, true).size()) { out.addAll(CardFactoryUtil.AI_getHumanCreature(2, card, true)); CardListUtil.sortFlying(out); } return out; }//getCreature() @Override public void resolve() { if (AllZoneUtil.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard())) { final Card c = getTargetCard(); c.addTempAttackBoost(-2); c.addTempDefenseBoost(-2); AllZone.getEndOfTurn().addUntil(new Command() { private static final long serialVersionUID = 1327455269456577020L; public void execute() { c.addTempAttackBoost(2); c.addTempDefenseBoost(2); } }); //get all creatures CardList list = AllZoneUtil.getCardsInPlay(); list = list.getName(getTargetCard().getName()); list.remove(getTargetCard()); if (!getTargetCard().isFaceDown()) for (int i = 0; i < list.size(); i++) { final Card crd = list.get(i); crd.addTempAttackBoost(-2); crd.addTempDefenseBoost(-2); AllZone.getEndOfTurn().addUntil(new Command() { private static final long serialVersionUID = 5151337777143949221L; public void execute() { crd.addTempAttackBoost(2); crd.addTempDefenseBoost(2); } }); } }//in play? }//resolve() };//SpellAbility card.addSpellAbility(spell); card.setSVar("PlayMain1", "TRUE"); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Hidetsugu's Second Rite")) { Target t = new Target(card, "Select target player", "Player"); Cost cost = new Cost("3 R", cardName, false); final SpellAbility spell = new Spell(card, cost, t) { private static final long serialVersionUID = 176857775451818523L; @Override public void resolve() { if (getTargetPlayer().getLife() == 10) { getTargetPlayer().addDamage(10, card); } } @Override public boolean canPlayAI() { return AllZone.getHumanPlayer().getLife() == 10; } }; spell.setChooseTargetAI(CardFactoryUtil.AI_targetHuman()); card.addSpellAbility(spell); card.setSVar("PlayMain1", "TRUE"); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Echoing Truth")) { final SpellAbility spell = new Spell(card) { private static final long serialVersionUID = 563933533543239220L; @Override public boolean canPlayAI() { CardList human = CardFactoryUtil.AI_getHumanCreature(card, true); return 4 < AllZone.getPhase().getTurn() && 0 < human.size(); } @Override public void chooseTargetAI() { CardList human = CardFactoryUtil.AI_getHumanCreature(card, true); setTargetCard(CardFactoryUtil.AI_getBestCreature(human)); } @Override public void resolve() { //if target card is not in play, just quit if (!AllZoneUtil.isCardInPlay(getTargetCard()) || !CardFactoryUtil.canTarget(card, getTargetCard())) return; //get all permanents CardList all = AllZoneUtil.getCardsInPlay(); CardList sameName = all.getName(getTargetCard().getName()); sameName = sameName.filter(new CardListFilter() { public boolean addCard(Card c) { return !c.isFaceDown(); } }); if (!getTargetCard().isFaceDown()) { //bounce all permanents with the same name for (int i = 0; i < sameName.size(); i++) { if (sameName.get(i).isToken()) AllZone.getGameAction().exile(sameName.get(i)); else { PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, sameName.get(i).getOwner()); AllZone.getGameAction().moveTo(hand, sameName.get(i)); } }//for }//if (!isFaceDown()) else { PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, getTargetCard().getOwner()); AllZone.getGameAction().moveTo(hand, getTargetCard()); } }//resolve() };//SpellAbility Input target = new Input() { private static final long serialVersionUID = -3978705328511825933L; @Override public void showMessage() { AllZone.getDisplay().showMessage("Select target nonland permanent for " + spell.getSourceCard()); ButtonUtil.enableOnlyCancel(); } @Override public void selectButtonCancel() { stop(); } @Override public void selectCard(Card card, PlayerZone zone) { if (!card.isLand() && zone.is(Constant.Zone.Battlefield) && CardFactoryUtil.canTarget(spell, card)) { spell.setTargetCard(card); if (this.isFree()) { this.setFree(false); AllZone.getStack().add(spell); stop(); } else stopSetNext(new Input_PayManaCost(spell)); } } };//Input card.setSVar("PlayMain1", "TRUE"); spell.setBeforePayMana(target); card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Banishing Knack")) { Cost cost = new Cost(card.getManaCost(), cardName, false); Target tgt = new Target(card, "C"); final SpellAbility spell = new Spell(card, cost, tgt) { private static final long serialVersionUID = 6518824567946786581L; @Override public boolean canPlayAI() { return false; } @Override public void resolve() { final Card creature = getTargetCard(); Cost abCost = new Cost("T", creature.getName(), true); Target tgt = new Target(card, "Select target nonland permanent", new String[]{"Permanent.nonLand"}); final Ability_Activated tBanish = new Ability_Activated(creature, abCost, tgt) { private static final long serialVersionUID = -1008113001678623984L; @Override public boolean canPlayAI() { return false; } @Override public void resolve() { StringBuilder sb = new StringBuilder(); sb.append(creature).append(" - Return").append(getTargetCard()).append("to its owner's hand"); setStackDescription(sb.toString()); final Card target = getTargetCard(); if (AllZoneUtil.isCardInPlay(target) && CardFactoryUtil.canTarget(creature, target)) { AllZone.getGameAction().moveToHand(target); } }//resolve() };//tBanish; tBanish.setDescription(abCost + "Return target nonland permanent to its owner's hand."); creature.addSpellAbility(tBanish); AllZone.getEndOfTurn().addUntil(new Command() { private static final long serialVersionUID = -7819140065166374666L; public void execute() { creature.removeSpellAbility(tBanish); } }); } };//SpellAbility card.addSpellAbility(spell); spell.setDescription("Until end of turn, target creature gains \"tap: Return target nonland permanent to its owner's hand.\""); spell.setStackDescription("Target creature gains \"tap: Return target nonland permanent to its owner's hand.\""); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Intuition")) { final SpellAbility spell = new Spell(card) { private static final long serialVersionUID = 8282597086298330698L; @Override public void resolve() { Player player = card.getController(); if (player.isHuman()) humanResolve(); else computerResolve(); player.shuffle(); } public void humanResolve() { CardList libraryList = AllZoneUtil.getPlayerCardsInLibrary(AllZone.getHumanPlayer()); CardList selectedCards = new CardList(); Object o = GuiUtils.getChoiceOptional("Select first card", libraryList.toArray()); if (o != null) { Card c1 = (Card) o; libraryList.remove(c1); selectedCards.add(c1); } else { return; } o = GuiUtils.getChoiceOptional("Select second card", libraryList.toArray()); if (o != null) { Card c2 = (Card) o; libraryList.remove(c2); selectedCards.add(c2); } else { return; } o = GuiUtils.getChoiceOptional("Select third card", libraryList.toArray()); if (o != null) { Card c3 = (Card) o; libraryList.remove(c3); selectedCards.add(c3); } else { return; } Card choice = selectedCards.get(MyRandom.random.nextInt(2)); //comp randomly selects one of the three cards selectedCards.remove(choice); AllZone.getGameAction().moveToHand(choice); for (Card trash : selectedCards) AllZone.getGameAction().moveToGraveyard(trash); } public void computerResolve() { CardList list = AllZoneUtil.getPlayerCardsInLibrary(AllZone.getComputerPlayer()); CardList selectedCards = new CardList(); //pick best creature Card c = CardFactoryUtil.AI_getBestCreature(list); if (c == null) { c = list.get(0); } list.remove(c); selectedCards.add(c); c = CardFactoryUtil.AI_getBestCreature(list); if (c == null) { c = list.get(0); } list.remove(c); selectedCards.add(c); c = CardFactoryUtil.AI_getBestCreature(list); if (c == null) { c = list.get(0); } list.remove(c); selectedCards.add(c); // NOTE: Using getChoiceOptional() results in a null error when you click on Cancel. Object o = GuiUtils.getChoice("Select card to give to computer", selectedCards.toArray()); Card choice = (Card) o; selectedCards.remove(choice); AllZone.getGameAction().moveToHand(choice); for (Card trash : selectedCards) AllZone.getGameAction().moveToGraveyard(trash); } @Override public boolean canPlay() { CardList library = AllZoneUtil.getPlayerCardsInLibrary(card.getController()); return library.size() >= 3; } @Override public boolean canPlayAI() { CardList creature = AllZoneUtil.getPlayerCardsInLibrary(AllZone.getComputerPlayer()); creature = creature.getType("Creature"); return creature.size() >= 3; } };//SpellAbility card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Echoing Courage")) { Cost cost = new Cost(card.getManaCost(), cardName, false); Target tgt = new Target(card, "C"); final SpellAbility spell = new Spell(card, cost, tgt) { private static final long serialVersionUID = -8649611733196156346L; public boolean canPlayAI() { CardList list = AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer()); if (list.isEmpty()) return false; else { setTargetCard(CardFactoryUtil.AI_getBestCreature(list)); return true; } }//canPlayAI() public void resolve() { if (AllZoneUtil.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard())) { final Card c = getTargetCard(); c.addTempAttackBoost(2); c.addTempDefenseBoost(2); AllZone.getEndOfTurn().addUntil(new Command() { private static final long serialVersionUID = 1327455269456577020L; public void execute() { c.addTempAttackBoost(-2); c.addTempDefenseBoost(-2); } }); //get all creatures CardList list = AllZoneUtil.getCardsInPlay(getTargetCard().getName()); list.remove(getTargetCard()); if (!getTargetCard().isFaceDown()) for (int i = 0; i < list.size(); i++) { final Card crd = list.get(i); crd.addTempAttackBoost(2); crd.addTempDefenseBoost(2); AllZone.getEndOfTurn().addUntil(new Command() { private static final long serialVersionUID = 5151337777143949221L; public void execute() { crd.addTempAttackBoost(-2); crd.addTempDefenseBoost(-2); } }); } }//in play? }//resolve() };//SpellAbility card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Hurkyl's Recall")) { /* * Return all artifacts target player owns to his or her hand. */ Target t = new Target(card, "Select target player", "Player"); Cost cost = new Cost("1 U", cardName, false); SpellAbility spell = new Spell(card, cost, t) { private static final long serialVersionUID = -4098702062413878046L; @Override public boolean canPlayAI() { CardList humanArts = AllZoneUtil.getPlayerCardsInPlay(AllZone.getHumanPlayer()); humanArts = humanArts.getType("Artifact"); return humanArts.size() > 0; }//canPlayAI @Override public void chooseTargetAI() { setTargetPlayer(AllZone.getHumanPlayer()); }//chooseTargetAI() @Override public void resolve() { Player player = getTargetPlayer(); CardList artifacts = AllZoneUtil.getCardsInPlay(); artifacts = artifacts.getType("Artifact"); for (int i = 0; i < artifacts.size(); i++) { Card thisArtifact = artifacts.get(i); if (thisArtifact.getOwner().equals(player)) { //moveToHand handles tokens AllZone.getGameAction().moveToHand(thisArtifact); } } }//resolve() }; card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Suffer the Past")) { Cost cost = new Cost("X B", cardName, false); Target tgt = new Target(card, "Select a Player", "Player"); final SpellAbility spell = new Spell(card, cost, tgt) { private static final long serialVersionUID = 1168802375190293222L; @Override public void resolve() { Player tPlayer = getTargetPlayer(); Player player = card.getController(); final int max = card.getXManaCostPaid(); CardList graveList = AllZoneUtil.getPlayerGraveyard(tPlayer); int X = Math.min(max, graveList.size()); if (player.isHuman()) { for (int i = 0; i < X; i++) { Object o = GuiUtils.getChoice("Remove from game", graveList.toArray()); if (o == null) break; Card c_1 = (Card) o; graveList.remove(c_1); //remove from the display list AllZone.getGameAction().exile(c_1); } } else { //Computer //Random random = MyRandom.random; for (int j = 0; j < X; j++) { //int index = random.nextInt(X-j); AllZone.getGameAction().exile(graveList.get(j)); } } tPlayer.loseLife(X, card); player.gainLife(X, card); card.setXManaCostPaid(0); } @Override public void chooseTargetAI() { setTargetPlayer(AllZone.getHumanPlayer()); }//chooseTargetAI() @Override public boolean canPlayAI() { CardList graveList = AllZoneUtil.getPlayerGraveyard(AllZone.getHumanPlayer()); final int maxX = ComputerUtil.getAvailableMana().size() - 1; return (maxX >= 3) && (graveList.size() > 0); } }; card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Demonic Consultation")) { final SpellAbility spell = new Spell(card) { private static final long serialVersionUID = 1481101852928051519L; @Override public void resolve() { Player player = card.getController(); CardList libList = AllZoneUtil.getPlayerCardsInLibrary(player); final String[] input = new String[1]; input[0] = JOptionPane.showInputDialog(null, "Which card?", "Pick card", JOptionPane.QUESTION_MESSAGE); for (int i = 0; i < 7; i++) { Card c = libList.get(i); AllZone.getGameAction().exile(c); } int max = libList.size(); int stop = 0; for (int i = 0; i < max; i++) { Card c = libList.get(i); if (c.getName().equals(input[0])) { if (stop == 0) { AllZone.getGameAction().moveToHand(c); stop = 1; } } else if (stop == 0) { AllZone.getGameAction().exile(c); } } } @Override public boolean canPlay() { CardList libList = AllZoneUtil.getPlayerCardsInLibrary(card.getController()); return libList.size() > 6 && super.canPlay(); } @Override public boolean canPlayAI() { return false; } };//SpellAbility spell.setStackDescription("Name a card. Exile the top six cards of your library, then reveal cards from the top of your library until you reveal the named card. Put that card into your hand and exile all other cards revealed this way"); card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Siren's Call")) { /* * Creatures the active player controls attack this turn if able. * * At the beginning of the next end step, destroy all non-Wall creatures * that player controls that didn't attack this turn. Ignore this effect * for each creature the player didn't control continuously since the * beginning of the turn. */ final SpellAbility spell = new Spell(card) { private static final long serialVersionUID = -5746330758531799264L; @Override public boolean canPlay() { return PhaseUtil.isBeforeAttackersAreDeclared() && AllZone.getPhase().isPlayerTurn(card.getController().getOpponent()); }//canPlay @Override public boolean canPlayAI() { return false; }//canPlayAI @Override public void resolve() { //this needs to get a list of opponents creatures and set the siren flag Player player = card.getController(); Player opponent = player.getOpponent(); CardList creatures = AllZoneUtil.getCreaturesInPlay(opponent); for (Card creature : creatures) { //skip walls, skip creatures with summoning sickness //also skip creatures with haste if they came onto the battlefield this turn if ((!creature.isWall() && !creature.hasSickness()) || (creature.hasKeyword("Haste") && creature.getTurnInZone() != 1)) { creature.setSirenAttackOrDestroy(true); //System.out.println("Siren's Call - setting flag for "+creature.getName()); } } final SpellAbility destroy = new Ability(card, "0") { @Override public void resolve() { Player player = card.getController(); Player opponent = player.getOpponent(); CardList creatures = AllZoneUtil.getCreaturesInPlay(opponent); for (Card creature : creatures) { //System.out.println("Siren's Call - EOT - "+creature.getName() +" flag: "+creature.getSirenAttackOrDestroy()); //System.out.println("Siren's Call - EOT - "+creature.getName() +" attacked?: "+creature.getCreatureAttackedThisCombat()); if (creature.getSirenAttackOrDestroy() && !creature.getCreatureAttackedThisTurn()) { if (AllZoneUtil.isCardInPlay(creature)) { //System.out.println("Siren's Call - destroying "+creature.getName()); //this should probably go on the stack AllZone.getGameAction().destroy(creature); } } creature.setSirenAttackOrDestroy(false); } } }; Command atEOT = new Command() { private static final long serialVersionUID = 5369528776959445848L; public void execute() { StringBuilder sb = new StringBuilder(); sb.append(card).append(" - At the beginning of the next end step, destroy all non-Wall creatures that player controls that didn't attack this turn. "); sb.append("Ignore this effect for each creature the player didn't control continuously since the beginning of the turn."); destroy.setDescription(sb.toString()); destroy.setStackDescription(sb.toString()); AllZone.getStack().addSimultaneousStackEntry(destroy); }//execute };//Command AllZone.getEndOfTurn().addAt(atEOT); }//resolve };//SpellAbility StringBuilder sb = new StringBuilder(); sb.append(card.getName()).append(" - All creatures that can attack must do so or be destroyed."); spell.setStackDescription(sb.toString()); card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Telling Time")) { final SpellAbility spell = new Spell(card) { private static final long serialVersionUID = 2626878556107707854L; String[] prompt = new String[]{ "Put a card into your hand", "Put a card on top of library", "Put a card on bottom of library" }; @Override public boolean canPlayAI() { return false; } @Override public void resolve() { PlayerZone lib = AllZone.getZone(Constant.Zone.Library, card.getController()); CardList choices = new CardList(); for (int i = 0; i < 3 && lib.size() > 0; i++) { choices.add(lib.get(i)); } for (int i = 0; i < 3 && !choices.isEmpty(); i++) { Object o = GuiUtils.getChoice(prompt[i], choices.toArray()); Card c1 = (Card) o; if (i == 0) AllZone.getGameAction().moveToHand(c1); else if (i == 1) AllZone.getGameAction().moveToLibrary(c1); else if (i == 2) AllZone.getGameAction().moveToBottomOfLibrary(c1); choices.remove(c1); } } }; card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Vengeful Dreams")) { final CardList targets = new CardList(); final SpellAbility spell = new Spell(card) { private static final long serialVersionUID = 1593405082929818055L; @Override public boolean canPlayAI() { return false; } @Override public void resolve() { for (Card c : targets) { if (AllZoneUtil.isCardInPlay(c) && CardFactoryUtil.canTarget(card, c)) { AllZone.getGameAction().exile(c); }//if isCardInPlay } targets.clear(); } }; Input runtime = new Input() { private static final long serialVersionUID = 4656252051002867111L; int max = 0; @Override public void showMessage() { PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, AllZone.getHumanPlayer()); AllZone.getGameAction().moveToStack(card); hand.updateObservers(); max = AllZoneUtil.getPlayerHand(card.getController()).size(); if (max == targets.size()) done(); StringBuilder sb = new StringBuilder(); sb.append(card.getName()).append(" - Select target attacking creatures. Currently, ("); sb.append(targets.size()).append(") selected."); sb.append(" Press OK when done."); AllZone.getDisplay().showMessage(sb.toString()); ButtonUtil.enableAll(); } @Override public void selectButtonCancel() { targets.clear(); AllZone.getGameAction().moveToHand(card); stop(); } @Override public void selectCard(Card c, PlayerZone zone) { if (zone.is(Constant.Zone.Battlefield) && !targets.contains(c) && CardFactoryUtil.canTarget(card, c) && c.isAttacking()) { targets.add(c); showMessage(); } } @Override public void selectButtonOK() { done(); } private void done() { if (targets.size() > AllZoneUtil.getPlayerHand(card.getController()).size()) stop(); else { card.getController().discard(targets.size(), spell, false); stopSetNext(new Input_PayManaCost(spell)); } } }; spell.setStackDescription(cardName + " - exile X attacking creatures."); spell.setBeforePayMana(runtime); card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Firestorm")) { final ArrayList<Object> targets = new ArrayList<Object>(); final SpellAbility spell = new Spell(card) { private static final long serialVersionUID = -3763504534745192451L; @Override public boolean canPlayAI() { return false; } @Override public void resolve() { int dmg = targets.size(); for (Object o : targets) { if (o instanceof Player) { if (((Player) o).canTarget(card)) { ((Player) o).addDamage(dmg, card); } } else if (o instanceof Card) { if (AllZoneUtil.isCardInPlay((Card) o) && CardFactoryUtil.canTarget(card, (Card) o)) { ((Card) o).addDamage(dmg, card); }//if isCardInPlay } } targets.clear(); } }; Input runtime = new Input() { private static final long serialVersionUID = 5261183989797221059L; @Override public void showMessage() { PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, AllZone.getHumanPlayer()); AllZone.getGameAction().moveToStack(card); hand.updateObservers(); StringBuilder sb = new StringBuilder(); sb.append(card.getName()).append(" - Select target creatures, players, and/or planeswalkers. Currently, ("); sb.append(targets.size()).append(") selected."); sb.append(" Press OK when done."); AllZone.getDisplay().showMessage(sb.toString()); ButtonUtil.enableAll(); } @Override public void selectButtonCancel() { targets.clear(); AllZone.getGameAction().moveToHand(card); stop(); } @Override public void selectCard(Card c, PlayerZone zone) { if (zone.is(Constant.Zone.Battlefield) && !targets.contains(c) && CardFactoryUtil.canTarget(card, c) && (c.isCreature() || c.isPlaneswalker())) { targets.add(c); showMessage(); } } @Override public void selectPlayer(Player p) { if (p.canTarget(card) && !targets.contains(p)) { targets.add(p); showMessage(); } } @Override public void selectButtonOK() { done(); } private void done() { if (targets.size() > AllZoneUtil.getPlayerHand(card.getController()).size()) stop(); else { card.getController().discard(targets.size(), spell, true); stopSetNext(new Input_PayManaCost(spell)); } } }; spell.setStackDescription(cardName + " - deals X damage to each of X target creatures and/or players."); spell.setBeforePayMana(runtime); card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Cryptic Command")) { final SpellAbility[] m_spell = new SpellAbility[1]; final Card[] m_perm = new Card[1]; final ArrayList<String> userChoice = new ArrayList<String>(); final String[] cardChoice = { "Counter target spell", "Return target permanent to its owner's hand", "Tap all creatures your opponents control", "Draw a card"}; final SpellAbility spell = new Spell(card) { private static final long serialVersionUID = 9178547049760990376L; @Override public void resolve() { //"Counter target spell", for (int i = 0; i < card.getChoices().size(); i++) { if (card.getChoice(i).equals(cardChoice[0])) { if (AllZone.getStack().size() > 0) { SpellAbility sa = AllZone.getStack().peekAbility(); if (sa.isSpell()) { AllZone.getStack().pop(); AllZone.getGameAction().moveToGraveyard(sa.getSourceCard()); } } } } //"Return target Permanent to its owner's hand", if (userChoice.contains(cardChoice[1]) || card.getChoices().contains(cardChoice[1])) { if (AllZoneUtil.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard())) { AllZone.getGameAction().moveToHand(getTargetCard()); } } //"Tap all creatures your opponents control", for (int i = 0; i < card.getChoices().size(); i++) { if (card.getChoice(i).equals(cardChoice[2])) { CardList creatures = AllZoneUtil.getCreaturesInPlay(card.getController().getOpponent()); for (Card c : creatures) c.tap(); } } //"Draw a card" if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3])) { card.getController().drawCard(); } }//resolve() @Override public boolean canPlayAI() { return false; } };//SpellAbility final Command setStackDescription = new Command() { private static final long serialVersionUID = -4833850318955216009L; public void execute() { ArrayList<String> a = new ArrayList<String>(); if (userChoice.contains(cardChoice[0]) || card.getChoices().contains(cardChoice[0])) a.add("counter target spell"); if (userChoice.contains(cardChoice[1]) || card.getChoices().contains(cardChoice[1])) a.add("return target permanent to its owner's hand"); if (userChoice.contains(cardChoice[2]) || card.getChoices().contains(cardChoice[2])) a.add("tap all creatures your opponents control"); if (userChoice.contains(cardChoice[3]) || card.getChoices().contains(cardChoice[3])) a.add(" Draw a card."); String s = a.get(0) + ", " + a.get(1); spell.setStackDescription(card.getName() + " - " + s); } };//Command final Input returnTarget = new Input() { private static final long serialVersionUID = 2736368243448655071L; @Override public void showMessage() { AllZone.getDisplay().showMessage("Select target permanent"); ButtonUtil.enableOnlyCancel(); } @Override public void selectButtonCancel() { stop(); } @Override public void selectCard(Card c, PlayerZone zone) { if (c.isPermanent() && zone.is(Constant.Zone.Battlefield) && CardFactoryUtil.canTarget(card, c)) { if (card.isCopiedSpell()) card.getChoiceTargets().remove(0); m_perm[0] = c; spell.setTargetCard(c); card.setSpellChoiceTarget(String.valueOf(c.getUniqueNumber())); setStackDescription.execute(); stopSetNext(new Input_PayManaCost(spell)); }//if }//selectCard() };//Input targetLand Input chooseTwoInput = new Input() { private static final long serialVersionUID = -4200213000203960667L; @Override public void showMessage() { if (card.isCopiedSpell()) { if (card.getChoices().contains(cardChoice[1])) stopSetNext(returnTarget); else { setStackDescription.execute(); stopSetNext(new Input_PayManaCost(spell)); } } else { //reset variables m_spell[0] = null; m_perm[0] = null; card.getChoices().clear(); card.getChoiceTargets().clear(); userChoice.clear(); ArrayList<String> display = new ArrayList<String>(); //get all CardList list = AllZoneUtil.getCardsInPlay(); if (AllZone.getStack().size() > 0) display.add("Counter target spell"); if (list.size() > 0) display.add("Return target permanent to its owner's hand"); display.add("Tap all creatures your opponents control"); display.add("Draw a card"); ArrayList<String> a = chooseTwo(display); //everything stops here if user cancelled if (a == null) { stop(); return; } userChoice.addAll(a); if (userChoice.contains(cardChoice[1])) stopSetNext(returnTarget); else { setStackDescription.execute(); stopSetNext(new Input_PayManaCost(spell)); } } }//showMessage() ArrayList<String> chooseTwo(ArrayList<String> choices) { ArrayList<String> out = new ArrayList<String>(); Object o = GuiUtils.getChoiceOptional("Choose Two", choices.toArray()); if (o == null) return null; out.add((String) o); card.addSpellChoice((String) o); choices.remove(out.get(0)); o = GuiUtils.getChoiceOptional("Choose Two", choices.toArray()); if (o == null) return null; out.add((String) o); card.addSpellChoice((String) o); return out; }//chooseTwo() };//Input chooseTwoInput card.addSpellAbility(spell); card.setSpellWithChoices(true); spell.setBeforePayMana(chooseTwoInput); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Remove Enchantments")) { final SpellAbility spell = new Spell(card) { private static final long serialVersionUID = -7324132132222075031L; @Override public boolean canPlayAI() { return false; } @Override public void resolve() { final Player you = card.getController(); CardList ens = AllZoneUtil.getTypeInPlay("Enchantment"); CardList toReturn = ens.filter(new CardListFilter() { public boolean addCard(Card c) { return (c.getOwner().isPlayer(you) && c.getController().isPlayer(you)) || (c.isAura() && c.getEnchanting().get(0).getController().isPlayer(you)) || (c.isAura() && c.getEnchanting().get(0).isAttacking() && c.getEnchanting().get(0).getController().isPlayer(you.getOpponent())); } }); for (Card c : toReturn) AllZone.getGameAction().moveToHand(c); for (Card c : ens) { if (!toReturn.contains(c)) AllZone.getGameAction().destroy(c); } } }; spell.setStackDescription(card + " - destroy/return enchantments."); card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Burn the Impure")) { /* * Burn the Impure deals 3 damage to target creature. If that * creature has infect, Burn the Impure deals 3 damage to that * creature's controller. */ Cost abCost = new Cost("1 R", cardName, false); final SpellAbility spell = new Spell(card, abCost, new Target(card, "TgtC")) { private static final long serialVersionUID = -3069135027502686218L; int damage = 3; @Override public void chooseTargetAI() { CardList creatures = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer()); creatures = creatures.filter(new CardListFilter() { public boolean addCard(Card c) { return c.getNetAttack() <= damage && !c.hasKeyword("Indestructible"); } }); CardList infect = creatures.filter(AllZoneUtil.getKeywordFilter("Infect")); if (infect.size() > 0) { Card c = CardFactoryUtil.AI_getBestCreature(infect); setTargetCard(c); } else { Card c = CardFactoryUtil.AI_getBestCreature(creatures); setTargetCard(c); } }//chooseTargetAI() @Override public boolean canPlayAI() { CardList creatures = AllZoneUtil.getCreaturesInPlay(AllZone.getHumanPlayer()); creatures = creatures.filter(new CardListFilter() { public boolean addCard(Card c) { return c.getNetAttack() <= damage && !c.hasKeyword("Indestructible"); } }); return creatures.size() > 0; } @Override public void resolve() { if (AllZoneUtil.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard())) { Card c = getTargetCard(); c.addDamage(damage, card); if (c.hasKeyword("Infect")) c.getController().addDamage(3, card); } } };//SpellAbility StringBuilder sb = new StringBuilder(); sb.append(cardName); sb.append(" deals 3 damage to target creature. If that creature has infect, "); sb.append(cardName); sb.append(" deals 3 damage to that creature's controller."); spell.setDescription(sb.toString()); card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Turnabout")) { /* * Choose artifact, creature, or land. Tap all untapped permanents of the chosen * type target player controls, or untap all tapped permanents of that type that * player controls. */ Cost abCost = new Cost("2 U U", cardName, false); Target target = new Target(card, "Select target player", "Player".split(",")); final SpellAbility spell = new Spell(card, abCost, target) { private static final long serialVersionUID = -2175586347805121896L; @Override public boolean canPlayAI() { return false; } @Override public void resolve() { String[] choices = new String[]{"Artifact", "Creature", "Land"}; Object o = GuiUtils.getChoice("Select permanent type", choices); String cardType = (String) o; CardList list = AllZoneUtil.getPlayerTypeInPlay(getTargetPlayer(), cardType); String[] tapOrUntap = new String[]{"Tap", "Untap"}; Object z = GuiUtils.getChoice("Tap or Untap?", tapOrUntap); boolean tap = (z.equals("Tap")) ? true : false; for (Card c : list) { if (tap) c.tap(); else c.untap(); } }//resolve() };//SpellAbility card.addSpellAbility(spell); }//*************** END ************ END ************************** //*************** START *********** START ************************** else if (cardName.equals("Wing Puncture")) { Target t2 = new Target(card, "Select target creature with flying", "Creature.withFlying".split(",")); final Ability_Sub sub = new Ability_Sub(card, t2) { private static final long serialVersionUID = 4618047889975691050L; @Override public boolean chkAI_Drawback() { return false; } @Override public void resolve() { Card myc = this.getParent().getTargetCard(); Card tgt = getTargetCard(); if (AllZoneUtil.isCardInPlay(myc) && AllZoneUtil.isCardInPlay(tgt)) { if (CardFactoryUtil.canTarget(card, myc) && CardFactoryUtil.canTarget(card, tgt)) { tgt.addDamage(myc.getNetAttack(), myc); } } } @Override public boolean doTrigger(boolean b) { return false; } }; Cost abCost = new Cost("G", cardName, false); Target t1 = new Target(card, "Select target creature you control", "Creature.YouCtrl".split(",")); final SpellAbility spell = new Spell(card, abCost, t1) { private static final long serialVersionUID = 8964235807056739219L; @Override public boolean canPlayAI() { return false; } @Override public void resolve() { sub.resolve(); } }; spell.setSubAbility(sub); spell.setDescription("Target creature you control deals damage equal to its power to target creature with flying."); spell.setStackDescription(card + " - Creature you control deals damage equal to its power to creature with flying."); card.addSpellAbility(spell); }//*************** END ************ END ************************** return card; }//getCard }