From d003cd898fb2aeda7f87277e71fdf2a5426e1ea8 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Mon, 4 Sep 2017 07:57:10 +0200 Subject: [PATCH 001/182] Image download by set with source restriction to supported sets. --- .../card/dl/sources/CardImageSource.java | 18 ++ .../dl/sources/MythicspoilerComSource.java | 37 ++- .../dl/sources/WizardCardsImageSource.java | 273 +++++++++++++++-- .../plugins/card/images/DownloadPictures.java | 286 +++++++++++------- .../target/maven-archiver/pom.properties | 10 +- 5 files changed, 488 insertions(+), 136 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java index 0f25bba72c..f76aeb953d 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java @@ -1,5 +1,6 @@ package org.mage.plugins.card.dl.sources; +import java.util.ArrayList; import org.mage.plugins.card.images.CardDownloadData; /** @@ -9,12 +10,29 @@ import org.mage.plugins.card.images.CardDownloadData; public interface CardImageSource { String generateURL(CardDownloadData card) throws Exception; + String generateTokenUrl(CardDownloadData card) throws Exception; + String getNextHttpImageUrl(); + String getFileForHttpImage(String httpImageUrl); + String getSourceName(); + float getAverageSize(); + int getTotalImages(); + boolean isTokenSource(); + void doPause(String httpImageUrl); + + default ArrayList getSupportedSets() { + return null; + } + + default boolean providesTokenImages() { + return false; + } +; } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java index 8368c76c45..d8ceaf19f2 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java @@ -35,9 +35,11 @@ import java.net.InetSocketAddress; import java.net.Proxy; import java.net.URL; import java.net.URLEncoder; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.prefs.Preferences; @@ -57,10 +59,11 @@ import org.mage.plugins.card.images.CardDownloadData; public enum MythicspoilerComSource implements CardImageSource { instance; - private Map setsAliases; - private Map cardNameAliases; - private Map> cardNameAliasesStart; + private final Map setsAliases; + private final Map cardNameAliases; + private final Map> cardNameAliasesStart; private final Map> sets; + private final Set supportedSets; @Override public String getSourceName() { @@ -68,6 +71,26 @@ public enum MythicspoilerComSource implements CardImageSource { } MythicspoilerComSource() { + supportedSets = new LinkedHashSet<>(); + supportedSets.add("V16"); + supportedSets.add("CN2"); + supportedSets.add("DDR"); + supportedSets.add("KLD"); + supportedSets.add("MPS"); + supportedSets.add("PZ2"); + supportedSets.add("C16"); + supportedSets.add("PCA"); + supportedSets.add("AER"); + supportedSets.add("MM3"); + supportedSets.add("DDS"); + supportedSets.add("W17"); + supportedSets.add("AKH"); + supportedSets.add("MPS"); + supportedSets.add("CMA"); + supportedSets.add("E01"); + supportedSets.add("HOU"); + supportedSets.add("C17"); + sets = new LinkedHashMap<>(); setsAliases = new HashMap<>(); setsAliases.put("exp", "bfz"); @@ -243,4 +266,12 @@ public enum MythicspoilerComSource implements CardImageSource { @Override public void doPause(String httpImageUrl) { } + + @Override + public ArrayList getSupportedSets() { + ArrayList supportedSetsCopy = new ArrayList<>(); + supportedSetsCopy.addAll(supportedSets); + return supportedSetsCopy; + } + } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java index a42cc1633a..4939fdcbe2 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java @@ -34,10 +34,13 @@ import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.URL; -import java.net.URLEncoder; +import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -46,6 +49,7 @@ import mage.client.MageFrame; import mage.client.dialog.PreferencesDialog; import mage.remote.Connection; import mage.remote.Connection.ProxyType; +import org.apache.log4j.Logger; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; @@ -58,10 +62,13 @@ import org.mage.plugins.card.images.CardDownloadData; public enum WizardCardsImageSource implements CardImageSource { instance; - private Map setsAliases; - private Map languageAliases; - private final Map> sets; + private static final Logger logger = Logger.getLogger(WizardCardsImageSource.class); + + private final Map setsAliases; + private final Map languageAliases; + private final Map> sets; + private final Set supportedSets; @Override public String getSourceName() { @@ -69,6 +76,197 @@ public enum WizardCardsImageSource implements CardImageSource { } WizardCardsImageSource() { + supportedSets = new LinkedHashSet<>(); + supportedSets.add("LEA"); + supportedSets.add("LEB"); + supportedSets.add("2ED"); + supportedSets.add("ARN"); + supportedSets.add("ATQ"); + supportedSets.add("3ED"); + supportedSets.add("LEG"); + supportedSets.add("DRK"); + supportedSets.add("FEM"); + supportedSets.add("4ED"); + supportedSets.add("ICE"); + supportedSets.add("CHR"); + supportedSets.add("HML"); + supportedSets.add("ALL"); + supportedSets.add("MIR"); + supportedSets.add("VIS"); + supportedSets.add("5ED"); + supportedSets.add("POR"); + supportedSets.add("WTH"); + supportedSets.add("TMP"); + supportedSets.add("STH"); + supportedSets.add("EXO"); + supportedSets.add("P02"); + supportedSets.add("UGL"); + supportedSets.add("USG"); + supportedSets.add("DD3DVD"); + supportedSets.add("DD3EVG"); + supportedSets.add("DD3GVL"); + supportedSets.add("DD3JVC"); + + supportedSets.add("ULG"); + supportedSets.add("6ED"); + supportedSets.add("UDS"); + supportedSets.add("PTK"); + supportedSets.add("S99"); + supportedSets.add("MMQ"); + // supportedSets.add("BRB");Battle Royale Box Set + supportedSets.add("NEM"); + supportedSets.add("S00"); + supportedSets.add("PCY"); + supportedSets.add("INV"); + // supportedSets.add("BTD"); // Beatdown Boxset + supportedSets.add("PLS"); + supportedSets.add("7ED"); + supportedSets.add("APC"); + supportedSets.add("ODY"); + // supportedSets.add("DKM"); // Deckmasters 2001 + supportedSets.add("TOR"); + supportedSets.add("JUD"); + supportedSets.add("ONS"); + supportedSets.add("LGN"); + supportedSets.add("SCG"); + supportedSets.add("8ED"); + supportedSets.add("MRD"); + supportedSets.add("DST"); + supportedSets.add("5DN"); + supportedSets.add("CHK"); + supportedSets.add("UNH"); + supportedSets.add("BOK"); + supportedSets.add("SOK"); + supportedSets.add("9ED"); + supportedSets.add("RAV"); + supportedSets.add("GPT"); + supportedSets.add("DIS"); + supportedSets.add("CSP"); + supportedSets.add("TSP"); + supportedSets.add("TSB"); + supportedSets.add("PLC"); + supportedSets.add("FUT"); + supportedSets.add("10E"); + supportedSets.add("MED"); + supportedSets.add("LRW"); + supportedSets.add("EVG"); + supportedSets.add("MOR"); + supportedSets.add("SHM"); + supportedSets.add("EVE"); + supportedSets.add("DRB"); + supportedSets.add("ME2"); + supportedSets.add("ALA"); + supportedSets.add("DD2"); + supportedSets.add("CON"); + supportedSets.add("DDC"); + supportedSets.add("ARB"); + supportedSets.add("M10"); + // supportedSets.add("TD0"); // Magic Online Deck Series + supportedSets.add("V09"); + supportedSets.add("HOP"); + supportedSets.add("ME3"); + supportedSets.add("ZEN"); + supportedSets.add("DDD"); + supportedSets.add("H09"); + supportedSets.add("WWK"); + supportedSets.add("DDE"); + supportedSets.add("ROE"); + supportedSets.add("DPA"); + supportedSets.add("ARC"); + supportedSets.add("M11"); + supportedSets.add("V10"); + supportedSets.add("DDF"); + supportedSets.add("SOM"); + // supportedSets.add("TD0"); // Commander Theme Decks + supportedSets.add("PD2"); + supportedSets.add("ME4"); + supportedSets.add("MBS"); + supportedSets.add("DDG"); + supportedSets.add("NPH"); + supportedSets.add("CMD"); + supportedSets.add("M12"); + supportedSets.add("V11"); + supportedSets.add("DDH"); + supportedSets.add("ISD"); + supportedSets.add("PD3"); + supportedSets.add("DKA"); + supportedSets.add("DDI"); + supportedSets.add("AVR"); + supportedSets.add("PC2"); + supportedSets.add("M13"); + supportedSets.add("V12"); + supportedSets.add("DDJ"); + supportedSets.add("RTR"); + supportedSets.add("CM1"); + // supportedSets.add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia + supportedSets.add("GTC"); + supportedSets.add("DDK"); + supportedSets.add("DGM"); + supportedSets.add("MMA"); + supportedSets.add("M14"); + supportedSets.add("V13"); + supportedSets.add("DDL"); + supportedSets.add("THS"); + supportedSets.add("C13"); + supportedSets.add("BNG"); + supportedSets.add("DDM"); + supportedSets.add("JOU"); + // supportedSets.add("MD1"); // Modern Event Deck + supportedSets.add("CNS"); + supportedSets.add("VMA"); + supportedSets.add("M15"); + supportedSets.add("V14"); + supportedSets.add("DDN"); + supportedSets.add("KTK"); + supportedSets.add("C14"); + // supportedSets.add("DD3"); // Duel Decks Anthology + supportedSets.add("FRF"); + supportedSets.add("DDO"); + supportedSets.add("DTK"); + supportedSets.add("TPR"); + supportedSets.add("MM2"); + supportedSets.add("ORI"); + supportedSets.add("V15"); + supportedSets.add("DDP"); + supportedSets.add("BFZ"); + supportedSets.add("EXP"); + supportedSets.add("C15"); + // supportedSets.add("PZ1"); // Legendary Cube + supportedSets.add("OGW"); + supportedSets.add("DDQ"); + supportedSets.add("W16"); + supportedSets.add("SOI"); + supportedSets.add("EMA"); + supportedSets.add("EMN"); + supportedSets.add("V16"); + supportedSets.add("CN2"); + supportedSets.add("DDR"); + supportedSets.add("KLD"); + supportedSets.add("MPS"); + // supportedSets.add("PZ2"); // Treasure Chests + supportedSets.add("C16"); + supportedSets.add("PCA"); + supportedSets.add("AER"); + supportedSets.add("MM3"); + supportedSets.add("DDS"); + supportedSets.add("W17"); + supportedSets.add("AKH"); + supportedSets.add("MPS"); + supportedSets.add("CMA"); + supportedSets.add("E01"); + supportedSets.add("HOU"); + supportedSets.add("C17"); +// supportedSets.add("XLN"); +// supportedSets.add("DDT"); +// supportedSets.add("IMA"); +// supportedSets.add("E02"); +// supportedSets.add("V17"); +// supportedSets.add("UST"); +// supportedSets.add("RIX"); +// supportedSets.add("A25"); +// supportedSets.add("DOM"); +// supportedSets.add("M19"); + sets = new HashMap<>(); setsAliases = new HashMap<>(); setsAliases.put("2ED", "Unlimited Edition"); @@ -102,6 +300,7 @@ public enum WizardCardsImageSource implements CardImageSource { setsAliases.put("C14", "Commander 2014"); setsAliases.put("C15", "Commander 2015"); setsAliases.put("C16", "Commander 2016"); + setsAliases.put("C17", "Commander 2017"); setsAliases.put("CMA", "Commander Anthology"); setsAliases.put("CHK", "Champions of Kamigawa"); setsAliases.put("CHR", "Chronicles"); @@ -140,6 +339,7 @@ public enum WizardCardsImageSource implements CardImageSource { setsAliases.put("DRK", "The Dark"); setsAliases.put("DST", "Darksteel"); setsAliases.put("DTK", "Dragons of Tarkir"); + setsAliases.put("E01", "Archenemy: Nicol Bolas"); setsAliases.put("EMN", "Eldritch Moon"); setsAliases.put("EMA", "Eternal Masters"); setsAliases.put("EVE", "Eventide"); @@ -272,18 +472,20 @@ public enum WizardCardsImageSource implements CardImageSource { } private Map getSetLinks(String cardSet) { - ConcurrentHashMap setLinks = new ConcurrentHashMap<>(); + LinkedHashMap setLinks = new LinkedHashMap<>(); ExecutorService executor = Executors.newFixedThreadPool(10); try { String setNames = setsAliases.get(cardSet); String preferedLanguage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, "en"); for (String setName : setNames.split("\\^")) { - String URLSetName = URLEncoder.encode(setName, "UTF-8"); + // String URLSetName = URLEncoder.encode(setName, "UTF-8"); + String URLSetName = setName.replaceAll(" ", "%20"); int page = 0; int firstMultiverseIdLastPage = 0; Pages: while (page < 999) { - String searchUrl = "http://gatherer.wizards.com/Pages/Search/Default.aspx?page=" + page + "&output=spoiler&method=visual&action=advanced&set=+[%22" + URLSetName + "%22]"; + String searchUrl = "http://gatherer.wizards.com/Pages/Search/Default.aspx?sort=cn+&page=" + page + "&action=advanced&output=spoiler&method=visual&set=+%5B%22" + URLSetName + "%22%5D"; + logger.debug("URL: " + searchUrl); Document doc = getDocument(searchUrl); Elements cardsImages = doc.select("img[src^=../../Handlers/]"); if (cardsImages.isEmpty()) { @@ -307,7 +509,7 @@ public enum WizardCardsImageSource implements CardImageSource { } } } catch (IOException ex) { - System.out.println("Exception when parsing the wizards page: " + ex.getMessage()); + logger.error("Exception when parsing the wizards page: " + ex.getMessage()); } executor.shutdown(); @@ -327,14 +529,15 @@ public enum WizardCardsImageSource implements CardImageSource { Connection.ProxyType proxyType = Connection.ProxyType.valueByText(prefs.get("proxyType", "None")); Document doc; if (proxyType == ProxyType.NONE) { - doc = Jsoup.connect(urlString).get(); + doc = Jsoup.connect(urlString).timeout(60 * 1000).get(); } else { String proxyServer = prefs.get("proxyAddress", ""); int proxyPort = Integer.parseInt(prefs.get("proxyPort", "0")); URL url = new URL(urlString); Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, proxyPort)); HttpURLConnection uc = (HttpURLConnection) url.openConnection(proxy); - + uc.setConnectTimeout(10000); + uc.setReadTimeout(60000); uc.connect(); String line; @@ -356,7 +559,7 @@ public enum WizardCardsImageSource implements CardImageSource { if (!variations.isEmpty()) { int landNumber = 1; for (Element variation : variations) { - Integer landMultiverseId = Integer.parseInt(variation.attr("onclick").replaceAll("[^\\d]", "")); + Integer landMultiverseId = Integer.parseInt(variation.attr("href").replaceAll("[^\\d]", "")); links.put((cardName + landNumber).toLowerCase(), generateLink(landMultiverseId)); landNumber++; } @@ -444,11 +647,11 @@ public enum WizardCardsImageSource implements CardImageSource { } int number = Integer.parseInt(collectorId.substring(0, length)); - - if (setLinks.size() >= number) { - link = setLinks.get(Integer.toString(number - 1)); - } else { - link = setLinks.get(Integer.toString(number - 21)); + List l = new ArrayList<>(setLinks.values()); + if (l.size() >= number) { + link = l.get(number - 1); + } else {; + link = l.get(number - 21); if (link != null) { link = link.replace(Integer.toString(number - 20), (Integer.toString(number - 20) + 'a')); } @@ -474,16 +677,24 @@ public enum WizardCardsImageSource implements CardImageSource { private final class GetImageLinkTask implements Runnable { - private final int multiverseId; - private final String cardName; - private final String preferedLanguage; - private final ConcurrentHashMap setLinks; + private int multiverseId; + private String cardName; + private String preferedLanguage; + private LinkedHashMap setLinks; - public GetImageLinkTask(int multiverseId, String cardName, String preferedLanguage, ConcurrentHashMap setLinks) { - this.multiverseId = multiverseId; - this.cardName = cardName; - this.preferedLanguage = preferedLanguage; - this.setLinks = setLinks; + public GetImageLinkTask(int multiverseId, String cardName, String preferedLanguage, LinkedHashMap setLinks) { + try { + this.multiverseId = multiverseId; + this.cardName = cardName; + this.preferedLanguage = preferedLanguage; + this.setLinks = setLinks; + } catch (Exception ex) { + logger.error(ex.getMessage()); + logger.error("multiverseId: " + multiverseId); + logger.error("cardName: " + cardName); + logger.error("preferedLanguage: " + preferedLanguage); + logger.error("setLinks: " + setLinks.toString()); + } } @Override @@ -496,7 +707,7 @@ public enum WizardCardsImageSource implements CardImageSource { setLinks.put(cardName.toLowerCase(), generateLink(preferedMultiverseId)); } } catch (IOException | NumberFormatException ex) { - System.out.println("Exception when parsing the wizards page: " + ex.getMessage()); + logger.error("Exception when parsing the wizards page: " + ex.getMessage()); } } @@ -515,4 +726,12 @@ public enum WizardCardsImageSource implements CardImageSource { @Override public void doPause(String httpImageUrl) { } + + @Override + public ArrayList getSupportedSets() { + ArrayList supportedSetsCopy = new ArrayList<>(); + supportedSetsCopy.addAll(supportedSets); + return supportedSetsCopy; + } + } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index 02e639ba19..c9b9a25d1b 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -21,11 +21,16 @@ import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.stream.FileImageOutputStream; import javax.swing.*; +import mage.cards.ExpansionSet; +import mage.cards.Sets; import mage.cards.repository.CardInfo; import mage.client.constants.Constants; import mage.client.dialog.PreferencesDialog; import mage.client.util.sets.ConstructedFormats; import mage.remote.Connection; +import static mage.remote.Connection.ProxyType.HTTP; +import static mage.remote.Connection.ProxyType.NONE; +import static mage.remote.Connection.ProxyType.SOCKS; import net.java.truevfs.access.TFile; import net.java.truevfs.access.TFileOutputStream; import net.java.truevfs.access.TVFS; @@ -39,18 +44,31 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab private static final Logger logger = Logger.getLogger(DownloadPictures.class); + public static final String ALL_CARDS = "- All cards from that source"; + public static final String ALL_STANDARD_CARDS = "- All cards from standard from that source"; + public static final String ALL_TOKENS = "- All token images from that source"; + private final JProgressBar bar; private final JOptionPane dlg; private boolean cancel; private final JButton closeButton; private final JButton startDownloadButton; private int cardIndex; - private List cards; - private List type2cards; - private final JComboBox jComboBox1; - private final JLabel jLabel1; - private static boolean offlineMode = false; - private JCheckBox checkBox; + private List allCardsMissingImage; + List cardsToDownload = new ArrayList<>(); + + private int missingCards = 0; + private int missingTokens = 0; + + List selectedSetCodes = new ArrayList<>(); + + private final JComboBox jComboBoxServer; + private final JLabel jLabelAllMissing; + private final JLabel jLabelServer; + + private final JComboBox jComboBoxSet; + private final JLabel jLabelSet; + private final Object sync = new Object(); private static CardImageSource cardImageSource; @@ -90,7 +108,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } public DownloadPictures(List cards) { - this.cards = cards; + this.allCardsMissingImage = cards; bar = new JProgressBar(this); @@ -98,15 +116,21 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab p0.setLayout(new BoxLayout(p0, BoxLayout.Y_AXIS)); p0.add(Box.createVerticalStrut(5)); - jLabel1 = new JLabel(); - jLabel1.setText("Please select server:"); - jLabel1.setAlignmentX(Component.LEFT_ALIGNMENT); + jLabelAllMissing = new JLabel(); - p0.add(jLabel1); + jLabelAllMissing.setAlignmentX(Component.LEFT_ALIGNMENT); + p0.add(jLabelAllMissing); p0.add(Box.createVerticalStrut(5)); - ComboBoxModel jComboBox1Model = new DefaultComboBoxModel(new String[]{ - // "magiccards.info", + + jLabelServer = new JLabel(); + jLabelServer.setText("Please select server:"); + jLabelServer.setAlignmentX(Component.LEFT_ALIGNMENT); + p0.add(jLabelServer); + + p0.add(Box.createVerticalStrut(5)); + + ComboBoxModel jComboBoxDownloadSourcesModel = new DefaultComboBoxModel(new String[]{ "wizards.com", "mythicspoiler.com", "tokens.mtg.onl", //"mtgimage.com (HQ)", @@ -114,50 +138,45 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab "alternative.mtg.onl", "GrabBag", "magidex.com", - "scryfall.com", //"mtgathering.ru HQ", + "scryfall.com", + "magiccards.info" + //"mtgathering.ru HQ", //"mtgathering.ru MQ", //"mtgathering.ru LQ", }); - jComboBox1 = new JComboBox(); + jComboBoxServer = new JComboBox(); - cardImageSource = MagicCardsImageSource.instance; + cardImageSource = WizardCardsImageSource.instance; - jComboBox1.setModel(jComboBox1Model); - jComboBox1.setAlignmentX(Component.LEFT_ALIGNMENT); - jComboBox1.addActionListener(e -> { - JComboBox cb = (JComboBox) e.getSource(); - switch (cb.getSelectedIndex() + 1) { - case 0: - cardImageSource = MagicCardsImageSource.instance; - break; - case 1: - cardImageSource = WizardCardsImageSource.instance; - break; - case 2: - cardImageSource = MythicspoilerComSource.instance; - break; - case 3: - cardImageSource = TokensMtgImageSource.instance; - break; - case 4: - cardImageSource = MtgOnlTokensImageSource.instance; - break; - case 5: - cardImageSource = AltMtgOnlTokensImageSource.instance; - break; - case 6: - cardImageSource = GrabbagImageSource.instance; - break; - case 7: - cardImageSource = MagidexImageSource.instance; - break; - case 8: - cardImageSource = ScryfallImageSource.instance; - break; + jComboBoxServer.setModel(jComboBoxDownloadSourcesModel); + jComboBoxServer.setAlignmentX(Component.LEFT_ALIGNMENT); + jComboBoxServer.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboBoxServerActionPerformed(evt); } - updateCardsToDownload(); }); - p0.add(jComboBox1); + p0.add(jComboBoxServer); + + p0.add(Box.createVerticalStrut(5)); + + // Set selection --------------------------------- + jLabelSet = new JLabel(); + jLabelSet.setText("Please select sets to download images for:"); + jLabelSet.setAlignmentX(Component.LEFT_ALIGNMENT); + p0.add(jLabelSet); + + jComboBoxSet = new JComboBox(); + jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); + jComboBoxSet.setAlignmentX(Component.LEFT_ALIGNMENT); + jComboBoxSet.addActionListener(new java.awt.event.ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboBoxSetActionPerformed(evt); + } + }); + p0.add(jComboBoxSet); + p0.add(Box.createVerticalStrut(5)); // Start @@ -165,31 +184,21 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab startDownloadButton.addActionListener(e -> { new Thread(DownloadPictures.this).start(); startDownloadButton.setEnabled(false); - checkBox.setEnabled(false); }); p0.add(Box.createVerticalStrut(5)); // Progress p0.add(bar); bar.setStringPainted(true); - int count = cards.size(); - float mb = (count * cardImageSource.getAverageSize()) / 1024; - bar.setString(String.format(cardIndex == cards.size() ? "%d of %d cards finished! Please close!" - : "%d of %d cards finished! Please wait! [%.1f Mb]", 0, cards.size(), mb)); Dimension d = bar.getPreferredSize(); d.width = 300; bar.setPreferredSize(d); - p0.add(Box.createVerticalStrut(5)); - checkBox = new JCheckBox("Download images for Standard (Type2) only"); - p0.add(checkBox); - p0.add(Box.createVerticalStrut(5)); - - checkBox.addActionListener(e -> updateCardsToDownload()); - // JOptionPane Object[] options = {startDownloadButton, closeButton = new JButton("Cancel")}; dlg = new JOptionPane(p0, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null, options, options[1]); + + updateCardsToDownload(); } public static boolean checkForMissingCardImages(List allCards) { @@ -209,31 +218,120 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab return missedCardTFiles.get(); } + private void comboBoxServerActionPerformed(java.awt.event.ActionEvent evt) { + JComboBox cb = (JComboBox) evt.getSource(); + switch (cb.getSelectedIndex()) { + case 0: + cardImageSource = WizardCardsImageSource.instance; + break; + case 1: + cardImageSource = MythicspoilerComSource.instance; + break; + case 2: + cardImageSource = TokensMtgImageSource.instance; + break; + case 3: + cardImageSource = MtgOnlTokensImageSource.instance; + break; + case 4: + cardImageSource = AltMtgOnlTokensImageSource.instance; + break; + case 5: + cardImageSource = GrabbagImageSource.instance; + break; + case 6: + cardImageSource = MagidexImageSource.instance; + break; + case 7: + cardImageSource = ScryfallImageSource.instance; + break; + case 8: + cardImageSource = MagicCardsImageSource.instance; + break; + } + jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); + updateCardsToDownload(); + } + + private Object[] getSetsForCurrentImageSource() { + // Set the available sets to the combo box + ArrayList supportedSets = cardImageSource.getSupportedSets(); + List setNames = new ArrayList<>(); + setNames.add(ALL_CARDS); + setNames.add(ALL_STANDARD_CARDS); + if (cardImageSource.providesTokenImages()) { + setNames.add(ALL_TOKENS); + } + if (supportedSets != null) { + for (String setCode : supportedSets) { + ExpansionSet expansionSet = Sets.findSet(setCode); + if (expansionSet != null) { + setNames.add(expansionSet.getName()); + } else { + logger.error(cardImageSource.getSourceName() + ": Expansion set for code " + setCode + " not found!"); + } + } + + } + return setNames.toArray(new String[0]); + } + private void updateCardsToDownload() { - List cardsToDownload = cards; - if (type2cardsOnly()) { - selectType2andTokenCardsIfNotYetDone(); - cardsToDownload = type2cards; + String expansionSelection = jComboBoxSet.getSelectedItem().toString(); + selectedSetCodes.clear(); + boolean tokens = false; + switch (expansionSelection) { + case ALL_CARDS: + if (cardImageSource.getSupportedSets() == null) { + selectedSetCodes = cardImageSource.getSupportedSets(); + } else { + selectedSetCodes.addAll(cardImageSource.getSupportedSets()); + } + break; + case ALL_STANDARD_CARDS: + List standardSets = ConstructedFormats.getSetsByFormat(ConstructedFormats.STANDARD); + for (String setCode : cardImageSource.getSupportedSets()) { + if (standardSets.contains(setCode)) { + selectedSetCodes.add(setCode); + } else { + logger.debug("Set code " + setCode + " from download source " + cardImageSource.getSourceName()); + } + } + break; + case ALL_TOKENS: + tokens = true; + default: + int nonSetEntries = 2; + if (cardImageSource.providesTokenImages()) { + nonSetEntries++; + } + selectedSetCodes.add(cardImageSource.getSupportedSets().get(jComboBoxSet.getSelectedIndex() - nonSetEntries)); + } + cardsToDownload.clear(); + for (CardDownloadData data : allCardsMissingImage) { + if ((data.isToken() && tokens) + || (!data.isToken() && selectedSetCodes.contains(data.getSet()))) { + cardsToDownload.add(data); + } } updateProgressText(cardsToDownload.size()); } - private boolean type2cardsOnly() { - return checkBox.isSelected(); - } - - private void selectType2andTokenCardsIfNotYetDone() { - if (type2cards == null) { - type2cards = new ArrayList<>(); - for (CardDownloadData data : cards) { - if (data.isType2() || data.isToken()) { - type2cards.add(data); - } - } - } + private void comboBoxSetActionPerformed(java.awt.event.ActionEvent evt) { + // Update the cards to download related to the selected set + updateCardsToDownload(); } private void updateProgressText(int cardCount) { + missingTokens = 0; + for (CardDownloadData card : allCardsMissingImage) { + if (card.isToken()) { + missingTokens++; + } + } + missingCards = allCardsMissingImage.size() - missingTokens; + jLabelAllMissing.setText("Missing: " + missingCards + " cards / " + missingTokens + " tokens"); + float mb = (cardCount * cardImageSource.getAverageSize()) / 1024; bar.setString(String.format(cardIndex == cardCount ? "%d of %d cards finished! Please close!" : "%d of %d cards finished! Please wait! [%.1f Mb]", 0, cardCount, mb)); @@ -262,11 +360,8 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab logger.warn("No formats defined. Try connecting to a server first!"); } - int numberCardImages = allCards.size(); - int numberWithoutTokens = 0; List allCardsUrls = Collections.synchronizedList(new ArrayList<>()); try { - offlineMode = true; allCards.parallelStream().forEach(card -> { if (!card.getCardNumber().isEmpty() && !"0".equals(card.getCardNumber()) && !card.getSetCode().isEmpty() && !ignoreUrls.contains(card.getSetCode())) { @@ -308,14 +403,11 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab logger.error("Card has no set name and won't be sent to client:" + card.getName()); } }); - numberWithoutTokens = allCards.size(); allCardsUrls.addAll(getTokenCardUrls()); } catch (Exception e) { logger.error(e); } - int numberAllTokenImages = allCardsUrls.size() - numberWithoutTokens; - /** * check to see which cards we already have */ @@ -329,22 +421,13 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } }); - int tokenImages = 0; - for (CardDownloadData card : cardsToDownload) { - logger.debug((card.isToken() ? "Token" : "Card") + " image to download: " + card.getName() + " (" + card.getSet() + ')'); - if (card.isToken()) { - tokenImages++; - } - } - logger.info("Check download images (total card images: " + numberCardImages + ", total token images: " + numberAllTokenImages + ')'); - logger.info(" => Missing card images: " + (cardsToDownload.size() - tokenImages)); - logger.info(" => Missing token images: " + tokenImages); return new ArrayList<>(cardsToDownload); } public static ArrayList getTokenCardUrls() throws RuntimeException { ArrayList list = new ArrayList<>(); - InputStream in = DownloadPictures.class.getClassLoader().getResourceAsStream("card-pictures-tok.txt"); + InputStream in = DownloadPictures.class + .getClassLoader().getResourceAsStream("card-pictures-tok.txt"); if (in == null) { logger.error("resources input stream is null"); @@ -446,9 +529,8 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab if (p != null) { HashSet ignoreUrls = SettingsManager.getIntance().getIgnoreUrls(); - List cardsToDownload = this.checkBox.isSelected() ? type2cards : cards; - update(0, cardsToDownload.size()); + logger.info("Started download of " + cardsToDownload.size() + " cards from source: " + cardImageSource.getSourceName()); int numberOfThreads = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_THREADS, "10")); ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); @@ -712,16 +794,18 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab card, count, mb)); } else { List remainingCards = Collections.synchronizedList(new ArrayList<>()); - DownloadPictures.this.cards.parallelStream().forEach(cardDownloadData -> { + DownloadPictures.this.allCardsMissingImage.parallelStream().forEach(cardDownloadData -> { TFile file = new TFile(CardImageUtils.generateImagePath(cardDownloadData)); if (!file.exists()) { remainingCards.add(cardDownloadData); } }); - DownloadPictures.this.cards = new ArrayList<>(remainingCards); + // remove the cards not downloaded to get the siccessfull downloaded cards + DownloadPictures.this.cardsToDownload.removeAll(remainingCards); + DownloadPictures.this.allCardsMissingImage.removeAll(DownloadPictures.this.cardsToDownload); - count = DownloadPictures.this.cards.size(); + count = remainingCards.size(); if (count == 0) { bar.setString("0 cards remaining! Please close!"); diff --git a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target/maven-archiver/pom.properties b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target/maven-archiver/pom.properties index d7097083df..03ac9e7681 100644 --- a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target/maven-archiver/pom.properties +++ b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target/maven-archiver/pom.properties @@ -1,5 +1,5 @@ -#Generated by Maven -#Mon Aug 28 09:53:46 CEST 2017 -version=1.4.26 -groupId=org.mage -artifactId=mage-game-pennydreadfulcommanderfreeforall +#Generated by Maven +#Sun Sep 03 07:46:59 CEST 2017 +version=1.4.26 +groupId=org.mage +artifactId=mage-game-pennydreadfulcommanderfreeforall From 5a1544050c855789ebe7635ff947868b8705f2a7 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Mon, 4 Sep 2017 18:25:31 +0200 Subject: [PATCH 002/182] Updated image download handling. --- .../src/main/java/mage/client/MageFrame.java | 22 +- .../card/dl/sources/CardImageSource.java | 13 +- .../dl/sources/MagicCardsImageSource.java | 216 +++++++++++++++++- .../dl/sources/MtgOnlTokensImageSource.java | 9 +- .../dl/sources/MythicspoilerComSource.java | 2 +- .../card/dl/sources/ScryfallImageSource.java | 203 +++++++++++++++- .../card/dl/sources/TokensMtgImageSource.java | 42 ++-- .../dl/sources/WizardCardsImageSource.java | 5 + .../plugins/card/images/DownloadPictures.java | 210 ++++++++--------- 9 files changed, 556 insertions(+), 166 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index d474fbd100..425172f7a6 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -44,8 +44,6 @@ import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import mage.cards.action.ActionCallback; import mage.cards.decks.Deck; -import mage.cards.repository.CardCriteria; -import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; import mage.client.cards.BigCard; import mage.client.chat.ChatPanelBasic; @@ -134,8 +132,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { private final BalloonTip balloonTip; - private java.util.List missingCards; - /** * @return the session */ @@ -513,18 +509,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { } private void checkForNewImages() { - long beforeCall = System.currentTimeMillis(); - missingCards = CardRepository.instance.findCards(new CardCriteria()); - LOGGER.info("Card pool load time: " + ((System.currentTimeMillis() - beforeCall) / 1000 + " seconds")); - beforeCall = System.currentTimeMillis(); - if (DownloadPictures.checkForMissingCardImages(missingCards)) { - LOGGER.info("Card images checking time: " + ((System.currentTimeMillis() - beforeCall) / 1000 + " seconds")); - UserRequestMessage message = new UserRequestMessage("New images available", "Card images are missing (" + missingCards.size() + "). Do you want to download the images?" - + "

You can deactivate the image download check on application start in the preferences."); - message.setButton1("No", null); - message.setButton2("Yes", PlayerAction.CLIENT_DOWNLOAD_CARD_IMAGES); - showUserRequestDialog(message); - } + // Removed TODO: Remove related pref code } public static void setActive(MagePane frame) { @@ -978,8 +963,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { }//GEN-LAST:event_btnImagesActionPerformed public void downloadImages() { - java.util.List cards = CardRepository.instance.findCards(new CardCriteria()); - DownloadPictures.startDownload(null, cards); + DownloadPictures.startDownload(); } public void exitApp() { @@ -1317,7 +1301,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { Plugins.instance.downloadSymbols(); break; case CLIENT_DOWNLOAD_CARD_IMAGES: - DownloadPictures.startDownload(null, missingCards); + DownloadPictures.startDownload(); break; case CLIENT_DISCONNECT: if (SessionHandler.isConnected()) { diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java index f76aeb953d..ed125d6f2b 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java @@ -23,16 +23,17 @@ public interface CardImageSource { int getTotalImages(); - boolean isTokenSource(); + default int getTokenImages() { + return 0; + } + + default boolean isTokenSource() { + return false; + } void doPause(String httpImageUrl); default ArrayList getSupportedSets() { return null; } - - default boolean providesTokenImages() { - return false; - } -; } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java index 3052a2dc41..78f55e9b7a 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java @@ -1,7 +1,10 @@ package org.mage.plugins.card.dl.sources; +import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.Map; +import java.util.Set; import mage.client.dialog.PreferencesDialog; import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.utils.CardImageUtils; @@ -13,6 +16,202 @@ import org.mage.plugins.card.utils.CardImageUtils; public enum MagicCardsImageSource implements CardImageSource { instance; + + private static final Set supportedSets = new LinkedHashSet() { + { + // add("PTC"); // Prerelease Events + add("LEA"); + add("LEB"); + add("2ED"); + add("ARN"); + add("ATQ"); + add("3ED"); + add("LEG"); + add("DRK"); + add("FEM"); + add("4ED"); + add("ICE"); + add("CHR"); + add("HML"); + add("ALL"); + add("MIR"); + add("VIS"); + add("5ED"); + add("POR"); + add("WTH"); + add("TMP"); + add("STH"); + add("EXO"); + add("P02"); + add("UGL"); + add("USG"); + add("DD3DVD"); + add("DD3EVG"); + add("DD3GVL"); + add("DD3JVC"); + + add("ULG"); + add("6ED"); + add("UDS"); + add("PTK"); + add("S99"); + add("MMQ"); + // add("BRB");Battle Royale Box Set + add("NEM"); + add("S00"); + add("PCY"); + add("INV"); + // add("BTD"); // Beatdown Boxset + add("PLS"); + add("7ED"); + add("APC"); + add("ODY"); + // add("DKM"); // Deckmasters 2001 + add("TOR"); + add("JUD"); + add("ONS"); + add("LGN"); + add("SCG"); + add("8ED"); + add("MRD"); + add("DST"); + add("5DN"); + add("CHK"); + add("UNH"); + add("BOK"); + add("SOK"); + add("9ED"); + add("RAV"); + add("GPT"); + add("DIS"); + add("CSP"); + add("TSP"); + add("TSB"); + add("PLC"); + add("FUT"); + add("10E"); + add("MED"); + add("LRW"); + add("EVG"); + add("MOR"); + add("SHM"); + add("EVE"); + add("DRB"); + add("ME2"); + add("ALA"); + add("DD2"); + add("CON"); + add("DDC"); + add("ARB"); + add("M10"); + // add("TD0"); // Magic Online Deck Series + add("V09"); + add("HOP"); + add("ME3"); + add("ZEN"); + add("DDD"); + add("H09"); + add("WWK"); + add("DDE"); + add("ROE"); + add("DPA"); + add("ARC"); + add("M11"); + add("V10"); + add("DDF"); + add("SOM"); + // add("TD0"); // Commander Theme Decks + add("PD2"); + add("ME4"); + add("MBS"); + add("DDG"); + add("NPH"); + add("CMD"); + add("M12"); + add("V11"); + add("DDH"); + add("ISD"); + add("PD3"); + add("DKA"); + add("DDI"); + add("AVR"); + add("PC2"); + add("M13"); + add("V12"); + add("DDJ"); + add("RTR"); + add("CM1"); + // add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia + add("GTC"); + add("DDK"); + add("DGM"); + add("MMA"); + add("M14"); + add("V13"); + add("DDL"); + add("THS"); + add("C13"); + add("BNG"); + add("DDM"); + add("JOU"); + // add("MD1"); // Modern Event Deck + add("CNS"); + add("VMA"); + add("M15"); + add("V14"); + add("DDN"); + add("KTK"); + add("C14"); + // add("DD3"); // Duel Decks Anthology + add("FRF"); + add("DDO"); + add("DTK"); + add("TPR"); + add("MM2"); + add("ORI"); + add("V15"); + add("DDP"); + add("BFZ"); + add("EXP"); + add("C15"); + // add("PZ1"); // Legendary Cube + add("OGW"); + add("DDQ"); + add("W16"); + add("SOI"); + add("EMA"); + add("EMN"); + add("V16"); + add("CN2"); + add("DDR"); + add("KLD"); + add("MPS"); + // add("PZ2"); // Treasure Chests + add("C16"); + add("PCA"); + add("AER"); + add("MM3"); + add("DDS"); + add("W17"); + add("AKH"); + add("MPS"); + add("CMA"); + add("E01"); + add("HOU"); + add("C17"); +// add("XLN"); +// add("DDT"); +// add("IMA"); +// add("E02"); +// add("V17"); +// add("UST"); +// add("RIX"); +// add("A25"); +// add("DOM"); +// add("M19"); + } + }; + private static final Map setNameTokenReplacement = new HashMap() { { put("10E", "tenth-edition"); @@ -146,12 +345,11 @@ public enum MagicCardsImageSource implements CardImageSource { return "magiccards.info"; } - @Override public String getNextHttpImageUrl() { return null; } - + @Override public String getFileForHttpImage(String httpImageUrl) { return null; @@ -210,18 +408,26 @@ public enum MagicCardsImageSource implements CardImageSource { public float getAverageSize() { return 70.0f; } - + @Override public int getTotalImages() { return -1; } - + @Override public boolean isTokenSource() { return true; } - + + @Override + public ArrayList getSupportedSets() { + ArrayList supportedSetsCopy = new ArrayList<>(); + supportedSetsCopy.addAll(supportedSets); + return supportedSetsCopy; + } + @Override public void doPause(String httpImageUrl) { } + } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgOnlTokensImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgOnlTokensImageSource.java index 56f42fac5a..41207d6b9c 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgOnlTokensImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgOnlTokensImageSource.java @@ -27,11 +27,10 @@ */ package org.mage.plugins.card.dl.sources; -import org.apache.log4j.Logger; -import org.mage.plugins.card.images.CardDownloadData; - import java.io.IOException; import java.util.HashMap; +import org.apache.log4j.Logger; +import org.mage.plugins.card.images.CardDownloadData; /** * @@ -368,12 +367,12 @@ public enum MtgOnlTokensImageSource implements CardImageSource { } return -1; } - + @Override public boolean isTokenSource() { return true; } - + @Override public void doPause(String httpImageUrl) { } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java index d8ceaf19f2..cf81ee5957 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java @@ -77,7 +77,7 @@ public enum MythicspoilerComSource implements CardImageSource { supportedSets.add("DDR"); supportedSets.add("KLD"); supportedSets.add("MPS"); - supportedSets.add("PZ2"); + // supportedSets.add("PZ2"); supportedSets.add("C16"); supportedSets.add("PCA"); supportedSets.add("AER"); diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index 1166e40fc8..a54e5c0118 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -1,18 +1,206 @@ package org.mage.plugins.card.dl.sources; -import org.mage.plugins.card.images.CardDownloadData; - +import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.Map; +import java.util.Set; +import org.mage.plugins.card.images.CardDownloadData; /** * @author Quercitron * */ -public enum ScryfallImageSource implements CardImageSource { +public enum ScryfallImageSource implements CardImageSource { instance; + private final Set supportedSets; + + ScryfallImageSource() { + supportedSets = new LinkedHashSet<>(); + // supportedSets.add("PTC"); // + supportedSets.add("LEA"); + supportedSets.add("LEB"); + supportedSets.add("2ED"); + supportedSets.add("ARN"); + supportedSets.add("ATQ"); + supportedSets.add("3ED"); + supportedSets.add("LEG"); + supportedSets.add("DRK"); + supportedSets.add("FEM"); + supportedSets.add("4ED"); + supportedSets.add("ICE"); + supportedSets.add("CHR"); + supportedSets.add("HML"); + supportedSets.add("ALL"); + supportedSets.add("MIR"); + supportedSets.add("VIS"); + supportedSets.add("5ED"); + supportedSets.add("POR"); + supportedSets.add("WTH"); + supportedSets.add("TMP"); + supportedSets.add("STH"); + supportedSets.add("EXO"); + supportedSets.add("P02"); + supportedSets.add("UGL"); + supportedSets.add("USG"); + supportedSets.add("DD3DVD"); + supportedSets.add("DD3EVG"); + supportedSets.add("DD3GVL"); + supportedSets.add("DD3JVC"); + + supportedSets.add("ULG"); + supportedSets.add("6ED"); + supportedSets.add("UDS"); + supportedSets.add("PTK"); + supportedSets.add("S99"); + supportedSets.add("MMQ"); + // supportedSets.add("BRB");Battle Royale Box Set + supportedSets.add("NEM"); + supportedSets.add("S00"); + supportedSets.add("PCY"); + supportedSets.add("INV"); + // supportedSets.add("BTD"); // Beatdown Boxset + supportedSets.add("PLS"); + supportedSets.add("7ED"); + supportedSets.add("APC"); + supportedSets.add("ODY"); + // supportedSets.add("DKM"); // Deckmasters 2001 + supportedSets.add("TOR"); + supportedSets.add("JUD"); + supportedSets.add("ONS"); + supportedSets.add("LGN"); + supportedSets.add("SCG"); + supportedSets.add("8ED"); + supportedSets.add("MRD"); + supportedSets.add("DST"); + supportedSets.add("5DN"); + supportedSets.add("CHK"); + supportedSets.add("UNH"); + supportedSets.add("BOK"); + supportedSets.add("SOK"); + supportedSets.add("9ED"); + supportedSets.add("RAV"); + supportedSets.add("GPT"); + supportedSets.add("DIS"); + supportedSets.add("CSP"); + supportedSets.add("TSP"); + supportedSets.add("TSB"); + supportedSets.add("PLC"); + supportedSets.add("FUT"); + supportedSets.add("10E"); + supportedSets.add("MED"); + supportedSets.add("LRW"); + supportedSets.add("EVG"); + supportedSets.add("MOR"); + supportedSets.add("SHM"); + supportedSets.add("EVE"); + supportedSets.add("DRB"); + supportedSets.add("ME2"); + supportedSets.add("ALA"); + supportedSets.add("DD2"); + supportedSets.add("CON"); + supportedSets.add("DDC"); + supportedSets.add("ARB"); + supportedSets.add("M10"); + // supportedSets.add("TD0"); // Magic Online Deck Series + supportedSets.add("V09"); + supportedSets.add("HOP"); + supportedSets.add("ME3"); + supportedSets.add("ZEN"); + supportedSets.add("DDD"); + supportedSets.add("H09"); + supportedSets.add("WWK"); + supportedSets.add("DDE"); + supportedSets.add("ROE"); + supportedSets.add("DPA"); + supportedSets.add("ARC"); + supportedSets.add("M11"); + supportedSets.add("V10"); + supportedSets.add("DDF"); + supportedSets.add("SOM"); + // supportedSets.add("TD0"); // Commander Theme Decks + supportedSets.add("PD2"); + supportedSets.add("ME4"); + supportedSets.add("MBS"); + supportedSets.add("DDG"); + supportedSets.add("NPH"); + supportedSets.add("CMD"); + supportedSets.add("M12"); + supportedSets.add("V11"); + supportedSets.add("DDH"); + supportedSets.add("ISD"); + supportedSets.add("PD3"); + supportedSets.add("DKA"); + supportedSets.add("DDI"); + supportedSets.add("AVR"); + supportedSets.add("PC2"); + supportedSets.add("M13"); + supportedSets.add("V12"); + supportedSets.add("DDJ"); + supportedSets.add("RTR"); + supportedSets.add("CM1"); + // supportedSets.add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia + supportedSets.add("GTC"); + supportedSets.add("DDK"); + supportedSets.add("DGM"); + supportedSets.add("MMA"); + supportedSets.add("M14"); + supportedSets.add("V13"); + supportedSets.add("DDL"); + supportedSets.add("THS"); + supportedSets.add("C13"); + supportedSets.add("BNG"); + supportedSets.add("DDM"); + supportedSets.add("JOU"); + // supportedSets.add("MD1"); // Modern Event Deck + supportedSets.add("CNS"); + supportedSets.add("VMA"); + supportedSets.add("M15"); + supportedSets.add("V14"); + supportedSets.add("DDN"); + supportedSets.add("KTK"); + supportedSets.add("C14"); + // supportedSets.add("DD3"); // Duel Decks Anthology + supportedSets.add("FRF"); + supportedSets.add("DDO"); + supportedSets.add("DTK"); + supportedSets.add("TPR"); + supportedSets.add("MM2"); + supportedSets.add("ORI"); + supportedSets.add("V15"); + supportedSets.add("DDP"); + supportedSets.add("BFZ"); + supportedSets.add("EXP"); + supportedSets.add("C15"); + // supportedSets.add("PZ1"); // Legendary Cube + supportedSets.add("OGW"); + supportedSets.add("DDQ"); + supportedSets.add("W16"); + supportedSets.add("SOI"); + supportedSets.add("EMA"); + supportedSets.add("EMN"); + supportedSets.add("V16"); + supportedSets.add("CN2"); + supportedSets.add("DDR"); + supportedSets.add("KLD"); + supportedSets.add("MPS"); + // supportedSets.add("PZ2"); + supportedSets.add("C16"); + supportedSets.add("PCA"); + supportedSets.add("AER"); + supportedSets.add("MM3"); + supportedSets.add("DDS"); + supportedSets.add("W17"); + supportedSets.add("AKH"); + supportedSets.add("MPS"); + supportedSets.add("CMA"); + supportedSets.add("E01"); + supportedSets.add("HOU"); + supportedSets.add("C17"); + } + @Override public String generateURL(CardDownloadData card) throws Exception { return "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/" + card.getCollectorId() + "?format=image"; @@ -40,7 +228,7 @@ public enum ScryfallImageSource implements CardImageSource { @Override public float getAverageSize() { - return 240; + return 90; } @Override @@ -75,4 +263,11 @@ public enum ScryfallImageSource implements CardImageSource { put("MBP", "pmei"); } }; + + @Override + public ArrayList getSupportedSets() { + ArrayList supportedSetsCopy = new ArrayList<>(); + supportedSetsCopy.addAll(supportedSets); + return supportedSetsCopy; + } } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java index 2f58b13a2c..7f932f3536 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java @@ -27,9 +27,6 @@ */ package org.mage.plugins.card.dl.sources; -import org.apache.log4j.Logger; -import org.mage.plugins.card.images.CardDownloadData; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -39,6 +36,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.log4j.Logger; +import org.mage.plugins.card.images.CardDownloadData; /** * @@ -46,10 +45,9 @@ import java.util.Map; */ public enum TokensMtgImageSource implements CardImageSource { - instance; + instance; private static final Logger logger = Logger.getLogger(TokensMtgImageSource.class); - private List tokensData; private final Object tokensDataSync = new Object(); @@ -137,6 +135,7 @@ public enum TokensMtgImageSource implements CardImageSource { List newTokensData = getTokensData(); if (newTokensData.isEmpty()) { + logger.info("Source " + getSourceName() + " provides no token data."); return null; } @@ -146,17 +145,18 @@ public enum TokensMtgImageSource implements CardImageSource { matchedTokens.add(token); } } -// -// if (matchedTokens.isEmpty()) { -// logger.info("Could not find data for token " + name + ", set " + set + "."); -// return null; -// } + + if (matchedTokens.isEmpty()) { + logger.info("Could not find data for token " + name + ", set " + set + "."); + return null; + } TokenData tokenData; if (type == 0) { if (matchedTokens.size() > 1) { logger.info("Multiple images were found for token " + name + ", set " + set + '.'); } + logger.info("Token found: " + name + ", set " + set + '.'); tokenData = matchedTokens.get(0); } else { if (type > matchedTokens.size()) { @@ -178,7 +178,7 @@ public enum TokensMtgImageSource implements CardImageSource { tokensData = new ArrayList<>(); // get tokens data from resource file - try(InputStream inputStream = this.getClass().getResourceAsStream("/tokens-mtg-onl-list.csv")) { + try (InputStream inputStream = this.getClass().getResourceAsStream("/tokens-mtg-onl-list.csv")) { List fileTokensData = parseTokensData(inputStream); tokensData.addAll(fileTokensData); } catch (Exception exception) { @@ -188,7 +188,7 @@ public enum TokensMtgImageSource implements CardImageSource { // description on site may contain new information // try to add it URL url = new URL("http://tokens.mtg.onl/data/SetsWithTokens.csv"); - try(InputStream inputStream = url.openStream()) { + try (InputStream inputStream = url.openStream()) { List siteTokensData = parseTokensData(inputStream); List newTokensData = new ArrayList<>(); for (TokenData siteData : siteTokensData) { @@ -219,8 +219,8 @@ public enum TokensMtgImageSource implements CardImageSource { private List parseTokensData(InputStream inputStream) throws IOException { List newTokensData = new ArrayList<>(); - try(InputStreamReader inputReader = new InputStreamReader(inputStream, "Cp1252"); - BufferedReader reader = new BufferedReader(inputReader)) { + try (InputStreamReader inputReader = new InputStreamReader(inputStream, "Cp1252"); + BufferedReader reader = new BufferedReader(inputReader)) { // we have to specify encoding to read special comma reader.readLine(); // skip header @@ -285,7 +285,19 @@ public enum TokensMtgImageSource implements CardImageSource { @Override public int getTotalImages() { - return -1; + return getTokenImages(); + } + + @Override + public int getTokenImages() { + int number = 0; + try { + List newTokensData = getTokensData(); + number = newTokensData.size(); + } catch (IOException ex) { + logger.error(getSourceName() + ": Loading available data failed. " + ex.getMessage()); + } + return number; } @Override diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java index 4939fdcbe2..50bf2c99ca 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java @@ -77,6 +77,7 @@ public enum WizardCardsImageSource implements CardImageSource { WizardCardsImageSource() { supportedSets = new LinkedHashSet<>(); + // supportedSets.add("PTC"); // Prerelease Events supportedSets.add("LEA"); supportedSets.add("LEB"); supportedSets.add("2ED"); @@ -638,6 +639,9 @@ public enum WizardCardsImageSource implements CardImageSource { String setNames = setsAliases.get(cardSet); if (setNames != null) { Map setLinks = sets.computeIfAbsent(cardSet, k -> getSetLinks(cardSet)); + if (setLinks == null || setLinks.isEmpty()) { + return null; + } String link = setLinks.get(card.getDownloadName().toLowerCase()); if (link == null) { int length = collectorId.length(); @@ -663,6 +667,7 @@ public enum WizardCardsImageSource implements CardImageSource { return link; } return null; + } @Override diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index c9b9a25d1b..86a16bc15a 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -1,6 +1,7 @@ package org.mage.plugins.card.images; import java.awt.*; +import java.awt.event.ItemEvent; import java.awt.image.BufferedImage; import java.io.*; import java.net.*; @@ -14,7 +15,6 @@ import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriteParam; @@ -23,7 +23,9 @@ import javax.imageio.stream.FileImageOutputStream; import javax.swing.*; import mage.cards.ExpansionSet; import mage.cards.Sets; +import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; +import mage.cards.repository.CardRepository; import mage.client.constants.Constants; import mage.client.dialog.PreferencesDialog; import mage.client.util.sets.ConstructedFormats; @@ -75,28 +77,56 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab private Proxy p = Proxy.NO_PROXY; - // private ExecutorService executor = Executors.newFixedThreadPool(10); - public static void main(String[] args) { - startDownload(null, null); + enum DownloadSources { + WIZARDS("wizards.com", WizardCardsImageSource.instance), + MYTHICSPOILER("mythicspoiler.com", MythicspoilerComSource.instance), + TOKENS("tokens.mtg.onl", TokensMtgImageSource.instance), + MTG_ONL("mtg.onl", MtgOnlTokensImageSource.instance), + ALTERNATIVE("alternative.mtg.onl", AltMtgOnlTokensImageSource.instance), + GRAB_BAG("GrabBag", GrabbagImageSource.instance), + MAGIDEX("magidex.com", MagidexImageSource.instance), + SCRYFALL("scryfall.com", ScryfallImageSource.instance), + MAGICCARDS("magiccards.info", MagicCardsImageSource.instance); + + private final String text; + private final CardImageSource source; + + DownloadSources(String text, CardImageSource sourceInstance) { + this.text = text; + this.source = sourceInstance; + } + + public CardImageSource getSource() { + return source; + } + + @Override + public String toString() { + return text; + } + } - public static void startDownload(JFrame frame, List allCards) { - List cards = getNeededCards(allCards); + public static void main(String[] args) { + startDownload(); + } + + public static void startDownload() { /* * if (cards == null || cards.isEmpty()) { * JOptionPane.showMessageDialog(null, * "All card pictures have been downloaded."); return; } */ - DownloadPictures download = new DownloadPictures(cards); - JDialog dlg = download.getDlg(frame); + DownloadPictures download = new DownloadPictures(); + JDialog dlg = download.getDlg(null); dlg.setVisible(true); dlg.dispose(); download.cancel = true; } public JDialog getDlg(JFrame frame) { - String title = "Downloading"; + String title = "Downloading images"; final JDialog dialog = this.dlg.createDialog(frame, title); closeButton.addActionListener(e -> dialog.setVisible(false)); @@ -107,11 +137,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab this.cancel = cancel; } - public DownloadPictures(List cards) { - this.allCardsMissingImage = cards; - - bar = new JProgressBar(this); - + public DownloadPictures() { JPanel p0 = new JPanel(); p0.setLayout(new BoxLayout(p0, BoxLayout.Y_AXIS)); @@ -120,61 +146,46 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab jLabelAllMissing = new JLabel(); jLabelAllMissing.setAlignmentX(Component.LEFT_ALIGNMENT); + // jLabelAllMissing.setText("Computing number of missing images..."); p0.add(jLabelAllMissing); p0.add(Box.createVerticalStrut(5)); jLabelServer = new JLabel(); - jLabelServer.setText("Please select server:"); + jLabelServer.setText("Please select image source:"); jLabelServer.setAlignmentX(Component.LEFT_ALIGNMENT); p0.add(jLabelServer); p0.add(Box.createVerticalStrut(5)); - ComboBoxModel jComboBoxDownloadSourcesModel = new DefaultComboBoxModel(new String[]{ - "wizards.com", - "mythicspoiler.com", - "tokens.mtg.onl", //"mtgimage.com (HQ)", - "mtg.onl", - "alternative.mtg.onl", - "GrabBag", - "magidex.com", - "scryfall.com", - "magiccards.info" - //"mtgathering.ru HQ", - //"mtgathering.ru MQ", - //"mtgathering.ru LQ", - }); jComboBoxServer = new JComboBox(); - - cardImageSource = WizardCardsImageSource.instance; - - jComboBoxServer.setModel(jComboBoxDownloadSourcesModel); + jComboBoxServer.setModel(new DefaultComboBoxModel(DownloadSources.values())); jComboBoxServer.setAlignmentX(Component.LEFT_ALIGNMENT); - jComboBoxServer.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(java.awt.event.ActionEvent evt) { - comboBoxServerActionPerformed(evt); + jComboBoxServer.addItemListener((ItemEvent event) -> { + if (event.getStateChange() == ItemEvent.SELECTED) { + comboBoxServerItemSelected(event); } }); p0.add(jComboBoxServer); + // set the first source as default + cardImageSource = WizardCardsImageSource.instance; p0.add(Box.createVerticalStrut(5)); // Set selection --------------------------------- jLabelSet = new JLabel(); - jLabelSet.setText("Please select sets to download images for:"); + jLabelSet.setText("Please select sets to download the images for:"); jLabelSet.setAlignmentX(Component.LEFT_ALIGNMENT); p0.add(jLabelSet); jComboBoxSet = new JComboBox(); jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); jComboBoxSet.setAlignmentX(Component.LEFT_ALIGNMENT); - jComboBoxSet.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(java.awt.event.ActionEvent evt) { - comboBoxSetActionPerformed(evt); + jComboBoxSet.addItemListener((ItemEvent event) -> { + if (event.getStateChange() == ItemEvent.SELECTED) { + comboBoxSetItemSelected(event); } }); + p0.add(jComboBoxSet); p0.add(Box.createVerticalStrut(5)); @@ -188,8 +199,10 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab p0.add(Box.createVerticalStrut(5)); // Progress + bar = new JProgressBar(this); p0.add(bar); bar.setStringPainted(true); + Dimension d = bar.getPreferredSize(); d.width = 300; bar.setPreferredSize(d); @@ -198,68 +211,31 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab Object[] options = {startDownloadButton, closeButton = new JButton("Cancel")}; dlg = new JOptionPane(p0, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null, options, options[1]); - updateCardsToDownload(); + setAllMissingCards(); } - public static boolean checkForMissingCardImages(List allCards) { - AtomicBoolean missedCardTFiles = new AtomicBoolean(); - allCards.parallelStream().forEach(card -> { - if (!missedCardTFiles.get()) { - if (!card.getCardNumber().isEmpty() && !"0".equals(card.getCardNumber()) && !card.getSetCode().isEmpty()) { - CardDownloadData url = new CardDownloadData(card.getName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), - 0, "", "", false, card.isDoubleFaced(), card.isNightCard()); - TFile file = new TFile(CardImageUtils.generateImagePath(url)); - if (!file.exists()) { - missedCardTFiles.set(true); - } - } - } - }); - return missedCardTFiles.get(); + public void setAllMissingCards() { + List cards = CardRepository.instance.findCards(new CardCriteria()); + this.allCardsMissingImage = getNeededCards(cards); + updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); } - private void comboBoxServerActionPerformed(java.awt.event.ActionEvent evt) { - JComboBox cb = (JComboBox) evt.getSource(); - switch (cb.getSelectedIndex()) { - case 0: - cardImageSource = WizardCardsImageSource.instance; - break; - case 1: - cardImageSource = MythicspoilerComSource.instance; - break; - case 2: - cardImageSource = TokensMtgImageSource.instance; - break; - case 3: - cardImageSource = MtgOnlTokensImageSource.instance; - break; - case 4: - cardImageSource = AltMtgOnlTokensImageSource.instance; - break; - case 5: - cardImageSource = GrabbagImageSource.instance; - break; - case 6: - cardImageSource = MagidexImageSource.instance; - break; - case 7: - cardImageSource = ScryfallImageSource.instance; - break; - case 8: - cardImageSource = MagicCardsImageSource.instance; - break; - } + private void comboBoxServerItemSelected(ItemEvent evt) { + cardImageSource = ((DownloadSources) evt.getItem()).getSource(); + // update the available sets / token comboBox jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); - updateCardsToDownload(); + updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); } private Object[] getSetsForCurrentImageSource() { // Set the available sets to the combo box ArrayList supportedSets = cardImageSource.getSupportedSets(); List setNames = new ArrayList<>(); - setNames.add(ALL_CARDS); - setNames.add(ALL_STANDARD_CARDS); - if (cardImageSource.providesTokenImages()) { + if (supportedSets != null) { + setNames.add(ALL_CARDS); + setNames.add(ALL_STANDARD_CARDS); + } + if (cardImageSource.isTokenSource()) { setNames.add(ALL_TOKENS); } if (supportedSets != null) { @@ -273,14 +249,17 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } } + if (setNames.isEmpty()) { + logger.error("Source " + cardImageSource.getSourceName() + " creates no selectable items."); + setNames.add("not avalable"); + } return setNames.toArray(new String[0]); } - private void updateCardsToDownload() { - String expansionSelection = jComboBoxSet.getSelectedItem().toString(); + private void updateCardsToDownload(String itemText) { selectedSetCodes.clear(); boolean tokens = false; - switch (expansionSelection) { + switch (itemText) { case ALL_CARDS: if (cardImageSource.getSupportedSets() == null) { selectedSetCodes = cardImageSource.getSupportedSets(); @@ -300,9 +279,13 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab break; case ALL_TOKENS: tokens = true; + break; default: - int nonSetEntries = 2; - if (cardImageSource.providesTokenImages()) { + int nonSetEntries = 0; + if (cardImageSource.getSupportedSets() != null) { + nonSetEntries = 2; + } + if (cardImageSource.isTokenSource()) { nonSetEntries++; } selectedSetCodes.add(cardImageSource.getSupportedSets().get(jComboBoxSet.getSelectedIndex() - nonSetEntries)); @@ -310,16 +293,20 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab cardsToDownload.clear(); for (CardDownloadData data : allCardsMissingImage) { if ((data.isToken() && tokens) - || (!data.isToken() && selectedSetCodes.contains(data.getSet()))) { + || (!data.isToken() && selectedSetCodes != null && selectedSetCodes.contains(data.getSet()))) { cardsToDownload.add(data); } } - updateProgressText(cardsToDownload.size()); + int numberTokenImagesAvailable = 0; + if (tokens) { + cardImageSource.getTokenImages(); + } + updateProgressText(cardsToDownload.size() + numberTokenImagesAvailable); } - private void comboBoxSetActionPerformed(java.awt.event.ActionEvent evt) { + private void comboBoxSetItemSelected(ItemEvent event) { // Update the cards to download related to the selected set - updateCardsToDownload(); + updateCardsToDownload(event.getItem().toString()); } private void updateProgressText(int cardCount) { @@ -330,11 +317,11 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } } missingCards = allCardsMissingImage.size() - missingTokens; - jLabelAllMissing.setText("Missing: " + missingCards + " cards / " + missingTokens + " tokens"); + jLabelAllMissing.setText("Missing: " + missingCards + " card images / " + missingTokens + " token images"); float mb = (cardCount * cardImageSource.getAverageSize()) / 1024; - bar.setString(String.format(cardIndex == cardCount ? "%d of %d cards finished! Please close!" - : "%d of %d cards finished! Please wait! [%.1f Mb]", 0, cardCount, mb)); + bar.setString(String.format(cardIndex == cardCount ? "%d of %d image downloads finished! Please close!" + : "%d of %d image downloads finished! Please wait! [%.1f Mb]", 0, cardCount, mb)); } private static String createDownloadName(CardInfo card) { @@ -530,7 +517,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab HashSet ignoreUrls = SettingsManager.getIntance().getIgnoreUrls(); update(0, cardsToDownload.size()); - logger.info("Started download of " + cardsToDownload.size() + " cards from source: " + cardImageSource.getSourceName()); + logger.info("Started download of " + cardsToDownload.size() + " images from source: " + cardImageSource.getSourceName()); int numberOfThreads = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_THREADS, "10")); ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); @@ -539,7 +526,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab CardDownloadData card = cardsToDownload.get(i); - logger.debug("Downloading card: " + card.getName() + " (" + card.getSet() + ')'); + logger.debug("Downloading image: " + card.getName() + " (" + card.getSet() + ')'); String url; if (ignoreUrls.contains(card.getSet()) || card.isToken()) { @@ -564,7 +551,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } catch (Exception ex) { } } else if (cardImageSource.getTotalImages() == -1) { - logger.info("Card not available on " + cardImageSource.getSourceName() + ": " + card.getName() + " (" + card.getSet() + ')'); + logger.info("Image not available on " + cardImageSource.getSourceName() + ": " + card.getName() + " (" + card.getSet() + ')'); synchronized (sync) { update(cardIndex + 1, cardsToDownload.size()); } @@ -595,6 +582,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab System.gc(); } closeButton.setText("Close"); + updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); } static String convertStreamToString(java.io.InputStream is) { @@ -790,7 +778,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab if (cardIndex < count) { float mb = ((count - card) * cardImageSource.getAverageSize()) / 1024; - bar.setString(String.format("%d of %d cards finished! Please wait! [%.1f Mb]", + bar.setString(String.format("%d of %d image downloads finished! Please wait! [%.1f Mb]", card, count, mb)); } else { List remainingCards = Collections.synchronizedList(new ArrayList<>()); @@ -808,9 +796,9 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab count = remainingCards.size(); if (count == 0) { - bar.setString("0 cards remaining! Please close!"); + bar.setString("0 images remaining! Please close!"); } else { - bar.setString(String.format("%d cards remaining! Please choose another source!", count)); +// bar.setString(String.format("%d cards remaining! Please choose another source!", count)); startDownloadButton.setEnabled(true); } } From 7329dc6c3f83a344c3b47b5cfaec82eb5c9eb927 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 5 Sep 2017 00:12:09 +0200 Subject: [PATCH 003/182] Some more changes to image download. --- .../card/dl/sources/GrabbagImageSource.java | 111 ++++++--- .../card/dl/sources/MagidexImageSource.java | 235 +++++++++++++++++- .../plugins/card/images/DownloadPictures.java | 1 + .../src/mage/cards/e/EssenceScatter.java | 1 + 4 files changed, 305 insertions(+), 43 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java index f0b6aa02d4..4eb98dd2e3 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java @@ -28,7 +28,11 @@ package org.mage.plugins.card.dl.sources; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import org.mage.plugins.card.images.CardDownloadData; @@ -37,12 +41,34 @@ import org.mage.plugins.card.images.CardDownloadData; * * @author spjspj */ -public enum GrabbagImageSource implements CardImageSource { +public enum GrabbagImageSource implements CardImageSource { instance; private static final Logger logger = Logger.getLogger(GrabbagImageSource.class); private static int maxTimes = 0; + private static final Set supportedSets = new LinkedHashSet() { + { + add("PTC"); + add("EXP"); + add("APAC"); + add("ARENA"); + add("FNMP"); + add("GPX"); + add("GRC"); + add("JR"); + add("MBP"); + add("MGDC"); + add("MLP"); + add("MPRP"); + add("MPS"); + add("SUS"); + add("UGIN"); + add("WMCQ"); + + } + }; + @Override public String getSourceName() { return ""; @@ -55,36 +81,37 @@ public enum GrabbagImageSource implements CardImageSource { @Override public String getNextHttpImageUrl() { - if (copyUrlToImage == null) { - setupLinks(); - } - - for (String key : copyUrlToImageDone.keySet()) { - if (copyUrlToImageDone.get(key) < maxTimes) { - copyUrlToImageDone.put(key, maxTimes); - return getSourceName(key) + key; - } - } - if (maxTimes < 2) { - maxTimes++; - } - for (String key : copyUrlToImageDone.keySet()) { - if (copyUrlToImageDone.get(key) < maxTimes) { - copyUrlToImageDone.put(key, maxTimes); - return getSourceName(key) + key; - } - } return null; +// if (copyUrlToImage == null) { +// setupLinks(); +// } +// +// for (String key : copyUrlToImageDone.keySet()) { +// if (copyUrlToImageDone.get(key) < maxTimes) { +// copyUrlToImageDone.put(key, maxTimes); +// return getSourceName(key) + key; +// } +// } +// if (maxTimes < 2) { +// maxTimes++; +// } +// for (String key : copyUrlToImageDone.keySet()) { +// if (copyUrlToImageDone.get(key) < maxTimes) { +// copyUrlToImageDone.put(key, maxTimes); +// return getSourceName(key) + key; +// } +// } +// return null; } @Override public String getFileForHttpImage(String httpImageUrl) { - String copy = httpImageUrl; - if (copy != null) { - copy = copy.replaceFirst("http:\\/\\/static.starcitygames.com\\/sales\\/cardscans\\/", ""); - copy = copy.replaceFirst("http:\\/\\/magiccards.info\\/scans\\/en\\/", ""); - return copyUrlToImage.get(copy); - } +// String copy = httpImageUrl; +// if (copy != null) { +// copy = copy.replaceFirst("http:\\/\\/static.starcitygames.com\\/sales\\/cardscans\\/", ""); +// copy = copy.replaceFirst("http:\\/\\/magiccards.info\\/scans\\/en\\/", ""); +// return copyUrlToImage.get(copy); +// } return null; } @@ -93,6 +120,11 @@ public enum GrabbagImageSource implements CardImageSource { if (copyUrlToImage == null) { setupLinks(); } + for (Map.Entry urlInfo : copyUrlToImage.entrySet()) { + if (urlInfo.getValue().contains(card.getSet()) && urlInfo.getValue().contains(card.getName())) { + return getSourceName(urlInfo.getValue()) + urlInfo.getKey(); + } + } return null; } @@ -108,16 +140,16 @@ public enum GrabbagImageSource implements CardImageSource { copyImageToUrl = new HashMap<>(); copyUrlToImageDone = new HashMap<>(); - //http://anonymouse.org/cgi-bin/anon-www.cgi/http://magiccards.info/scans/en/arena/42.jpg - copyUrlToImage.put("MTG/BNG/en/promo/ArbiterOfTheIdeal.jpg", "PTC.zip/PTC/Arbiter of the Ideal.full.jpg"); - copyUrlToImage.put("MTG/BNG/en/promo/CourserOfKruphix.jpg", "PTC.zip/PTC/Courser of Kruphix.full.jpg"); - copyUrlToImage.put("MTG/BNG/en/promo/EaterOfHope.jpg", "PTC.zip/PTC/Eater of Hope.full.jpg"); - copyUrlToImage.put("MTG/BNG/en/promo/FatedReturn.jpg", "PTC.zip/PTC/Fated Return.full.jpg"); - copyUrlToImage.put("MTG/BNG/en/promo/ForgestokerDragon.jpg", "PTC.zip/PTC/Forgestoker Dragon.full.jpg"); - copyUrlToImage.put("MTG/BNG/en/promo/NessianWildsRavager.jpg", "PTC.zip/PTC/Nessian Wilds Ravager.full.jpg"); - copyUrlToImage.put("MTG/BNG/en/promo/PainSeer.jpg", "PTC.zip/PTC/Pain Seer.full.jpg"); - copyUrlToImage.put("MTG/BNG/en/promo/SilentSentinel.jpg", "PTC.zip/PTC/Silent Sentinel.full.jpg"); - copyUrlToImage.put("MTG/BNG/en/promo/Tromokratis.jpg", "PTC.zip/PTC/Tromokratis.full.jpg"); + copyUrlToImage.put("PTC/Arbiter of the Ideal", "MTG/BNG/en/promo/ArbiterOfTheIdeal.jpg"); + copyUrlToImage.put("PTC/Courser of Kruphix", "MTG/BNG/en/promo/CourserOfKruphix.jpg"); + copyUrlToImage.put("PTC/Eater of Hope", "MTG/BNG/en/promo/EaterOfHope.jpg"); + copyUrlToImage.put("PTC/Fated Return", "MTG/BNG/en/promo/FatedReturn.jpg"); + copyUrlToImage.put("PTC/Forgestoker Dragon", "MTG/BNG/en/promo/ForgestokerDragon.jpg"); + copyUrlToImage.put("PTC/Nessian Wilds Ravager", "MTG/BNG/en/promo/NessianWildsRavager.jpg"); + copyUrlToImage.put("PTC/Pain Seer", "MTG/BNG/en/promo/PainSeer.jpg"); + copyUrlToImage.put("PTC/Silent Sentinel", "MTG/BNG/en/promo/SilentSentinel.jpg"); + copyUrlToImage.put("PTC/Tromokratis", "MTG/BNG/en/promo/Tromokratis.jpg"); + copyUrlToImage.put("MTG/FRF/en/promo/prerelease/AleshaWhoSmilesAtDeath.jpg", "PTC.zip/PTC/Alesha, Who Smiles at Death.full.jpg"); copyUrlToImage.put("MTG/FRF/en/promo/prerelease/Arcbond.jpg", "PTC.zip/PTC/Arcbond.full.jpg"); copyUrlToImage.put("MTG/FRF/en/promo/prerelease/ArchfiendOfDepravity.jpg", "PTC.zip/PTC/Archfiend of Depravity.full.jpg"); @@ -1687,6 +1719,13 @@ public enum GrabbagImageSource implements CardImageSource { } } + @Override + public ArrayList getSupportedSets() { + ArrayList supportedSetsCopy = new ArrayList<>(); + supportedSetsCopy.addAll(supportedSets); + return supportedSetsCopy; + } + @Override public void doPause(String httpImageUrl) { if (!httpImageUrl.startsWith("/MTG")) { diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagidexImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagidexImageSource.java index 2c0ab80e75..7261ad4cbc 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagidexImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagidexImageSource.java @@ -24,20 +24,221 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package org.mage.plugins.card.dl.sources; -import org.mage.plugins.card.images.CardDownloadData; import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import org.mage.plugins.card.images.CardDownloadData; /** * * @author Pete Rossi */ +public enum MagidexImageSource implements CardImageSource { + instance; -public enum MagidexImageSource implements CardImageSource { - instance; + private final Set supportedSets; + + MagidexImageSource() { + supportedSets = new LinkedHashSet<>(); + // supportedSets.add("PTC"); // Prerelease Events + // supportedSets.add("FNMP"); + supportedSets.add("JR"); + supportedSets.add("LEA"); + supportedSets.add("LEB"); + supportedSets.add("2ED"); + supportedSets.add("ARN"); + supportedSets.add("ATQ"); + supportedSets.add("3ED"); + supportedSets.add("LEG"); + supportedSets.add("DRK"); + supportedSets.add("FEM"); + supportedSets.add("4ED"); + supportedSets.add("ICE"); + supportedSets.add("CHR"); + supportedSets.add("HML"); + supportedSets.add("ALL"); + supportedSets.add("MIR"); + supportedSets.add("VIS"); + supportedSets.add("5ED"); + supportedSets.add("POR"); + supportedSets.add("WTH"); + supportedSets.add("TMP"); + supportedSets.add("STH"); + supportedSets.add("EXO"); + supportedSets.add("P02"); + supportedSets.add("UGL"); + supportedSets.add("USG"); + supportedSets.add("DD3DVD"); + supportedSets.add("DD3EVG"); + supportedSets.add("DD3GVL"); + supportedSets.add("DD3JVC"); + + supportedSets.add("ULG"); + supportedSets.add("6ED"); + supportedSets.add("UDS"); + supportedSets.add("PTK"); + supportedSets.add("S99"); + supportedSets.add("MMQ"); + // supportedSets.add("BRB");Battle Royale Box Set + supportedSets.add("NEM"); + supportedSets.add("S00"); + supportedSets.add("PCY"); + supportedSets.add("INV"); + // supportedSets.add("BTD"); // Beatdown Boxset + supportedSets.add("PLS"); + supportedSets.add("7ED"); + supportedSets.add("APC"); + supportedSets.add("ODY"); + // supportedSets.add("DKM"); // Deckmasters 2001 + supportedSets.add("TOR"); + supportedSets.add("JUD"); + supportedSets.add("ONS"); + supportedSets.add("LGN"); + supportedSets.add("SCG"); + supportedSets.add("8ED"); + supportedSets.add("MRD"); + supportedSets.add("DST"); + supportedSets.add("5DN"); + supportedSets.add("CHK"); + supportedSets.add("UNH"); + supportedSets.add("BOK"); + supportedSets.add("SOK"); + supportedSets.add("9ED"); + supportedSets.add("RAV"); + supportedSets.add("GPT"); + supportedSets.add("DIS"); + supportedSets.add("CSP"); + supportedSets.add("TSP"); + supportedSets.add("TSB"); + supportedSets.add("PLC"); + supportedSets.add("FUT"); + supportedSets.add("10E"); + supportedSets.add("MED"); + supportedSets.add("LRW"); + supportedSets.add("EVG"); + supportedSets.add("MOR"); + supportedSets.add("SHM"); + supportedSets.add("EVE"); + supportedSets.add("DRB"); + supportedSets.add("ME2"); + supportedSets.add("ALA"); + supportedSets.add("DD2"); + supportedSets.add("CON"); + supportedSets.add("DDC"); + supportedSets.add("ARB"); + supportedSets.add("M10"); + // supportedSets.add("TD0"); // Magic Online Deck Series + supportedSets.add("V09"); + supportedSets.add("HOP"); + supportedSets.add("ME3"); + supportedSets.add("ZEN"); + supportedSets.add("DDD"); + supportedSets.add("H09"); + supportedSets.add("WWK"); + supportedSets.add("DDE"); + supportedSets.add("ROE"); + supportedSets.add("DPA"); + supportedSets.add("ARC"); + supportedSets.add("M11"); + supportedSets.add("V10"); + supportedSets.add("DDF"); + supportedSets.add("SOM"); + // supportedSets.add("TD0"); // Commander Theme Decks + supportedSets.add("PD2"); + supportedSets.add("ME4"); + supportedSets.add("MBS"); + supportedSets.add("DDG"); + supportedSets.add("NPH"); + supportedSets.add("CMD"); + supportedSets.add("M12"); + supportedSets.add("V11"); + supportedSets.add("DDH"); + supportedSets.add("ISD"); + supportedSets.add("PD3"); + supportedSets.add("DKA"); + supportedSets.add("DDI"); + supportedSets.add("AVR"); + supportedSets.add("PC2"); + supportedSets.add("M13"); + supportedSets.add("V12"); + supportedSets.add("DDJ"); + supportedSets.add("RTR"); + supportedSets.add("CM1"); + // supportedSets.add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia + supportedSets.add("GTC"); + supportedSets.add("DDK"); + supportedSets.add("DGM"); + supportedSets.add("MMA"); + supportedSets.add("M14"); + supportedSets.add("V13"); + supportedSets.add("DDL"); + supportedSets.add("THS"); + supportedSets.add("C13"); + supportedSets.add("BNG"); + supportedSets.add("DDM"); + supportedSets.add("JOU"); + // supportedSets.add("MD1"); // Modern Event Deck + supportedSets.add("CNS"); + supportedSets.add("VMA"); + supportedSets.add("M15"); + supportedSets.add("V14"); + supportedSets.add("DDN"); + supportedSets.add("KTK"); + supportedSets.add("C14"); + // supportedSets.add("DD3"); // Duel Decks Anthology + supportedSets.add("FRF"); + supportedSets.add("DDO"); + supportedSets.add("DTK"); + supportedSets.add("TPR"); + supportedSets.add("MM2"); + supportedSets.add("ORI"); + supportedSets.add("V15"); + supportedSets.add("DDP"); + supportedSets.add("BFZ"); + supportedSets.add("EXP"); + supportedSets.add("C15"); + // supportedSets.add("PZ1"); // Legendary Cube + supportedSets.add("OGW"); + supportedSets.add("DDQ"); + supportedSets.add("W16"); + supportedSets.add("SOI"); + supportedSets.add("EMA"); + supportedSets.add("EMN"); + supportedSets.add("V16"); + supportedSets.add("CN2"); + supportedSets.add("DDR"); + supportedSets.add("KLD"); + supportedSets.add("MPS"); + // supportedSets.add("PZ2"); // Treasure Chests + supportedSets.add("C16"); + supportedSets.add("PCA"); + supportedSets.add("AER"); + supportedSets.add("MM3"); + supportedSets.add("DDS"); + supportedSets.add("W17"); + supportedSets.add("AKH"); + supportedSets.add("MPS"); + supportedSets.add("CMA"); + supportedSets.add("E01"); + supportedSets.add("HOU"); + supportedSets.add("C17"); +// supportedSets.add("XLN"); +// supportedSets.add("DDT"); +// supportedSets.add("IMA"); +// supportedSets.add("E02"); +// supportedSets.add("V17"); +// supportedSets.add("UST"); +// supportedSets.add("RIX"); +// supportedSets.add("A25"); +// supportedSets.add("DOM"); +// supportedSets.add("M19"); + } @Override public String getSourceName() { @@ -68,10 +269,23 @@ public enum MagidexImageSource implements CardImageSource { } // This will properly escape the url - URI uri = new URI("http", "magidex.com", "/extstatic/card/" + cardSet + '/' + cardDownloadName + ".jpg", null, null); - return uri.toASCIIString(); + URI uri = new URI("http", "magidex.com", "/extstatic/card/" + formatSetName(cardSet) + '/' + cardDownloadName + ".jpg", null, null); + return uri.toASCIIString(); } + private String formatSetName(String setName) { + if (setNameReplacement.containsKey(setName)) { + setName = setNameReplacement.get(setName); + } + return setName; + } + + private static final Map setNameReplacement = new HashMap() { + { + put("JR", "pJGP"); + } + }; + @Override public String generateTokenUrl(CardDownloadData card) { return null; @@ -95,4 +309,11 @@ public enum MagidexImageSource implements CardImageSource { @Override public void doPause(String httpImageUrl) { } + + @Override + public ArrayList getSupportedSets() { + ArrayList supportedSetsCopy = new ArrayList<>(); + supportedSetsCopy.addAll(supportedSets); + return supportedSetsCopy; + } } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index 86a16bc15a..be4345dadf 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -674,6 +674,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab if (temporaryFile != null && temporaryFile.length() > 100) { useTempFile = true; } else { + cardImageSource.doPause(url.getPath()); httpConn = url.openConnection(p); httpConn.connect(); diff --git a/Mage.Sets/src/mage/cards/e/EssenceScatter.java b/Mage.Sets/src/mage/cards/e/EssenceScatter.java index 136b54c670..653ffbe8fd 100644 --- a/Mage.Sets/src/mage/cards/e/EssenceScatter.java +++ b/Mage.Sets/src/mage/cards/e/EssenceScatter.java @@ -44,6 +44,7 @@ public class EssenceScatter extends CardImpl { public EssenceScatter(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + // Counter target creature spell. this.getSpellAbility().addTarget(new TargetSpell(new FilterCreatureSpell())); this.getSpellAbility().addEffect(new CounterTargetEffect()); } From c9327b718dabb0301c9f9fa3fa394f0e1166710b Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 6 Sep 2017 17:49:55 +0200 Subject: [PATCH 004/182] Updated some logic. --- .../card/dl/sources/CardImageSource.java | 8 + .../card/dl/sources/GrabbagImageSource.java | 3455 +++++++++-------- .../plugins/card/images/DownloadPictures.java | 4 +- 3 files changed, 1877 insertions(+), 1590 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java index ed125d6f2b..e49c334a1c 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java @@ -36,4 +36,12 @@ public interface CardImageSource { default ArrayList getSupportedSets() { return null; } + + default boolean isSetSupportedComplete(String setCode) { + return true; + } + + default boolean isImageProvided(String setCode, String cardName) { + return false; + } } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java index 4eb98dd2e3..501b1c61e9 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java @@ -31,7 +31,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashSet; -import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; @@ -45,26 +44,26 @@ public enum GrabbagImageSource implements CardImageSource { instance; private static final Logger logger = Logger.getLogger(GrabbagImageSource.class); - private static int maxTimes = 0; private static final Set supportedSets = new LinkedHashSet() { { add("PTC"); - add("EXP"); - add("APAC"); - add("ARENA"); - add("FNMP"); - add("GPX"); - add("GRC"); - add("JR"); - add("MBP"); - add("MGDC"); - add("MLP"); - add("MPRP"); - add("MPS"); - add("SUS"); - add("UGIN"); - add("WMCQ"); + add("SWS"); +// add("EXP"); +// add("APAC"); +// add("ARENA"); +// add("FNMP"); +// add("GPX"); +// add("GRC"); +// add("JR"); +// add("MBP"); +// add("MGDC"); +// add("MLP"); +// add("MPRP"); +// add("MPS"); +// add("SUS"); +// add("UGIN"); +// add("WMCQ"); } }; @@ -82,22 +81,22 @@ public enum GrabbagImageSource implements CardImageSource { @Override public String getNextHttpImageUrl() { return null; -// if (copyUrlToImage == null) { +// if (singleLinks == null) { // setupLinks(); // } // -// for (String key : copyUrlToImageDone.keySet()) { -// if (copyUrlToImageDone.get(key) < maxTimes) { -// copyUrlToImageDone.put(key, maxTimes); +// for (String key : singleLinksDone.keySet()) { +// if (singleLinksDone.get(key) < maxTimes) { +// singleLinksDone.put(key, maxTimes); // return getSourceName(key) + key; // } // } // if (maxTimes < 2) { // maxTimes++; // } -// for (String key : copyUrlToImageDone.keySet()) { -// if (copyUrlToImageDone.get(key) < maxTimes) { -// copyUrlToImageDone.put(key, maxTimes); +// for (String key : singleLinksDone.keySet()) { +// if (singleLinksDone.get(key) < maxTimes) { +// singleLinksDone.put(key, maxTimes); // return getSourceName(key) + key; // } // } @@ -110,1584 +109,1846 @@ public enum GrabbagImageSource implements CardImageSource { // if (copy != null) { // copy = copy.replaceFirst("http:\\/\\/static.starcitygames.com\\/sales\\/cardscans\\/", ""); // copy = copy.replaceFirst("http:\\/\\/magiccards.info\\/scans\\/en\\/", ""); -// return copyUrlToImage.get(copy); +// return singleLinks.get(copy); // } return null; } @Override public String generateURL(CardDownloadData card) throws Exception { - if (copyUrlToImage == null) { + if (singleLinks == null) { setupLinks(); } - for (Map.Entry urlInfo : copyUrlToImage.entrySet()) { - if (urlInfo.getValue().contains(card.getSet()) && urlInfo.getValue().contains(card.getName())) { - return getSourceName(urlInfo.getValue()) + urlInfo.getKey(); - } + String url = singleLinks.get(card.getSet() + "/" + card.getName()); + if (url != null) { + return getSourceName(card, url) + url; } return null; } - HashMap copyUrlToImage = null; - HashMap copyImageToUrl = null; - HashMap copyUrlToImageDone = null; + HashMap singleLinks = null; private void setupLinks() { - if (copyUrlToImage != null) { + if (singleLinks != null) { return; } - copyUrlToImage = new HashMap<>(); - copyImageToUrl = new HashMap<>(); - copyUrlToImageDone = new HashMap<>(); + singleLinks = new HashMap<>(); + singleLinks.put("PTC/Arbiter of the Ideal", "MTG/BNG/en/promo/ArbiterOfTheIdeal.jpg"); + singleLinks.put("PTC/Courser of Kruphix", "MTG/BNG/en/promo/CourserOfKruphix.jpg"); + singleLinks.put("PTC/Eater of Hope", "MTG/BNG/en/promo/EaterOfHope.jpg"); + singleLinks.put("PTC/Fated Return", "MTG/BNG/en/promo/FatedReturn.jpg"); + singleLinks.put("PTC/Forgestoker Dragon", "MTG/BNG/en/promo/ForgestokerDragon.jpg"); + singleLinks.put("PTC/Nessian Wilds Ravager", "MTG/BNG/en/promo/NessianWildsRavager.jpg"); + singleLinks.put("PTC/Pain Seer", "MTG/BNG/en/promo/PainSeer.jpg"); + singleLinks.put("PTC/Silent Sentinel", "MTG/BNG/en/promo/SilentSentinel.jpg"); + singleLinks.put("PTC/Tromokratis", "MTG/BNG/en/promo/Tromokratis.jpg"); - copyUrlToImage.put("PTC/Arbiter of the Ideal", "MTG/BNG/en/promo/ArbiterOfTheIdeal.jpg"); - copyUrlToImage.put("PTC/Courser of Kruphix", "MTG/BNG/en/promo/CourserOfKruphix.jpg"); - copyUrlToImage.put("PTC/Eater of Hope", "MTG/BNG/en/promo/EaterOfHope.jpg"); - copyUrlToImage.put("PTC/Fated Return", "MTG/BNG/en/promo/FatedReturn.jpg"); - copyUrlToImage.put("PTC/Forgestoker Dragon", "MTG/BNG/en/promo/ForgestokerDragon.jpg"); - copyUrlToImage.put("PTC/Nessian Wilds Ravager", "MTG/BNG/en/promo/NessianWildsRavager.jpg"); - copyUrlToImage.put("PTC/Pain Seer", "MTG/BNG/en/promo/PainSeer.jpg"); - copyUrlToImage.put("PTC/Silent Sentinel", "MTG/BNG/en/promo/SilentSentinel.jpg"); - copyUrlToImage.put("PTC/Tromokratis", "MTG/BNG/en/promo/Tromokratis.jpg"); + singleLinks.put("SWS/AAT-1", "CqmDY8V.jpg"); + singleLinks.put("SWS/Acklay of the Arena", "ESVRm6F.jpg"); + singleLinks.put("SWS/Acquire Target", "FOskB4q.jpg"); + singleLinks.put("SWS/Admiral Ackbar", "JdGpP3p.jpg"); + singleLinks.put("SWS/Adroit Hateflayer", "0gSIQ4K.jpg"); + singleLinks.put("SWS/Anakin Skywalker", "3pGvZZEg.png"); + singleLinks.put("SWS/Ancient Holocron", "fH2dVP5.jpg"); + singleLinks.put("SWS/Aqualish Bounty Hunter", "Wm2aKa2.jpg"); + singleLinks.put("SWS/Armed Protocol Droid", "mywdKgN.jpg"); + singleLinks.put("SWS/Arrest", "VXLnNUo.jpg"); + singleLinks.put("SWS/Asajj Ventress", "rOXSIwO.jpg"); + singleLinks.put("SWS/AT-ST", "9sMcy3C.jpg"); + singleLinks.put("SWS/Aurra Sing, Bane of Jedi", "VgbndqZ.png"); + singleLinks.put("SWS/A-Wing", "4TaYoRO.jpg"); + singleLinks.put("SWS/Bantha Herd", "9rLPE2a.jpg"); + singleLinks.put("SWS/Bathe in Bacta", "sPynQAZ.jpg"); + singleLinks.put("SWS/Battle Tactics", "zoon1p4.jpg"); + singleLinks.put("SWS/Bib Fortuna", "AqAmOEw.jpg"); + singleLinks.put("SWS/Black Market Dealer", "EJpIxna.jpg"); + singleLinks.put("SWS/Blind Worship", "GonJyeF.jpg"); + singleLinks.put("SWS/Boba Fett", "XE83Ks7.jpg"); + singleLinks.put("SWS/Bossk", "m91vUdJ.jpg"); + singleLinks.put("SWS/Bounty Collector", "GHHxvb0.jpg"); + singleLinks.put("SWS/Bounty Sniper", "ANTNrsS.jpg"); + singleLinks.put("SWS/Bounty Spotter", "aB6LAZs.jpg"); + singleLinks.put("SWS/Bull Rancor", "eG4mJ7o.jpg"); + singleLinks.put("SWS/C-3PO and R2D2", "RTv4ikx.jpg"); + singleLinks.put("SWS/Cantina Band", "PqMQP0o.jpg"); + singleLinks.put("SWS/Capture", "jxoTOyC.jpg"); + singleLinks.put("SWS/Carbonite Chamber", "rqEr1gm.jpg"); + singleLinks.put("SWS/Chewbacca", "D3D5T42.jpg"); + singleLinks.put("SWS/Chief Chirpa", "Gx3hLsg.jpg"); + singleLinks.put("SWS/Cloaking Device", "Vtz1NZU.jpg"); + singleLinks.put("SWS/Commander Cody", "9PGV2pV.jpg"); + singleLinks.put("SWS/Condemn", "36yejT2.jpg"); + singleLinks.put("SWS/Corellian Corvette", "j8uPQDY.jpg"); + singleLinks.put("SWS/Crossfire", "Iz9OdPh.jpg"); + singleLinks.put("SWS/Cruelty of the Sith", "q3WIYAt.jpg"); + singleLinks.put("SWS/Cunning Abduction", "CueTNo7.jpg"); + singleLinks.put("SWS/Dagobah Maw Slug", "SqmdUMp.jpg"); + singleLinks.put("SWS/Dark Apprenticeship", "yf5MthH.jpg"); + singleLinks.put("SWS/Dark Decision", "2HB5lYN.jpg"); + singleLinks.put("SWS/Dark Trooper", "atKdUTA.jpg"); + singleLinks.put("SWS/Darth Maul", "EwC1e1Q.jpg"); + singleLinks.put("SWS/Darth Sidious, Sith Lord", "UYk3KnH.png"); + singleLinks.put("SWS/Darth Tyranus, Count of Serenno", "AXUfNuO.png"); + singleLinks.put("SWS/Darth Vader", "3pGvZZE.png"); + singleLinks.put("SWS/Death Trooper", "j7lWmPJ.jpg"); + singleLinks.put("SWS/Deploy The Troops", "QtcN0qV.jpg"); + singleLinks.put("SWS/Doom Blade", "cSuxWUr.jpg"); + singleLinks.put("SWS/Droid Commando", "HkKiaBQ.jpg"); + singleLinks.put("SWS/Droid Factory", "34L3ykD.jpg"); + singleLinks.put("SWS/Droid Foundry", "qYijxSk.jpg"); + singleLinks.put("SWS/Droideka", "BXN7t1i.jpg"); + singleLinks.put("SWS/Drone Holocron", "cHzqK4v.jpg"); + singleLinks.put("SWS/Echo Base Commando", "AdLjV4Y.jpg"); + singleLinks.put("SWS/EMP Blast", "Y0JWgRO.jpg"); + singleLinks.put("SWS/Escape Pod", "vj8gQ1u.jpg"); + singleLinks.put("SWS/Ewok Ambush", "219aufH.jpg"); + singleLinks.put("SWS/Ewok Firedancers", "DFAB3h4.jpg"); + singleLinks.put("SWS/Ewok Village", "rgQevhZ.jpg"); + singleLinks.put("SWS/Exogorth", "cS6fq3u.jpg"); + singleLinks.put("SWS/Ferocity of the Underworld", "lTqtVab.jpg"); + singleLinks.put("SWS/Flames of Remembrance", "WAKhi9i.jpg"); + singleLinks.put("SWS/Force Choke", "Uu1QUf9.jpg"); + singleLinks.put("SWS/Force Denial", "qwYGiUg.jpg"); + singleLinks.put("SWS/Force Drain", "prHdDXa.jpg"); + singleLinks.put("SWS/Force Healing", "kDGRFoj.jpg"); + singleLinks.put("SWS/Force Lightning", "DhAE9lZ.jpg"); + singleLinks.put("SWS/Force Mastery", "XPCWaP8.jpg"); + singleLinks.put("SWS/Force Pull", "rWWfkhX.jpg"); + singleLinks.put("SWS/Force Push", "aN8n4sk.jpg"); + singleLinks.put("SWS/Force Reflex", "RIlvXTz.jpg"); + singleLinks.put("SWS/Force Scream", "EsagOnR.jpg"); + singleLinks.put("SWS/Force Spark", "14MOM1y.jpg"); + singleLinks.put("SWS/Forest", "LIpeeP9.jpg"); + singleLinks.put("SWS/Forest", "jKwDwH7.jpg"); + singleLinks.put("SWS/Forest", "CVb3582.jpg"); + singleLinks.put("SWS/Forest", "q09fMW0.jpg"); + singleLinks.put("SWS/Fulfill Contract", "FtLMpHK.jpg"); + singleLinks.put("SWS/Gamorrean Prison Guard", "4dgOMPA.jpg"); + singleLinks.put("SWS/General Grievous", "tRLM8Hz.jpg"); + singleLinks.put("SWS/Gifted Initiate", "NDePdLv.jpg"); + singleLinks.put("SWS/Grand Moff Tarkin", "QXq1V40.jpg"); + singleLinks.put("SWS/Greater Krayt Dragon", "dzIiXXg.jpg"); + singleLinks.put("SWS/Greedo", "IRKwsX0.jpg"); + singleLinks.put("SWS/Gundark", "zLxfLM8.jpg"); + singleLinks.put("SWS/Gungan Captain", "1Q4DNWh.jpg"); + singleLinks.put("SWS/Han Solo", "G0Awota.jpg"); + singleLinks.put("SWS/Hazard Trooper", "ZOutamG.jpg"); + singleLinks.put("SWS/Head Hunting", "7OT1bGZ.jpg"); + singleLinks.put("SWS/Heavy Trooper", "HhZWs2N.jpg"); + singleLinks.put("SWS/Hot Pursuit", "ih1GT5Z.jpg"); + singleLinks.put("SWS/Hungry Dragonsnake", "23v7RTm.jpg"); + singleLinks.put("SWS/Hunt to Extinction", "3eJyfzZ.jpg"); + singleLinks.put("SWS/Hutt Crime Lord", "NAzK7Hp.jpg"); + singleLinks.put("SWS/Hutt Palace", "HEb2JN5.jpg"); + singleLinks.put("SWS/IG-88B", "YZUZJC8.jpg"); + singleLinks.put("SWS/Images of the Past", "sOXEk4Q.jpg"); + singleLinks.put("SWS/Imperial Gunner", "9KpZ8AX.jpg"); + singleLinks.put("SWS/Impulsive Wager", "lLutRRs.jpg"); + singleLinks.put("SWS/Insatiable Rakghoul", "IYqBnTK.jpg"); + singleLinks.put("SWS/Interrogation", "kI2bIbo.jpg"); + singleLinks.put("SWS/Ion Cannon", "Tb546IK.jpg"); + singleLinks.put("SWS/Iron Fist of the Empire", "9Ui7NRn.jpg"); + singleLinks.put("SWS/Island", "GxITXBO.jpg"); + singleLinks.put("SWS/Island", "vKdg4fG.jpg"); + singleLinks.put("SWS/Island", "NPMxIew.jpg"); + singleLinks.put("SWS/Island", "cnqFMa6.jpg"); + singleLinks.put("SWS/Ithorian Initiate", "2RYpp5o.jpg"); + singleLinks.put("SWS/Jabba the Hutt", "QMz0sKa.jpg"); + singleLinks.put("SWS/Jango Fett", "nEnspQP.jpg"); + singleLinks.put("SWS/Jar Jar Binks", "GCnx72b.jpg"); + singleLinks.put("SWS/Jar'Kai Battle Stance", "GLavgj7.jpg"); + singleLinks.put("SWS/Jedi Battle Healer", "RyIJON5.jpg"); + singleLinks.put("SWS/Jedi Battle Mage", "V9qHRGq.jpg"); + singleLinks.put("SWS/Jedi Battle Sage", "sZVlGWE.jpg"); + singleLinks.put("SWS/Jedi Enclave", "FlibBhx.jpg"); + singleLinks.put("SWS/Jedi Holocron", "ojbt2av.jpg"); + singleLinks.put("SWS/Jedi Inquirer", "ghFQA76.jpg"); + singleLinks.put("SWS/Jedi Instructor", "IwEpVkz.jpg"); + singleLinks.put("SWS/Jedi Knight", "VXNHpZs.jpg"); + singleLinks.put("SWS/Jedi Mind Trick", "aaVfgSA.jpg"); + singleLinks.put("SWS/Jedi Sentinel", "cae3O1s.jpg"); + singleLinks.put("SWS/Jedi Starfighter", "Ta20jjD.jpg"); + singleLinks.put("SWS/Jedi Temple", "ZkOUJnM.jpg"); + singleLinks.put("SWS/Jedi Training", "7L1LWie.jpg"); + singleLinks.put("SWS/Jump Trooper", "62Pg5r4.jpg"); + singleLinks.put("SWS/Jungle Village", "3a1KN8u.jpg"); + singleLinks.put("SWS/Kamino Cloning Facility", "kwBudvf.jpg"); + singleLinks.put("SWS/Ki-Adi-Mundi", "atqNF3H.jpg"); + singleLinks.put("SWS/LAAT Gunship", "DEMXleY.jpg"); + singleLinks.put("SWS/Lando Calrissian", "jcoTjGV.jpg"); + singleLinks.put("SWS/Legacy of the Beloved", "Y0ObvQg.jpg"); + singleLinks.put("SWS/Lightning Bolt", "XSNGQYi.jpg"); + singleLinks.put("SWS/Lightsaber", "YrpWygk.jpg"); + singleLinks.put("SWS/Loyal Tauntaun", "JKDV2WK.jpg"); + singleLinks.put("SWS/Luke Skywalker", "9worW6q.jpg"); + singleLinks.put("SWS/Mace Windu", "rmTuBGT.jpg"); + singleLinks.put("SWS/Maintenance Droid", "A66IIC1.jpg"); + singleLinks.put("SWS/Maintenance Hangar", "DzCYnH3.jpg"); + singleLinks.put("SWS/Mantellian Savrip", "a9JIDEM.jpg"); + singleLinks.put("SWS/March of the Droids", "A4HIQ5V.jpg"); + singleLinks.put("SWS/Massiff Swarm", "0qRPfbC.jpg"); + singleLinks.put("SWS/Might of the Wild", "eNXOdxp.jpg"); + singleLinks.put("SWS/Millennium Falcon", "aZ6sIn2.jpg"); + singleLinks.put("SWS/Miraculous Recovery", "DH6Cei8.jpg"); + singleLinks.put("SWS/Moisture Farm", "S6kJHtL.jpg"); + singleLinks.put("SWS/Mon Calamari Cruiser", "ZHdTV7p.jpg"); + singleLinks.put("SWS/Mon Calamari Initiate", "GBuXdGP.jpg"); + singleLinks.put("SWS/Mountain", "MCii4g1.jpg"); + singleLinks.put("SWS/Mountain", "Tb0ic31.jpg"); + singleLinks.put("SWS/Mountain", "wqXTdsC.jpg"); + singleLinks.put("SWS/Mountain", "9oBNCHk.jpg"); + singleLinks.put("SWS/N-1 Starfighter", "UH3qd7x.jpg"); + singleLinks.put("SWS/Nebulon-B Frigate", "IwEpVkz.jpg"); + singleLinks.put("SWS/Neophyte Hateflayer", "Has2AIW.jpg"); + singleLinks.put("SWS/Nerf Herder", "VUX0LHV.jpg"); + singleLinks.put("SWS/Nexu Stalker", "E1xxHe1.jpg"); + singleLinks.put("SWS/Nightspider", "H1po0uV.jpg"); + singleLinks.put("SWS/No Contest", "6SwC9ri.jpg"); + singleLinks.put("SWS/Novice Bounty Hunter", "WfNSsLY.jpg"); + singleLinks.put("SWS/Nute Gunray", "UZg12DD.jpg"); + singleLinks.put("SWS/Obi-Wan Kenobi", "BHkbjdL.png"); + singleLinks.put("SWS/Open Season", "E4iM90K.jpg"); + singleLinks.put("SWS/Orbital Bombardment", "Ov1mB3A.jpg"); + singleLinks.put("SWS/Order 66", "jZituQQ.jpg"); + singleLinks.put("SWS/Ortolan Keyboardist", "dYDgEUB.jpg"); + singleLinks.put("SWS/Outer Rim Slaver", "xq8ozqq.jpg"); + singleLinks.put("SWS/Outlaw Holocron", "mWbyX78.jpg"); + singleLinks.put("SWS/Personal Energy Shield", "v6TGLne.jpg"); + singleLinks.put("SWS/Plains", "HgXaAKh.jpg"); + singleLinks.put("SWS/Plains", "Y0i7MBh.jpg"); + singleLinks.put("SWS/Plains", "4grXQVd.jpg"); + singleLinks.put("SWS/Plains", "kTmN8MM.jpg"); + singleLinks.put("SWS/Plo Koon", "dDNi8CV.jpg"); + singleLinks.put("SWS/Precipice of Mortis", "TRAPT86.jpg"); + singleLinks.put("SWS/Predator's Strike", "pcBoUny.jpg"); + singleLinks.put("SWS/Preordain", "u8nSNQW.jpg"); + singleLinks.put("SWS/Primal Instinct", "bInouYH.jpg"); + singleLinks.put("SWS/Princess Leia", "pnHyPWg.jpg"); + singleLinks.put("SWS/Probe Droid", "0r84uUM.jpg"); + singleLinks.put("SWS/Qui-Gon Jinn", "7DdumG2.jpg"); + singleLinks.put("SWS/Raging Reek", "9maXaMR.jpg"); + singleLinks.put("SWS/Rallying Fire", "wtaTlhd.jpg"); + singleLinks.put("SWS/Ravenous Wampa", "rHDaKDD.jpg"); + singleLinks.put("SWS/Regression", "j5z0TOE.jpg"); + singleLinks.put("SWS/Republic Frigate", "LzNpjxP.jpg"); + singleLinks.put("SWS/Repurpose", "BvRMy3f.jpg"); + singleLinks.put("SWS/Revenge", "xkKzMRX.jpg"); + singleLinks.put("SWS/Riding Ronto", "xECBi7G.jpg"); + singleLinks.put("SWS/Rocket Trooper", "94wUTH5.jpg"); + singleLinks.put("SWS/Rogue's Passage", "UunpJPZ.jpg"); + singleLinks.put("SWS/Rule of two", "wNqZWLJ.jpg"); + singleLinks.put("SWS/Rumination", "nSD3UHQ.jpg"); + singleLinks.put("SWS/Rumor Monger", "wSN6H6v.jpg"); + singleLinks.put("SWS/Sabacc Game", "qIcFb3U.jpg"); + singleLinks.put("SWS/Salvage Squad", "ThYSxmD.jpg"); + singleLinks.put("SWS/Sand Trooper", "ysfpyL8.jpg"); + singleLinks.put("SWS/Sarlacc Pit", "N4dcnln.png"); + singleLinks.put("SWS/Scout the Perimeter", "2cObUbz.jpg"); + singleLinks.put("SWS/Scout Trooper", "9RAY4U1.jpg"); + singleLinks.put("SWS/Security Droid", "dzy8m4v.jpg"); + singleLinks.put("SWS/Senator Bail Organa", "BRkUuYU.jpg"); + singleLinks.put("SWS/Senator Lott Dod", "yYQtXZo.jpg"); + singleLinks.put("SWS/Senator Onaconda Farr", "oPez77z.png"); + singleLinks.put("SWS/Senator Padmé Amidala", "287deD9.jpg"); + singleLinks.put("SWS/Senator Passel Argente", "51qpnaE.jpg"); + singleLinks.put("SWS/Shaak Herd", "PtnZD0I.jpg"); + singleLinks.put("SWS/Shadow Trooper", "09NAiGa.jpg"); + singleLinks.put("SWS/Shock Trooper", "UVNOxMR.jpg"); + singleLinks.put("SWS/Show of Dominance", "ru2D3Qp.jpg"); + singleLinks.put("SWS/Sith Assassin", "Nt8WUCj.jpg"); + singleLinks.put("SWS/Sith Citadel", "bBCbK30.jpg"); + singleLinks.put("SWS/Sith Evoker", "jwRzCEB.jpg"); + singleLinks.put("SWS/Sith Holocron", "07Ufx5X.jpg"); + singleLinks.put("SWS/Sith Inquisitor", "NivI1E5.jpg"); + singleLinks.put("SWS/Sith Lord", "lWBfQoA.jpg"); + singleLinks.put("SWS/Sith Magic", "cDPFeve.jpg"); + singleLinks.put("SWS/Sith Manipulator", "Q7CIvyz.jpg"); + singleLinks.put("SWS/Sith Marauder", "9zZUSJW.jpg"); + singleLinks.put("SWS/Sith Mindseer", "Lmps3oO.jpg"); + singleLinks.put("SWS/Sith Ravager", "nl9Dp41.jpg"); + singleLinks.put("SWS/Sith Ruins", "oSqiYyO.jpg"); + singleLinks.put("SWS/Sith Sorcerer", "Pq37iop.jpg"); + singleLinks.put("SWS/Sith Thoughtseeker", "YzIY1di.jpg"); + singleLinks.put("SWS/Slave I", "QUGpxlb.jpg"); + singleLinks.put("SWS/Smash to Smithereens", "UlzDZWp.jpg"); + singleLinks.put("SWS/Snow Trooper", "28Jp5JL.jpg"); + singleLinks.put("SWS/Speeder Trooper", "BIEnTDL.jpg"); + singleLinks.put("SWS/Star Destroyer", "DYUMXHZ.jpg"); + singleLinks.put("SWS/Strike Team Commando", "783ZFsF.jpg"); + singleLinks.put("SWS/Super Battle Droid", "T8IjrKD.jpg"); + singleLinks.put("SWS/Surprise Maneuver", "uaAmzz8.jpg"); + singleLinks.put("SWS/Swamp", "kBGj6vk.jpg"); + singleLinks.put("SWS/Swamp", "BLJl2lf.jpg"); + singleLinks.put("SWS/Swamp", "MLH5o2u.jpg"); + singleLinks.put("SWS/Swamp", "Rmrv9tC.jpg"); + singleLinks.put("SWS/Swarm the Skies", "Ti1McaV.jpg"); + singleLinks.put("SWS/Syndicate Enforcer", "xZ0g2Sx.jpg"); + singleLinks.put("SWS/Tank Droid", "N4YyMje.jpg"); + singleLinks.put("SWS/Terentatek Cub", "nbmBxst.jpg"); + singleLinks.put("SWS/The Battle of Endor", "vhL6gdI.jpg"); + singleLinks.put("SWS/The Battle of Geonosis", "7Fnr2MD.jpg"); + singleLinks.put("SWS/The Battle of Hoth", "wcVJwKP.jpg"); + singleLinks.put("SWS/The Battle of Naboo", "aesSN9E.jpg"); + singleLinks.put("SWS/The Battle of Yavin", "AtGE49k.jpg"); + singleLinks.put("SWS/The Death Star", "2LjSXa9.jpg"); + singleLinks.put("SWS/TIE Bomber", "R2l7ZXQ.jpg"); + singleLinks.put("SWS/TIE Interceptor", "fYY4PUR.jpg"); + singleLinks.put("SWS/Trade Federation Battleship", "sKN9Gzv.jpg"); + singleLinks.put("SWS/Tri-Fighter", "IhwHzqT.jpg"); + singleLinks.put("SWS/Trooper Armor", "nqnFj9f.jpg"); + singleLinks.put("SWS/Trooper Commando", "PiAYXJv.jpg"); + singleLinks.put("SWS/Twi'lek Seductress", "iPhUxUV.jpg"); + singleLinks.put("SWS/Ugnaught Scrap Worker", "fuuNN3n.jpg"); + singleLinks.put("SWS/Underworld Slums", "o4CFq3x.jpg"); + singleLinks.put("SWS/Unity of the Droids", "WFAIRy3.jpg"); + singleLinks.put("SWS/Unruly Sureshot", "AHymfLc.jpg"); + singleLinks.put("SWS/Vapor Snag", "8g3q0ny.jpg"); + singleLinks.put("SWS/V-Wing", "7eThuU9.jpg"); + singleLinks.put("SWS/Weequay Beastmaster", "metAs1p.jpg"); + singleLinks.put("SWS/Wild Holocron", "adw7dFO.jpg"); + singleLinks.put("SWS/Wisdom of the Jedi", "TgTj2Dd.jpg"); + singleLinks.put("SWS/Womp Rat", "XKF79Hr.jpg"); + singleLinks.put("SWS/Wookiee Bounty Hunter", "A76UGTJ.jpg"); + singleLinks.put("SWS/Wookiee Mystic", "8DCkOVe.jpg"); + singleLinks.put("SWS/Wookiee Raidleader", "ZZTduL5.jpg"); + singleLinks.put("SWS/X-Wing", "AV1LPuZ.jpg"); + singleLinks.put("SWS/Yoda, Jedi Master", "6arN1Hl.png"); + singleLinks.put("SWS/Y-Wing", "aQQ5zwA.jpg"); + singleLinks.put("SWS/Zam Wesell", "ToG0C1r.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/AleshaWhoSmilesAtDeath.jpg", "PTC.zip/PTC/Alesha, Who Smiles at Death.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/Arcbond.jpg", "PTC.zip/PTC/Arcbond.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/ArchfiendOfDepravity.jpg", "PTC.zip/PTC/Archfiend of Depravity.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/AtarkaWorldRender.jpg", "PTC.zip/PTC/Atarka, World Render.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/BrutalHordechief.jpg", "PTC.zip/PTC/Brutal Hordechief.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/DaghatarTheAdamant.jpg", "PTC.zip/PTC/Daghatar the Adamant.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/DragonscaleGeneral.jpg", "PTC.zip/PTC/Dragonscale General.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/DromokaTheEternal.jpg", "PTC.zip/PTC/Dromoka, the Eternal.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/FlamerushRider.jpg", "PTC.zip/PTC/Flamerush Rider.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/FlamewakePhoenix.jpg", "PTC.zip/PTC/Flamewake Phoenix.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/JeskaiInfiltrator.jpg", "PTC.zip/PTC/Jeskai Infiltrator.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/KolaghanTheStormsFury.jpg", "PTC.zip/PTC/Kolaghan, the Storm's Fury.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/MarduStrikeLeader.jpg", "PTC.zip/PTC/Mardu Strike leader.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/MasteryOfTheUnseen.jpg", "PTC.zip/PTC/Mastery of the Unseen.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/OjutaiSoulOfWinter.jpg", "PTC.zip/PTC/Ojutai, Soul of Winter.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/RallyTheAncestors.jpg", "PTC.zip/PTC/Rally the Ancestors.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/SageEyeAvengers.jpg", "PTC.zip/PTC/Sage-Eye Avengers.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/SandsteppeMastodon.jpg", "PTC.zip/PTC/Sandsteppe Mastodon.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/ShamanOfTheGreatHunt.jpg", "PTC.zip/PTC/Shaman of the Great Hunt.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/ShamanicRevelation.jpg", "PTC.zip/PTC/Shamanic Revelation.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/ShuYunTheSilentTempest.jpg", "PTC.zip/PTC/Shu Yun, the Silent Tempest.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/SilumgarTheDriftingDeath.jpg", "PTC.zip/PTC/Silumgar, the Drifting Death.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/SoulfireGrandMaster.jpg", "PTC.zip/PTC/Soulfire Grand Master.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/Soulflayer.jpg", "PTC.zip/PTC/Soulflayer.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/SupplantForm.jpg", "PTC.zip/PTC/Supplant Form.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/TasigurTheGoldenFang.jpg", "PTC.zip/PTC/Tasigur, the Golden Fang.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/TorrentElemental.jpg", "PTC.zip/PTC/Torrent Elemental.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/WardenOfTheFirstTree.jpg", "PTC.zip/PTC/Warden of the First Tree.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/Wildcall.jpg", "PTC.zip/PTC/Wildcall.full.jpg"); - copyUrlToImage.put("MTG/FRF/en/promo/prerelease/YasovaDragonclaw.jpg", "PTC.zip/PTC/Yasova Dragonclaw.full.jpg"); - copyUrlToImage.put("MTG/JOU/en/promo/DawnbringerCharioteers.jpg", "PTC.zip/PTC/Dawnbringer Charioteers.full.jpg"); - copyUrlToImage.put("MTG/JOU/en/promo/DictateOfKruphix.jpg", "PTC.zip/PTC/Dictate of Kruphix.full.jpg"); - copyUrlToImage.put("MTG/JOU/en/promo/DictateOfTheTwinGods.jpg", "PTC.zip/PTC/Dictate of the Twin Gods.full.jpg"); - copyUrlToImage.put("MTG/JOU/en/promo/DoomwakeGiant.jpg", "PTC.zip/PTC/Doomwake Giant.full.jpg"); - copyUrlToImage.put("MTG/JOU/en/promo/EidolonOfBlossoms.jpg", "PTC.zip/PTC/Eidolon of Blossoms.full.jpg"); - copyUrlToImage.put("MTG/JOU/en/promo/ScourgeOfSkolaVale.jpg", "PTC.zip/PTC/Scourge of Skola Vale.full.jpg"); - copyUrlToImage.put("MTG/JOU/en/promo/SpawnOfThraxes.jpg", "PTC.zip/PTC/Spawn of Thraxes.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/AbzanAscendancy.jpg", "PTC.zip/PTC/Abzan Ascendancy.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/AnafenzaTheForemost.jpg", "PTC.zip/PTC/Anafenza, the Foremost.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/AnkleShanker.jpg", "PTC.zip/PTC/Ankle Shanker.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/AvalancheTusker.jpg", "PTC.zip/PTC/Avalanche Tusker.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/BloodsoakedChampion.jpg", "PTC.zip/PTC/Bloodsoaked Champion.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/ButcherOfTheHorde.jpg", "PTC.zip/PTC/Butcher of the Horde.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/CracklingDoom.jpg", "PTC.zip/PTC/Crackling Doom.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/CratersClaws.jpg", "PTC.zip/PTC/Crater's Claws.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/DeflectingPalm.jpg", "PTC.zip/PTC/Deflecting Palm.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/DigThroughTime.jpg", "PTC.zip/PTC/Dig Through Time.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/DragonStyleTwins.jpg", "PTC.zip/PTC/Dragon-Style Twins.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/DragonThroneOfTarkir.jpg", "PTC.zip/PTC/Dragon Throne of Tarkir.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/Duneblast.jpg", "PTC.zip/PTC/Duneblast.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/FlyingCraneTechnique.jpg", "PTC.zip/PTC/Flying Crane Technique.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/GrimHaruspex.jpg", "PTC.zip/PTC/Grim Haruspex.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/HardenedScales.jpg", "PTC.zip/PTC/Hardened Scales.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/HeraldOfTorment.jpg", "PTC.zip/PTC/Herald of Torment.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/HighSentinelsOfArashin.jpg", "PTC.zip/PTC/High Sentinels of Arashin.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/IcyBlast.jpg", "PTC.zip/PTC/Icy Blast.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/IvorytuskFortress.jpg", "PTC.zip/PTC/Ivorytusk Fortress.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/JeeringInstigator.jpg", "PTC.zip/PTC/Jeering Instigator.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/JeskaiAscendancy.jpg", "PTC.zip/PTC/Jeskai Ascendancy.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/KheruSpellsnatcher.jpg", "PTC.zip/PTC/Kheru Spellsnatcher.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/MarduAscendancy.jpg", "PTC.zip/PTC/Mardu Ascendancy.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/MasterOfPearls.jpg", "PTC.zip/PTC/Master of Pearls.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/NarsetEnlightenedMaster.jpg", "PTC.zip/PTC/Narset, Enlightened Master.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/NecropolisFiend.jpg", "PTC.zip/PTC/Necropolis Fiend.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/RakshasaVizier.jpg", "PTC.zip/PTC/Rakshasa Vizier.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/RattleclawMystic.jpg", "PTC.zip/PTC/Rattleclaw Mystic.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/SageOfTheInwardEye.jpg", "PTC.zip/PTC/Sage of the Inward Eye.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/SidisiBroodTyrant.jpg", "PTC.zip/PTC/Sidisi, Brood Tyrant.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/SiegeRhino.jpg", "PTC.zip/PTC/Siege Rhino.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/SultaiAscendancy.jpg", "PTC.zip/PTC/Sultai Ascendancy.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/SurrakDragonclaw.jpg", "PTC.zip/PTC/Surrak Dragonclaw.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/TemurAscendancy.jpg", "PTC.zip/PTC/Temur Ascendancy.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/ThousandWinds.jpg", "PTC.zip/PTC/Thousand Winds.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/TrailOfMystery.jpg", "PTC.zip/PTC/Trail of Mystery.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/TrapEssence.jpg", "PTC.zip/PTC/Trap Essence.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/UtterEnd.jpg", "PTC.zip/PTC/Utter End.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/VillainousWealth.jpg", "PTC.zip/PTC/Villainous Wealth.full.jpg"); - copyUrlToImage.put("MTG/KTK/en/promo/ZurgoHelmsmasher.jpg", "PTC.zip/PTC/Zurgo Helmsmasher.full.jpg"); - copyUrlToImage.put("MTG/M15/en/promo/ChiefEngineer.jpg", "PTC.zip/PTC/Chief Engineer.full.jpg"); - copyUrlToImage.put("MTG/M15/en/promo/InGarruksWake.jpg", "PTC.zip/PTC/In Garruk's Wake.full.jpg"); - copyUrlToImage.put("MTG/M15/en/promo/IndulgentTormentor.jpg", "PTC.zip/PTC/Indulgent Tormentor.full.jpg"); - copyUrlToImage.put("MTG/M15/en/promo/MercurialPretender.jpg", "PTC.zip/PTC/Mercurial Pretender.full.jpg"); - copyUrlToImage.put("MTG/M15/en/promo/PhyrexianRevoker.jpg", "PTC.zip/PTC/Phyrexian Revoker.full.jpg"); - copyUrlToImage.put("MTG/M15/en/promo/Phytotitan.jpg", "PTC.zip/PTC/Phytotitan.full.jpg"); - copyUrlToImage.put("MTG/M15/en/promo/ResoluteArchangel.jpg", "PTC.zip/PTC/Resolute Archangel.full.jpg"); - copyUrlToImage.put("MTG/M15/en/promo/SiegeDragon.jpg", "PTC.zip/PTC/Siege Dragon.full.jpg"); - copyUrlToImage.put("MTG/M15/en/promo/SoulOfRavnica.jpg", "PTC.zip/PTC/Soul of Ravnica.full.jpg"); - copyUrlToImage.put("MTG/M15/en/promo/SoulOfZendikar.jpg", "PTC.zip/PTC/Soul of Zendikar.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/AzusaLostButSeeking.jpg", "JR.zip/JR/Azusa, Lost but Seeking.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/Bitterblossom.jpg", "JR.zip/JR/Bitterblossom.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/BloodstainedMire.jpg", "JR.zip/JR/Bloodstained Mire.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/CommandBeacon.jpg", "JR.zip/JR/Command Beacon.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/DarkRitual.jpg", "JR.zip/JR/Dark Ritual.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/DecreeOfJustice.jpg", "JR.zip/JR/Decree of Justice.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/DefenseOfTheHeart.jpg", "JR.zip/JR/Defense of the Heart.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/ExaltedAngel.jpg", "JR.zip/JR/Exalted Angel.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/FeldonOfTheThirdPath.jpg", "JR.zip/JR/Feldon of the Third Path.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/ForceOfWill.jpg", "JR.zip/JR/Force of Will.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/GaeasCradle.jpg", "JR.zip/JR/Gaea's Cradle.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/ImperialRecruiter.jpg", "JR.zip/JR/Imperial Recruiter.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/LandTax.jpg", "JR.zip/JR/Land Tax.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/MindsDesire.jpg", "JR.zip/JR/Mind's Desire.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/MishrasFactory.jpg", "JR.zip/JR/Mishra's Factory.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/RishadanPort.jpg", "JR.zip/JR/Rishadan Port.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/ShardlessAgent.jpg", "JR.zip/JR/Shardless Agent.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/ThawingGlaciers.jpg", "JR.zip/JR/Thawing Glaciers.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/Vindicate2007.jpg", "JR.zip/JR/Vindicate.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/Vindicate2013.jpg", "JR.zip/JR/Vindicate 1.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/Wasteland2010.jpg", "JR.zip/JR/Wasteland 1.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/Wasteland2015.jpg", "JR.zip/JR/Wasteland.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/WindsweptHeath.jpg", "JR.zip/JR/Windswept Heath.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/XiahouDunTheOneEyed.jpg", "JR.zip/JR/Xiahou Dun, the One-Eyed.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/YawgmothsWill.jpg", "JR.zip/JR/Yawgmoth's Will.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Judge/ZurtheEnchanter.jpg", "JR.zip/JR/Zur the Enchanter.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/AkoumFirebird.jpg", "PTC.zip/PTC/Akoum Firebird.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/AkoumHellkite.jpg", "PTC.zip/PTC/Akoum Hellkite.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/AlignedHedronNetwork.jpg", "PTC.zip/PTC/Aligned Hedron Network.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/AllyEncampment.jpg", "PTC.zip/PTC/Ally Encampment.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/AngelicCaptain.jpg", "PTC.zip/PTC/Angelic Captain.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/BarrageTyrant.jpg", "PTC.zip/PTC/Barrage Tyrant.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/BeastcallerSavant.jpg", "PTC.zip/PTC/Beastcaller Savant.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/BlightHerder.jpg", "PTC.zip/PTC/Blight Herder.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/BringToLight.jpg", "PTC.zip/PTC/Bring to Light.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/BroodButcher.jpg", "PTC.zip/PTC/Brood Butcher.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/BrutalExpulsion.jpg", "PTC.zip/PTC/Brutal Expulsion.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/CanopyVista.jpg", "PTC.zip/PTC/Canopy Vista.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/CinderGlade.jpg", "PTC.zip/PTC/Cinder Glade.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/ConduitOfRuin.jpg", "PTC.zip/PTC/Conduit of Ruin.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/DefiantBloodlord.jpg", "PTC.zip/PTC/Defiant Bloodlord.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/DesolationTwin.jpg", "PTC.zip/PTC/Desolation Twin.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/DragonmasterOutcast.jpg", "PTC.zip/PTC/Dragonmaster Outcast.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/DranasChosen.jpg", "PTC.zip/PTC/Drana's Chosen.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/DrownerOfHope.jpg", "PTC.zip/PTC/Drowner of Hope.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/DustStalker.jpg", "PTC.zip/PTC/Dust Stalker.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/EmeriaShepherd.jpg", "PTC.zip/PTC/Emeria Shepherd.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/EndlessOne.jpg", "PTC.zip/PTC/Endless One.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/ExertInfluence.jpg", "PTC.zip/PTC/Exert Influence.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/FathomFeeder.jpg", "PTC.zip/PTC/Fathom Feeder.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/FelidarSovereign.jpg", "PTC.zip/PTC/Felidar Sovereign.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/FromBeyond.jpg", "PTC.zip/PTC/From Beyond.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/GideonAllyOfZendikar.jpg", "PTC.zip/PTC/Gideon, Ally of Zendikar.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/GreenwardenOfMurasa.jpg", "PTC.zip/PTC/Greenwarden of Murasa.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/GruesomeSlaughter.jpg", "PTC.zip/PTC/Gruesome Slaughter.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/GuardianOfTazeem.jpg", "PTC.zip/PTC/Guardian of Tazeem.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/GuulDrazOverseer.jpg", "PTC.zip/PTC/Guul Draz Overseer.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/HeroOfGomaFada.jpg", "PTC.zip/PTC/Hero of Goma Fada.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/HerosDownfall.jpg", "PTC.zip/PTC/Hero's Downfall.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/KioraMasterOfTheDepths.jpg", "PTC.zip/PTC/Kiora, Master of the Depths.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/KioraTheCrashingWave.jpg", "PTC.zip/PTC/Kiora, the Crashing Wave.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/LanternScout.jpg", "PTC.zip/PTC/Lantern Scout.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/LumberingFalls.jpg", "PTC.zip/PTC/Lumbering Falls.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/MarchFromTheTomb.jpg", "PTC.zip/PTC/March from the Tomb.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/MundaAmbushLeader.jpg", "PTC.zip/PTC/Munda, Ambush Leader.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/NissasRenewal.jpg", "PTC.zip/PTC/Nissa's Renewal.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/NoyanDarRoilShaper.jpg", "PTC.zip/PTC/Noyan Dar, Roil Shaper.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/ObNixilisReignited.jpg", "PTC.zip/PTC/Ob Nixilis Reignited.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/ObNixilisUnshackled.jpg", "PTC.zip/PTC/Ob Nixilis, Unshackled.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/OblivionSower.jpg", "PTC.zip/PTC/Oblivion Sower.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/OmnathLocusOfRage.jpg", "PTC.zip/PTC/Omnath, Locus of Rage.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/OranRiefHydra.jpg", "PTC.zip/PTC/Oran-Rief Hydra.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/PainfulTruths.jpg", "PTC.zip/PTC/Painful Truths.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/PartTheWaterveil.jpg", "PTC.zip/PTC/Part the Waterveil.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/PlanarOutburst.jpg", "PTC.zip/PTC/Planar Outburst.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/PrairieStream.jpg", "PTC.zip/PTC/Prairie Stream.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/PrismArray.jpg", "PTC.zip/PTC/Prism Array.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/QuarantineField.jpg", "PTC.zip/PTC/Quarantine Field.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/RadiantFlames.jpg", "PTC.zip/PTC/Radiant Flames.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/RuinousPath.jpg", "PTC.zip/PTC/Ruinous Path.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/SanctumOfUgin.jpg", "PTC.zip/PTC/Sanctum of Ugin.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/ScatterToTheWinds.jpg", "PTC.zip/PTC/Scatter to the Winds.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/SerpentineSpike.jpg", "PTC.zip/PTC/Serpentine Spike.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/ShamblingVent.jpg", "PTC.zip/PTC/Shambling Vent.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/ShrineOfTheForsakenGods.jpg", "PTC.zip/PTC/Shrine of the Forsaken Gods.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/SireOfStagnation.jpg", "PTC.zip/PTC/Sire of Stagnation.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/SmolderingMarsh.jpg", "PTC.zip/PTC/Smoldering Marsh.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/SmotheringAbomination.jpg", "PTC.zip/PTC/Smothering Abomination.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/SunkenHollow.jpg", "PTC.zip/PTC/Sunken Hollow.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/UginsInsight.jpg", "PTC.zip/PTC/Ugin's Insight.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/UginsNexus.jpg", "PTC.zip/PTC/Ugin's Nexus.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/UlamogTheCeaselessHunger.jpg", "PTC.zip/PTC/Ulamog, the Ceaseless Hunger.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/UndergrowthChampion.jpg", "PTC.zip/PTC/Undergrowth Champion.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/VeteranWarleader.jpg", "PTC.zip/PTC/Veteran Warleader.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/VoidWinnower.jpg", "PTC.zip/PTC/Void Winnower.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/WastelandStrangler.jpg", "PTC.zip/PTC/Wasteland Strangler.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/WoodlandWanderer.jpg", "PTC.zip/PTC/Woodland Wanderer.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/BFZ/ZadaHedronGrinder.jpg", "PTC.zip/PTC/Zada, Hedron Grinder.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/AetherfluxReservoir.jpg", "PTC.zip/PTC/Aetherflux Reservoir.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/AethersquallAncient.jpg", "PTC.zip/PTC/Aethersquall Ancient.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/AetherstormRoc.jpg", "PTC.zip/PTC/Aetherstorm Roc.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/AetherworksMarvel.jpg", "PTC.zip/PTC/Aetherworks Marvel.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/AngelOfInvention.jpg", "PTC.zip/PTC/Angel of Invention.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/AnimationModule.jpg", "PTC.zip/PTC/Animation Module.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/ArchitectOfTheUntamed.jpg", "PTC.zip/PTC/Architect of the Untamed.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/AuthorityOfTheConsuls.jpg", "PTC.zip/PTC/Authority of the Consuls.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/BloomingMarsh.jpg", "PTC.zip/PTC/Blooming Marsh.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/BomatCourier.jpg", "PTC.zip/PTC/Bomat Courier.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/BotanicalSanctum.jpg", "PTC.zip/PTC/Botanical Sanctum.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/BristlingHydra.jpg", "PTC.zip/PTC/Bristling Hydra.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/CapturedByTheConsulate.jpg", "PTC.zip/PTC/Captured by the Consulate.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/CataclysmicGearhulk.jpg", "PTC.zip/PTC/Cataclysmic Gearhulk.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/ChandraTorchOfDefiance.jpg", "PTC.zip/PTC/Chandra, Torch of Defiance.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/CombustibleGearhulk.jpg", "PTC.zip/PTC/Combustible Gearhulk.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/ConcealedCourtyard.jpg", "PTC.zip/PTC/Concealed Courtyard.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/ConfiscationCoup.jpg", "PTC.zip/PTC/Confiscation Coup.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/CultivatorOfBlades.jpg", "PTC.zip/PTC/Cultivator of Blades.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/CultivatorsCaravan.jpg", "PTC.zip/PTC/Cultivator's Caravan.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/DeadlockTrap.jpg", "PTC.zip/PTC/Deadlock Trap.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/DemonOfDarkSchemes.jpg", "PTC.zip/PTC/Demon of Dark Schemes.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/DepalaPilotExemplar.jpg", "PTC.zip/PTC/Depala, Pilot Exemplar.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/DovinBaan.jpg", "PTC.zip/PTC/Dovin Baan.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/DubiousChallenge.jpg", "PTC.zip/PTC/Dubious Challenge.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/DynavoltTower.jpg", "PTC.zip/PTC/Dynavolt Tower.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/ElectrostaticPummeler.jpg", "PTC.zip/PTC/Electrostatic Pummeler.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/EliminateTheCompetition.jpg", "PTC.zip/PTC/Eliminate the Competition.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/FatefulShowdown.jpg", "PTC.zip/PTC/Fateful Showdown.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/FleetwheelCruiser.jpg", "PTC.zip/PTC/Fleetwheel Cruiser.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/Fumigate.jpg", "PTC.zip/PTC/Fumigate.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/GhirapurOrrery.jpg", "PTC.zip/PTC/Ghirapur Orrery.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/GontiLordOfLuxury.jpg", "PTC.zip/PTC/Gonti, Lord of Luxury.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/InsidiousWill.jpg", "PTC.zip/PTC/Insidious Will.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/InspiringVantage.jpg", "PTC.zip/PTC/Inspiring Vantage.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/InventorsFair.jpg", "PTC.zip/PTC/Inventors' Fair.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/KambalConsulOfAllocation.jpg", "PTC.zip/PTC/Kambal, Consul of Allocation.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/KeyToTheCity.jpg", "PTC.zip/PTC/Key to the City.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/LathnuHellion.jpg", "PTC.zip/PTC/Lathnu Hellion.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/LostLegacy.jpg", "PTC.zip/PTC/Lost Legacy.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/MadcapExperiment.jpg", "PTC.zip/PTC/Madcap Experiment.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/MarionetteMaster.jpg", "PTC.zip/PTC/Marionette Master.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/MasterTrinketeer.jpg", "PTC.zip/PTC/Master Trinketeer.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/MetallurgicSummonings.jpg", "PTC.zip/PTC/Metallurgic Summonings.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/MetalworkColossus.jpg", "PTC.zip/PTC/Metalwork Colossus.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/MidnightOil.jpg", "PTC.zip/PTC/Midnight Oil.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/MultiformWonder.jpg", "PTC.zip/PTC/Multiform Wonder.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/NissaVitalForce.jpg", "PTC.zip/PTC/Nissa, Vital Force.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/NoxiousGearhulk.jpg", "PTC.zip/PTC/Noxious Gearhulk.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/OviyaPashiriSageLifecrafter.jpg", "PTC.zip/PTC/Oviya Pashiri, Sage Lifecrafter.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/PadeemConsulOfInnovation.jpg", "PTC.zip/PTC/Padeem, Consul of Innovation.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/Panharmonicon.jpg", "PTC.zip/PTC/Panharmonicon.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/ParadoxicalOutcome.jpg", "PTC.zip/PTC/Paradoxical Outcome.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/PiaNalaar.jpg", "PTC.zip/PTC/Pia Nalaar.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/RashmiEternitiesCrafter.jpg", "PTC.zip/PTC/Rashmi, Eternities Crafter.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/SaheeliRai.jpg", "PTC.zip/PTC/Saheeli Rai.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/SaheelisArtistry.jpg", "PTC.zip/PTC/Saheeli's Artistry.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/ScrapheapScrounger.jpg", "PTC.zip/PTC/Scrapheap Scrounger.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/SkyshipStalker.jpg", "PTC.zip/PTC/Skyship Stalker.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/SkysovereignConsulFlagship.jpg", "PTC.zip/PTC/Skysovereign, Consul Flagship.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/SmugglersCopter.jpg", "PTC.zip/PTC/Smuggler's Copter.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/SpirebluffCanal.jpg", "PTC.zip/PTC/Spirebluff Canal.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/SyndicateTrafficker.jpg", "PTC.zip/PTC/Syndicate Trafficker.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/TerritorialGorger.jpg", "PTC.zip/PTC/Territorial Gorger.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/ToolcraftExemplar.jpg", "PTC.zip/PTC/Toolcraft Exemplar.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/TorrentialGearhulk.jpg", "PTC.zip/PTC/Torrential Gearhulk.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/VerdurousGearhulk.jpg", "PTC.zip/PTC/Verdurous Gearhulk.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/KLD/WildestDreams.jpg", "PTC.zip/PTC/Wildest Dreams.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/AyliEternalPilgrim.jpg", "PTC.zip/PTC/Ayli, Eternal Pilgrim.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/BearerOfSilence.jpg", "PTC.zip/PTC/Bearer of Silence.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/BearerOfTheHeavens.jpg", "PTC.zip/PTC/Bearer of the Heavens.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/CallTheGatewatch.jpg", "PTC.zip/PTC/Call the Gatewatch.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/CaptainsClaws.jpg", "PTC.zip/PTC/Captain's Claws.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/ChandraFlamecaller.jpg", "PTC.zip/PTC/Chandra, Flamecaller.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/ChandraPyromaster.jpg", "PTC.zip/PTC/Chandra, Pyromaster.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/CorruptedCrossroads.jpg", "PTC.zip/PTC/Corrupted Crossroads.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/CrushOfTentacles.jpg", "PTC.zip/PTC/Crush of Tentacles.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/DeceiverOfForm.jpg", "PTC.zip/PTC/Deceiver of Form.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/DeepfathomSkulker.jpg", "PTC.zip/PTC/Deepfathom Skulker.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/DimensionalInfiltrator.jpg", "PTC.zip/PTC/Dimensional Infiltrator.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/DranaLiberatorOfMalakir.jpg", "PTC.zip/PTC/Drana, Liberator of Malakir.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/DreadDefiler.jpg", "PTC.zip/PTC/Dread Defiler.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/EldraziDisplacer.jpg", "PTC.zip/PTC/Eldrazi Displacer.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/EldraziMimic.jpg", "PTC.zip/PTC/Eldrazi Mimic.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/EldraziObligator.jpg", "PTC.zip/PTC/Eldrazi Obligator.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/EndHostilities.jpg", "PTC.zip/PTC/End Hostilities.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/Endbringer.jpg", "PTC.zip/PTC/Endbringer.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/FallOfTheTitans.jpg", "PTC.zip/PTC/Fall of the Titans.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/GeneralTazri.jpg", "PTC.zip/PTC/General Tazri.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/GladehartCavalry.jpg", "PTC.zip/PTC/Gladehart Cavalry.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/GoblinDarkDwellers.jpg", "PTC.zip/PTC/Goblin Dark-Dwellers.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/GoblinRabblemaster.jpg", "PTC.zip/PTC/Goblin Rabblemaster.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/HedronAlignment.jpg", "PTC.zip/PTC/Hedron Alignment.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/HissingQuagmire.jpg", "PTC.zip/PTC/Hissing Quagmire.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/InverterOfTruth.jpg", "PTC.zip/PTC/Inverter of Truth.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/JoriEnRuinDiver.jpg", "PTC.zip/PTC/Jori En, Ruin Diver.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/KalitasTraitorOfGhet.jpg", "PTC.zip/PTC/Kalitas, Traitor of Ghet.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/KozilekTheGreatDistortion.jpg", "PTC.zip/PTC/Kozilek, the Great Distortion.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/KozileksReturn.jpg", "PTC.zip/PTC/Kozilek's Return.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/LinvalaThePreserver.jpg", "PTC.zip/PTC/Linvala, the Preserver.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/MatterReshaper.jpg", "PTC.zip/PTC/Matter Reshaper.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/MinaAndDennWildborn.jpg", "PTC.zip/PTC/Mina and Denn, Wildborn.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/Mirrorpool.jpg", "PTC.zip/PTC/Mirrorpool.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/MundasVanguard.jpg", "PTC.zip/PTC/Munda's Vanguard.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/NeedleSpires.jpg", "PTC.zip/PTC/Needle Spires.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/NissaVoiceOfZendikar.jpg", "PTC.zip/PTC/Nissa, Voice of Zendikar.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/OathOfChandra.jpg", "PTC.zip/PTC/Oath of Chandra.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/OathOfGideon.jpg", "PTC.zip/PTC/Oath of Gideon.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/OathOfJace.jpg", "PTC.zip/PTC/Oath of Jace.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/OathOfNissa.jpg", "PTC.zip/PTC/Oath of Nissa.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/OverwhelmingDenial.jpg", "PTC.zip/PTC/Overwhelming Denial.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/RealitySmasher.jpg", "PTC.zip/PTC/Reality Smasher.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/RemorselessPunishment.jpg", "PTC.zip/PTC/Remorseless Punishment.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/RuinsOfOranRief.jpg", "PTC.zip/PTC/Ruins of Oran-Rief.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/SeaGateWreckage.jpg", "PTC.zip/PTC/Sea Gate Wreckage.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/SifterOfSkulls.jpg", "PTC.zip/PTC/Sifter of Skulls.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/SphinxOfTheFinalWord.jpg", "PTC.zip/PTC/Sphinx of the Final Word.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/StoneHavenOutfitter.jpg", "PTC.zip/PTC/Stone Haven Outfitter.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/StoneforgeMasterwork.jpg", "PTC.zip/PTC/Stoneforge Masterwork.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/SylvanAdvocate.jpg", "PTC.zip/PTC/Sylvan Advocate.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/SylvanCaryatid.jpg", "PTC.zip/PTC/Sylvan Caryatid.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/ThoughtKnotSeer.jpg", "PTC.zip/PTC/Thought-Knot Seer.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/TyrantOfValakut.jpg", "PTC.zip/PTC/Tyrant of Valakut.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/VileRedeemer.jpg", "PTC.zip/PTC/Vile Redeemer.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/WanderingFumarole.jpg", "PTC.zip/PTC/Wandering Fumarole.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/WorldBreaker.jpg", "PTC.zip/PTC/World Breaker.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/OGW/ZendikarResurgent.jpg", "PTC.zip/PTC/Zendikar Resurgent.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/AlteredEgo.jpg", "PTC.zip/PTC/Altered Ego.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/AlwaysWatching.jpg", "PTC.zip/PTC/Always Watching.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/AngelOfDeliverance.jpg", "PTC.zip/PTC/Angel of Deliverance.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/AnguishedUnmaking.jpg", "PTC.zip/PTC/Anguished Unmaking.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/ArchangelAvacyn.jpg", "PTC.zip/PTC/Archangel Avacyn.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/ArlinnKord.jpg", "PTC.zip/PTC/Arlinn Kord.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/AsylumVisitor.jpg", "PTC.zip/PTC/Asylum Visitor.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/AvacynGuardianAngel.jpg", "PTC.zip/PTC/Avacyn, Guardian Angel.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/AvacynsJudgment.jpg", "PTC.zip/PTC/Avacyn's Judgement.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/BeholdTheBeyond.jpg", "PTC.zip/PTC/Behold the Beyond.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/BrainInAJar.jpg", "PTC.zip/PTC/Brain in a Jar.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/BurnFromWithin.jpg", "PTC.zip/PTC/Burn from Within.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/BygoneBishop.jpg", "PTC.zip/PTC/Bygone Bishop.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/ChokedEstuary.jpg", "PTC.zip/PTC/Choked Estuary.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/ConfirmSuspicions.jpg", "PTC.zip/PTC/Confirm Suspicions.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/CorruptedGrafstone.jpg", "PTC.zip/PTC/Corrupted Grafstone.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/CryptolithRite.jpg", "PTC.zip/PTC/Cryptolith Rite.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/DeathcapCultivator.jpg", "PTC.zip/PTC/Deathcap Cultivator.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/DeclarationInStone.jpg", "PTC.zip/PTC/Declaration in Stone.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/DescendUponTheSinful.jpg", "PTC.zip/PTC/Descend upon the Sinful.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/DevilsPlayground.jpg", "PTC.zip/PTC/Devils' Playground.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/DiregrafColossus.jpg", "PTC.zip/PTC/Diregraf Colossus.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/DrogskolCavalry.jpg", "PTC.zip/PTC/Drogskol Cavalry.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/DrownyardTemple.jpg", "PTC.zip/PTC/Drownyard Temple.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/EerieInterlude.jpg", "PTC.zip/PTC/Eerie Interlude.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/EngulfTheShore.jpg", "PTC.zip/PTC/Engulf the Shore.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/EpiphanyAtTheDrownyard.jpg", "PTC.zip/PTC/Epiphany at the Drownyard.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/EverAfter.jpg", "PTC.zip/PTC/Ever After.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/FalkenrathGorger.jpg", "PTC.zip/PTC/Falkenrath Gorger.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/FeveredVisions.jpg", "PTC.zip/PTC/Fevered Visions.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/FlamebladeAngel.jpg", "PTC.zip/PTC/Flameblade Angel.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/ForebodingRuins.jpg", "PTC.zip/PTC/Foreboding Ruins.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/ForgottenCreation.jpg", "PTC.zip/PTC/Forgotten Creation.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/FortifiedVillage.jpg", "PTC.zip/PTC/Fortified Village.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/FromUnderTheFloorboards.jpg", "PTC.zip/PTC/From Under the Floorboards.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/GameTrail.jpg", "PTC.zip/PTC/Game Trail.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/GeierReachBandit.jpg", "PTC.zip/PTC/Geier Reach Bandit.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/GeierReachSanitarium.jpg", "PTC.zip/PTC/Geier Reach Sanitarium.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/GeralfsMasterpiece.jpg", "PTC.zip/PTC/Geralf's Masterpiece.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/GoldnightCastigator.jpg", "PTC.zip/PTC/Goldnight Castigator.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/HanweirMilitiaCaptain.jpg", "PTC.zip/PTC/Hanweir Militia Captain.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/HarnessTheStorm.jpg", "PTC.zip/PTC/Harness the Storm.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/InexorableBlob.jpg", "PTC.zip/PTC/Inexorable Blob.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/InvocationOfSaintTraft.jpg", "PTC.zip/PTC/Invocation of Saint Traft.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/JaceTheLivingGuildpact.jpg", "PTC.zip/PTC/Jace, the Living Guildpact.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/JaceUnravelerOfSecrets.jpg", "PTC.zip/PTC/Jace, Unraveler of Secrets.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/MarkovDreadknight.jpg", "PTC.zip/PTC/Markov Dreadknight.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/MindwrackDemon.jpg", "PTC.zip/PTC/Mindwrack Demon.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/NahiriTheHarbinger.jpg", "PTC.zip/PTC/Nahiri, the Harbinger.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/NephaliaMoondrakes.jpg", "PTC.zip/PTC/Nephalia Moondrakes.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/OdricLunarchMarshal.jpg", "PTC.zip/PTC/Odric, Lunarch Marshal.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/OliviaMobilizedForWar.jpg", "PTC.zip/PTC/Olivia, Mobilized for War.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/OrmendahlProfanePrince.jpg", "PTC.zip/PTC/Ormendahl, Profane Prince.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/PortTown.jpg", "PTC.zip/PTC/Port Town.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/PrizedAmalgam.jpg", "PTC.zip/PTC/Prized Amalgam.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/Rattlechains.jpg", "PTC.zip/PTC/Rattlechains.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/RelentlessDead.jpg", "PTC.zip/PTC/Relentless Dead.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/SageOfAncientLore.jpg", "PTC.zip/PTC/Sage of Ancient Lore.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/ScourgeWolf.jpg", "PTC.zip/PTC/Scourge Wolf.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/SeasonsPast.jpg", "PTC.zip/PTC/Seasons Past.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/SecondHarvest.jpg", "PTC.zip/PTC/Second Harvest.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/SigardaHeronsGrace.jpg", "PTC.zip/PTC/Sigarda, Heron's Grace.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/SilverfurPartisan.jpg", "PTC.zip/PTC/Silverfur Partisan.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/SinProdder.jpg", "PTC.zip/PTC/Sin Prodder.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/SlayersPlate.jpg", "PTC.zip/PTC/Slayer's Plate.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/SorinGrimNemesis.jpg", "PTC.zip/PTC/Sorin, Grim Nemesis.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/SorinSolemnVisitor.jpg", "PTC.zip/PTC/Sorin, Solemn Visitor.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/SoulSwallower.jpg", "PTC.zip/PTC/Soul Swallower.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/StartledAwake.jpg", "PTC.zip/PTC/Startled Awake.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/TamiyoFieldResearcher.jpg", "PTC.zip/PTC/Tamiyo, Field Researcher.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/TamiyosJournal.jpg", "PTC.zip/PTC/Tamiyo's Journal.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/ThaliaHereticCathar.jpg", "PTC.zip/PTC/Thalia, Heretic Cathar.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/ThaliasLieutenant.jpg", "PTC.zip/PTC/Thalia's Lieutenant.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/TheGitrogMonster.jpg", "PTC.zip/PTC/The Gitrog Monster.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/ThingInTheIce.jpg", "PTC.zip/PTC/Thing in the Ice.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/TirelessTracker.jpg", "PTC.zip/PTC/Tireless Tracker.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/ToTheSlaughter.jpg", "PTC.zip/PTC/To the Slaughter.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/TraverseTheUlvenwald.jpg", "PTC.zip/PTC/Traverse the Ulvenwald.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/Triskaidekaphobia.jpg", "PTC.zip/PTC/Triskaidekaphobia.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/UlvenwaldObserver.jpg", "PTC.zip/PTC/Ulvenwald Observer.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/WelcomeToTheFold.jpg", "PTC.zip/PTC/Welcome to the Fold.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/WestvaleAbbey.jpg", "PTC.zip/PTC/Westvale Abbey.full.jpg"); - copyUrlToImage.put("MTG/PRM/en/foil/Prerelease/SOI/WolfOfDevilsBreach.jpg", "PTC.zip/PTC/Wolf of Devil's Breach.full.jpg"); - copyUrlToImage.put("MTG/THS/en/promo/HerosDownfall.jpg", "PTC.zip/PTC/Hero's Downfall.full.jpg"); - copyUrlToImage.put("MTG/THS/en/promo/ReaperOfTheWilds.jpg", "PTC.zip/PTC/Reaper of the Wilds.full.jpg"); - copyUrlToImage.put("MTG/THS/en/promo/WhipOfErebos.jpg", "PTC.zip/PTC/Whip of Erebos.full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/AncientTomb.jpg", "EXP.zip/EXP/Ancient Tomb .full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/CascadeBluffs.jpg", "EXP.zip/EXP/Cascade Bluffs .full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/DustBowl.jpg", "EXP.zip/EXP/Dust Bowl .full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/EyeOfUgin.jpg", "EXP.zip/EXP/Eye of Ugin .full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/FetidHeath.jpg", "EXP.zip/EXP/Fetid Heath .full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/FireLitThicket.jpg", "EXP.zip/EXP/Fire-Lit Thicket .full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/FloodedGrove.jpg", "EXP.zip/EXP/Flooded Grove .full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/ForbiddenOrchard.jpg", "EXP.zip/EXP/Forbidden Orchard .full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/GravenCairns.jpg", "EXP.zip/EXP/Graven Cairns .full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/HorizonCanopy.jpg", "EXP.zip/EXP/Horizon Canopy.full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/KorHaven.jpg", "EXP.zip/EXP/Kor Haven.full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/ManaConfluence.jpg", "EXP.zip/EXP/Mana Confluence.full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/MysticGate.jpg", "EXP.zip/EXP/Mystic Gate.full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/RuggedPrairie.jpg", "EXP.zip/EXP/Rugged Prairie.full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/StripMine.jpg", "EXP.zip/EXP/Strip Mine.full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/SunkenRuins.jpg", "EXP.zip/EXP/Sunken Ruins.full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/TectonicEdge.jpg", "EXP.zip/EXP/Tectonic Edge.full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/TwilightMire.jpg", "EXP.zip/EXP/Twilight Mire.full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/Wasteland.jpg", "EXP.zip/EXP/Wasteland.full.jpg"); - copyUrlToImage.put("MTG/EXP/en/foil/WoodedBastion.jpg", "EXP.zip/EXP/Wooded Bastion.full.jpg"); - copyUrlToImage.put("apac/1.jpg", "APAC.zip/APAC/Forest.1.full.jpg"); - copyUrlToImage.put("apac/10.jpg", "APAC.zip/APAC/Swamp.10.full.jpg"); - copyUrlToImage.put("apac/11.jpg", "APAC.zip/APAC/Forest.11.full.jpg"); - copyUrlToImage.put("apac/12.jpg", "APAC.zip/APAC/Island.7.full.jpg"); - copyUrlToImage.put("apac/13.jpg", "APAC.zip/APAC/Mountain.13.full.jpg"); - copyUrlToImage.put("apac/14.jpg", "APAC.zip/APAC/Plains.14.full.jpg"); - copyUrlToImage.put("apac/15.jpg", "APAC.zip/APAC/Swamp.15.full.jpg"); - copyUrlToImage.put("apac/2.jpg", "APAC.zip/APAC/Island.2.full.jpg"); - copyUrlToImage.put("apac/3.jpg", "APAC.zip/APAC/Mountain.3.full.jpg"); - copyUrlToImage.put("apac/4.jpg", "APAC.zip/APAC/Plains.4.full.jpg"); - copyUrlToImage.put("apac/5.jpg", "APAC.zip/APAC/Swamp.5.full.jpg"); - copyUrlToImage.put("apac/6.jpg", "APAC.zip/APAC/Forest.6.full.jpg"); - copyUrlToImage.put("apac/7.jpg", "APAC.zip/APAC/Island.12.full.jpg"); - copyUrlToImage.put("apac/8.jpg", "APAC.zip/APAC/Mountain.8.full.jpg"); - copyUrlToImage.put("apac/9.jpg", "APAC.zip/APAC/Plains.9.full.jpg"); - copyUrlToImage.put("arena/1.jpg", "ARENA.zip/ARENA/Plains.1.full.jpg"); - copyUrlToImage.put("arena/10.jpg", "ARENA.zip/ARENA/Swamp.10.full.jpg"); - copyUrlToImage.put("arena/11.jpg", "ARENA.zip/ARENA/Mountain.11.full.jpg"); - copyUrlToImage.put("arena/12.jpg", "ARENA.zip/ARENA/Forest.12.full.jpg"); - copyUrlToImage.put("arena/13.jpg", "ARENA.zip/ARENA/Pouncing Jaguar.full.jpg"); - copyUrlToImage.put("arena/14.jpg", "ARENA.zip/ARENA/Skittering Skirge.full.jpg"); - copyUrlToImage.put("arena/15.jpg", "ARENA.zip/ARENA/Rewind.full.jpg"); - copyUrlToImage.put("arena/16.jpg", "ARENA.zip/ARENA/Karn, Silver Golem.full.jpg"); - copyUrlToImage.put("arena/17.jpg", "ARENA.zip/ARENA/Duress.full.jpg"); - copyUrlToImage.put("arena/18.jpg", "ARENA.zip/ARENA/Uktabi Orangutan.full.jpg"); - copyUrlToImage.put("arena/19.jpg", "ARENA.zip/ARENA/Chill.full.jpg"); - copyUrlToImage.put("arena/2.jpg", "ARENA.zip/ARENA/Island.2.full.jpg"); - copyUrlToImage.put("arena/20.jpg", "ARENA.zip/ARENA/Pillage.full.jpg"); - copyUrlToImage.put("arena/21.jpg", "ARENA.zip/ARENA/Enlightened Tutor.full.jpg"); - copyUrlToImage.put("arena/22.jpg", "ARENA.zip/ARENA/Stupor.full.jpg"); - copyUrlToImage.put("arena/23.jpg", "ARENA.zip/ARENA/Plains.23.full.jpg"); - copyUrlToImage.put("arena/24.jpg", "ARENA.zip/ARENA/Island.24.full.jpg"); - copyUrlToImage.put("arena/25.jpg", "ARENA.zip/ARENA/Swamp.25.full.jpg"); - copyUrlToImage.put("arena/26.jpg", "ARENA.zip/ARENA/Mountain.26.full.jpg"); - copyUrlToImage.put("arena/27.jpg", "ARENA.zip/ARENA/Forest.27.full.jpg"); - copyUrlToImage.put("arena/28.jpg", "ARENA.zip/ARENA/Creeping Mold.full.jpg"); - copyUrlToImage.put("arena/29.jpg", "ARENA.zip/ARENA/Dismiss.full.jpg"); - copyUrlToImage.put("arena/3.jpg", "ARENA.zip/ARENA/Swamp.3.full.jpg"); - copyUrlToImage.put("arena/30.jpg", "ARENA.zip/ARENA/Fling.full.jpg"); - copyUrlToImage.put("arena/31.jpg", "ARENA.zip/ARENA/Empyrial Armor.full.jpg"); - copyUrlToImage.put("arena/32.jpg", "ARENA.zip/ARENA/Plains.32.full.jpg"); - copyUrlToImage.put("arena/33.jpg", "ARENA.zip/ARENA/Island.33.full.jpg"); - copyUrlToImage.put("arena/34.jpg", "ARENA.zip/ARENA/Swamp.34.full.jpg"); - copyUrlToImage.put("arena/35.jpg", "ARENA.zip/ARENA/Mountain.35.full.jpg"); - copyUrlToImage.put("arena/36.jpg", "ARENA.zip/ARENA/Forest.36.full.jpg"); - copyUrlToImage.put("arena/37.jpg", "ARENA.zip/ARENA/Diabolic Edict.full.jpg"); - copyUrlToImage.put("arena/38.jpg", "ARENA.zip/ARENA/Gaea's Blessing.full.jpg"); - copyUrlToImage.put("arena/39.jpg", "ARENA.zip/ARENA/Island.39.full.jpg"); - copyUrlToImage.put("arena/4.jpg", "ARENA.zip/ARENA/Mountain.4.full.jpg"); - copyUrlToImage.put("arena/40.jpg", "ARENA.zip/ARENA/Forest.40.full.jpg"); - copyUrlToImage.put("arena/41.jpg", "ARENA.zip/ARENA/Man-o'-War.full.jpg"); - copyUrlToImage.put("arena/42.jpg", "ARENA.zip/ARENA/Arc Lightning.full.jpg"); - copyUrlToImage.put("arena/43.jpg", "ARENA.zip/ARENA/Dauthi Slayer.full.jpg"); - copyUrlToImage.put("arena/44.jpg", "ARENA.zip/ARENA/Mana Leak.full.jpg"); - copyUrlToImage.put("arena/45.jpg", "ARENA.zip/ARENA/Plains.45.full.jpg"); - copyUrlToImage.put("arena/46.jpg", "ARENA.zip/ARENA/Island.46.full.jpg"); - copyUrlToImage.put("arena/47.jpg", "ARENA.zip/ARENA/Swamp.47.full.jpg"); - copyUrlToImage.put("arena/48.jpg", "ARENA.zip/ARENA/Mountain.48.full.jpg"); - copyUrlToImage.put("arena/5.jpg", "ARENA.zip/ARENA/Forest.5.full.jpg"); - copyUrlToImage.put("arena/50.jpg", "ARENA.zip/ARENA/Skirk Marauder.full.jpg"); - copyUrlToImage.put("arena/51.jpg", "ARENA.zip/ARENA/Elvish Aberration.full.jpg"); - copyUrlToImage.put("arena/52.jpg", "ARENA.zip/ARENA/Bonesplitter.full.jpg"); - copyUrlToImage.put("arena/53.jpg", "ARENA.zip/ARENA/Plains.53.full.jpg"); - copyUrlToImage.put("arena/54.jpg", "ARENA.zip/ARENA/Island.54.full.jpg"); - copyUrlToImage.put("arena/55.jpg", "ARENA.zip/ARENA/Swamp.55.full.jpg"); - copyUrlToImage.put("arena/56.jpg", "ARENA.zip/ARENA/Mountain.56.full.jpg"); - copyUrlToImage.put("arena/57.jpg", "ARENA.zip/ARENA/Forest.57.full.jpg"); - copyUrlToImage.put("arena/58.jpg", "ARENA.zip/ARENA/Darksteel Ingot.full.jpg"); - copyUrlToImage.put("arena/59.jpg", "ARENA.zip/ARENA/Serum Visions.full.jpg"); - copyUrlToImage.put("arena/6.jpg", "ARENA.zip/ARENA/Disenchant.full.jpg"); - copyUrlToImage.put("arena/60.jpg", "ARENA.zip/ARENA/Glacial Ray.full.jpg"); - copyUrlToImage.put("arena/61.jpg", "ARENA.zip/ARENA/Circle of Protection Art.full.jpg"); - copyUrlToImage.put("arena/62.jpg", "ARENA.zip/ARENA/Mise.full.jpg"); - copyUrlToImage.put("arena/63.jpg", "ARENA.zip/ARENA/Booster Tutor.full.jpg"); - copyUrlToImage.put("arena/64.jpg", "ARENA.zip/ARENA/Goblin Mime.full.jpg"); - copyUrlToImage.put("arena/65.jpg", "ARENA.zip/ARENA/Granny's Payback.full.jpg"); - copyUrlToImage.put("arena/66.jpg", "ARENA.zip/ARENA/Ashnod's Coupon.full.jpg"); - copyUrlToImage.put("arena/67.jpg", "ARENA.zip/ARENA/Plains.67.full.jpg"); - copyUrlToImage.put("arena/68.jpg", "ARENA.zip/ARENA/Island.68.full.jpg"); - copyUrlToImage.put("arena/69.jpg", "ARENA.zip/ARENA/Swamp.69.full.jpg"); - copyUrlToImage.put("arena/7.jpg", "ARENA.zip/ARENA/Fireball.full.jpg"); - copyUrlToImage.put("arena/70.jpg", "ARENA.zip/ARENA/Mountain.70.full.jpg"); - copyUrlToImage.put("arena/71.jpg", "ARENA.zip/ARENA/Forest.71.full.jpg"); - copyUrlToImage.put("arena/72.jpg", "ARENA.zip/ARENA/Genju of the Spires.full.jpg"); - copyUrlToImage.put("arena/73.jpg", "ARENA.zip/ARENA/Okina Nightwatch.full.jpg"); - copyUrlToImage.put("arena/74.jpg", "ARENA.zip/ARENA/Skyknight Legionnaire.full.jpg"); - copyUrlToImage.put("arena/75.jpg", "ARENA.zip/ARENA/Plains.75.full.jpg"); - copyUrlToImage.put("arena/76.jpg", "ARENA.zip/ARENA/Island.76.full.jpg"); - copyUrlToImage.put("arena/77.jpg", "ARENA.zip/ARENA/Swamp.77.full.jpg"); - copyUrlToImage.put("arena/78.jpg", "ARENA.zip/ARENA/Mountain.78.full.jpg"); - copyUrlToImage.put("arena/8.jpg", "ARENA.zip/ARENA/Plains.8.full.jpg"); - copyUrlToImage.put("arena/80.jpg", "ARENA.zip/ARENA/Castigate.full.jpg"); - copyUrlToImage.put("arena/81.jpg", "ARENA.zip/ARENA/Wee Dragonauts.full.jpg"); - copyUrlToImage.put("arena/82.jpg", "ARENA.zip/ARENA/Coiling Oracle.full.jpg"); - copyUrlToImage.put("arena/83.jpg", "ARENA.zip/ARENA/Surging Flame.full.jpg"); - copyUrlToImage.put("arena/9.jpg", "ARENA.zip/ARENA/Island.9.full.jpg"); - copyUrlToImage.put("euro/1.jpg", "EURO.zip/EURO/Forest.1.full.jpg"); - copyUrlToImage.put("euro/10.jpg", "EURO.zip/EURO/Swamp.10.full.jpg"); - copyUrlToImage.put("euro/11.jpg", "EURO.zip/EURO/Forest.11.full.jpg"); - copyUrlToImage.put("euro/12.jpg", "EURO.zip/EURO/Island.12.full.jpg"); - copyUrlToImage.put("euro/13.jpg", "EURO.zip/EURO/Mountain.13.full.jpg"); - copyUrlToImage.put("euro/14.jpg", "EURO.zip/EURO/Plains.14.full.jpg"); - copyUrlToImage.put("euro/15.jpg", "EURO.zip/EURO/Swamp.15.full.jpg"); - copyUrlToImage.put("euro/2.jpg", "EURO.zip/EURO/Island.2.full.jpg"); - copyUrlToImage.put("euro/3.jpg", "EURO.zip/EURO/Mountain.3.full.jpg"); - copyUrlToImage.put("euro/4.jpg", "EURO.zip/EURO/Plains.4.full.jpg"); - copyUrlToImage.put("euro/5.jpg", "EURO.zip/EURO/Swamp.5.full.jpg"); - copyUrlToImage.put("euro/6.jpg", "EURO.zip/EURO/Forest.6.full.jpg"); - copyUrlToImage.put("euro/7.jpg", "EURO.zip/EURO/Island.7.full.jpg"); - copyUrlToImage.put("euro/8.jpg", "EURO.zip/EURO/Mountain.8.full.jpg"); - copyUrlToImage.put("euro/9.jpg", "EURO.zip/EURO/Plains.9.full.jpg"); - copyUrlToImage.put("exp/1.jpg", "EXP.zip/EXP/Prairie Stream.full.jpg"); - copyUrlToImage.put("exp/10.jpg", "EXP.zip/EXP/Temple Garden.full.jpg"); - copyUrlToImage.put("exp/11.jpg", "EXP.zip/EXP/Godless Shrine.full.jpg"); - copyUrlToImage.put("exp/12.jpg", "EXP.zip/EXP/Steam Vents.full.jpg"); - copyUrlToImage.put("exp/13.jpg", "EXP.zip/EXP/Overgrown Tomb.full.jpg"); - copyUrlToImage.put("exp/14.jpg", "EXP.zip/EXP/Sacred Foundry.full.jpg"); - copyUrlToImage.put("exp/15.jpg", "EXP.zip/EXP/Breeding Pool.full.jpg"); - copyUrlToImage.put("exp/16.jpg", "EXP.zip/EXP/Flooded Strand.full.jpg"); - copyUrlToImage.put("exp/17.jpg", "EXP.zip/EXP/Polluted Delta.full.jpg"); - copyUrlToImage.put("exp/18.jpg", "EXP.zip/EXP/Bloodstained Mire.full.jpg"); - copyUrlToImage.put("exp/19.jpg", "EXP.zip/EXP/Wooded Foothills.full.jpg"); - copyUrlToImage.put("exp/2.jpg", "EXP.zip/EXP/Sunken Hollow.full.jpg"); - copyUrlToImage.put("exp/20.jpg", "EXP.zip/EXP/Windswept Heath.full.jpg"); - copyUrlToImage.put("exp/21.jpg", "EXP.zip/EXP/Marsh Flats.full.jpg"); - copyUrlToImage.put("exp/22.jpg", "EXP.zip/EXP/Scalding Tarn.full.jpg"); - copyUrlToImage.put("exp/23.jpg", "EXP.zip/EXP/Verdant Catacombs.full.jpg"); - copyUrlToImage.put("exp/24.jpg", "EXP.zip/EXP/Arid Mesa.full.jpg"); - copyUrlToImage.put("exp/25.jpg", "EXP.zip/EXP/Misty Rainforest.full.jpg"); - copyUrlToImage.put("exp/3.jpg", "EXP.zip/EXP/Smoldering Marsh.full.jpg"); - copyUrlToImage.put("exp/4.jpg", "EXP.zip/EXP/Cinder Glade.full.jpg"); - copyUrlToImage.put("exp/5.jpg", "EXP.zip/EXP/Canopy Vista.full.jpg"); - copyUrlToImage.put("exp/6.jpg", "EXP.zip/EXP/Hallowed Fountain.full.jpg"); - copyUrlToImage.put("exp/7.jpg", "EXP.zip/EXP/Watery Grave.full.jpg"); - copyUrlToImage.put("exp/8.jpg", "EXP.zip/EXP/Blood Crypt.full.jpg"); - copyUrlToImage.put("exp/9.jpg", "EXP.zip/EXP/Stomping Ground.full.jpg"); - copyUrlToImage.put("fnmp/1.jpg", "FNMP.zip/FNMP/River Boa.full.jpg"); - copyUrlToImage.put("fnmp/10.jpg", "FNMP.zip/FNMP/Stone Rain.full.jpg"); - copyUrlToImage.put("fnmp/100.jpg", "FNMP.zip/FNMP/Thirst for Knowledge.full.jpg"); - copyUrlToImage.put("fnmp/101.jpg", "FNMP.zip/FNMP/Serrated Arrows.full.jpg"); - copyUrlToImage.put("fnmp/102.jpg", "FNMP.zip/FNMP/Isochron Scepter.full.jpg"); - copyUrlToImage.put("fnmp/103.jpg", "FNMP.zip/FNMP/Shrapnel Blast.full.jpg"); - copyUrlToImage.put("fnmp/104.jpg", "FNMP.zip/FNMP/Magma Jet.full.jpg"); - copyUrlToImage.put("fnmp/105.jpg", "FNMP.zip/FNMP/Myr Enforcer.full.jpg"); - copyUrlToImage.put("fnmp/106.jpg", "FNMP.zip/FNMP/Kitchen Finks.full.jpg"); - copyUrlToImage.put("fnmp/107.jpg", "FNMP.zip/FNMP/Merrow Reejerey.full.jpg"); - copyUrlToImage.put("fnmp/108.jpg", "FNMP.zip/FNMP/Wren's Run Vanquisher.full.jpg"); - copyUrlToImage.put("fnmp/109.jpg", "FNMP.zip/FNMP/Mulldrifter.full.jpg"); - copyUrlToImage.put("fnmp/11.jpg", "FNMP.zip/FNMP/Llanowar Elves.full.jpg"); - copyUrlToImage.put("fnmp/110.jpg", "FNMP.zip/FNMP/Murderous Redcap.full.jpg"); - copyUrlToImage.put("fnmp/111.jpg", "FNMP.zip/FNMP/Lightning Greaves.full.jpg"); - copyUrlToImage.put("fnmp/112.jpg", "FNMP.zip/FNMP/Watchwolf.full.jpg"); - copyUrlToImage.put("fnmp/113.jpg", "FNMP.zip/FNMP/Browbeat.full.jpg"); - copyUrlToImage.put("fnmp/114.jpg", "FNMP.zip/FNMP/Oblivion Ring.full.jpg"); - copyUrlToImage.put("fnmp/115.jpg", "FNMP.zip/FNMP/Sakura-Tribe Elder.full.jpg"); - copyUrlToImage.put("fnmp/116.jpg", "FNMP.zip/FNMP/Tidehollow Sculler.full.jpg"); - copyUrlToImage.put("fnmp/117.jpg", "FNMP.zip/FNMP/Ghostly Prison.full.jpg"); - copyUrlToImage.put("fnmp/118.jpg", "FNMP.zip/FNMP/Ancient Ziggurat.full.jpg"); - copyUrlToImage.put("fnmp/119.jpg", "FNMP.zip/FNMP/Bloodbraid Elf.full.jpg"); - copyUrlToImage.put("fnmp/12.jpg", "FNMP.zip/FNMP/Swords to Plowshares.full.jpg"); - copyUrlToImage.put("fnmp/120.jpg", "FNMP.zip/FNMP/Cloudpost.full.jpg"); - copyUrlToImage.put("fnmp/121.jpg", "FNMP.zip/FNMP/Elvish Visionary.full.jpg"); - copyUrlToImage.put("fnmp/122.jpg", "FNMP.zip/FNMP/Anathemancer.full.jpg"); - copyUrlToImage.put("fnmp/123.jpg", "FNMP.zip/FNMP/Krosan Grip.full.jpg"); - copyUrlToImage.put("fnmp/124.jpg", "FNMP.zip/FNMP/Qasali Pridemage.full.jpg"); - copyUrlToImage.put("fnmp/125.jpg", "FNMP.zip/FNMP/Rift Bolt.full.jpg"); - copyUrlToImage.put("fnmp/126.jpg", "FNMP.zip/FNMP/Gatekeeper of Malakir.full.jpg"); - copyUrlToImage.put("fnmp/127.jpg", "FNMP.zip/FNMP/Wild Nacatl.full.jpg"); - copyUrlToImage.put("fnmp/128.jpg", "FNMP.zip/FNMP/Everflowing Chalice.full.jpg"); - copyUrlToImage.put("fnmp/129.jpg", "FNMP.zip/FNMP/Spellstutter Sprite.full.jpg"); - copyUrlToImage.put("fnmp/13.jpg", "FNMP.zip/FNMP/Ophidian.full.jpg"); - copyUrlToImage.put("fnmp/130.jpg", "FNMP.zip/FNMP/Wall of Omens.full.jpg"); - copyUrlToImage.put("fnmp/131.jpg", "FNMP.zip/FNMP/Artisan of Kozilek.full.jpg"); - copyUrlToImage.put("fnmp/132.jpg", "FNMP.zip/FNMP/Squadron Hawk.full.jpg"); - copyUrlToImage.put("fnmp/133.jpg", "FNMP.zip/FNMP/Rhox War Monk.full.jpg"); - copyUrlToImage.put("fnmp/134.jpg", "FNMP.zip/FNMP/Jace's Ingenuity.full.jpg"); - copyUrlToImage.put("fnmp/135.jpg", "FNMP.zip/FNMP/Cultivate.full.jpg"); - copyUrlToImage.put("fnmp/136.jpg", "FNMP.zip/FNMP/Teetering Peaks.full.jpg"); - copyUrlToImage.put("fnmp/137.jpg", "FNMP.zip/FNMP/Contagion Clasp.full.jpg"); - copyUrlToImage.put("fnmp/138.jpg", "FNMP.zip/FNMP/Go for the Throat.full.jpg"); - copyUrlToImage.put("fnmp/139.jpg", "FNMP.zip/FNMP/Savage Lands.full.jpg"); - copyUrlToImage.put("fnmp/14.jpg", "FNMP.zip/FNMP/Jackal Pup.full.jpg"); - copyUrlToImage.put("fnmp/140.jpg", "FNMP.zip/FNMP/Glistener Elf.full.jpg"); - copyUrlToImage.put("fnmp/141.jpg", "FNMP.zip/FNMP/Despise.full.jpg"); - copyUrlToImage.put("fnmp/142.jpg", "FNMP.zip/FNMP/Tectonic Edge.full.jpg"); - copyUrlToImage.put("fnmp/143.jpg", "FNMP.zip/FNMP/Dismember.full.jpg"); - copyUrlToImage.put("fnmp/144.jpg", "FNMP.zip/FNMP/Ancient Grudge.full.jpg"); - copyUrlToImage.put("fnmp/145.jpg", "FNMP.zip/FNMP/Acidic Slime.full.jpg"); - copyUrlToImage.put("fnmp/146.jpg", "FNMP.zip/FNMP/Forbidden Alchemy.full.jpg"); - copyUrlToImage.put("fnmp/147.jpg", "FNMP.zip/FNMP/Avacyn's Pilgrim.full.jpg"); - copyUrlToImage.put("fnmp/148.jpg", "FNMP.zip/FNMP/Lingering Souls.full.jpg"); - copyUrlToImage.put("fnmp/149.jpg", "FNMP.zip/FNMP/Evolving Wilds.full.jpg"); - copyUrlToImage.put("fnmp/15.jpg", "FNMP.zip/FNMP/Quirion Ranger.full.jpg"); - copyUrlToImage.put("fnmp/150.jpg", "FNMP.zip/FNMP/Pillar of Flame.full.jpg"); - copyUrlToImage.put("fnmp/151.jpg", "FNMP.zip/FNMP/Gitaxian Probe.full.jpg"); - copyUrlToImage.put("fnmp/152.jpg", "FNMP.zip/FNMP/Searing Spear.full.jpg"); - copyUrlToImage.put("fnmp/153.jpg", "FNMP.zip/FNMP/Reliquary Tower.full.jpg"); - copyUrlToImage.put("fnmp/154.jpg", "FNMP.zip/FNMP/Farseek.full.jpg"); - copyUrlToImage.put("fnmp/155.jpg", "FNMP.zip/FNMP/Call of the Conclave.full.jpg"); - copyUrlToImage.put("fnmp/156.jpg", "FNMP.zip/FNMP/Judge's Familiar.full.jpg"); - copyUrlToImage.put("fnmp/157.jpg", "FNMP.zip/FNMP/Izzet Charm.full.jpg"); - copyUrlToImage.put("fnmp/158.jpg", "FNMP.zip/FNMP/Rakdos Cackler.full.jpg"); - copyUrlToImage.put("fnmp/159.jpg", "FNMP.zip/FNMP/Dimir Charm.full.jpg"); - copyUrlToImage.put("fnmp/16.jpg", "FNMP.zip/FNMP/Carnophage.full.jpg"); - copyUrlToImage.put("fnmp/160.jpg", "FNMP.zip/FNMP/Experiment One.full.jpg"); - copyUrlToImage.put("fnmp/161.jpg", "FNMP.zip/FNMP/Ghor-Clan Rampager.full.jpg"); - copyUrlToImage.put("fnmp/162.jpg", "FNMP.zip/FNMP/Grisly Salvage.full.jpg"); - copyUrlToImage.put("fnmp/163.jpg", "FNMP.zip/FNMP/Sin Collector.full.jpg"); - copyUrlToImage.put("fnmp/164.jpg", "FNMP.zip/FNMP/Warleader's Helix.full.jpg"); - copyUrlToImage.put("fnmp/165.jpg", "FNMP.zip/FNMP/Elvish Mystic.full.jpg"); - copyUrlToImage.put("fnmp/166.jpg", "FNMP.zip/FNMP/Banisher Priest.full.jpg"); - copyUrlToImage.put("fnmp/167.jpg", "FNMP.zip/FNMP/Encroaching Wastes.full.jpg"); - copyUrlToImage.put("fnmp/168.jpg", "FNMP.zip/FNMP/Tormented Hero.full.jpg"); - copyUrlToImage.put("fnmp/169.jpg", "FNMP.zip/FNMP/Dissolve.full.jpg"); - copyUrlToImage.put("fnmp/17.jpg", "FNMP.zip/FNMP/Impulse.full.jpg"); - copyUrlToImage.put("fnmp/170.jpg", "FNMP.zip/FNMP/Magma Spray.full.jpg"); - copyUrlToImage.put("fnmp/171.jpg", "FNMP.zip/FNMP/Bile Blight.full.jpg"); - copyUrlToImage.put("fnmp/172.jpg", "FNMP.zip/FNMP/Banishing Light.full.jpg"); - copyUrlToImage.put("fnmp/173.jpg", "FNMP.zip/FNMP/Fanatic of Xenagos.full.jpg"); - copyUrlToImage.put("fnmp/174.jpg", "FNMP.zip/FNMP/Brain Maggot.full.jpg"); - copyUrlToImage.put("fnmp/175.jpg", "FNMP.zip/FNMP/Stoke the Flames.full.jpg"); - copyUrlToImage.put("fnmp/176.jpg", "FNMP.zip/FNMP/Frenzied Goblin.full.jpg"); - copyUrlToImage.put("fnmp/177.jpg", "FNMP.zip/FNMP/Disdainful Stroke.full.jpg"); - copyUrlToImage.put("fnmp/178.jpg", "FNMP.zip/FNMP/Hordeling Outburst.full.jpg"); - copyUrlToImage.put("fnmp/179.jpg", "FNMP.zip/FNMP/Suspension Field.full.jpg"); - copyUrlToImage.put("fnmp/18.jpg", "FNMP.zip/FNMP/Fireblast.full.jpg"); - copyUrlToImage.put("fnmp/180.jpg", "FNMP.zip/FNMP/Abzan Beastmaster.full.jpg"); - copyUrlToImage.put("fnmp/181.jpg", "FNMP.zip/FNMP/Frost Walker.full.jpg"); - copyUrlToImage.put("fnmp/182.jpg", "FNMP.zip/FNMP/Path to Exile.full.jpg"); - copyUrlToImage.put("fnmp/183.jpg", "FNMP.zip/FNMP/Serum Visions.full.jpg"); - copyUrlToImage.put("fnmp/184.jpg", "FNMP.zip/FNMP/Orator of Ojutai.full.jpg"); - copyUrlToImage.put("fnmp/186.jpg", "FNMP.zip/FNMP/Roast.full.jpg"); - copyUrlToImage.put("fnmp/187.jpg", "FNMP.zip/FNMP/Anticipate.full.jpg"); - copyUrlToImage.put("fnmp/188.jpg", "FNMP.zip/FNMP/Nissa's Pilgrimage.full.jpg"); - copyUrlToImage.put("fnmp/189.jpg", "FNMP.zip/FNMP/Clash of Wills.full.jpg"); - copyUrlToImage.put("fnmp/19.jpg", "FNMP.zip/FNMP/Soltari Priest.full.jpg"); - copyUrlToImage.put("fnmp/190.jpg", "FNMP.zip/FNMP/Smash to Smithereens.full.jpg"); - copyUrlToImage.put("fnmp/191.jpg", "FNMP.zip/FNMP/Blighted Fen.full.jpg"); - copyUrlToImage.put("fnmp/2.jpg", "FNMP.zip/FNMP/Terror.full.jpg"); - copyUrlToImage.put("fnmp/20.jpg", "FNMP.zip/FNMP/Albino Troll.full.jpg"); - copyUrlToImage.put("fnmp/21.jpg", "FNMP.zip/FNMP/Dissipate.full.jpg"); - copyUrlToImage.put("fnmp/22.jpg", "FNMP.zip/FNMP/Black Knight.full.jpg"); - copyUrlToImage.put("fnmp/23.jpg", "FNMP.zip/FNMP/Wall of Blossoms.full.jpg"); - copyUrlToImage.put("fnmp/24.jpg", "FNMP.zip/FNMP/Fireslinger.full.jpg"); - copyUrlToImage.put("fnmp/25.jpg", "FNMP.zip/FNMP/Drain Life.full.jpg"); - copyUrlToImage.put("fnmp/26.jpg", "FNMP.zip/FNMP/Aura of Silence.full.jpg"); - copyUrlToImage.put("fnmp/27.jpg", "FNMP.zip/FNMP/Forbid.full.jpg"); - copyUrlToImage.put("fnmp/28.jpg", "FNMP.zip/FNMP/Spike Feeder.full.jpg"); - copyUrlToImage.put("fnmp/29.jpg", "FNMP.zip/FNMP/Mogg Fanatic.full.jpg"); - copyUrlToImage.put("fnmp/3.jpg", "FNMP.zip/FNMP/Longbow Archer.full.jpg"); - copyUrlToImage.put("fnmp/30.jpg", "FNMP.zip/FNMP/White Knight.full.jpg"); - copyUrlToImage.put("fnmp/31.jpg", "FNMP.zip/FNMP/Disenchant.full.jpg"); - copyUrlToImage.put("fnmp/32.jpg", "FNMP.zip/FNMP/Bottle Gnomes.full.jpg"); - copyUrlToImage.put("fnmp/33.jpg", "FNMP.zip/FNMP/Muscle Sliver.full.jpg"); - copyUrlToImage.put("fnmp/34.jpg", "FNMP.zip/FNMP/Crystalline Sliver.full.jpg"); - copyUrlToImage.put("fnmp/35.jpg", "FNMP.zip/FNMP/Capsize.full.jpg"); - copyUrlToImage.put("fnmp/36.jpg", "FNMP.zip/FNMP/Priest of Titania.full.jpg"); - copyUrlToImage.put("fnmp/37.jpg", "FNMP.zip/FNMP/Goblin Bombardment.full.jpg"); - copyUrlToImage.put("fnmp/38.jpg", "FNMP.zip/FNMP/Scragnoth.full.jpg"); - copyUrlToImage.put("fnmp/39.jpg", "FNMP.zip/FNMP/Smother.full.jpg"); - copyUrlToImage.put("fnmp/4.jpg", "FNMP.zip/FNMP/Volcanic Geyser.full.jpg"); - copyUrlToImage.put("fnmp/40.jpg", "FNMP.zip/FNMP/Whipcorder.full.jpg"); - copyUrlToImage.put("fnmp/41.jpg", "FNMP.zip/FNMP/Sparksmith.full.jpg"); - copyUrlToImage.put("fnmp/42.jpg", "FNMP.zip/FNMP/Krosan Tusker.full.jpg"); - copyUrlToImage.put("fnmp/43.jpg", "FNMP.zip/FNMP/Withered Wretch.full.jpg"); - copyUrlToImage.put("fnmp/44.jpg", "FNMP.zip/FNMP/Willbender.full.jpg"); - copyUrlToImage.put("fnmp/45.jpg", "FNMP.zip/FNMP/Slice and Dice.full.jpg"); - copyUrlToImage.put("fnmp/46.jpg", "FNMP.zip/FNMP/Silver Knight.full.jpg"); - copyUrlToImage.put("fnmp/47.jpg", "FNMP.zip/FNMP/Krosan Warchief.full.jpg"); - copyUrlToImage.put("fnmp/48.jpg", "FNMP.zip/FNMP/Lightning Rift.full.jpg"); - copyUrlToImage.put("fnmp/49.jpg", "FNMP.zip/FNMP/Carrion Feeder.full.jpg"); - copyUrlToImage.put("fnmp/5.jpg", "FNMP.zip/FNMP/Mind Warp.full.jpg"); - copyUrlToImage.put("fnmp/50.jpg", "FNMP.zip/FNMP/Treetop Village.full.jpg"); - copyUrlToImage.put("fnmp/51.jpg", "FNMP.zip/FNMP/Accumulated Knowledge.full.jpg"); - copyUrlToImage.put("fnmp/52.jpg", "FNMP.zip/FNMP/Avalanche Riders.full.jpg"); - copyUrlToImage.put("fnmp/53.jpg", "FNMP.zip/FNMP/Reanimate.full.jpg"); - copyUrlToImage.put("fnmp/54.jpg", "FNMP.zip/FNMP/Mother of Runes.full.jpg"); - copyUrlToImage.put("fnmp/55.jpg", "FNMP.zip/FNMP/Brainstorm.full.jpg"); - copyUrlToImage.put("fnmp/56.jpg", "FNMP.zip/FNMP/Rancor.full.jpg"); - copyUrlToImage.put("fnmp/57.jpg", "FNMP.zip/FNMP/Seal of Cleansing.full.jpg"); - copyUrlToImage.put("fnmp/58.jpg", "FNMP.zip/FNMP/Flametongue Kavu.full.jpg"); - copyUrlToImage.put("fnmp/59.jpg", "FNMP.zip/FNMP/Blastoderm.full.jpg"); - copyUrlToImage.put("fnmp/6.jpg", "FNMP.zip/FNMP/Shock.full.jpg"); - copyUrlToImage.put("fnmp/60.jpg", "FNMP.zip/FNMP/Cabal Therapy.full.jpg"); - copyUrlToImage.put("fnmp/61.jpg", "FNMP.zip/FNMP/Fact or Fiction.full.jpg"); - copyUrlToImage.put("fnmp/62.jpg", "FNMP.zip/FNMP/Juggernaut.full.jpg"); - copyUrlToImage.put("fnmp/63.jpg", "FNMP.zip/FNMP/Circle of Protection Red.full.jpg"); - copyUrlToImage.put("fnmp/64.jpg", "FNMP.zip/FNMP/Kird Ape.full.jpg"); - copyUrlToImage.put("fnmp/65.jpg", "FNMP.zip/FNMP/Duress.full.jpg"); - copyUrlToImage.put("fnmp/66.jpg", "FNMP.zip/FNMP/Counterspell.full.jpg"); - copyUrlToImage.put("fnmp/67.jpg", "FNMP.zip/FNMP/Icy Manipulator.full.jpg"); - copyUrlToImage.put("fnmp/68.jpg", "FNMP.zip/FNMP/Elves of Deep Shadow.full.jpg"); - copyUrlToImage.put("fnmp/69.jpg", "FNMP.zip/FNMP/Armadillo Cloak.full.jpg"); - copyUrlToImage.put("fnmp/7.jpg", "FNMP.zip/FNMP/Staunch Defenders.full.jpg"); - copyUrlToImage.put("fnmp/70.jpg", "FNMP.zip/FNMP/Terminate.full.jpg"); - copyUrlToImage.put("fnmp/71.jpg", "FNMP.zip/FNMP/Lobotomy.full.jpg"); - copyUrlToImage.put("fnmp/72.jpg", "FNMP.zip/FNMP/Goblin Warchief.full.jpg"); - copyUrlToImage.put("fnmp/73.jpg", "FNMP.zip/FNMP/Wild Mongrel.full.jpg"); - copyUrlToImage.put("fnmp/74.jpg", "FNMP.zip/FNMP/Chainer's Edict.full.jpg"); - copyUrlToImage.put("fnmp/75.jpg", "FNMP.zip/FNMP/Circular Logic.full.jpg"); - copyUrlToImage.put("fnmp/76.jpg", "FNMP.zip/FNMP/Astral Slide.full.jpg"); - copyUrlToImage.put("fnmp/77.jpg", "FNMP.zip/FNMP/Arrogant Wurm.full.jpg"); - copyUrlToImage.put("fnmp/78a.jpg", "FNMP.zip/FNMP/Life (Life/Death.full.jpg"); - copyUrlToImage.put("fnmp/78b.jpg", "FNMP.zip/FNMP/Death (Life/Death).full.jpg"); - copyUrlToImage.put("fnmp/79a.jpg", "FNMP.zip/FNMP/Fire (Fire/Ice).full.jpg"); - copyUrlToImage.put("fnmp/79b.jpg", "FNMP.zip/FNMP/Ice (Fire/Ice).full.jpg"); - copyUrlToImage.put("fnmp/8.jpg", "FNMP.zip/FNMP/Giant Growth.full.jpg"); - copyUrlToImage.put("fnmp/80.jpg", "FNMP.zip/FNMP/Firebolt.full.jpg"); - copyUrlToImage.put("fnmp/81.jpg", "FNMP.zip/FNMP/Deep Analysis.full.jpg"); - copyUrlToImage.put("fnmp/82.jpg", "FNMP.zip/FNMP/Gerrard's Verdict.full.jpg"); - copyUrlToImage.put("fnmp/83.jpg", "FNMP.zip/FNMP/Basking Rootwalla.full.jpg"); - copyUrlToImage.put("fnmp/84.jpg", "FNMP.zip/FNMP/Wonder.full.jpg"); - copyUrlToImage.put("fnmp/85.jpg", "FNMP.zip/FNMP/Goblin Legionnaire.full.jpg"); - copyUrlToImage.put("fnmp/86.jpg", "FNMP.zip/FNMP/Engineered Plague.full.jpg"); - copyUrlToImage.put("fnmp/87.jpg", "FNMP.zip/FNMP/Goblin Ringleader.full.jpg"); - copyUrlToImage.put("fnmp/88.jpg", "FNMP.zip/FNMP/Wing Shards.full.jpg"); - copyUrlToImage.put("fnmp/89.jpg", "FNMP.zip/FNMP/Cabal Coffers.full.jpg"); - copyUrlToImage.put("fnmp/9.jpg", "FNMP.zip/FNMP/Prodigal Sorcerer.full.jpg"); - copyUrlToImage.put("fnmp/90.jpg", "FNMP.zip/FNMP/Roar of the Wurm.full.jpg"); - copyUrlToImage.put("fnmp/91.jpg", "FNMP.zip/FNMP/Force Spike.full.jpg"); - copyUrlToImage.put("fnmp/92.jpg", "FNMP.zip/FNMP/Remand.full.jpg"); - copyUrlToImage.put("fnmp/93.jpg", "FNMP.zip/FNMP/Tormod's Crypt.full.jpg"); - copyUrlToImage.put("fnmp/94.jpg", "FNMP.zip/FNMP/Eternal Witness.full.jpg"); - copyUrlToImage.put("fnmp/95.jpg", "FNMP.zip/FNMP/Tendrils of Agony.full.jpg"); - copyUrlToImage.put("fnmp/96.jpg", "FNMP.zip/FNMP/Pendelhaven.full.jpg"); - copyUrlToImage.put("fnmp/97.jpg", "FNMP.zip/FNMP/Resurrection.full.jpg"); - copyUrlToImage.put("fnmp/98.jpg", "FNMP.zip/FNMP/Wall of Roots.full.jpg"); - copyUrlToImage.put("fnmp/99.jpg", "FNMP.zip/FNMP/Desert.full.jpg"); - copyUrlToImage.put("gpx/1.jpg", "GPX.zip/GPX/Spiritmonger.full.jpg"); - copyUrlToImage.put("gpx/10.jpg", "GPX.zip/GPX/Batterskull.full.jpg"); - copyUrlToImage.put("gpx/11.jpg", "GPX.zip/GPX/Griselbrand.full.jpg"); - copyUrlToImage.put("gpx/12.jpg", "GPX.zip/GPX/Stoneforge Mystic.full.jpg"); - copyUrlToImage.put("gpx/2.jpg", "GPX.zip/GPX/Call of the Herd.full.jpg"); - copyUrlToImage.put("gpx/3.jpg", "GPX.zip/GPX/Chrome Mox.full.jpg"); - copyUrlToImage.put("gpx/4.jpg", "GPX.zip/GPX/Umezawa's Jitte.full.jpg"); - copyUrlToImage.put("gpx/5.jpg", "GPX.zip/GPX/Maelstrom Pulse.full.jpg"); - copyUrlToImage.put("gpx/6.jpg", "GPX.zip/GPX/Goblin Guide.full.jpg"); - copyUrlToImage.put("gpx/7.jpg", "GPX.zip/GPX/Lotus Cobra.full.jpg"); - copyUrlToImage.put("gpx/8.jpg", "GPX.zip/GPX/Primeval Titan.full.jpg"); - copyUrlToImage.put("gpx/9.jpg", "GPX.zip/GPX/All Is Dust.full.jpg"); - copyUrlToImage.put("grc/1.jpg", "GRC.zip/GRC/Wood Elves.full.jpg"); - copyUrlToImage.put("grc/10.jpg", "GRC.zip/GRC/Mogg Fanatic.full.jpg"); - copyUrlToImage.put("grc/11.jpg", "GRC.zip/GRC/Mind Stone.full.jpg"); - copyUrlToImage.put("grc/12.jpg", "GRC.zip/GRC/Dauntless Dourbark.full.jpg"); - copyUrlToImage.put("grc/13.jpg", "GRC.zip/GRC/Lava Axe.full.jpg"); - copyUrlToImage.put("grc/14.jpg", "GRC.zip/GRC/Cenn's Tactician.full.jpg"); - copyUrlToImage.put("grc/15.jpg", "GRC.zip/GRC/Oona's Blackguard.full.jpg"); - copyUrlToImage.put("grc/16.jpg", "GRC.zip/GRC/Gravedigger.full.jpg"); - copyUrlToImage.put("grc/17.jpg", "GRC.zip/GRC/Boggart Ram-Gang.full.jpg"); - copyUrlToImage.put("grc/18.jpg", "GRC.zip/GRC/Wilt-Leaf Cavaliers.full.jpg"); - copyUrlToImage.put("grc/19.jpg", "GRC.zip/GRC/Duergar Hedge-Mage.full.jpg"); - copyUrlToImage.put("grc/2.jpg", "GRC.zip/GRC/Icatian Javelineers.full.jpg"); - copyUrlToImage.put("grc/20.jpg", "GRC.zip/GRC/Selkie Hedge-Mage.full.jpg"); - copyUrlToImage.put("grc/21.jpg", "GRC.zip/GRC/Sprouting Thrinax.full.jpg"); - copyUrlToImage.put("grc/22.jpg", "GRC.zip/GRC/Woolly Thoctar.full.jpg"); - copyUrlToImage.put("grc/24.jpg", "GRC.zip/GRC/Path to Exile.full.jpg"); - copyUrlToImage.put("grc/25.jpg", "GRC.zip/GRC/Hellspark Elemental.full.jpg"); - copyUrlToImage.put("grc/26.jpg", "GRC.zip/GRC/Marisi's Twinclaws.full.jpg"); - copyUrlToImage.put("grc/27.jpg", "GRC.zip/GRC/Slave of Bolas.full.jpg"); - copyUrlToImage.put("grc/28.jpg", "GRC.zip/GRC/Mycoid Shepherd.full.jpg"); - copyUrlToImage.put("grc/29.jpg", "GRC.zip/GRC/Naya Sojourners.full.jpg"); - copyUrlToImage.put("grc/3.jpg", "GRC.zip/GRC/Fiery Temper.full.jpg"); - copyUrlToImage.put("grc/30.jpg", "GRC.zip/GRC/Mind Control.full.jpg"); - copyUrlToImage.put("grc/31.jpg", "GRC.zip/GRC/Rise from the Grave.full.jpg"); - copyUrlToImage.put("grc/32.jpg", "GRC.zip/GRC/Kor Duelist.full.jpg"); - copyUrlToImage.put("grc/33.jpg", "GRC.zip/GRC/Vampire Nighthawk.full.jpg"); - copyUrlToImage.put("grc/34.jpg", "GRC.zip/GRC/Nissa's Chosen.full.jpg"); - copyUrlToImage.put("grc/35.jpg", "GRC.zip/GRC/Emeria Angel.full.jpg"); - copyUrlToImage.put("grc/36.jpg", "GRC.zip/GRC/Kor Firewalker.full.jpg"); - copyUrlToImage.put("grc/37.jpg", "GRC.zip/GRC/Leatherback Baloth.full.jpg"); - copyUrlToImage.put("grc/38.jpg", "GRC.zip/GRC/Hada Freeblade.full.jpg"); - copyUrlToImage.put("grc/39.jpg", "GRC.zip/GRC/Kalastria Highborn.full.jpg"); - copyUrlToImage.put("grc/4.jpg", "GRC.zip/GRC/Boomerang.full.jpg"); - copyUrlToImage.put("grc/40.jpg", "GRC.zip/GRC/Syphon Mind.full.jpg"); - copyUrlToImage.put("grc/46.jpg", "GRC.zip/GRC/Pathrazer of Ulamog.full.jpg"); - copyUrlToImage.put("grc/47.jpg", "GRC.zip/GRC/Curse of Wizardry.full.jpg"); - copyUrlToImage.put("grc/48.jpg", "GRC.zip/GRC/Staggershock.full.jpg"); - copyUrlToImage.put("grc/49.jpg", "GRC.zip/GRC/Deathless Angel.full.jpg"); - copyUrlToImage.put("grc/5.jpg", "GRC.zip/GRC/Calciderm.full.jpg"); - copyUrlToImage.put("grc/50.jpg", "GRC.zip/GRC/Fling.full.jpg"); - copyUrlToImage.put("grc/51.jpg", "GRC.zip/GRC/Sylvan Ranger.full.jpg"); - copyUrlToImage.put("grc/59.jpg", "GRC.zip/GRC/Plague Stinger.full.jpg"); - copyUrlToImage.put("grc/6.jpg", "GRC.zip/GRC/Reckless Wurm.full.jpg"); - copyUrlToImage.put("grc/60.jpg", "GRC.zip/GRC/Golem's Heart.full.jpg"); - copyUrlToImage.put("grc/63.jpg", "GRC.zip/GRC/Skinrender.full.jpg"); - copyUrlToImage.put("grc/64.jpg", "GRC.zip/GRC/Master's Call.full.jpg"); - copyUrlToImage.put("grc/65.jpg", "GRC.zip/GRC/Plague Myr.full.jpg"); - copyUrlToImage.put("grc/66.jpg", "GRC.zip/GRC/Signal Pest.full.jpg"); - copyUrlToImage.put("grc/69.jpg", "GRC.zip/GRC/Fling.full.jpg"); - copyUrlToImage.put("grc/7.jpg", "GRC.zip/GRC/Yixlid Jailer.full.jpg"); - copyUrlToImage.put("grc/70.jpg", "GRC.zip/GRC/Sylvan Ranger.full.jpg"); - copyUrlToImage.put("grc/71.jpg", "GRC.zip/GRC/Vault Skirge.full.jpg"); - copyUrlToImage.put("grc/72.jpg", "GRC.zip/GRC/Maul Splicer.full.jpg"); - copyUrlToImage.put("grc/73.jpg", "GRC.zip/GRC/Shrine of Burning Rage.full.jpg"); - copyUrlToImage.put("grc/76.jpg", "GRC.zip/GRC/Tormented Soul.full.jpg"); - copyUrlToImage.put("grc/77.jpg", "GRC.zip/GRC/Auramancer.full.jpg"); - copyUrlToImage.put("grc/78.jpg", "GRC.zip/GRC/Circle of Flame.full.jpg"); - copyUrlToImage.put("grc/79.jpg", "GRC.zip/GRC/Gather the Townsfolk.full.jpg"); - copyUrlToImage.put("grc/8.jpg", "GRC.zip/GRC/Zoetic Cavern.full.jpg"); - copyUrlToImage.put("grc/80.jpg", "GRC.zip/GRC/Curse of the Bloody Tome.full.jpg"); - copyUrlToImage.put("grc/81.jpg", "GRC.zip/GRC/Curse of Thirst.full.jpg"); - copyUrlToImage.put("grc/82.jpg", "GRC.zip/GRC/Nearheath Stalker.full.jpg"); - copyUrlToImage.put("grc/83.jpg", "GRC.zip/GRC/Bloodcrazed Neonate.full.jpg"); - copyUrlToImage.put("grc/84.jpg", "GRC.zip/GRC/Boneyard Wurm.full.jpg"); - copyUrlToImage.put("grc/9.jpg", "GRC.zip/GRC/Llanowar Elves.full.jpg"); - copyUrlToImage.put("jr/1.jpg", "JP.zip/JP/Lightning Bolt.full.jpg"); - copyUrlToImage.put("jr/10.jpg", "JP.zip/JP/Tradewind Rider.full.jpg"); - copyUrlToImage.put("jr/100.jpg", "JP.zip/JP/Feldon of the Third Path.full.jpg"); - copyUrlToImage.put("jr/101.jpg", "JP.zip/JP/Wasteland.full.jpg"); - copyUrlToImage.put("jr/103.jpg", "JP.zip/JP/Mana Drain.full.jpg"); - copyUrlToImage.put("jr/105.jpg", "JP.zip/JP/Command Beacon.full.jpg"); - copyUrlToImage.put("jr/11.jpg", "JP.zip/JP/Intuition.full.jpg"); - copyUrlToImage.put("jr/12.jpg", "JP.zip/JP/Argothian Enchantress.full.jpg"); - copyUrlToImage.put("jr/13.jpg", "JP.zip/JP/Living Death.full.jpg"); - copyUrlToImage.put("jr/14.jpg", "JP.zip/JP/Armageddon.full.jpg"); - copyUrlToImage.put("jr/15.jpg", "JP.zip/JP/Balance.full.jpg"); - copyUrlToImage.put("jr/16.jpg", "JP.zip/JP/Time Warp.full.jpg"); - copyUrlToImage.put("jr/17.jpg", "JP.zip/JP/Phyrexian Negator.full.jpg"); - copyUrlToImage.put("jr/18.jpg", "JP.zip/JP/Deranged Hermit.full.jpg"); - copyUrlToImage.put("jr/19.jpg", "JP.zip/JP/Hermit Druid.full.jpg"); - copyUrlToImage.put("jr/2.jpg", "JP.zip/JP/Stroke of Genius.full.jpg"); - copyUrlToImage.put("jr/20.jpg", "JP.zip/JP/Gemstone Mine.full.jpg"); - copyUrlToImage.put("jr/21.jpg", "JP.zip/JP/Regrowth.full.jpg"); - copyUrlToImage.put("jr/22.jpg", "JP.zip/JP/Sol Ring.full.jpg"); - copyUrlToImage.put("jr/23.jpg", "JP.zip/JP/Mishra's Factory.full.jpg"); - copyUrlToImage.put("jr/24.jpg", "JP.zip/JP/Exalted Angel.full.jpg"); - copyUrlToImage.put("jr/25.jpg", "JP.zip/JP/Grim Lavamancer.full.jpg"); - copyUrlToImage.put("jr/26.jpg", "JP.zip/JP/Meddling Mage.full.jpg"); - copyUrlToImage.put("jr/27.jpg", "JP.zip/JP/Pernicious Deed.full.jpg"); - copyUrlToImage.put("jr/28.jpg", "JP.zip/JP/Ravenous Baloth.full.jpg"); - copyUrlToImage.put("jr/29.jpg", "JP.zip/JP/Cunning Wish.full.jpg"); - copyUrlToImage.put("jr/3.jpg", "JP.zip/JP/Gaea's Cradle.full.jpg"); - copyUrlToImage.put("jr/30.jpg", "JP.zip/JP/Yawgmoth's Will.full.jpg"); - copyUrlToImage.put("jr/31.jpg", "JP.zip/JP/Vindicate.full.jpg"); - copyUrlToImage.put("jr/32.jpg", "JP.zip/JP/Decree of Justice.full.jpg"); - copyUrlToImage.put("jr/33.jpg", "JP.zip/JP/Orim's Chant.full.jpg"); - copyUrlToImage.put("jr/34.jpg", "JP.zip/JP/Mind's Desire.full.jpg"); - copyUrlToImage.put("jr/35.jpg", "JP.zip/JP/Demonic Tutor.full.jpg"); - copyUrlToImage.put("jr/36.jpg", "JP.zip/JP/Goblin Piledriver.full.jpg"); - copyUrlToImage.put("jr/37.jpg", "JP.zip/JP/Living Wish.full.jpg"); - copyUrlToImage.put("jr/38.jpg", "JP.zip/JP/Dark Ritual.full.jpg"); - copyUrlToImage.put("jr/39.jpg", "JP.zip/JP/Maze of Ith.full.jpg"); - copyUrlToImage.put("jr/4.jpg", "JP.zip/JP/Memory Lapse.full.jpg"); - copyUrlToImage.put("jr/40.jpg", "JP.zip/JP/Stifle.full.jpg"); - copyUrlToImage.put("jr/41.jpg", "JP.zip/JP/Survival of the Fittest.full.jpg"); - copyUrlToImage.put("jr/42.jpg", "JP.zip/JP/Burning Wish.full.jpg"); - copyUrlToImage.put("jr/43.jpg", "JP.zip/JP/Bloodstained Mire.full.jpg"); - copyUrlToImage.put("jr/44.jpg", "JP.zip/JP/Flooded Strand.full.jpg"); - copyUrlToImage.put("jr/45.jpg", "JP.zip/JP/Polluted Delta.full.jpg"); - copyUrlToImage.put("jr/46.jpg", "JP.zip/JP/Windswept Heath.full.jpg"); - copyUrlToImage.put("jr/47.jpg", "JP.zip/JP/Wooded Foothills.full.jpg"); - copyUrlToImage.put("jr/48.jpg", "JP.zip/JP/Sinkhole.full.jpg"); - copyUrlToImage.put("jr/49.jpg", "JP.zip/JP/Natural Order.full.jpg"); - copyUrlToImage.put("jr/5.jpg", "JP.zip/JP/Counterspell.full.jpg"); - copyUrlToImage.put("jr/50.jpg", "JP.zip/JP/Phyrexian Dreadnought.full.jpg"); - copyUrlToImage.put("jr/51.jpg", "JP.zip/JP/Thawing Glaciers.full.jpg"); - copyUrlToImage.put("jr/52.jpg", "JP.zip/JP/Land Tax.full.jpg"); - copyUrlToImage.put("jr/53.jpg", "JP.zip/JP/Morphling.full.jpg"); - copyUrlToImage.put("jr/54.jpg", "JP.zip/JP/Wheel of Fortune.full.jpg"); - copyUrlToImage.put("jr/55.jpg", "JP.zip/JP/Wasteland.full.jpg"); - copyUrlToImage.put("jr/56.jpg", "JP.zip/JP/Entomb.full.jpg"); - copyUrlToImage.put("jr/57.jpg", "JP.zip/JP/Sword of Fire and Ice.full.jpg"); - copyUrlToImage.put("jr/58.jpg", "JP.zip/JP/Vendilion Clique.full.jpg"); - copyUrlToImage.put("jr/59.jpg", "JP.zip/JP/Bitterblossom.full.jpg"); - copyUrlToImage.put("jr/6.jpg", "JP.zip/JP/Vampiric Tutor.full.jpg"); - copyUrlToImage.put("jr/60.jpg", "JP.zip/JP/Mana Crypt.full.jpg"); - copyUrlToImage.put("jr/61.jpg", "JP.zip/JP/Dark Confidant.full.jpg"); - copyUrlToImage.put("jr/62.jpg", "JP.zip/JP/Doubling Season.full.jpg"); - copyUrlToImage.put("jr/63.jpg", "JP.zip/JP/Goblin Welder.full.jpg"); - copyUrlToImage.put("jr/64.jpg", "JP.zip/JP/Xiahou Dun, the One-Eyed.full.jpg"); - copyUrlToImage.put("jr/65.jpg", "JP.zip/JP/Flusterstorm.full.jpg"); - copyUrlToImage.put("jr/66.jpg", "JP.zip/JP/Noble Hierarch.full.jpg"); - copyUrlToImage.put("jr/67.jpg", "JP.zip/JP/Karmic Guide.full.jpg"); - copyUrlToImage.put("jr/68.jpg", "JP.zip/JP/Sneak Attack.full.jpg"); - copyUrlToImage.put("jr/69.jpg", "JP.zip/JP/Karakas.full.jpg"); - copyUrlToImage.put("jr/7.jpg", "JP.zip/JP/Ball Lightning.full.jpg"); - copyUrlToImage.put("jr/70.jpg", "JP.zip/JP/Sword of Light and Shadow.full.jpg"); - copyUrlToImage.put("jr/71.jpg", "JP.zip/JP/Command Tower.full.jpg"); - copyUrlToImage.put("jr/72.jpg", "JP.zip/JP/Swords to Plowshares.full.jpg"); - copyUrlToImage.put("jr/73.jpg", "JP.zip/JP/Bribery.full.jpg"); - copyUrlToImage.put("jr/74.jpg", "JP.zip/JP/Imperial Recruiter.full.jpg"); - copyUrlToImage.put("jr/75.jpg", "JP.zip/JP/Crucible of Worlds.full.jpg"); - copyUrlToImage.put("jr/76.jpg", "JP.zip/JP/Overwhelming Forces.full.jpg"); - copyUrlToImage.put("jr/77.jpg", "JP.zip/JP/Show and Tell.full.jpg"); - copyUrlToImage.put("jr/78.jpg", "JP.zip/JP/Vindicate.full.jpg"); - copyUrlToImage.put("jr/79.jpg", "JP.zip/JP/Genesis.full.jpg"); - copyUrlToImage.put("jr/8.jpg", "JP.zip/JP/Oath of Druids.full.jpg"); - copyUrlToImage.put("jr/80.jpg", "JP.zip/JP/Karador, Ghost Chieftain.full.jpg"); - copyUrlToImage.put("jr/81.jpg", "JP.zip/JP/Greater Good.full.jpg"); - copyUrlToImage.put("jr/82.jpg", "JP.zip/JP/Riku of Two Reflections.full.jpg"); - copyUrlToImage.put("jr/83.jpg", "JP.zip/JP/Force of Will.full.jpg"); - copyUrlToImage.put("jr/84.jpg", "JP.zip/JP/Hanna, Ship's Navigator.full.jpg"); - copyUrlToImage.put("jr/85.jpg", "JP.zip/JP/Sword of Feast and Famine.full.jpg"); - copyUrlToImage.put("jr/86.jpg", "JP.zip/JP/Nekusar, the Mindrazer.full.jpg"); - copyUrlToImage.put("jr/87.jpg", "JP.zip/JP/Elesh Norn, Grand Cenobite.full.jpg"); - copyUrlToImage.put("jr/88.jpg", "JP.zip/JP/Oloro, Ageless Ascetic.full.jpg"); - copyUrlToImage.put("jr/89.jpg", "JP.zip/JP/Plains.full.jpg"); - copyUrlToImage.put("jr/9.jpg", "JP.zip/JP/Hammer of Bogardan.full.jpg"); - copyUrlToImage.put("jr/90.jpg", "JP.zip/JP/Island.full.jpg"); - copyUrlToImage.put("jr/91.jpg", "JP.zip/JP/Swamp.full.jpg"); - copyUrlToImage.put("jr/92.jpg", "JP.zip/JP/Mountain.full.jpg"); - copyUrlToImage.put("jr/93.jpg", "JP.zip/JP/Forest.full.jpg"); - copyUrlToImage.put("jr/97.jpg", "JP.zip/JP/Ravages of War.full.jpg"); - copyUrlToImage.put("jr/98.jpg", "JP.zip/JP/Damnation.full.jpg"); - copyUrlToImage.put("jr/99.jpg", "JP.zip/JP/Dualcaster Mage.full.jpg"); - copyUrlToImage.put("mbp/1.jpg", "MBP.zip/MBP/Arena.full.jpg"); - copyUrlToImage.put("mbp/10.jpg", "MBP.zip/MBP/Lightning Hounds.full.jpg"); - copyUrlToImage.put("mbp/100.jpg", "MBP.zip/MBP/Jace, the Living Guildpact.full.jpg"); - copyUrlToImage.put("mbp/101.jpg", "MBP.zip/MBP/Liliana Vess.full.jpg"); - copyUrlToImage.put("mbp/102.jpg", "MBP.zip/MBP/Chandra, Pyromaster.full.jpg"); - copyUrlToImage.put("mbp/103.jpg", "MBP.zip/MBP/Nissa, Worldwaker.full.jpg"); - copyUrlToImage.put("mbp/104.jpg", "MBP.zip/MBP/Garruk, Apex Predator.full.jpg"); - copyUrlToImage.put("mbp/105.jpg", "MBP.zip/MBP/Shamanic Revelation.full.jpg"); - copyUrlToImage.put("mbp/106.jpg", "MBP.zip/MBP/Ojutai's Command.full.jpg"); - copyUrlToImage.put("mbp/107.jpg", "MBP.zip/MBP/Dragonscale General.full.jpg"); - copyUrlToImage.put("mbp/108.jpg", "MBP.zip/MBP/Sage-Eye Avengers.full.jpg"); - copyUrlToImage.put("mbp/109.jpg", "MBP.zip/MBP/Archfiend of Depravity.full.jpg"); - copyUrlToImage.put("mbp/11.jpg", "MBP.zip/MBP/Spined Wurm.full.jpg"); - copyUrlToImage.put("mbp/110.jpg", "MBP.zip/MBP/Flamerush Rider.full.jpg"); - copyUrlToImage.put("mbp/111.jpg", "MBP.zip/MBP/Temur War Shaman.full.jpg"); - copyUrlToImage.put("mbp/112.jpg", "MBP.zip/MBP/Arashin Sovereign.full.jpg"); - copyUrlToImage.put("mbp/113.jpg", "MBP.zip/MBP/Pristine Skywise.full.jpg"); - copyUrlToImage.put("mbp/114.jpg", "MBP.zip/MBP/Necromaster Dragon.full.jpg"); - copyUrlToImage.put("mbp/115.jpg", "MBP.zip/MBP/Boltwing Marauder.full.jpg"); - copyUrlToImage.put("mbp/116.jpg", "MBP.zip/MBP/Harbinger of the Hunt.full.jpg"); - copyUrlToImage.put("mbp/117.jpg", "MBP.zip/MBP/Sultai Charm.full.jpg"); - copyUrlToImage.put("mbp/118.jpg", "MBP.zip/MBP/Aeronaut Tinkerer.full.jpg"); - copyUrlToImage.put("mbp/119.jpg", "MBP.zip/MBP/Dragon Fodder.full.jpg"); - copyUrlToImage.put("mbp/12.jpg", "MBP.zip/MBP/Warmonger.full.jpg"); - copyUrlToImage.put("mbp/120.jpg", "MBP.zip/MBP/Dragonlord's Servant.full.jpg"); - copyUrlToImage.put("mbp/121.jpg", "MBP.zip/MBP/Evolving Wilds.full.jpg"); - copyUrlToImage.put("mbp/122.jpg", "MBP.zip/MBP/Foe-Razer Regent.full.jpg"); - copyUrlToImage.put("mbp/123.jpg", "MBP.zip/MBP/Relic Seeker.full.jpg"); - copyUrlToImage.put("mbp/124.jpg", "MBP.zip/MBP/Alhammarret, High Arbiter.full.jpg"); - copyUrlToImage.put("mbp/125.jpg", "MBP.zip/MBP/Dwynen, Gilt-Leaf Daen.full.jpg"); - copyUrlToImage.put("mbp/126.jpg", "MBP.zip/MBP/Hixus, Prison Warden.full.jpg"); - copyUrlToImage.put("mbp/127.jpg", "MBP.zip/MBP/Kothophed, Soul Hoarder.full.jpg"); - copyUrlToImage.put("mbp/128.jpg", "MBP.zip/MBP/Pia and Kiran Nalaar.full.jpg"); - copyUrlToImage.put("mbp/129.jpg", "MBP.zip/MBP/Honored Hierarch.full.jpg"); - copyUrlToImage.put("mbp/13.jpg", "MBP.zip/MBP/Silver Drake.full.jpg"); - copyUrlToImage.put("mbp/130.jpg", "MBP.zip/MBP/Seeker of the Way.full.jpg"); - copyUrlToImage.put("mbp/131.jpg", "MBP.zip/MBP/Valorous Stance.full.jpg"); - copyUrlToImage.put("mbp/132.jpg", "MBP.zip/MBP/Dromoka, the Eternal.full.jpg"); - copyUrlToImage.put("mbp/133.jpg", "MBP.zip/MBP/Siege Rhino.full.jpg"); - copyUrlToImage.put("mbp/134.jpg", "MBP.zip/MBP/Sandsteppe Citadel.full.jpg"); - copyUrlToImage.put("mbp/135.jpg", "MBP.zip/MBP/Ruinous Path.full.jpg"); - copyUrlToImage.put("mbp/136.jpg", "MBP.zip/MBP/Hero of Goma Fada.full.jpg"); - copyUrlToImage.put("mbp/137.jpg", "MBP.zip/MBP/Drowner of Hope.full.jpg"); - copyUrlToImage.put("mbp/138.jpg", "MBP.zip/MBP/Defiant Bloodlord.full.jpg"); - copyUrlToImage.put("mbp/139.jpg", "MBP.zip/MBP/Barrage Tyrant.full.jpg"); - copyUrlToImage.put("mbp/14.jpg", "MBP.zip/MBP/Phyrexian Rager.full.jpg"); - copyUrlToImage.put("mbp/140.jpg", "MBP.zip/MBP/Oran-Rief Hydra.full.jpg"); - copyUrlToImage.put("mbp/141.jpg", "MBP.zip/MBP/Scythe Leopard.full.jpg"); - copyUrlToImage.put("mbp/142.jpg", "MBP.zip/MBP/Genesis Hydra.full.jpg"); - copyUrlToImage.put("mbp/143.jpg", "MBP.zip/MBP/Munda's Vanguard.full.jpg"); - copyUrlToImage.put("mbp/144.jpg", "MBP.zip/MBP/Deepfathom Skulker.full.jpg"); - copyUrlToImage.put("mbp/145.jpg", "MBP.zip/MBP/Dread Defiler.full.jpg"); - copyUrlToImage.put("mbp/146.jpg", "MBP.zip/MBP/Tyrant of Valakut.full.jpg"); - copyUrlToImage.put("mbp/147.jpg", "MBP.zip/MBP/Gladehart Cavalry.full.jpg"); - copyUrlToImage.put("mbp/148.jpg", "MBP.zip/MBP/Goblin Dark-Dwellers.full.jpg"); - copyUrlToImage.put("mbp/15.jpg", "MBP.zip/MBP/Jace Beleren.full.jpg"); - copyUrlToImage.put("mbp/16.jpg", "MBP.zip/MBP/Garruk Wildspeaker.full.jpg"); - copyUrlToImage.put("mbp/17.jpg", "MBP.zip/MBP/Brion Stoutarm.full.jpg"); - copyUrlToImage.put("mbp/18.jpg", "MBP.zip/MBP/Jaya Ballard, Task Mage.full.jpg"); - copyUrlToImage.put("mbp/19.jpg", "MBP.zip/MBP/Broodmate Dragon.full.jpg"); - copyUrlToImage.put("mbp/2.jpg", "MBP.zip/MBP/Sewers of Estark.full.jpg"); - copyUrlToImage.put("mbp/20.jpg", "MBP.zip/MBP/Honor of the Pure.full.jpg"); - copyUrlToImage.put("mbp/21.jpg", "MBP.zip/MBP/Steward of Valeron.full.jpg"); - copyUrlToImage.put("mbp/22.jpg", "MBP.zip/MBP/Day of Judgment.full.jpg"); - copyUrlToImage.put("mbp/23.jpg", "MBP.zip/MBP/Celestial Colonnade.full.jpg"); - copyUrlToImage.put("mbp/24.jpg", "MBP.zip/MBP/Retaliator Griffin.full.jpg"); - copyUrlToImage.put("mbp/25.jpg", "MBP.zip/MBP/Kor Skyfisher.full.jpg"); - copyUrlToImage.put("mbp/26.jpg", "MBP.zip/MBP/Guul Draz Assassin.full.jpg"); - copyUrlToImage.put("mbp/27.jpg", "MBP.zip/MBP/Nissa Revane.full.jpg"); - copyUrlToImage.put("mbp/28.jpg", "MBP.zip/MBP/Birds of Paradise.full.jpg"); - copyUrlToImage.put("mbp/29.jpg", "MBP.zip/MBP/Memoricide.full.jpg"); - copyUrlToImage.put("mbp/3.jpg", "MBP.zip/MBP/Nalathni Dragon.full.jpg"); - copyUrlToImage.put("mbp/30.jpg", "MBP.zip/MBP/Liliana Vess.full.jpg"); - copyUrlToImage.put("mbp/31.jpg", "MBP.zip/MBP/Bloodthrone Vampire.full.jpg"); - copyUrlToImage.put("mbp/32.jpg", "MBP.zip/MBP/Mirran Crusader.full.jpg"); - copyUrlToImage.put("mbp/33.jpg", "MBP.zip/MBP/Surgical Extraction.full.jpg"); - copyUrlToImage.put("mbp/34.jpg", "MBP.zip/MBP/Frost Titan.full.jpg"); - copyUrlToImage.put("mbp/35.jpg", "MBP.zip/MBP/Grave Titan.full.jpg"); - copyUrlToImage.put("mbp/36.jpg", "MBP.zip/MBP/Inferno Titan.full.jpg"); - copyUrlToImage.put("mbp/37.jpg", "MBP.zip/MBP/Chandra's Phoenix.full.jpg"); - copyUrlToImage.put("mbp/38.jpg", "MBP.zip/MBP/Treasure Hunt.full.jpg"); - copyUrlToImage.put("mbp/39.jpg", "MBP.zip/MBP/Faithless Looting.full.jpg"); - copyUrlToImage.put("mbp/4.jpg", "MBP.zip/MBP/Fireball.full.jpg"); - copyUrlToImage.put("mbp/40.jpg", "MBP.zip/MBP/Devil's Play.full.jpg"); - copyUrlToImage.put("mbp/41.jpg", "MBP.zip/MBP/Gravecrawler.full.jpg"); - copyUrlToImage.put("mbp/42.jpg", "MBP.zip/MBP/Electrolyze.full.jpg"); - copyUrlToImage.put("mbp/43.jpg", "MBP.zip/MBP/Feast of Blood.full.jpg"); - copyUrlToImage.put("mbp/44.jpg", "MBP.zip/MBP/Silverblade Paladin.full.jpg"); - copyUrlToImage.put("mbp/45.jpg", "MBP.zip/MBP/Merfolk Mesmerist.full.jpg"); - copyUrlToImage.put("mbp/46.jpg", "MBP.zip/MBP/Knight Exemplar.full.jpg"); - copyUrlToImage.put("mbp/47.jpg", "MBP.zip/MBP/Sunblast Angel.full.jpg"); - copyUrlToImage.put("mbp/48.jpg", "MBP.zip/MBP/Serra Avatar.full.jpg"); - copyUrlToImage.put("mbp/49.jpg", "MBP.zip/MBP/Primordial Hydra.full.jpg"); - copyUrlToImage.put("mbp/5.jpg", "MBP.zip/MBP/Blue Elemental Blast.full.jpg"); - copyUrlToImage.put("mbp/50.jpg", "MBP.zip/MBP/Vampire Nocturnus.full.jpg"); - copyUrlToImage.put("mbp/51.jpg", "MBP.zip/MBP/Cathedral of War.full.jpg"); - copyUrlToImage.put("mbp/52.jpg", "MBP.zip/MBP/Terastodon.full.jpg"); - copyUrlToImage.put("mbp/53.jpg", "MBP.zip/MBP/Arrest.full.jpg"); - copyUrlToImage.put("mbp/54.jpg", "MBP.zip/MBP/Consume Spirit.full.jpg"); - copyUrlToImage.put("mbp/55.jpg", "MBP.zip/MBP/Dreg Mangler.full.jpg"); - copyUrlToImage.put("mbp/56.jpg", "MBP.zip/MBP/Supreme Verdict.full.jpg"); - copyUrlToImage.put("mbp/57.jpg", "MBP.zip/MBP/Standstill.full.jpg"); - copyUrlToImage.put("mbp/58.jpg", "MBP.zip/MBP/Breath of Malfegor.full.jpg"); - copyUrlToImage.put("mbp/59.jpg", "MBP.zip/MBP/Angel of Glory's Rise.full.jpg"); - copyUrlToImage.put("mbp/6.jpg", "MBP.zip/MBP/Mana Crypt.full.jpg"); - copyUrlToImage.put("mbp/60.jpg", "MBP.zip/MBP/Turnabout.full.jpg"); - copyUrlToImage.put("mbp/61.jpg", "MBP.zip/MBP/Nightveil Specter.full.jpg"); - copyUrlToImage.put("mbp/62.jpg", "MBP.zip/MBP/Voidmage Husher.full.jpg"); - copyUrlToImage.put("mbp/63.jpg", "MBP.zip/MBP/Ogre Arsonist.full.jpg"); - copyUrlToImage.put("mbp/64.jpg", "MBP.zip/MBP/Corrupt.full.jpg"); - copyUrlToImage.put("mbp/65.jpg", "MBP.zip/MBP/Chandra's Fury.full.jpg"); - copyUrlToImage.put("mbp/66.jpg", "MBP.zip/MBP/Render Silent.full.jpg"); - copyUrlToImage.put("mbp/67.jpg", "MBP.zip/MBP/Ratchet Bomb.full.jpg"); - copyUrlToImage.put("mbp/68.jpg", "MBP.zip/MBP/Bonescythe Sliver.full.jpg"); - copyUrlToImage.put("mbp/69.jpg", "MBP.zip/MBP/Ogre Battledriver.full.jpg"); - copyUrlToImage.put("mbp/7.jpg", "MBP.zip/MBP/Windseeker Centaur.full.jpg"); - copyUrlToImage.put("mbp/70.jpg", "MBP.zip/MBP/Scavenging Ooze.full.jpg"); - copyUrlToImage.put("mbp/71.jpg", "MBP.zip/MBP/Hamletback Goliath.full.jpg"); - copyUrlToImage.put("mbp/72.jpg", "MBP.zip/MBP/Ajani, Caller of the Pride.full.jpg"); - copyUrlToImage.put("mbp/73.jpg", "MBP.zip/MBP/Jace, Memory Adept.full.jpg"); - copyUrlToImage.put("mbp/74.jpg", "MBP.zip/MBP/Liliana of the Dark Realms.full.jpg"); - copyUrlToImage.put("mbp/75.jpg", "MBP.zip/MBP/Chandra, Pyromaster.full.jpg"); - copyUrlToImage.put("mbp/76.jpg", "MBP.zip/MBP/Garruk, Caller of Beasts.full.jpg"); - copyUrlToImage.put("mbp/77.jpg", "MBP.zip/MBP/Sylvan Caryatid.full.jpg"); - copyUrlToImage.put("mbp/78.jpg", "MBP.zip/MBP/Karametra's Acolyte.full.jpg"); - copyUrlToImage.put("mbp/79.jpg", "MBP.zip/MBP/Fated Conflagration.full.jpg"); - copyUrlToImage.put("mbp/8.jpg", "MBP.zip/MBP/Giant Badger.full.jpg"); - copyUrlToImage.put("mbp/80.jpg", "MBP.zip/MBP/High Tide.full.jpg"); - copyUrlToImage.put("mbp/81.jpg", "MBP.zip/MBP/Gaze of Granite.full.jpg"); - copyUrlToImage.put("mbp/82.jpg", "MBP.zip/MBP/Wash Out.full.jpg"); - copyUrlToImage.put("mbp/83.jpg", "MBP.zip/MBP/Acquire.full.jpg"); - copyUrlToImage.put("mbp/84.jpg", "MBP.zip/MBP/Duress.full.jpg"); - copyUrlToImage.put("mbp/85.jpg", "MBP.zip/MBP/Eidolon of Blossoms.full.jpg"); - copyUrlToImage.put("mbp/86.jpg", "MBP.zip/MBP/Magister of Worth.full.jpg"); - copyUrlToImage.put("mbp/87.jpg", "MBP.zip/MBP/Soul of Ravnica.full.jpg"); - copyUrlToImage.put("mbp/88.jpg", "MBP.zip/MBP/Soul of Zendikar.full.jpg"); - copyUrlToImage.put("mbp/89.jpg", "MBP.zip/MBP/Stealer of Secrets.full.jpg"); - copyUrlToImage.put("mbp/9.jpg", "MBP.zip/MBP/Scent of Cinder.full.jpg"); - copyUrlToImage.put("mbp/90.jpg", "MBP.zip/MBP/Angelic Skirmisher.full.jpg"); - copyUrlToImage.put("mbp/91.jpg", "MBP.zip/MBP/Xathrid Necromancer.full.jpg"); - copyUrlToImage.put("mbp/92.jpg", "MBP.zip/MBP/Rattleclaw Mystic.full.jpg"); - copyUrlToImage.put("mbp/93.jpg", "MBP.zip/MBP/Ankle Shanker.full.jpg"); - copyUrlToImage.put("mbp/94.jpg", "MBP.zip/MBP/Avalanche Tusker.full.jpg"); - copyUrlToImage.put("mbp/95.jpg", "MBP.zip/MBP/Ivorytusk Fortress.full.jpg"); - copyUrlToImage.put("mbp/96.jpg", "MBP.zip/MBP/Rakshasa Vizier.full.jpg"); - copyUrlToImage.put("mbp/97.jpg", "MBP.zip/MBP/Sage of the Inward Eye.full.jpg"); - copyUrlToImage.put("mbp/98.jpg", "MBP.zip/MBP/Goblin Rabblemaster.full.jpg"); - copyUrlToImage.put("mbp/99.jpg", "MBP.zip/MBP/Ajani Steadfast.full.jpg"); - copyUrlToImage.put("mgdc/1.jpg", "MGDC.zip/MGDC/Reya Dawnbringer.full.jpg"); - copyUrlToImage.put("mgdc/10.jpg", "MGDC.zip/MGDC/Stormblood Berserker.full.jpg"); - copyUrlToImage.put("mgdc/11.jpg", "MGDC.zip/MGDC/Dungrove Elder.full.jpg"); - copyUrlToImage.put("mgdc/12.jpg", "MGDC.zip/MGDC/Diregraf Ghoul.full.jpg"); - copyUrlToImage.put("mgdc/13.jpg", "MGDC.zip/MGDC/Elite Inquisitor.full.jpg"); - copyUrlToImage.put("mgdc/14.jpg", "MGDC.zip/MGDC/Zombie Apocalypse.full.jpg"); - copyUrlToImage.put("mgdc/15.jpg", "MGDC.zip/MGDC/Strangleroot Geist.full.jpg"); - copyUrlToImage.put("mgdc/16.jpg", "MGDC.zip/MGDC/Suture Priest.full.jpg"); - copyUrlToImage.put("mgdc/17.jpg", "MGDC.zip/MGDC/Pristine Talisman.full.jpg"); - copyUrlToImage.put("mgdc/18.jpg", "MGDC.zip/MGDC/Latch Seeker.full.jpg"); - copyUrlToImage.put("mgdc/19.jpg", "MGDC.zip/MGDC/Killing Wave.full.jpg"); - copyUrlToImage.put("mgdc/2.jpg", "MGDC.zip/MGDC/Liliana's Specter.full.jpg"); - copyUrlToImage.put("mgdc/20.jpg", "MGDC.zip/MGDC/Magmaquake.full.jpg"); - copyUrlToImage.put("mgdc/21.jpg", "MGDC.zip/MGDC/Mwonvuli Beast Tracker.full.jpg"); - copyUrlToImage.put("mgdc/22.jpg", "MGDC.zip/MGDC/Cryptborn Horror.full.jpg"); - copyUrlToImage.put("mgdc/23.jpg", "MGDC.zip/MGDC/Dryad Militant.full.jpg"); - copyUrlToImage.put("mgdc/24.jpg", "MGDC.zip/MGDC/Firemane Avenger.full.jpg"); - copyUrlToImage.put("mgdc/25.jpg", "MGDC.zip/MGDC/Zameck Guildmage.full.jpg"); - copyUrlToImage.put("mgdc/26.jpg", "MGDC.zip/MGDC/Melek, Izzet Paragon.full.jpg"); - copyUrlToImage.put("mgdc/27.jpg", "MGDC.zip/MGDC/Trostani's Summoner.full.jpg"); - copyUrlToImage.put("mgdc/28.jpg", "MGDC.zip/MGDC/Hive Stirrings.full.jpg"); - copyUrlToImage.put("mgdc/29.jpg", "MGDC.zip/MGDC/Goblin Diplomats.full.jpg"); - copyUrlToImage.put("mgdc/3.jpg", "MGDC.zip/MGDC/Mitotic Slime.full.jpg"); - copyUrlToImage.put("mgdc/30.jpg", "MGDC.zip/MGDC/Phalanx Leader.full.jpg"); - copyUrlToImage.put("mgdc/31.jpg", "MGDC.zip/MGDC/Nighthowler.full.jpg"); - copyUrlToImage.put("mgdc/32.jpg", "MGDC.zip/MGDC/Pain Seer.full.jpg"); - copyUrlToImage.put("mgdc/33.jpg", "MGDC.zip/MGDC/Kiora's Follower.full.jpg"); - copyUrlToImage.put("mgdc/34.jpg", "MGDC.zip/MGDC/Squelching Leeches.full.jpg"); - copyUrlToImage.put("mgdc/35.jpg", "MGDC.zip/MGDC/Dictate of Kruphix.full.jpg"); - copyUrlToImage.put("mgdc/36.jpg", "MGDC.zip/MGDC/Hall of Triumph.full.jpg"); - copyUrlToImage.put("mgdc/37.jpg", "MGDC.zip/MGDC/Heir of the Wilds.full.jpg"); - copyUrlToImage.put("mgdc/38.jpg", "MGDC.zip/MGDC/Utter End.full.jpg"); - copyUrlToImage.put("mgdc/39.jpg", "MGDC.zip/MGDC/Reclamation Sage.full.jpg"); - copyUrlToImage.put("mgdc/4.jpg", "MGDC.zip/MGDC/Memnite.full.jpg"); - copyUrlToImage.put("mgdc/40.jpg", "MGDC.zip/MGDC/Chief Engineer.full.jpg"); - copyUrlToImage.put("mgdc/41.jpg", "MGDC.zip/MGDC/Mardu Shadowspear.full.jpg"); - copyUrlToImage.put("mgdc/42.jpg", "MGDC.zip/MGDC/Supplant Form.full.jpg"); - copyUrlToImage.put("mgdc/43.jpg", "MGDC.zip/MGDC/Thunderbreak Regent.full.jpg"); - copyUrlToImage.put("mgdc/44.jpg", "MGDC.zip/MGDC/Scaleguard Sentinels.full.jpg"); - copyUrlToImage.put("mgdc/45.jpg", "MGDC.zip/MGDC/Conclave Naturalists.full.jpg"); - copyUrlToImage.put("mgdc/46.jpg", "MGDC.zip/MGDC/Languish.full.jpg"); - copyUrlToImage.put("mgdc/47.jpg", "MGDC.zip/MGDC/Stasis Snare.full.jpg"); - copyUrlToImage.put("mgdc/48.jpg", "MGDC.zip/MGDC/Radiant Flames.full.jpg"); - copyUrlToImage.put("mgdc/49.jpg", "MGDC.zip/MGDC/Immolating Glare.full.jpg"); - copyUrlToImage.put("mgdc/5.jpg", "MGDC.zip/MGDC/Tempered Steel.full.jpg"); - copyUrlToImage.put("mgdc/50.jpg", "MGDC.zip/MGDC/Jori En, Ruin Diver.full.jpg"); - copyUrlToImage.put("mgdc/6.jpg", "MGDC.zip/MGDC/Treasure Mage.full.jpg"); - copyUrlToImage.put("mgdc/7.jpg", "MGDC.zip/MGDC/Black Sun's Zenith.full.jpg"); - copyUrlToImage.put("mgdc/8.jpg", "MGDC.zip/MGDC/Myr Superion.full.jpg"); - copyUrlToImage.put("mgdc/9.jpg", "MGDC.zip/MGDC/Priest of Urabrask.full.jpg"); - copyUrlToImage.put("mlp/1.jpg", "MLP.zip/MLP/Earwig Squad.full.jpg"); - copyUrlToImage.put("mlp/10.jpg", "MLP.zip/MLP/Lord of Shatterskull Pass.full.jpg"); - copyUrlToImage.put("mlp/11.jpg", "MLP.zip/MLP/Ancient Hellkite.full.jpg"); - copyUrlToImage.put("mlp/12.jpg", "MLP.zip/MLP/Steel Hellkite.full.jpg"); - copyUrlToImage.put("mlp/13.jpg", "MLP.zip/MLP/Thopter Assembly.full.jpg"); - copyUrlToImage.put("mlp/14.jpg", "MLP.zip/MLP/Phyrexian Metamorph.full.jpg"); - copyUrlToImage.put("mlp/15.jpg", "MLP.zip/MLP/Garruk's Horde.full.jpg"); - copyUrlToImage.put("mlp/16a.jpg", "MLP.zip/MLP/Ludevic's Test Subject.full.jpg"); - copyUrlToImage.put("mlp/16b.jpg", "MLP.zip/MLP/Ludevic's Abomination.full.jpg"); - copyUrlToImage.put("mlp/17a.jpg", "MLP.zip/MLP/Mondronen Shaman.full.jpg"); - copyUrlToImage.put("mlp/17b.jpg", "MLP.zip/MLP/Tovolar's Magehunter.full.jpg"); - copyUrlToImage.put("mlp/18.jpg", "MLP.zip/MLP/Restoration Angel.full.jpg"); - copyUrlToImage.put("mlp/19.jpg", "MLP.zip/MLP/Staff of Nin.full.jpg"); - copyUrlToImage.put("mlp/2.jpg", "MLP.zip/MLP/Vexing Shusher.full.jpg"); - copyUrlToImage.put("mlp/20.jpg", "MLP.zip/MLP/Deadbridge Goliath.full.jpg"); - copyUrlToImage.put("mlp/21.jpg", "MLP.zip/MLP/Skarrg Goliath.full.jpg"); - copyUrlToImage.put("mlp/22a.jpg", "MLP.zip/MLP/Breaking (Breaking/Entering).full.jpg"); - copyUrlToImage.put("mlp/22b.jpg", "MLP.zip/MLP/Entering (Breaking/Entering).full.jpg"); - copyUrlToImage.put("mlp/23.jpg", "MLP.zip/MLP/Colossal Whale.full.jpg"); - copyUrlToImage.put("mlp/24.jpg", "MLP.zip/MLP/Bident of Thassa.full.jpg"); - copyUrlToImage.put("mlp/25.jpg", "MLP.zip/MLP/Tromokratis.full.jpg"); - copyUrlToImage.put("mlp/26.jpg", "MLP.zip/MLP/Dictate of the Twin Gods.full.jpg"); - copyUrlToImage.put("mlp/27.jpg", "MLP.zip/MLP/Dragone Throne of Tarkir.full.jpg"); - copyUrlToImage.put("mlp/28.jpg", "MLP.zip/MLP/In Garruk's Wake.full.jpg"); - copyUrlToImage.put("mlp/29.jpg", "MLP.zip/MLP/Sandsteppe Mastodon.full.jpg"); - copyUrlToImage.put("mlp/3.jpg", "MLP.zip/MLP/Figure of Destiny.full.jpg"); - copyUrlToImage.put("mlp/31.jpg", "MLP.zip/MLP/Deathbringer Regent.full.jpg"); - copyUrlToImage.put("mlp/32.jpg", "MLP.zip/MLP/Mizzium Meddler.full.jpg"); - copyUrlToImage.put("mlp/33.jpg", "MLP.zip/MLP/Blight Herder.full.jpg"); - copyUrlToImage.put("mlp/34.jpg", "MLP.zip/MLP/Endbringer.full.jpg"); - copyUrlToImage.put("mlp/4.jpg", "MLP.zip/MLP/Ajani Vengeant.full.jpg"); - copyUrlToImage.put("mlp/5.jpg", "MLP.zip/MLP/Obelisk of Alara.full.jpg"); - copyUrlToImage.put("mlp/6.jpg", "MLP.zip/MLP/Knight of New Alara.full.jpg"); - copyUrlToImage.put("mlp/7.jpg", "MLP.zip/MLP/Ant Queen.full.jpg"); - copyUrlToImage.put("mlp/8.jpg", "MLP.zip/MLP/Valakut, the Molten Pinnacle.full.jpg"); - copyUrlToImage.put("mlp/9.jpg", "MLP.zip/MLP/Joraga Warcaller.full.jpg"); - copyUrlToImage.put("mprp/1.jpg", "MPRP.zip/MPRP/Wasteland.full.jpg"); - copyUrlToImage.put("mprp/10.jpg", "MPRP.zip/MPRP/Hypnotic Specter.full.jpg"); - copyUrlToImage.put("mprp/11.jpg", "MPRP.zip/MPRP/Hinder.full.jpg"); - copyUrlToImage.put("mprp/12.jpg", "MPRP.zip/MPRP/Pyroclasm.full.jpg"); - copyUrlToImage.put("mprp/13.jpg", "MPRP.zip/MPRP/Giant Growth.full.jpg"); - copyUrlToImage.put("mprp/14.jpg", "MPRP.zip/MPRP/Putrefy.full.jpg"); - copyUrlToImage.put("mprp/15.jpg", "MPRP.zip/MPRP/Zombify.full.jpg"); - copyUrlToImage.put("mprp/16.jpg", "MPRP.zip/MPRP/Lightning Helix.full.jpg"); - copyUrlToImage.put("mprp/17.jpg", "MPRP.zip/MPRP/Wrath of God.full.jpg"); - copyUrlToImage.put("mprp/18.jpg", "MPRP.zip/MPRP/Condemn.full.jpg"); - copyUrlToImage.put("mprp/19.jpg", "MPRP.zip/MPRP/Mortify.full.jpg"); - copyUrlToImage.put("mprp/2.jpg", "MPRP.zip/MPRP/Voidmage Prodigy.full.jpg"); - copyUrlToImage.put("mprp/20.jpg", "MPRP.zip/MPRP/Psionic Blast.full.jpg"); - copyUrlToImage.put("mprp/21.jpg", "MPRP.zip/MPRP/Cruel Edict.full.jpg"); - copyUrlToImage.put("mprp/22.jpg", "MPRP.zip/MPRP/Disenchant.full.jpg"); - copyUrlToImage.put("mprp/23.jpg", "MPRP.zip/MPRP/Recollect.full.jpg"); - copyUrlToImage.put("mprp/24.jpg", "MPRP.zip/MPRP/Damnation.full.jpg"); - copyUrlToImage.put("mprp/25.jpg", "MPRP.zip/MPRP/Tidings.full.jpg"); - copyUrlToImage.put("mprp/26.jpg", "MPRP.zip/MPRP/Incinerate.full.jpg"); - copyUrlToImage.put("mprp/27.jpg", "MPRP.zip/MPRP/Mana Tithe.full.jpg"); - copyUrlToImage.put("mprp/28.jpg", "MPRP.zip/MPRP/Harmonize.full.jpg"); - copyUrlToImage.put("mprp/29.jpg", "MPRP.zip/MPRP/Ponder.full.jpg"); - copyUrlToImage.put("mprp/3.jpg", "MPRP.zip/MPRP/Powder Keg.full.jpg"); - copyUrlToImage.put("mprp/30.jpg", "MPRP.zip/MPRP/Corrupt.full.jpg"); - copyUrlToImage.put("mprp/31.jpg", "MPRP.zip/MPRP/Cryptic Command.full.jpg"); - copyUrlToImage.put("mprp/32.jpg", "MPRP.zip/MPRP/Flame Javelin.full.jpg"); - copyUrlToImage.put("mprp/33.jpg", "MPRP.zip/MPRP/Unmake.full.jpg"); - copyUrlToImage.put("mprp/34.jpg", "MPRP.zip/MPRP/Nameless Inversion.full.jpg"); - copyUrlToImage.put("mprp/35.jpg", "MPRP.zip/MPRP/Remove Soul.full.jpg"); - copyUrlToImage.put("mprp/36.jpg", "MPRP.zip/MPRP/Blightning.full.jpg"); - copyUrlToImage.put("mprp/37.jpg", "MPRP.zip/MPRP/Rampant Growth.full.jpg"); - copyUrlToImage.put("mprp/38.jpg", "MPRP.zip/MPRP/Negate.full.jpg"); - copyUrlToImage.put("mprp/39.jpg", "MPRP.zip/MPRP/Terminate.full.jpg"); - copyUrlToImage.put("mprp/4.jpg", "MPRP.zip/MPRP/Psychatog.full.jpg"); - copyUrlToImage.put("mprp/40.jpg", "MPRP.zip/MPRP/Lightning Bolt.full.jpg"); - copyUrlToImage.put("mprp/41.jpg", "MPRP.zip/MPRP/Cancel.full.jpg"); - copyUrlToImage.put("mprp/42.jpg", "MPRP.zip/MPRP/Sign in Blood.full.jpg"); - copyUrlToImage.put("mprp/43.jpg", "MPRP.zip/MPRP/Infest.full.jpg"); - copyUrlToImage.put("mprp/44.jpg", "MPRP.zip/MPRP/Volcanic Fallout.full.jpg"); - copyUrlToImage.put("mprp/45.jpg", "MPRP.zip/MPRP/Celestial Purge.full.jpg"); - copyUrlToImage.put("mprp/46.jpg", "MPRP.zip/MPRP/Bituminous Blast.full.jpg"); - copyUrlToImage.put("mprp/47.jpg", "MPRP.zip/MPRP/Burst Lightning.full.jpg"); - copyUrlToImage.put("mprp/48.jpg", "MPRP.zip/MPRP/Harrow.full.jpg"); - copyUrlToImage.put("mprp/49.jpg", "MPRP.zip/MPRP/Day of Judgment.full.jpg"); - copyUrlToImage.put("mprp/5.jpg", "MPRP.zip/MPRP/Terror.full.jpg"); - copyUrlToImage.put("mprp/50.jpg", "MPRP.zip/MPRP/Brave the Elements.full.jpg"); - copyUrlToImage.put("mprp/51.jpg", "MPRP.zip/MPRP/Doom Blade.full.jpg"); - copyUrlToImage.put("mprp/52.jpg", "MPRP.zip/MPRP/Treasure Hunt.full.jpg"); - copyUrlToImage.put("mprp/53.jpg", "MPRP.zip/MPRP/Searing Blaze.full.jpg"); - copyUrlToImage.put("mprp/6.jpg", "MPRP.zip/MPRP/Fireball.full.jpg"); - copyUrlToImage.put("mprp/7.jpg", "MPRP.zip/MPRP/Oxidize.full.jpg"); - copyUrlToImage.put("mprp/8.jpg", "MPRP.zip/MPRP/Mana Leak.full.jpg"); - copyUrlToImage.put("mprp/9.jpg", "MPRP.zip/MPRP/Reciprocate.full.jpg"); - copyUrlToImage.put("mpskld/1.jpg", "MPS.zip/MPS/Cataclysmic Gearhulk.full.jpg"); - copyUrlToImage.put("mpskld/10.jpg", "MPS.zip/MPS/Cloudstone Curio.full.jpg"); - copyUrlToImage.put("mpskld/11.jpg", "MPS.zip/MPS/Crucible of Worlds.full.jpg"); - copyUrlToImage.put("mpskld/12.jpg", "MPS.zip/MPS/Gauntlet of Power.full.jpg"); - copyUrlToImage.put("mpskld/13.jpg", "MPS.zip/MPS/Hangarback Walker.full.jpg"); - copyUrlToImage.put("mpskld/14.jpg", "MPS.zip/MPS/Lightning Greaves.full.jpg"); - copyUrlToImage.put("mpskld/15.jpg", "MPS.zip/MPS/Lotus Petal.full.jpg"); - copyUrlToImage.put("mpskld/16.jpg", "MPS.zip/MPS/Mana Crypt.full.jpg"); - copyUrlToImage.put("mpskld/17.jpg", "MPS.zip/MPS/Mana Vault.full.jpg"); - copyUrlToImage.put("mpskld/18.jpg", "MPS.zip/MPS/Mind's Eye.full.jpg"); - copyUrlToImage.put("mpskld/19.jpg", "MPS.zip/MPS/Mox Opal.full.jpg"); - copyUrlToImage.put("mpskld/2.jpg", "MPS.zip/MPS/Torrential Gearhulk.full.jpg"); - copyUrlToImage.put("mpskld/20.jpg", "MPS.zip/MPS/Painter's Servant.full.jpg"); - copyUrlToImage.put("mpskld/21.jpg", "MPS.zip/MPS/Rings of Brighthearth.full.jpg"); - copyUrlToImage.put("mpskld/22.jpg", "MPS.zip/MPS/Scroll Rack.full.jpg"); - copyUrlToImage.put("mpskld/23.jpg", "MPS.zip/MPS/Sculpting Steel.full.jpg"); - copyUrlToImage.put("mpskld/24.jpg", "MPS.zip/MPS/Sol Ring.full.jpg"); - copyUrlToImage.put("mpskld/25.jpg", "MPS.zip/MPS/Solemn Simulacrum.full.jpg"); - copyUrlToImage.put("mpskld/26.jpg", "MPS.zip/MPS/Static Orb.full.jpg"); - copyUrlToImage.put("mpskld/27.jpg", "MPS.zip/MPS/Steel Overseer.full.jpg"); - copyUrlToImage.put("mpskld/28.jpg", "MPS.zip/MPS/Sword of Feast and Famine.full.jpg"); - copyUrlToImage.put("mpskld/29.jpg", "MPS.zip/MPS/Sword of Fire and Ice.full.jpg"); - copyUrlToImage.put("mpskld/3.jpg", "MPS.zip/MPS/Noxious Gearhulk.full.jpg"); - copyUrlToImage.put("mpskld/30.jpg", "MPS.zip/MPS/Sword of Light and Shadow.full.jpg"); - copyUrlToImage.put("mpskld/4.jpg", "MPS.zip/MPS/Combustible Gearhulk.full.jpg"); - copyUrlToImage.put("mpskld/5.jpg", "MPS.zip/MPS/Verdurous Gearhulk.full.jpg"); - copyUrlToImage.put("mpskld/6.jpg", "MPS.zip/MPS/Aether Vial.full.jpg"); - copyUrlToImage.put("mpskld/7.jpg", "MPS.zip/MPS/Champion's Helm.full.jpg"); - copyUrlToImage.put("mpskld/8.jpg", "MPS.zip/MPS/Chromatic Lantern.full.jpg"); - copyUrlToImage.put("mpskld/9.jpg", "MPS.zip/MPS/Chrome Mox.full.jpg"); - copyUrlToImage.put("ptc/1.jpg", "PTC.zip/PTC/Dirtcowl Wurm.full.jpg"); - copyUrlToImage.put("ptc/10.jpg", "PTC.zip/PTC/Rathi Assassin.full.jpg"); - copyUrlToImage.put("ptc/100.jpg", "PTC.zip/PTC/Flying Crane Technique.full.jpg"); - copyUrlToImage.put("ptc/101.jpg", "PTC.zip/PTC/Grim Haruspex.full.jpg"); - copyUrlToImage.put("ptc/102.jpg", "PTC.zip/PTC/Hardened Scales.full.jpg"); - copyUrlToImage.put("ptc/103.jpg", "PTC.zip/PTC/Herald of Anafenza.full.jpg"); - copyUrlToImage.put("ptc/104.jpg", "PTC.zip/PTC/High Sentinels of Arashin.full.jpg"); - copyUrlToImage.put("ptc/105.jpg", "PTC.zip/PTC/Icy Blast.full.jpg"); - copyUrlToImage.put("ptc/106.jpg", "PTC.zip/PTC/Ivorytusk Fortress.full.jpg"); - copyUrlToImage.put("ptc/107.jpg", "PTC.zip/PTC/Jeering Instigator.full.jpg"); - copyUrlToImage.put("ptc/108.jpg", "PTC.zip/PTC/Jeskai Ascendancy.full.jpg"); - copyUrlToImage.put("ptc/109.jpg", "PTC.zip/PTC/Kheru Lich Lord.full.jpg"); - copyUrlToImage.put("ptc/11.jpg", "PTC.zip/PTC/Avatar of Hope.full.jpg"); - copyUrlToImage.put("ptc/110.jpg", "PTC.zip/PTC/Mardu Ascendancy.full.jpg"); - copyUrlToImage.put("ptc/111.jpg", "PTC.zip/PTC/Master of Pearls.full.jpg"); - copyUrlToImage.put("ptc/112.jpg", "PTC.zip/PTC/Narset, Enlightened Master.full.jpg"); - copyUrlToImage.put("ptc/113.jpg", "PTC.zip/PTC/Necropolis Fiend.full.jpg"); - copyUrlToImage.put("ptc/114.jpg", "PTC.zip/PTC/Rakshasa Vizier.full.jpg"); - copyUrlToImage.put("ptc/115.jpg", "PTC.zip/PTC/Rattleclaw Mystic.full.jpg"); - copyUrlToImage.put("ptc/116.jpg", "PTC.zip/PTC/Sage of the Inward Eye.full.jpg"); - copyUrlToImage.put("ptc/117.jpg", "PTC.zip/PTC/Sidisi, Brood Tyrant.full.jpg"); - copyUrlToImage.put("ptc/118.jpg", "PTC.zip/PTC/Siege Rhino.full.jpg"); - copyUrlToImage.put("ptc/119.jpg", "PTC.zip/PTC/Sultai Ascendacy.full.jpg"); - copyUrlToImage.put("ptc/12.jpg", "PTC.zip/PTC/Raging Kavu.full.jpg"); - copyUrlToImage.put("ptc/120.jpg", "PTC.zip/PTC/Surrak Dragonclaw.full.jpg"); - copyUrlToImage.put("ptc/121.jpg", "PTC.zip/PTC/Temur Ascendancy.full.jpg"); - copyUrlToImage.put("ptc/122.jpg", "PTC.zip/PTC/Thousand Winds.full.jpg"); - copyUrlToImage.put("ptc/123.jpg", "PTC.zip/PTC/Trail of Mystery.full.jpg"); - copyUrlToImage.put("ptc/124.jpg", "PTC.zip/PTC/Trap Essence.full.jpg"); - copyUrlToImage.put("ptc/125.jpg", "PTC.zip/PTC/Utter End.full.jpg"); - copyUrlToImage.put("ptc/126.jpg", "PTC.zip/PTC/Villainous Wealth.full.jpg"); - copyUrlToImage.put("ptc/127.jpg", "PTC.zip/PTC/Zurgo Helmsmasher.full.jpg"); - copyUrlToImage.put("ptc/128.jpg", "PTC.zip/PTC/Alesha, Who Smiles at Death.full.jpg"); - copyUrlToImage.put("ptc/129.jpg", "PTC.zip/PTC/Arcbond.full.jpg"); - copyUrlToImage.put("ptc/13.jpg", "PTC.zip/PTC/Questing Phelddagrif.full.jpg"); - copyUrlToImage.put("ptc/130.jpg", "PTC.zip/PTC/Archfiend of Depravity.full.jpg"); - copyUrlToImage.put("ptc/131.jpg", "PTC.zip/PTC/Atarka, World Render.full.jpg"); - copyUrlToImage.put("ptc/132.jpg", "PTC.zip/PTC/Brutal Hordechief.full.jpg"); - copyUrlToImage.put("ptc/133.jpg", "PTC.zip/PTC/Daghatar the Adamant.full.jpg"); - copyUrlToImage.put("ptc/134.jpg", "PTC.zip/PTC/Dragonscale General.full.jpg"); - copyUrlToImage.put("ptc/135.jpg", "PTC.zip/PTC/Dromoka, the Eternal.full.jpg"); - copyUrlToImage.put("ptc/136.jpg", "PTC.zip/PTC/Flamerush Rider.full.jpg"); - copyUrlToImage.put("ptc/137.jpg", "PTC.zip/PTC/Flamewake Phoenix.full.jpg"); - copyUrlToImage.put("ptc/138.jpg", "PTC.zip/PTC/Jeskai Infiltrator.full.jpg"); - copyUrlToImage.put("ptc/14.jpg", "PTC.zip/PTC/Fungal Shambler.full.jpg"); - copyUrlToImage.put("ptc/141.jpg", "PTC.zip/PTC/Mastery of the Unseen.full.jpg"); - copyUrlToImage.put("ptc/142.jpg", "PTC.zip/PTC/Ojutai, Soul of Winter.full.jpg"); - copyUrlToImage.put("ptc/143.jpg", "PTC.zip/PTC/Rally the Ancestors.full.jpg"); - copyUrlToImage.put("ptc/145.jpg", "PTC.zip/PTC/Sandsteppe Mastodon.full.jpg"); - copyUrlToImage.put("ptc/147.jpg", "PTC.zip/PTC/Shamanic Revelation.full.jpg"); - copyUrlToImage.put("ptc/15.jpg", "PTC.zip/PTC/Stone-Tongue Basilisk.full.jpg"); - copyUrlToImage.put("ptc/150.jpg", "PTC.zip/PTC/Soulfire Grand Master.full.jpg"); - copyUrlToImage.put("ptc/151.jpg", "PTC.zip/PTC/Soulflayer.full.jpg"); - copyUrlToImage.put("ptc/152.jpg", "PTC.zip/PTC/Supplant Form.full.jpg"); - copyUrlToImage.put("ptc/153.jpg", "PTC.zip/PTC/Tasigur, the Golden Fang.full.jpg"); - copyUrlToImage.put("ptc/154.jpg", "PTC.zip/PTC/Torrent Elemental.full.jpg"); - copyUrlToImage.put("ptc/157.jpg", "PTC.zip/PTC/Yasova Dragonclaw.full.jpg"); - copyUrlToImage.put("ptc/16.jpg", "PTC.zip/PTC/Laquatus's Champion.full.jpg"); - copyUrlToImage.put("ptc/166.jpg", "PTC.zip/PTC/Crater Elemental.full.jpg"); - copyUrlToImage.put("ptc/168.jpg", "PTC.zip/PTC/Deathbringer Regent.full.jpg"); - copyUrlToImage.put("ptc/17.jpg", "PTC.zip/PTC/Glory.full.jpg"); - copyUrlToImage.put("ptc/18.jpg", "PTC.zip/PTC/Silent Specter.full.jpg"); - copyUrlToImage.put("ptc/181.jpg", "PTC.zip/PTC/Kolaghan's Command.full.jpg"); - copyUrlToImage.put("ptc/183.jpg", "PTC.zip/PTC/Myth Realized.full.jpg"); - copyUrlToImage.put("ptc/185.jpg", "PTC.zip/PTC/Ojutai's Command.full.jpg"); - copyUrlToImage.put("ptc/19.jpg", "PTC.zip/PTC/Feral Throwback.full.jpg"); - copyUrlToImage.put("ptc/196.jpg", "PTC.zip/PTC/Volcanic Vision.full.jpg"); - copyUrlToImage.put("ptc/198.jpg", "PTC.zip/PTC/Abbot of Keral Keep.full.jpg"); - copyUrlToImage.put("ptc/2.jpg", "PTC.zip/PTC/Revenant.full.jpg"); - copyUrlToImage.put("ptc/20.jpg", "PTC.zip/PTC/Soul Collector.full.jpg"); - copyUrlToImage.put("ptc/21.jpg", "PTC.zip/PTC/Sword of Kaldra.full.jpg"); - copyUrlToImage.put("ptc/210.jpg", "PTC.zip/PTC/Gilt-Leaf Winnower.full.jpg"); - copyUrlToImage.put("ptc/212.jpg", "PTC.zip/PTC/Graveblade Marauder.full.jpg"); - copyUrlToImage.put("ptc/216.jpg", "PTC.zip/PTC/Jace, Vryn's Prodigy.full.jpg"); - copyUrlToImage.put("ptc/22.jpg", "PTC.zip/PTC/Shield of Kaldra.full.jpg"); - copyUrlToImage.put("ptc/225.jpg", "PTC.zip/PTC/Nissa's Revelation.full.jpg"); - copyUrlToImage.put("ptc/227.jpg", "PTC.zip/PTC/Outland Colossus.full.jpg"); - copyUrlToImage.put("ptc/23.jpg", "PTC.zip/PTC/Helm of Kaldra.full.jpg"); - copyUrlToImage.put("ptc/238.jpg", "PTC.zip/PTC/Akoum Firebird.full.jpg"); - copyUrlToImage.put("ptc/239.jpg", "PTC.zip/PTC/Akoum Hellkite.full.jpg"); - copyUrlToImage.put("ptc/24.jpg", "PTC.zip/PTC/Ryusei, the Falling Star.full.jpg"); - copyUrlToImage.put("ptc/240.jpg", "PTC.zip/PTC/Aligned Hedron Network.full.jpg"); - copyUrlToImage.put("ptc/241.jpg", "PTC.zip/PTC/Ally Encampment.full.jpg"); - copyUrlToImage.put("ptc/242.jpg", "PTC.zip/PTC/Angelic Captain.full.jpg"); - copyUrlToImage.put("ptc/243.jpg", "PTC.zip/PTC/Barrage Tyrant.full.jpg"); - copyUrlToImage.put("ptc/244.jpg", "PTC.zip/PTC/Beastcaller Savant.full.jpg"); - copyUrlToImage.put("ptc/245.jpg", "PTC.zip/PTC/Blight Herder.full.jpg"); - copyUrlToImage.put("ptc/246.jpg", "PTC.zip/PTC/Bring to Light.full.jpg"); - copyUrlToImage.put("ptc/247.jpg", "PTC.zip/PTC/Brood Butcher.full.jpg"); - copyUrlToImage.put("ptc/248.jpg", "PTC.zip/PTC/Brutal Expulsion.full.jpg"); - copyUrlToImage.put("ptc/249.jpg", "PTC.zip/PTC/Canopy Vista.full.jpg"); - copyUrlToImage.put("ptc/25.jpg", "PTC.zip/PTC/Ink-Eyes, Servant of Oni.full.jpg"); - copyUrlToImage.put("ptc/250.jpg", "PTC.zip/PTC/Cinder Glade.full.jpg"); - copyUrlToImage.put("ptc/251.jpg", "PTC.zip/PTC/Conduit of Ruin.full.jpg"); - copyUrlToImage.put("ptc/252.jpg", "PTC.zip/PTC/Defiant Bloodlord.full.jpg"); - copyUrlToImage.put("ptc/253.jpg", "PTC.zip/PTC/Desolation Twin.full.jpg"); - copyUrlToImage.put("ptc/254.jpg", "PTC.zip/PTC/Dragonmaster Outcast.full.jpg"); - copyUrlToImage.put("ptc/255.jpg", "PTC.zip/PTC/Drana, Liberator of Malakir.full.jpg"); - copyUrlToImage.put("ptc/256.jpg", "PTC.zip/PTC/Drowner of Hope.full.jpg"); - copyUrlToImage.put("ptc/257.jpg", "PTC.zip/PTC/Dust Stalker.full.jpg"); - copyUrlToImage.put("ptc/258.jpg", "PTC.zip/PTC/Emeria Shepherd.full.jpg"); - copyUrlToImage.put("ptc/259.jpg", "PTC.zip/PTC/Endless One.full.jpg"); - copyUrlToImage.put("ptc/26.jpg", "PTC.zip/PTC/Kiyomaro, First to Stand.full.jpg"); - copyUrlToImage.put("ptc/260.jpg", "PTC.zip/PTC/Exert Influence.full.jpg"); - copyUrlToImage.put("ptc/261.jpg", "PTC.zip/PTC/Fathom Feeder.full.jpg"); - copyUrlToImage.put("ptc/262.jpg", "PTC.zip/PTC/Felidar Sovereign.full.jpg"); - copyUrlToImage.put("ptc/263.jpg", "PTC.zip/PTC/From Beyond.full.jpg"); - copyUrlToImage.put("ptc/264.jpg", "PTC.zip/PTC/Gideon, Ally of Zendikar.full.jpg"); - copyUrlToImage.put("ptc/265.jpg", "PTC.zip/PTC/Greenwarden of Murasa.full.jpg"); - copyUrlToImage.put("ptc/266.jpg", "PTC.zip/PTC/Gruesome Slaughter.full.jpg"); - copyUrlToImage.put("ptc/267.jpg", "PTC.zip/PTC/Guardian of Tazeem.full.jpg"); - copyUrlToImage.put("ptc/268.jpg", "PTC.zip/PTC/Guul Draz Overseer.full.jpg"); - copyUrlToImage.put("ptc/27.jpg", "PTC.zip/PTC/Gleancrawler.full.jpg"); - copyUrlToImage.put("ptc/271.jpg", "PTC.zip/PTC/Lantern Scout.full.jpg"); - copyUrlToImage.put("ptc/272.jpg", "PTC.zip/PTC/Lumbering Falls.full.jpg"); - copyUrlToImage.put("ptc/273.jpg", "PTC.zip/PTC/March from the Tomb.full.jpg"); - copyUrlToImage.put("ptc/274.jpg", "PTC.zip/PTC/Munda, Ambush Leader.full.jpg"); - copyUrlToImage.put("ptc/275.jpg", "PTC.zip/PTC/Nissa's Renewal.full.jpg"); - copyUrlToImage.put("ptc/276.jpg", "PTC.zip/PTC/Noyan Dar, Roil Shaper.full.jpg"); - copyUrlToImage.put("ptc/277.jpg", "PTC.zip/PTC/Ob Nixilis Reignited.full.jpg"); - copyUrlToImage.put("ptc/278.jpg", "PTC.zip/PTC/Oblivion Sower.full.jpg"); - copyUrlToImage.put("ptc/279.jpg", "PTC.zip/PTC/Omnath, Locus of Rage.full.jpg"); - copyUrlToImage.put("ptc/28.jpg", "PTC.zip/PTC/Djinn Illuminatus.full.jpg"); - copyUrlToImage.put("ptc/280.jpg", "PTC.zip/PTC/Oran-Rief Hydra.full.jpg"); - copyUrlToImage.put("ptc/281.jpg", "PTC.zip/PTC/Painful Truths.full.jpg"); - copyUrlToImage.put("ptc/282.jpg", "PTC.zip/PTC/Part the Waterveil.full.jpg"); - copyUrlToImage.put("ptc/283.jpg", "PTC.zip/PTC/Planar Outburst.full.jpg"); - copyUrlToImage.put("ptc/284.jpg", "PTC.zip/PTC/Prairie Stream.full.jpg"); - copyUrlToImage.put("ptc/285.jpg", "PTC.zip/PTC/Prism Array.full.jpg"); - copyUrlToImage.put("ptc/286.jpg", "PTC.zip/PTC/Quarantine Field.full.jpg"); - copyUrlToImage.put("ptc/287.jpg", "PTC.zip/PTC/Radiant Flames.full.jpg"); - copyUrlToImage.put("ptc/288.jpg", "PTC.zip/PTC/Ruinous Path.full.jpg"); - copyUrlToImage.put("ptc/289.jpg", "PTC.zip/PTC/Sanctum of Ugin.full.jpg"); - copyUrlToImage.put("ptc/29.jpg", "PTC.zip/PTC/Avatar of Discord.full.jpg"); - copyUrlToImage.put("ptc/290.jpg", "PTC.zip/PTC/Scatter to the Winds.full.jpg"); - copyUrlToImage.put("ptc/291.jpg", "PTC.zip/PTC/Serpentine Spike.full.jpg"); - copyUrlToImage.put("ptc/292.jpg", "PTC.zip/PTC/Shambling Vent.full.jpg"); - copyUrlToImage.put("ptc/293.jpg", "PTC.zip/PTC/Shrine of the Forsaken Gods.full.jpg"); - copyUrlToImage.put("ptc/294.jpg", "PTC.zip/PTC/Sire of Stagnation.full.jpg"); - copyUrlToImage.put("ptc/295.jpg", "PTC.zip/PTC/Smoldering Marsh.full.jpg"); - copyUrlToImage.put("ptc/296.jpg", "PTC.zip/PTC/Smothering Abomination.full.jpg"); - copyUrlToImage.put("ptc/297.jpg", "PTC.zip/PTC/Sunken Hollow.full.jpg"); - copyUrlToImage.put("ptc/298.jpg", "PTC.zip/PTC/Ugin's Insight.full.jpg"); - copyUrlToImage.put("ptc/299.jpg", "PTC.zip/PTC/Ulamog, the Ceaseless Hunger.full.jpg"); - copyUrlToImage.put("ptc/3.jpg", "PTC.zip/PTC/Monstrous Hound.full.jpg"); - copyUrlToImage.put("ptc/30.jpg", "PTC.zip/PTC/Allosaurus Rider.full.jpg"); - copyUrlToImage.put("ptc/300.jpg", "PTC.zip/PTC/Undergrowth Champion.full.jpg"); - copyUrlToImage.put("ptc/301.jpg", "PTC.zip/PTC/Veteran Warleader.full.jpg"); - copyUrlToImage.put("ptc/302.jpg", "PTC.zip/PTC/Void Winnower.full.jpg"); - copyUrlToImage.put("ptc/303.jpg", "PTC.zip/PTC/Wasteland Strangler.full.jpg"); - copyUrlToImage.put("ptc/304.jpg", "PTC.zip/PTC/Woodland Wanderer.full.jpg"); - copyUrlToImage.put("ptc/305.jpg", "PTC.zip/PTC/Zada, Hedron Grinder.full.jpg"); - copyUrlToImage.put("ptc/31.jpg", "PTC.zip/PTC/Lotus Bloom.full.jpg"); - copyUrlToImage.put("ptc/32.jpg", "PTC.zip/PTC/Oros, the Avenger.full.jpg"); - copyUrlToImage.put("ptc/33.jpg", "PTC.zip/PTC/Korlash, Heir to Blackblade.full.jpg"); - copyUrlToImage.put("ptc/34.jpg", "PTC.zip/PTC/Wren's Run Packmaster.full.jpg"); - copyUrlToImage.put("ptc/35.jpg", "PTC.zip/PTC/Door of Destinies.full.jpg"); - copyUrlToImage.put("ptc/36.jpg", "PTC.zip/PTC/Demigod of Revenge.full.jpg"); - copyUrlToImage.put("ptc/37.jpg", "PTC.zip/PTC/Overbeing of Myth.full.jpg"); - copyUrlToImage.put("ptc/38.jpg", "PTC.zip/PTC/Ajani Vengeant.full.jpg"); - copyUrlToImage.put("ptc/39.jpg", "PTC.zip/PTC/Malfegor.full.jpg"); - copyUrlToImage.put("ptc/4.jpg", "PTC.zip/PTC/Lightning Dragon.full.jpg"); - copyUrlToImage.put("ptc/40.jpg", "PTC.zip/PTC/Dragon Broodmother.full.jpg"); - copyUrlToImage.put("ptc/41.jpg", "PTC.zip/PTC/Vampire Nocturnus.full.jpg"); - copyUrlToImage.put("ptc/42.jpg", "PTC.zip/PTC/Rampaging Baloths.full.jpg"); - copyUrlToImage.put("ptc/43.jpg", "PTC.zip/PTC/Comet Storm.full.jpg"); - copyUrlToImage.put("ptc/44.jpg", "PTC.zip/PTC/Emrakul, the Aeons Torn.full.jpg"); - copyUrlToImage.put("ptc/45.jpg", "PTC.zip/PTC/Sun Titan.full.jpg"); - copyUrlToImage.put("ptc/46.jpg", "PTC.zip/PTC/Wurmcoil Engine.full.jpg"); - copyUrlToImage.put("ptc/47.jpg", "PTC.zip/PTC/Hero of Bladehold.full.jpg"); - copyUrlToImage.put("ptc/48.jpg", "PTC.zip/PTC/Glissa, the Traitor.full.jpg"); - copyUrlToImage.put("ptc/49.jpg", "PTC.zip/PTC/Sheoldred, Whispering One.full.jpg"); - copyUrlToImage.put("ptc/5.jpg", "PTC.zip/PTC/Beast of Burden.full.jpg"); - copyUrlToImage.put("ptc/50.jpg", "PTC.zip/PTC/Bloodlord of Vaasgoth.full.jpg"); - copyUrlToImage.put("ptc/51a.jpg", "PTC.zip/PTC/Mayor of Avabruck.full.jpg"); - copyUrlToImage.put("ptc/51b.jpg", "PTC.zip/PTC/Howlpack Alpha.full.jpg"); - copyUrlToImage.put("ptc/52a.jpg", "PTC.zip/PTC/Ravenous Demon.full.jpg"); - copyUrlToImage.put("ptc/52b.jpg", "PTC.zip/PTC/Archdemon of Greed.full.jpg"); - copyUrlToImage.put("ptc/53.jpg", "PTC.zip/PTC/Moonsilver Spear.full.jpg"); - copyUrlToImage.put("ptc/54.jpg", "PTC.zip/PTC/Xathrid Gorgon.full.jpg"); - copyUrlToImage.put("ptc/55.jpg", "PTC.zip/PTC/Archon of the Triumvirate.full.jpg"); - copyUrlToImage.put("ptc/56.jpg", "PTC.zip/PTC/Hypersonic Dragon.full.jpg"); - copyUrlToImage.put("ptc/57.jpg", "PTC.zip/PTC/Carnival Hellsteed.full.jpg"); - copyUrlToImage.put("ptc/58.jpg", "PTC.zip/PTC/Corpsejack Menace.full.jpg"); - copyUrlToImage.put("ptc/59.jpg", "PTC.zip/PTC/Grove of the Guardian.full.jpg"); - copyUrlToImage.put("ptc/6.jpg", "PTC.zip/PTC/Lu Bu, Master-at-Arms.full.jpg"); - copyUrlToImage.put("ptc/60.jpg", "PTC.zip/PTC/Consuming Aberration.full.jpg"); - copyUrlToImage.put("ptc/61.jpg", "PTC.zip/PTC/Fathom Mage.full.jpg"); - copyUrlToImage.put("ptc/62.jpg", "PTC.zip/PTC/Foundry Champion.full.jpg"); - copyUrlToImage.put("ptc/63.jpg", "PTC.zip/PTC/Rubblehulk.full.jpg"); - copyUrlToImage.put("ptc/64.jpg", "PTC.zip/PTC/Treasury Thrull.full.jpg"); - copyUrlToImage.put("ptc/65.jpg", "PTC.zip/PTC/Maze's End.full.jpg"); - copyUrlToImage.put("ptc/66.jpg", "PTC.zip/PTC/Plains.66.full.jpg"); - copyUrlToImage.put("ptc/67.jpg", "PTC.zip/PTC/Megantic Sliver.full.jpg"); - copyUrlToImage.put("ptc/68.jpg", "PTC.zip/PTC/Celestial Archon.full.jpg"); - copyUrlToImage.put("ptc/69.jpg", "PTC.zip/PTC/Shipbreaker Kraken.full.jpg"); - copyUrlToImage.put("ptc/7.jpg", "PTC.zip/PTC/False Prophet.full.jpg"); - copyUrlToImage.put("ptc/70.jpg", "PTC.zip/PTC/Abhorrent Overlord.full.jpg"); - copyUrlToImage.put("ptc/71.jpg", "PTC.zip/PTC/Ember Swallower.full.jpg"); - copyUrlToImage.put("ptc/72.jpg", "PTC.zip/PTC/Anthousa, Setessan Hero.full.jpg"); - copyUrlToImage.put("ptc/73.jpg", "PTC.zip/PTC/Silent Sentinel.full.jpg"); - copyUrlToImage.put("ptc/74.jpg", "PTC.zip/PTC/Arbiter of the Ideal.full.jpg"); - copyUrlToImage.put("ptc/75.jpg", "PTC.zip/PTC/Eater of Hope.full.jpg"); - copyUrlToImage.put("ptc/76.jpg", "PTC.zip/PTC/Forgestoker Dragon.full.jpg"); - copyUrlToImage.put("ptc/77.jpg", "PTC.zip/PTC/Nessian Wilds Ravager.full.jpg"); - copyUrlToImage.put("ptc/78.jpg", "PTC.zip/PTC/Dawnbringer Charioteers.full.jpg"); - copyUrlToImage.put("ptc/79.jpg", "PTC.zip/PTC/Scourge of Fleets.full.jpg"); - copyUrlToImage.put("ptc/8.jpg", "PTC.zip/PTC/Lu Bu, Master-at-Arms.full.jpg"); - copyUrlToImage.put("ptc/80.jpg", "PTC.zip/PTC/Doomwake Giant.full.jpg"); - copyUrlToImage.put("ptc/81.jpg", "PTC.zip/PTC/Spawn of Thraxes.full.jpg"); - copyUrlToImage.put("ptc/82.jpg", "PTC.zip/PTC/Heroes' Bane.full.jpg"); - copyUrlToImage.put("ptc/83.jpg", "PTC.zip/PTC/Resolute Archangel.full.jpg"); - copyUrlToImage.put("ptc/84.jpg", "PTC.zip/PTC/Mercurial Pretender.full.jpg"); - copyUrlToImage.put("ptc/85.jpg", "PTC.zip/PTC/Indulgent Tormentor.full.jpg"); - copyUrlToImage.put("ptc/86.jpg", "PTC.zip/PTC/Siege Dragon.full.jpg"); - copyUrlToImage.put("ptc/87.jpg", "PTC.zip/PTC/Phytotitan.full.jpg"); - copyUrlToImage.put("ptc/88.jpg", "PTC.zip/PTC/Abzan Ascendancy.full.jpg"); - copyUrlToImage.put("ptc/89.jpg", "PTC.zip/PTC/Anafenza, the Foremost.full.jpg"); - copyUrlToImage.put("ptc/9.jpg", "PTC.zip/PTC/Overtaker.full.jpg"); - copyUrlToImage.put("ptc/90.jpg", "PTC.zip/PTC/Ankle Shanker.full.jpg"); - copyUrlToImage.put("ptc/91.jpg", "PTC.zip/PTC/Avalanche Tusker.full.jpg"); - copyUrlToImage.put("ptc/92.jpg", "PTC.zip/PTC/Bloodsoaked Champion.full.jpg"); - copyUrlToImage.put("ptc/93.jpg", "PTC.zip/PTC/Butcher of the Horde.full.jpg"); - copyUrlToImage.put("ptc/94.jpg", "PTC.zip/PTC/Crackling Doom.full.jpg"); - copyUrlToImage.put("ptc/95.jpg", "PTC.zip/PTC/Crater's Claws.full.jpg"); - copyUrlToImage.put("ptc/96.jpg", "PTC.zip/PTC/Deflecting Palm.full.jpg"); - copyUrlToImage.put("ptc/97.jpg", "PTC.zip/PTC/Dig Through Time.full.jpg"); - copyUrlToImage.put("ptc/98.jpg", "PTC.zip/PTC/Dragon-Style Twins.full.jpg"); - copyUrlToImage.put("ptc/99.jpg", "PTC.zip/PTC/Duneblast.full.jpg"); - copyUrlToImage.put("sus/1.jpg", "SUS.zip/SUS/Thran Quarry.full.jpg"); - copyUrlToImage.put("sus/10.jpg", "SUS.zip/SUS/Slith Firewalker.full.jpg"); - copyUrlToImage.put("sus/11.jpg", "SUS.zip/SUS/Royal Assassin.full.jpg"); - copyUrlToImage.put("sus/12.jpg", "SUS.zip/SUS/Sakura-Tribe Elder.full.jpg"); - copyUrlToImage.put("sus/13.jpg", "SUS.zip/SUS/Shard Phoenix.full.jpg"); - copyUrlToImage.put("sus/14.jpg", "SUS.zip/SUS/Soltari Priest.full.jpg"); - copyUrlToImage.put("sus/15.jpg", "SUS.zip/SUS/Whirling Dervish.full.jpg"); - copyUrlToImage.put("sus/16.jpg", "SUS.zip/SUS/Glorious Anthem.full.jpg"); - copyUrlToImage.put("sus/17.jpg", "SUS.zip/SUS/Elvish Champion.full.jpg"); - copyUrlToImage.put("sus/18.jpg", "SUS.zip/SUS/Mad Auntie.full.jpg"); - copyUrlToImage.put("sus/19.jpg", "SUS.zip/SUS/Slith Firewalker.full.jpg"); - copyUrlToImage.put("sus/2.jpg", "SUS.zip/SUS/Serra Avatar.full.jpg"); - copyUrlToImage.put("sus/20.jpg", "SUS.zip/SUS/Royal Assassin.full.jpg"); - copyUrlToImage.put("sus/21.jpg", "SUS.zip/SUS/Sakura-Tribe Elder.full.jpg"); - copyUrlToImage.put("sus/22.jpg", "SUS.zip/SUS/Shard Phoenix.full.jpg"); - copyUrlToImage.put("sus/23.jpg", "SUS.zip/SUS/Soltari Priest.full.jpg"); - copyUrlToImage.put("sus/24.jpg", "SUS.zip/SUS/Whirling Dervish.full.jpg"); - copyUrlToImage.put("sus/25.jpg", "SUS.zip/SUS/Glorious Anthem.full.jpg"); - copyUrlToImage.put("sus/26.jpg", "SUS.zip/SUS/Elvish Champion.full.jpg"); - copyUrlToImage.put("sus/27.jpg", "SUS.zip/SUS/Sakura-Tribe Elder.full.jpg"); - copyUrlToImage.put("sus/28.jpg", "SUS.zip/SUS/Shard Phoenix.full.jpg"); - copyUrlToImage.put("sus/29.jpg", "SUS.zip/SUS/Soltari Priest.full.jpg"); - copyUrlToImage.put("sus/3.jpg", "SUS.zip/SUS/Lord of Atlantis.full.jpg"); - copyUrlToImage.put("sus/30.jpg", "SUS.zip/SUS/Whirling Dervish.full.jpg"); - copyUrlToImage.put("sus/31.jpg", "SUS.zip/SUS/Glorious Anthem.full.jpg"); - copyUrlToImage.put("sus/32.jpg", "SUS.zip/SUS/Elvish Champion.full.jpg"); - copyUrlToImage.put("sus/4.jpg", "SUS.zip/SUS/Crusade.full.jpg"); - copyUrlToImage.put("sus/5.jpg", "SUS.zip/SUS/Elvish Lyrist.full.jpg"); - copyUrlToImage.put("sus/6.jpg", "SUS.zip/SUS/City of Brass.full.jpg"); - copyUrlToImage.put("sus/7.jpg", "SUS.zip/SUS/Volcanic Hammer.full.jpg"); - copyUrlToImage.put("sus/8.jpg", "SUS.zip/SUS/Giant Growth.full.jpg"); - copyUrlToImage.put("sus/9.jpg", "SUS.zip/SUS/Two-Headed Dragon.full.jpg"); - copyUrlToImage.put("ugin/1.jpg", "UGIN.zip/UGIN/Ugin, the Spirit Dragon.full.jpg"); - copyUrlToImage.put("ugin/113.jpg", "UGIN.zip/UGIN/Jeering Instigator.full.jpg"); - copyUrlToImage.put("ugin/123.jpg", "UGIN.zip/UGIN/Arashin War Beast.full.jpg"); - copyUrlToImage.put("ugin/129.jpg", "UGIN.zip/UGIN/Formless Nurturing.full.jpg"); - copyUrlToImage.put("ugin/131.jpg", "UGIN.zip/UGIN/Dragonscale Boon.full.jpg"); - copyUrlToImage.put("ugin/146.jpg", "UGIN.zip/UGIN/Wildcall.full.jpg"); - copyUrlToImage.put("ugin/161.jpg", "UGIN.zip/UGIN/Hewed Stone Retainers.full.jpg"); - copyUrlToImage.put("ugin/164.jpg", "UGIN.zip/UGIN/Ugin's Construct.full.jpg"); - copyUrlToImage.put("ugin/19.jpg", "UGIN.zip/UGIN/Mastery of the Unseen.full.jpg"); - copyUrlToImage.put("ugin/216.jpg", "UGIN.zip/UGIN/Altar of the Brood.full.jpg"); - copyUrlToImage.put("ugin/217.jpg", "UGIN.zip/UGIN/Briber's Purse.full.jpg"); - copyUrlToImage.put("ugin/220.jpg", "UGIN.zip/UGIN/Ghostfire Blade.full.jpg"); - copyUrlToImage.put("ugin/24.jpg", "UGIN.zip/UGIN/Smite the Monstrous.full.jpg"); - copyUrlToImage.put("ugin/26.jpg", "UGIN.zip/UGIN/Soul Summons.full.jpg"); - copyUrlToImage.put("ugin/30.jpg", "UGIN.zip/UGIN/Watcher of the Roost.full.jpg"); - copyUrlToImage.put("ugin/36.jpg", "UGIN.zip/UGIN/Jeskai Infiltrator.full.jpg"); - copyUrlToImage.put("ugin/46.jpg", "UGIN.zip/UGIN/Reality Shift.full.jpg"); - copyUrlToImage.put("ugin/48.jpg", "UGIN.zip/UGIN/Mystic of the Hidden Way.full.jpg"); - copyUrlToImage.put("ugin/59.jpg", "UGIN.zip/UGIN/Write into Being.full.jpg"); - copyUrlToImage.put("ugin/68.jpg", "UGIN.zip/UGIN/Debilitating Injury.full.jpg"); - copyUrlToImage.put("ugin/73.jpg", "UGIN.zip/UGIN/Grim Haruspex.full.jpg"); - copyUrlToImage.put("ugin/85.jpg", "UGIN.zip/UGIN/Sultai Emissary.full.jpg"); - copyUrlToImage.put("ugin/88.jpg", "UGIN.zip/UGIN/Ruthless Ripper.full.jpg"); - copyUrlToImage.put("ugin/96.jpg", "UGIN.zip/UGIN/Ainok Tracker.full.jpg"); - copyUrlToImage.put("ugin/97.jpg", "UGIN.zip/UGIN/Arc Lightning.full.jpg"); - copyUrlToImage.put("ugin/98.jpg", "UGIN.zip/UGIN/Fierce Invocation.full.jpg"); - copyUrlToImage.put("wmcq/1.jpg", "WMCQ.zip/WMCQ/Vengevine.full.jpg"); - copyUrlToImage.put("wmcq/2.jpg", "WMCQ.zip/WMCQ/Geist of Saint Traft.full.jpg"); - copyUrlToImage.put("wmcq/3.jpg", "WMCQ.zip/WMCQ/Thalia, Guardian of Thraben.full.jpg"); - copyUrlToImage.put("wmcq/4.jpg", "WMCQ.zip/WMCQ/Liliana of the Veil.full.jpg"); - copyUrlToImage.put("wmcq/5.jpg", "WMCQ.zip/WMCQ/Snapcaster Mage.full.jpg"); - - for (String key : copyUrlToImage.keySet()) { - copyUrlToImageDone.put(key, maxTimes); - copyImageToUrl.put(copyUrlToImage.get(key), key); - } +// singleLinks.put("MTG/FRF/en/promo/prerelease/AleshaWhoSmilesAtDeath.jpg", "PTC.zip/PTC/Alesha, Who Smiles at Death.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/Arcbond.jpg", "PTC.zip/PTC/Arcbond.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/ArchfiendOfDepravity.jpg", "PTC.zip/PTC/Archfiend of Depravity.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/AtarkaWorldRender.jpg", "PTC.zip/PTC/Atarka, World Render.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/BrutalHordechief.jpg", "PTC.zip/PTC/Brutal Hordechief.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/DaghatarTheAdamant.jpg", "PTC.zip/PTC/Daghatar the Adamant.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/DragonscaleGeneral.jpg", "PTC.zip/PTC/Dragonscale General.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/DromokaTheEternal.jpg", "PTC.zip/PTC/Dromoka, the Eternal.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/FlamerushRider.jpg", "PTC.zip/PTC/Flamerush Rider.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/FlamewakePhoenix.jpg", "PTC.zip/PTC/Flamewake Phoenix.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/JeskaiInfiltrator.jpg", "PTC.zip/PTC/Jeskai Infiltrator.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/KolaghanTheStormsFury.jpg", "PTC.zip/PTC/Kolaghan, the Storm's Fury.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/MarduStrikeLeader.jpg", "PTC.zip/PTC/Mardu Strike leader.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/MasteryOfTheUnseen.jpg", "PTC.zip/PTC/Mastery of the Unseen.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/OjutaiSoulOfWinter.jpg", "PTC.zip/PTC/Ojutai, Soul of Winter.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/RallyTheAncestors.jpg", "PTC.zip/PTC/Rally the Ancestors.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/SageEyeAvengers.jpg", "PTC.zip/PTC/Sage-Eye Avengers.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/SandsteppeMastodon.jpg", "PTC.zip/PTC/Sandsteppe Mastodon.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/ShamanOfTheGreatHunt.jpg", "PTC.zip/PTC/Shaman of the Great Hunt.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/ShamanicRevelation.jpg", "PTC.zip/PTC/Shamanic Revelation.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/ShuYunTheSilentTempest.jpg", "PTC.zip/PTC/Shu Yun, the Silent Tempest.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/SilumgarTheDriftingDeath.jpg", "PTC.zip/PTC/Silumgar, the Drifting Death.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/SoulfireGrandMaster.jpg", "PTC.zip/PTC/Soulfire Grand Master.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/Soulflayer.jpg", "PTC.zip/PTC/Soulflayer.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/SupplantForm.jpg", "PTC.zip/PTC/Supplant Form.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/TasigurTheGoldenFang.jpg", "PTC.zip/PTC/Tasigur, the Golden Fang.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/TorrentElemental.jpg", "PTC.zip/PTC/Torrent Elemental.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/WardenOfTheFirstTree.jpg", "PTC.zip/PTC/Warden of the First Tree.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/Wildcall.jpg", "PTC.zip/PTC/Wildcall.full.jpg"); +// singleLinks.put("MTG/FRF/en/promo/prerelease/YasovaDragonclaw.jpg", "PTC.zip/PTC/Yasova Dragonclaw.full.jpg"); +// singleLinks.put("MTG/JOU/en/promo/DawnbringerCharioteers.jpg", "PTC.zip/PTC/Dawnbringer Charioteers.full.jpg"); +// singleLinks.put("MTG/JOU/en/promo/DictateOfKruphix.jpg", "PTC.zip/PTC/Dictate of Kruphix.full.jpg"); +// singleLinks.put("MTG/JOU/en/promo/DictateOfTheTwinGods.jpg", "PTC.zip/PTC/Dictate of the Twin Gods.full.jpg"); +// singleLinks.put("MTG/JOU/en/promo/DoomwakeGiant.jpg", "PTC.zip/PTC/Doomwake Giant.full.jpg"); +// singleLinks.put("MTG/JOU/en/promo/EidolonOfBlossoms.jpg", "PTC.zip/PTC/Eidolon of Blossoms.full.jpg"); +// singleLinks.put("MTG/JOU/en/promo/ScourgeOfSkolaVale.jpg", "PTC.zip/PTC/Scourge of Skola Vale.full.jpg"); +// singleLinks.put("MTG/JOU/en/promo/SpawnOfThraxes.jpg", "PTC.zip/PTC/Spawn of Thraxes.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/AbzanAscendancy.jpg", "PTC.zip/PTC/Abzan Ascendancy.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/AnafenzaTheForemost.jpg", "PTC.zip/PTC/Anafenza, the Foremost.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/AnkleShanker.jpg", "PTC.zip/PTC/Ankle Shanker.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/AvalancheTusker.jpg", "PTC.zip/PTC/Avalanche Tusker.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/BloodsoakedChampion.jpg", "PTC.zip/PTC/Bloodsoaked Champion.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/ButcherOfTheHorde.jpg", "PTC.zip/PTC/Butcher of the Horde.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/CracklingDoom.jpg", "PTC.zip/PTC/Crackling Doom.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/CratersClaws.jpg", "PTC.zip/PTC/Crater's Claws.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/DeflectingPalm.jpg", "PTC.zip/PTC/Deflecting Palm.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/DigThroughTime.jpg", "PTC.zip/PTC/Dig Through Time.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/DragonStyleTwins.jpg", "PTC.zip/PTC/Dragon-Style Twins.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/DragonThroneOfTarkir.jpg", "PTC.zip/PTC/Dragon Throne of Tarkir.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/Duneblast.jpg", "PTC.zip/PTC/Duneblast.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/FlyingCraneTechnique.jpg", "PTC.zip/PTC/Flying Crane Technique.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/GrimHaruspex.jpg", "PTC.zip/PTC/Grim Haruspex.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/HardenedScales.jpg", "PTC.zip/PTC/Hardened Scales.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/HeraldOfTorment.jpg", "PTC.zip/PTC/Herald of Torment.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/HighSentinelsOfArashin.jpg", "PTC.zip/PTC/High Sentinels of Arashin.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/IcyBlast.jpg", "PTC.zip/PTC/Icy Blast.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/IvorytuskFortress.jpg", "PTC.zip/PTC/Ivorytusk Fortress.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/JeeringInstigator.jpg", "PTC.zip/PTC/Jeering Instigator.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/JeskaiAscendancy.jpg", "PTC.zip/PTC/Jeskai Ascendancy.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/KheruSpellsnatcher.jpg", "PTC.zip/PTC/Kheru Spellsnatcher.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/MarduAscendancy.jpg", "PTC.zip/PTC/Mardu Ascendancy.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/MasterOfPearls.jpg", "PTC.zip/PTC/Master of Pearls.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/NarsetEnlightenedMaster.jpg", "PTC.zip/PTC/Narset, Enlightened Master.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/NecropolisFiend.jpg", "PTC.zip/PTC/Necropolis Fiend.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/RakshasaVizier.jpg", "PTC.zip/PTC/Rakshasa Vizier.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/RattleclawMystic.jpg", "PTC.zip/PTC/Rattleclaw Mystic.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/SageOfTheInwardEye.jpg", "PTC.zip/PTC/Sage of the Inward Eye.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/SidisiBroodTyrant.jpg", "PTC.zip/PTC/Sidisi, Brood Tyrant.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/SiegeRhino.jpg", "PTC.zip/PTC/Siege Rhino.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/SultaiAscendancy.jpg", "PTC.zip/PTC/Sultai Ascendancy.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/SurrakDragonclaw.jpg", "PTC.zip/PTC/Surrak Dragonclaw.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/TemurAscendancy.jpg", "PTC.zip/PTC/Temur Ascendancy.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/ThousandWinds.jpg", "PTC.zip/PTC/Thousand Winds.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/TrailOfMystery.jpg", "PTC.zip/PTC/Trail of Mystery.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/TrapEssence.jpg", "PTC.zip/PTC/Trap Essence.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/UtterEnd.jpg", "PTC.zip/PTC/Utter End.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/VillainousWealth.jpg", "PTC.zip/PTC/Villainous Wealth.full.jpg"); +// singleLinks.put("MTG/KTK/en/promo/ZurgoHelmsmasher.jpg", "PTC.zip/PTC/Zurgo Helmsmasher.full.jpg"); +// singleLinks.put("MTG/M15/en/promo/ChiefEngineer.jpg", "PTC.zip/PTC/Chief Engineer.full.jpg"); +// singleLinks.put("MTG/M15/en/promo/InGarruksWake.jpg", "PTC.zip/PTC/In Garruk's Wake.full.jpg"); +// singleLinks.put("MTG/M15/en/promo/IndulgentTormentor.jpg", "PTC.zip/PTC/Indulgent Tormentor.full.jpg"); +// singleLinks.put("MTG/M15/en/promo/MercurialPretender.jpg", "PTC.zip/PTC/Mercurial Pretender.full.jpg"); +// singleLinks.put("MTG/M15/en/promo/PhyrexianRevoker.jpg", "PTC.zip/PTC/Phyrexian Revoker.full.jpg"); +// singleLinks.put("MTG/M15/en/promo/Phytotitan.jpg", "PTC.zip/PTC/Phytotitan.full.jpg"); +// singleLinks.put("MTG/M15/en/promo/ResoluteArchangel.jpg", "PTC.zip/PTC/Resolute Archangel.full.jpg"); +// singleLinks.put("MTG/M15/en/promo/SiegeDragon.jpg", "PTC.zip/PTC/Siege Dragon.full.jpg"); +// singleLinks.put("MTG/M15/en/promo/SoulOfRavnica.jpg", "PTC.zip/PTC/Soul of Ravnica.full.jpg"); +// singleLinks.put("MTG/M15/en/promo/SoulOfZendikar.jpg", "PTC.zip/PTC/Soul of Zendikar.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/AzusaLostButSeeking.jpg", "JR.zip/JR/Azusa, Lost but Seeking.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/Bitterblossom.jpg", "JR.zip/JR/Bitterblossom.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/BloodstainedMire.jpg", "JR.zip/JR/Bloodstained Mire.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/CommandBeacon.jpg", "JR.zip/JR/Command Beacon.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/DarkRitual.jpg", "JR.zip/JR/Dark Ritual.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/DecreeOfJustice.jpg", "JR.zip/JR/Decree of Justice.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/DefenseOfTheHeart.jpg", "JR.zip/JR/Defense of the Heart.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/ExaltedAngel.jpg", "JR.zip/JR/Exalted Angel.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/FeldonOfTheThirdPath.jpg", "JR.zip/JR/Feldon of the Third Path.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/ForceOfWill.jpg", "JR.zip/JR/Force of Will.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/GaeasCradle.jpg", "JR.zip/JR/Gaea's Cradle.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/ImperialRecruiter.jpg", "JR.zip/JR/Imperial Recruiter.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/LandTax.jpg", "JR.zip/JR/Land Tax.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/MindsDesire.jpg", "JR.zip/JR/Mind's Desire.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/MishrasFactory.jpg", "JR.zip/JR/Mishra's Factory.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/RishadanPort.jpg", "JR.zip/JR/Rishadan Port.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/ShardlessAgent.jpg", "JR.zip/JR/Shardless Agent.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/ThawingGlaciers.jpg", "JR.zip/JR/Thawing Glaciers.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/Vindicate2007.jpg", "JR.zip/JR/Vindicate.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/Vindicate2013.jpg", "JR.zip/JR/Vindicate 1.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/Wasteland2010.jpg", "JR.zip/JR/Wasteland 1.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/Wasteland2015.jpg", "JR.zip/JR/Wasteland.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/WindsweptHeath.jpg", "JR.zip/JR/Windswept Heath.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/XiahouDunTheOneEyed.jpg", "JR.zip/JR/Xiahou Dun, the One-Eyed.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/YawgmothsWill.jpg", "JR.zip/JR/Yawgmoth's Will.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Judge/ZurtheEnchanter.jpg", "JR.zip/JR/Zur the Enchanter.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/AkoumFirebird.jpg", "PTC.zip/PTC/Akoum Firebird.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/AkoumHellkite.jpg", "PTC.zip/PTC/Akoum Hellkite.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/AlignedHedronNetwork.jpg", "PTC.zip/PTC/Aligned Hedron Network.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/AllyEncampment.jpg", "PTC.zip/PTC/Ally Encampment.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/AngelicCaptain.jpg", "PTC.zip/PTC/Angelic Captain.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/BarrageTyrant.jpg", "PTC.zip/PTC/Barrage Tyrant.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/BeastcallerSavant.jpg", "PTC.zip/PTC/Beastcaller Savant.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/BlightHerder.jpg", "PTC.zip/PTC/Blight Herder.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/BringToLight.jpg", "PTC.zip/PTC/Bring to Light.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/BroodButcher.jpg", "PTC.zip/PTC/Brood Butcher.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/BrutalExpulsion.jpg", "PTC.zip/PTC/Brutal Expulsion.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/CanopyVista.jpg", "PTC.zip/PTC/Canopy Vista.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/CinderGlade.jpg", "PTC.zip/PTC/Cinder Glade.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/ConduitOfRuin.jpg", "PTC.zip/PTC/Conduit of Ruin.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/DefiantBloodlord.jpg", "PTC.zip/PTC/Defiant Bloodlord.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/DesolationTwin.jpg", "PTC.zip/PTC/Desolation Twin.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/DragonmasterOutcast.jpg", "PTC.zip/PTC/Dragonmaster Outcast.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/DranasChosen.jpg", "PTC.zip/PTC/Drana's Chosen.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/DrownerOfHope.jpg", "PTC.zip/PTC/Drowner of Hope.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/DustStalker.jpg", "PTC.zip/PTC/Dust Stalker.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/EmeriaShepherd.jpg", "PTC.zip/PTC/Emeria Shepherd.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/EndlessOne.jpg", "PTC.zip/PTC/Endless One.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/ExertInfluence.jpg", "PTC.zip/PTC/Exert Influence.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/FathomFeeder.jpg", "PTC.zip/PTC/Fathom Feeder.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/FelidarSovereign.jpg", "PTC.zip/PTC/Felidar Sovereign.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/FromBeyond.jpg", "PTC.zip/PTC/From Beyond.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/GideonAllyOfZendikar.jpg", "PTC.zip/PTC/Gideon, Ally of Zendikar.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/GreenwardenOfMurasa.jpg", "PTC.zip/PTC/Greenwarden of Murasa.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/GruesomeSlaughter.jpg", "PTC.zip/PTC/Gruesome Slaughter.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/GuardianOfTazeem.jpg", "PTC.zip/PTC/Guardian of Tazeem.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/GuulDrazOverseer.jpg", "PTC.zip/PTC/Guul Draz Overseer.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/HeroOfGomaFada.jpg", "PTC.zip/PTC/Hero of Goma Fada.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/HerosDownfall.jpg", "PTC.zip/PTC/Hero's Downfall.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/KioraMasterOfTheDepths.jpg", "PTC.zip/PTC/Kiora, Master of the Depths.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/KioraTheCrashingWave.jpg", "PTC.zip/PTC/Kiora, the Crashing Wave.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/LanternScout.jpg", "PTC.zip/PTC/Lantern Scout.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/LumberingFalls.jpg", "PTC.zip/PTC/Lumbering Falls.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/MarchFromTheTomb.jpg", "PTC.zip/PTC/March from the Tomb.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/MundaAmbushLeader.jpg", "PTC.zip/PTC/Munda, Ambush Leader.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/NissasRenewal.jpg", "PTC.zip/PTC/Nissa's Renewal.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/NoyanDarRoilShaper.jpg", "PTC.zip/PTC/Noyan Dar, Roil Shaper.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/ObNixilisReignited.jpg", "PTC.zip/PTC/Ob Nixilis Reignited.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/ObNixilisUnshackled.jpg", "PTC.zip/PTC/Ob Nixilis, Unshackled.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/OblivionSower.jpg", "PTC.zip/PTC/Oblivion Sower.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/OmnathLocusOfRage.jpg", "PTC.zip/PTC/Omnath, Locus of Rage.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/OranRiefHydra.jpg", "PTC.zip/PTC/Oran-Rief Hydra.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/PainfulTruths.jpg", "PTC.zip/PTC/Painful Truths.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/PartTheWaterveil.jpg", "PTC.zip/PTC/Part the Waterveil.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/PlanarOutburst.jpg", "PTC.zip/PTC/Planar Outburst.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/PrairieStream.jpg", "PTC.zip/PTC/Prairie Stream.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/PrismArray.jpg", "PTC.zip/PTC/Prism Array.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/QuarantineField.jpg", "PTC.zip/PTC/Quarantine Field.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/RadiantFlames.jpg", "PTC.zip/PTC/Radiant Flames.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/RuinousPath.jpg", "PTC.zip/PTC/Ruinous Path.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/SanctumOfUgin.jpg", "PTC.zip/PTC/Sanctum of Ugin.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/ScatterToTheWinds.jpg", "PTC.zip/PTC/Scatter to the Winds.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/SerpentineSpike.jpg", "PTC.zip/PTC/Serpentine Spike.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/ShamblingVent.jpg", "PTC.zip/PTC/Shambling Vent.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/ShrineOfTheForsakenGods.jpg", "PTC.zip/PTC/Shrine of the Forsaken Gods.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/SireOfStagnation.jpg", "PTC.zip/PTC/Sire of Stagnation.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/SmolderingMarsh.jpg", "PTC.zip/PTC/Smoldering Marsh.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/SmotheringAbomination.jpg", "PTC.zip/PTC/Smothering Abomination.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/SunkenHollow.jpg", "PTC.zip/PTC/Sunken Hollow.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/UginsInsight.jpg", "PTC.zip/PTC/Ugin's Insight.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/UginsNexus.jpg", "PTC.zip/PTC/Ugin's Nexus.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/UlamogTheCeaselessHunger.jpg", "PTC.zip/PTC/Ulamog, the Ceaseless Hunger.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/UndergrowthChampion.jpg", "PTC.zip/PTC/Undergrowth Champion.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/VeteranWarleader.jpg", "PTC.zip/PTC/Veteran Warleader.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/VoidWinnower.jpg", "PTC.zip/PTC/Void Winnower.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/WastelandStrangler.jpg", "PTC.zip/PTC/Wasteland Strangler.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/WoodlandWanderer.jpg", "PTC.zip/PTC/Woodland Wanderer.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/BFZ/ZadaHedronGrinder.jpg", "PTC.zip/PTC/Zada, Hedron Grinder.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/AetherfluxReservoir.jpg", "PTC.zip/PTC/Aetherflux Reservoir.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/AethersquallAncient.jpg", "PTC.zip/PTC/Aethersquall Ancient.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/AetherstormRoc.jpg", "PTC.zip/PTC/Aetherstorm Roc.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/AetherworksMarvel.jpg", "PTC.zip/PTC/Aetherworks Marvel.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/AngelOfInvention.jpg", "PTC.zip/PTC/Angel of Invention.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/AnimationModule.jpg", "PTC.zip/PTC/Animation Module.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/ArchitectOfTheUntamed.jpg", "PTC.zip/PTC/Architect of the Untamed.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/AuthorityOfTheConsuls.jpg", "PTC.zip/PTC/Authority of the Consuls.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/BloomingMarsh.jpg", "PTC.zip/PTC/Blooming Marsh.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/BomatCourier.jpg", "PTC.zip/PTC/Bomat Courier.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/BotanicalSanctum.jpg", "PTC.zip/PTC/Botanical Sanctum.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/BristlingHydra.jpg", "PTC.zip/PTC/Bristling Hydra.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/CapturedByTheConsulate.jpg", "PTC.zip/PTC/Captured by the Consulate.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/CataclysmicGearhulk.jpg", "PTC.zip/PTC/Cataclysmic Gearhulk.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/ChandraTorchOfDefiance.jpg", "PTC.zip/PTC/Chandra, Torch of Defiance.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/CombustibleGearhulk.jpg", "PTC.zip/PTC/Combustible Gearhulk.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/ConcealedCourtyard.jpg", "PTC.zip/PTC/Concealed Courtyard.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/ConfiscationCoup.jpg", "PTC.zip/PTC/Confiscation Coup.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/CultivatorOfBlades.jpg", "PTC.zip/PTC/Cultivator of Blades.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/CultivatorsCaravan.jpg", "PTC.zip/PTC/Cultivator's Caravan.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/DeadlockTrap.jpg", "PTC.zip/PTC/Deadlock Trap.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/DemonOfDarkSchemes.jpg", "PTC.zip/PTC/Demon of Dark Schemes.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/DepalaPilotExemplar.jpg", "PTC.zip/PTC/Depala, Pilot Exemplar.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/DovinBaan.jpg", "PTC.zip/PTC/Dovin Baan.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/DubiousChallenge.jpg", "PTC.zip/PTC/Dubious Challenge.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/DynavoltTower.jpg", "PTC.zip/PTC/Dynavolt Tower.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/ElectrostaticPummeler.jpg", "PTC.zip/PTC/Electrostatic Pummeler.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/EliminateTheCompetition.jpg", "PTC.zip/PTC/Eliminate the Competition.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/FatefulShowdown.jpg", "PTC.zip/PTC/Fateful Showdown.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/FleetwheelCruiser.jpg", "PTC.zip/PTC/Fleetwheel Cruiser.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/Fumigate.jpg", "PTC.zip/PTC/Fumigate.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/GhirapurOrrery.jpg", "PTC.zip/PTC/Ghirapur Orrery.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/GontiLordOfLuxury.jpg", "PTC.zip/PTC/Gonti, Lord of Luxury.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/InsidiousWill.jpg", "PTC.zip/PTC/Insidious Will.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/InspiringVantage.jpg", "PTC.zip/PTC/Inspiring Vantage.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/InventorsFair.jpg", "PTC.zip/PTC/Inventors' Fair.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/KambalConsulOfAllocation.jpg", "PTC.zip/PTC/Kambal, Consul of Allocation.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/KeyToTheCity.jpg", "PTC.zip/PTC/Key to the City.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/LathnuHellion.jpg", "PTC.zip/PTC/Lathnu Hellion.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/LostLegacy.jpg", "PTC.zip/PTC/Lost Legacy.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/MadcapExperiment.jpg", "PTC.zip/PTC/Madcap Experiment.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/MarionetteMaster.jpg", "PTC.zip/PTC/Marionette Master.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/MasterTrinketeer.jpg", "PTC.zip/PTC/Master Trinketeer.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/MetallurgicSummonings.jpg", "PTC.zip/PTC/Metallurgic Summonings.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/MetalworkColossus.jpg", "PTC.zip/PTC/Metalwork Colossus.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/MidnightOil.jpg", "PTC.zip/PTC/Midnight Oil.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/MultiformWonder.jpg", "PTC.zip/PTC/Multiform Wonder.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/NissaVitalForce.jpg", "PTC.zip/PTC/Nissa, Vital Force.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/NoxiousGearhulk.jpg", "PTC.zip/PTC/Noxious Gearhulk.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/OviyaPashiriSageLifecrafter.jpg", "PTC.zip/PTC/Oviya Pashiri, Sage Lifecrafter.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/PadeemConsulOfInnovation.jpg", "PTC.zip/PTC/Padeem, Consul of Innovation.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/Panharmonicon.jpg", "PTC.zip/PTC/Panharmonicon.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/ParadoxicalOutcome.jpg", "PTC.zip/PTC/Paradoxical Outcome.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/PiaNalaar.jpg", "PTC.zip/PTC/Pia Nalaar.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/RashmiEternitiesCrafter.jpg", "PTC.zip/PTC/Rashmi, Eternities Crafter.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/SaheeliRai.jpg", "PTC.zip/PTC/Saheeli Rai.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/SaheelisArtistry.jpg", "PTC.zip/PTC/Saheeli's Artistry.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/ScrapheapScrounger.jpg", "PTC.zip/PTC/Scrapheap Scrounger.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/SkyshipStalker.jpg", "PTC.zip/PTC/Skyship Stalker.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/SkysovereignConsulFlagship.jpg", "PTC.zip/PTC/Skysovereign, Consul Flagship.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/SmugglersCopter.jpg", "PTC.zip/PTC/Smuggler's Copter.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/SpirebluffCanal.jpg", "PTC.zip/PTC/Spirebluff Canal.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/SyndicateTrafficker.jpg", "PTC.zip/PTC/Syndicate Trafficker.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/TerritorialGorger.jpg", "PTC.zip/PTC/Territorial Gorger.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/ToolcraftExemplar.jpg", "PTC.zip/PTC/Toolcraft Exemplar.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/TorrentialGearhulk.jpg", "PTC.zip/PTC/Torrential Gearhulk.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/VerdurousGearhulk.jpg", "PTC.zip/PTC/Verdurous Gearhulk.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/KLD/WildestDreams.jpg", "PTC.zip/PTC/Wildest Dreams.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/AyliEternalPilgrim.jpg", "PTC.zip/PTC/Ayli, Eternal Pilgrim.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/BearerOfSilence.jpg", "PTC.zip/PTC/Bearer of Silence.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/BearerOfTheHeavens.jpg", "PTC.zip/PTC/Bearer of the Heavens.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/CallTheGatewatch.jpg", "PTC.zip/PTC/Call the Gatewatch.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/CaptainsClaws.jpg", "PTC.zip/PTC/Captain's Claws.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/ChandraFlamecaller.jpg", "PTC.zip/PTC/Chandra, Flamecaller.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/ChandraPyromaster.jpg", "PTC.zip/PTC/Chandra, Pyromaster.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/CorruptedCrossroads.jpg", "PTC.zip/PTC/Corrupted Crossroads.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/CrushOfTentacles.jpg", "PTC.zip/PTC/Crush of Tentacles.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/DeceiverOfForm.jpg", "PTC.zip/PTC/Deceiver of Form.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/DeepfathomSkulker.jpg", "PTC.zip/PTC/Deepfathom Skulker.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/DimensionalInfiltrator.jpg", "PTC.zip/PTC/Dimensional Infiltrator.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/DranaLiberatorOfMalakir.jpg", "PTC.zip/PTC/Drana, Liberator of Malakir.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/DreadDefiler.jpg", "PTC.zip/PTC/Dread Defiler.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/EldraziDisplacer.jpg", "PTC.zip/PTC/Eldrazi Displacer.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/EldraziMimic.jpg", "PTC.zip/PTC/Eldrazi Mimic.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/EldraziObligator.jpg", "PTC.zip/PTC/Eldrazi Obligator.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/EndHostilities.jpg", "PTC.zip/PTC/End Hostilities.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/Endbringer.jpg", "PTC.zip/PTC/Endbringer.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/FallOfTheTitans.jpg", "PTC.zip/PTC/Fall of the Titans.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/GeneralTazri.jpg", "PTC.zip/PTC/General Tazri.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/GladehartCavalry.jpg", "PTC.zip/PTC/Gladehart Cavalry.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/GoblinDarkDwellers.jpg", "PTC.zip/PTC/Goblin Dark-Dwellers.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/GoblinRabblemaster.jpg", "PTC.zip/PTC/Goblin Rabblemaster.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/HedronAlignment.jpg", "PTC.zip/PTC/Hedron Alignment.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/HissingQuagmire.jpg", "PTC.zip/PTC/Hissing Quagmire.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/InverterOfTruth.jpg", "PTC.zip/PTC/Inverter of Truth.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/JoriEnRuinDiver.jpg", "PTC.zip/PTC/Jori En, Ruin Diver.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/KalitasTraitorOfGhet.jpg", "PTC.zip/PTC/Kalitas, Traitor of Ghet.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/KozilekTheGreatDistortion.jpg", "PTC.zip/PTC/Kozilek, the Great Distortion.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/KozileksReturn.jpg", "PTC.zip/PTC/Kozilek's Return.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/LinvalaThePreserver.jpg", "PTC.zip/PTC/Linvala, the Preserver.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/MatterReshaper.jpg", "PTC.zip/PTC/Matter Reshaper.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/MinaAndDennWildborn.jpg", "PTC.zip/PTC/Mina and Denn, Wildborn.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/Mirrorpool.jpg", "PTC.zip/PTC/Mirrorpool.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/MundasVanguard.jpg", "PTC.zip/PTC/Munda's Vanguard.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/NeedleSpires.jpg", "PTC.zip/PTC/Needle Spires.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/NissaVoiceOfZendikar.jpg", "PTC.zip/PTC/Nissa, Voice of Zendikar.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/OathOfChandra.jpg", "PTC.zip/PTC/Oath of Chandra.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/OathOfGideon.jpg", "PTC.zip/PTC/Oath of Gideon.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/OathOfJace.jpg", "PTC.zip/PTC/Oath of Jace.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/OathOfNissa.jpg", "PTC.zip/PTC/Oath of Nissa.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/OverwhelmingDenial.jpg", "PTC.zip/PTC/Overwhelming Denial.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/RealitySmasher.jpg", "PTC.zip/PTC/Reality Smasher.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/RemorselessPunishment.jpg", "PTC.zip/PTC/Remorseless Punishment.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/RuinsOfOranRief.jpg", "PTC.zip/PTC/Ruins of Oran-Rief.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/SeaGateWreckage.jpg", "PTC.zip/PTC/Sea Gate Wreckage.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/SifterOfSkulls.jpg", "PTC.zip/PTC/Sifter of Skulls.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/SphinxOfTheFinalWord.jpg", "PTC.zip/PTC/Sphinx of the Final Word.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/StoneHavenOutfitter.jpg", "PTC.zip/PTC/Stone Haven Outfitter.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/StoneforgeMasterwork.jpg", "PTC.zip/PTC/Stoneforge Masterwork.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/SylvanAdvocate.jpg", "PTC.zip/PTC/Sylvan Advocate.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/SylvanCaryatid.jpg", "PTC.zip/PTC/Sylvan Caryatid.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/ThoughtKnotSeer.jpg", "PTC.zip/PTC/Thought-Knot Seer.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/TyrantOfValakut.jpg", "PTC.zip/PTC/Tyrant of Valakut.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/VileRedeemer.jpg", "PTC.zip/PTC/Vile Redeemer.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/WanderingFumarole.jpg", "PTC.zip/PTC/Wandering Fumarole.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/WorldBreaker.jpg", "PTC.zip/PTC/World Breaker.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/OGW/ZendikarResurgent.jpg", "PTC.zip/PTC/Zendikar Resurgent.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/AlteredEgo.jpg", "PTC.zip/PTC/Altered Ego.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/AlwaysWatching.jpg", "PTC.zip/PTC/Always Watching.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/AngelOfDeliverance.jpg", "PTC.zip/PTC/Angel of Deliverance.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/AnguishedUnmaking.jpg", "PTC.zip/PTC/Anguished Unmaking.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/ArchangelAvacyn.jpg", "PTC.zip/PTC/Archangel Avacyn.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/ArlinnKord.jpg", "PTC.zip/PTC/Arlinn Kord.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/AsylumVisitor.jpg", "PTC.zip/PTC/Asylum Visitor.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/AvacynGuardianAngel.jpg", "PTC.zip/PTC/Avacyn, Guardian Angel.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/AvacynsJudgment.jpg", "PTC.zip/PTC/Avacyn's Judgement.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/BeholdTheBeyond.jpg", "PTC.zip/PTC/Behold the Beyond.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/BrainInAJar.jpg", "PTC.zip/PTC/Brain in a Jar.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/BurnFromWithin.jpg", "PTC.zip/PTC/Burn from Within.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/BygoneBishop.jpg", "PTC.zip/PTC/Bygone Bishop.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/ChokedEstuary.jpg", "PTC.zip/PTC/Choked Estuary.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/ConfirmSuspicions.jpg", "PTC.zip/PTC/Confirm Suspicions.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/CorruptedGrafstone.jpg", "PTC.zip/PTC/Corrupted Grafstone.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/CryptolithRite.jpg", "PTC.zip/PTC/Cryptolith Rite.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/DeathcapCultivator.jpg", "PTC.zip/PTC/Deathcap Cultivator.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/DeclarationInStone.jpg", "PTC.zip/PTC/Declaration in Stone.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/DescendUponTheSinful.jpg", "PTC.zip/PTC/Descend upon the Sinful.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/DevilsPlayground.jpg", "PTC.zip/PTC/Devils' Playground.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/DiregrafColossus.jpg", "PTC.zip/PTC/Diregraf Colossus.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/DrogskolCavalry.jpg", "PTC.zip/PTC/Drogskol Cavalry.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/DrownyardTemple.jpg", "PTC.zip/PTC/Drownyard Temple.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/EerieInterlude.jpg", "PTC.zip/PTC/Eerie Interlude.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/EngulfTheShore.jpg", "PTC.zip/PTC/Engulf the Shore.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/EpiphanyAtTheDrownyard.jpg", "PTC.zip/PTC/Epiphany at the Drownyard.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/EverAfter.jpg", "PTC.zip/PTC/Ever After.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/FalkenrathGorger.jpg", "PTC.zip/PTC/Falkenrath Gorger.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/FeveredVisions.jpg", "PTC.zip/PTC/Fevered Visions.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/FlamebladeAngel.jpg", "PTC.zip/PTC/Flameblade Angel.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/ForebodingRuins.jpg", "PTC.zip/PTC/Foreboding Ruins.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/ForgottenCreation.jpg", "PTC.zip/PTC/Forgotten Creation.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/FortifiedVillage.jpg", "PTC.zip/PTC/Fortified Village.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/FromUnderTheFloorboards.jpg", "PTC.zip/PTC/From Under the Floorboards.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/GameTrail.jpg", "PTC.zip/PTC/Game Trail.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/GeierReachBandit.jpg", "PTC.zip/PTC/Geier Reach Bandit.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/GeierReachSanitarium.jpg", "PTC.zip/PTC/Geier Reach Sanitarium.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/GeralfsMasterpiece.jpg", "PTC.zip/PTC/Geralf's Masterpiece.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/GoldnightCastigator.jpg", "PTC.zip/PTC/Goldnight Castigator.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/HanweirMilitiaCaptain.jpg", "PTC.zip/PTC/Hanweir Militia Captain.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/HarnessTheStorm.jpg", "PTC.zip/PTC/Harness the Storm.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/InexorableBlob.jpg", "PTC.zip/PTC/Inexorable Blob.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/InvocationOfSaintTraft.jpg", "PTC.zip/PTC/Invocation of Saint Traft.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/JaceTheLivingGuildpact.jpg", "PTC.zip/PTC/Jace, the Living Guildpact.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/JaceUnravelerOfSecrets.jpg", "PTC.zip/PTC/Jace, Unraveler of Secrets.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/MarkovDreadknight.jpg", "PTC.zip/PTC/Markov Dreadknight.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/MindwrackDemon.jpg", "PTC.zip/PTC/Mindwrack Demon.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/NahiriTheHarbinger.jpg", "PTC.zip/PTC/Nahiri, the Harbinger.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/NephaliaMoondrakes.jpg", "PTC.zip/PTC/Nephalia Moondrakes.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/OdricLunarchMarshal.jpg", "PTC.zip/PTC/Odric, Lunarch Marshal.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/OliviaMobilizedForWar.jpg", "PTC.zip/PTC/Olivia, Mobilized for War.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/OrmendahlProfanePrince.jpg", "PTC.zip/PTC/Ormendahl, Profane Prince.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/PortTown.jpg", "PTC.zip/PTC/Port Town.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/PrizedAmalgam.jpg", "PTC.zip/PTC/Prized Amalgam.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/Rattlechains.jpg", "PTC.zip/PTC/Rattlechains.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/RelentlessDead.jpg", "PTC.zip/PTC/Relentless Dead.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/SageOfAncientLore.jpg", "PTC.zip/PTC/Sage of Ancient Lore.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/ScourgeWolf.jpg", "PTC.zip/PTC/Scourge Wolf.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/SeasonsPast.jpg", "PTC.zip/PTC/Seasons Past.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/SecondHarvest.jpg", "PTC.zip/PTC/Second Harvest.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/SigardaHeronsGrace.jpg", "PTC.zip/PTC/Sigarda, Heron's Grace.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/SilverfurPartisan.jpg", "PTC.zip/PTC/Silverfur Partisan.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/SinProdder.jpg", "PTC.zip/PTC/Sin Prodder.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/SlayersPlate.jpg", "PTC.zip/PTC/Slayer's Plate.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/SorinGrimNemesis.jpg", "PTC.zip/PTC/Sorin, Grim Nemesis.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/SorinSolemnVisitor.jpg", "PTC.zip/PTC/Sorin, Solemn Visitor.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/SoulSwallower.jpg", "PTC.zip/PTC/Soul Swallower.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/StartledAwake.jpg", "PTC.zip/PTC/Startled Awake.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/TamiyoFieldResearcher.jpg", "PTC.zip/PTC/Tamiyo, Field Researcher.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/TamiyosJournal.jpg", "PTC.zip/PTC/Tamiyo's Journal.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/ThaliaHereticCathar.jpg", "PTC.zip/PTC/Thalia, Heretic Cathar.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/ThaliasLieutenant.jpg", "PTC.zip/PTC/Thalia's Lieutenant.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/TheGitrogMonster.jpg", "PTC.zip/PTC/The Gitrog Monster.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/ThingInTheIce.jpg", "PTC.zip/PTC/Thing in the Ice.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/TirelessTracker.jpg", "PTC.zip/PTC/Tireless Tracker.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/ToTheSlaughter.jpg", "PTC.zip/PTC/To the Slaughter.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/TraverseTheUlvenwald.jpg", "PTC.zip/PTC/Traverse the Ulvenwald.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/Triskaidekaphobia.jpg", "PTC.zip/PTC/Triskaidekaphobia.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/UlvenwaldObserver.jpg", "PTC.zip/PTC/Ulvenwald Observer.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/WelcomeToTheFold.jpg", "PTC.zip/PTC/Welcome to the Fold.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/WestvaleAbbey.jpg", "PTC.zip/PTC/Westvale Abbey.full.jpg"); +// singleLinks.put("MTG/PRM/en/foil/Prerelease/SOI/WolfOfDevilsBreach.jpg", "PTC.zip/PTC/Wolf of Devil's Breach.full.jpg"); +// singleLinks.put("MTG/THS/en/promo/HerosDownfall.jpg", "PTC.zip/PTC/Hero's Downfall.full.jpg"); +// singleLinks.put("MTG/THS/en/promo/ReaperOfTheWilds.jpg", "PTC.zip/PTC/Reaper of the Wilds.full.jpg"); +// singleLinks.put("MTG/THS/en/promo/WhipOfErebos.jpg", "PTC.zip/PTC/Whip of Erebos.full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/AncientTomb.jpg", "EXP.zip/EXP/Ancient Tomb .full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/CascadeBluffs.jpg", "EXP.zip/EXP/Cascade Bluffs .full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/DustBowl.jpg", "EXP.zip/EXP/Dust Bowl .full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/EyeOfUgin.jpg", "EXP.zip/EXP/Eye of Ugin .full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/FetidHeath.jpg", "EXP.zip/EXP/Fetid Heath .full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/FireLitThicket.jpg", "EXP.zip/EXP/Fire-Lit Thicket .full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/FloodedGrove.jpg", "EXP.zip/EXP/Flooded Grove .full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/ForbiddenOrchard.jpg", "EXP.zip/EXP/Forbidden Orchard .full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/GravenCairns.jpg", "EXP.zip/EXP/Graven Cairns .full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/HorizonCanopy.jpg", "EXP.zip/EXP/Horizon Canopy.full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/KorHaven.jpg", "EXP.zip/EXP/Kor Haven.full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/ManaConfluence.jpg", "EXP.zip/EXP/Mana Confluence.full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/MysticGate.jpg", "EXP.zip/EXP/Mystic Gate.full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/RuggedPrairie.jpg", "EXP.zip/EXP/Rugged Prairie.full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/StripMine.jpg", "EXP.zip/EXP/Strip Mine.full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/SunkenRuins.jpg", "EXP.zip/EXP/Sunken Ruins.full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/TectonicEdge.jpg", "EXP.zip/EXP/Tectonic Edge.full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/TwilightMire.jpg", "EXP.zip/EXP/Twilight Mire.full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/Wasteland.jpg", "EXP.zip/EXP/Wasteland.full.jpg"); +// singleLinks.put("MTG/EXP/en/foil/WoodedBastion.jpg", "EXP.zip/EXP/Wooded Bastion.full.jpg"); +// singleLinks.put("apac/1.jpg", "APAC.zip/APAC/Forest.1.full.jpg"); +// singleLinks.put("apac/10.jpg", "APAC.zip/APAC/Swamp.10.full.jpg"); +// singleLinks.put("apac/11.jpg", "APAC.zip/APAC/Forest.11.full.jpg"); +// singleLinks.put("apac/12.jpg", "APAC.zip/APAC/Island.7.full.jpg"); +// singleLinks.put("apac/13.jpg", "APAC.zip/APAC/Mountain.13.full.jpg"); +// singleLinks.put("apac/14.jpg", "APAC.zip/APAC/Plains.14.full.jpg"); +// singleLinks.put("apac/15.jpg", "APAC.zip/APAC/Swamp.15.full.jpg"); +// singleLinks.put("apac/2.jpg", "APAC.zip/APAC/Island.2.full.jpg"); +// singleLinks.put("apac/3.jpg", "APAC.zip/APAC/Mountain.3.full.jpg"); +// singleLinks.put("apac/4.jpg", "APAC.zip/APAC/Plains.4.full.jpg"); +// singleLinks.put("apac/5.jpg", "APAC.zip/APAC/Swamp.5.full.jpg"); +// singleLinks.put("apac/6.jpg", "APAC.zip/APAC/Forest.6.full.jpg"); +// singleLinks.put("apac/7.jpg", "APAC.zip/APAC/Island.12.full.jpg"); +// singleLinks.put("apac/8.jpg", "APAC.zip/APAC/Mountain.8.full.jpg"); +// singleLinks.put("apac/9.jpg", "APAC.zip/APAC/Plains.9.full.jpg"); +// singleLinks.put("arena/1.jpg", "ARENA.zip/ARENA/Plains.1.full.jpg"); +// singleLinks.put("arena/10.jpg", "ARENA.zip/ARENA/Swamp.10.full.jpg"); +// singleLinks.put("arena/11.jpg", "ARENA.zip/ARENA/Mountain.11.full.jpg"); +// singleLinks.put("arena/12.jpg", "ARENA.zip/ARENA/Forest.12.full.jpg"); +// singleLinks.put("arena/13.jpg", "ARENA.zip/ARENA/Pouncing Jaguar.full.jpg"); +// singleLinks.put("arena/14.jpg", "ARENA.zip/ARENA/Skittering Skirge.full.jpg"); +// singleLinks.put("arena/15.jpg", "ARENA.zip/ARENA/Rewind.full.jpg"); +// singleLinks.put("arena/16.jpg", "ARENA.zip/ARENA/Karn, Silver Golem.full.jpg"); +// singleLinks.put("arena/17.jpg", "ARENA.zip/ARENA/Duress.full.jpg"); +// singleLinks.put("arena/18.jpg", "ARENA.zip/ARENA/Uktabi Orangutan.full.jpg"); +// singleLinks.put("arena/19.jpg", "ARENA.zip/ARENA/Chill.full.jpg"); +// singleLinks.put("arena/2.jpg", "ARENA.zip/ARENA/Island.2.full.jpg"); +// singleLinks.put("arena/20.jpg", "ARENA.zip/ARENA/Pillage.full.jpg"); +// singleLinks.put("arena/21.jpg", "ARENA.zip/ARENA/Enlightened Tutor.full.jpg"); +// singleLinks.put("arena/22.jpg", "ARENA.zip/ARENA/Stupor.full.jpg"); +// singleLinks.put("arena/23.jpg", "ARENA.zip/ARENA/Plains.23.full.jpg"); +// singleLinks.put("arena/24.jpg", "ARENA.zip/ARENA/Island.24.full.jpg"); +// singleLinks.put("arena/25.jpg", "ARENA.zip/ARENA/Swamp.25.full.jpg"); +// singleLinks.put("arena/26.jpg", "ARENA.zip/ARENA/Mountain.26.full.jpg"); +// singleLinks.put("arena/27.jpg", "ARENA.zip/ARENA/Forest.27.full.jpg"); +// singleLinks.put("arena/28.jpg", "ARENA.zip/ARENA/Creeping Mold.full.jpg"); +// singleLinks.put("arena/29.jpg", "ARENA.zip/ARENA/Dismiss.full.jpg"); +// singleLinks.put("arena/3.jpg", "ARENA.zip/ARENA/Swamp.3.full.jpg"); +// singleLinks.put("arena/30.jpg", "ARENA.zip/ARENA/Fling.full.jpg"); +// singleLinks.put("arena/31.jpg", "ARENA.zip/ARENA/Empyrial Armor.full.jpg"); +// singleLinks.put("arena/32.jpg", "ARENA.zip/ARENA/Plains.32.full.jpg"); +// singleLinks.put("arena/33.jpg", "ARENA.zip/ARENA/Island.33.full.jpg"); +// singleLinks.put("arena/34.jpg", "ARENA.zip/ARENA/Swamp.34.full.jpg"); +// singleLinks.put("arena/35.jpg", "ARENA.zip/ARENA/Mountain.35.full.jpg"); +// singleLinks.put("arena/36.jpg", "ARENA.zip/ARENA/Forest.36.full.jpg"); +// singleLinks.put("arena/37.jpg", "ARENA.zip/ARENA/Diabolic Edict.full.jpg"); +// singleLinks.put("arena/38.jpg", "ARENA.zip/ARENA/Gaea's Blessing.full.jpg"); +// singleLinks.put("arena/39.jpg", "ARENA.zip/ARENA/Island.39.full.jpg"); +// singleLinks.put("arena/4.jpg", "ARENA.zip/ARENA/Mountain.4.full.jpg"); +// singleLinks.put("arena/40.jpg", "ARENA.zip/ARENA/Forest.40.full.jpg"); +// singleLinks.put("arena/41.jpg", "ARENA.zip/ARENA/Man-o'-War.full.jpg"); +// singleLinks.put("arena/42.jpg", "ARENA.zip/ARENA/Arc Lightning.full.jpg"); +// singleLinks.put("arena/43.jpg", "ARENA.zip/ARENA/Dauthi Slayer.full.jpg"); +// singleLinks.put("arena/44.jpg", "ARENA.zip/ARENA/Mana Leak.full.jpg"); +// singleLinks.put("arena/45.jpg", "ARENA.zip/ARENA/Plains.45.full.jpg"); +// singleLinks.put("arena/46.jpg", "ARENA.zip/ARENA/Island.46.full.jpg"); +// singleLinks.put("arena/47.jpg", "ARENA.zip/ARENA/Swamp.47.full.jpg"); +// singleLinks.put("arena/48.jpg", "ARENA.zip/ARENA/Mountain.48.full.jpg"); +// singleLinks.put("arena/5.jpg", "ARENA.zip/ARENA/Forest.5.full.jpg"); +// singleLinks.put("arena/50.jpg", "ARENA.zip/ARENA/Skirk Marauder.full.jpg"); +// singleLinks.put("arena/51.jpg", "ARENA.zip/ARENA/Elvish Aberration.full.jpg"); +// singleLinks.put("arena/52.jpg", "ARENA.zip/ARENA/Bonesplitter.full.jpg"); +// singleLinks.put("arena/53.jpg", "ARENA.zip/ARENA/Plains.53.full.jpg"); +// singleLinks.put("arena/54.jpg", "ARENA.zip/ARENA/Island.54.full.jpg"); +// singleLinks.put("arena/55.jpg", "ARENA.zip/ARENA/Swamp.55.full.jpg"); +// singleLinks.put("arena/56.jpg", "ARENA.zip/ARENA/Mountain.56.full.jpg"); +// singleLinks.put("arena/57.jpg", "ARENA.zip/ARENA/Forest.57.full.jpg"); +// singleLinks.put("arena/58.jpg", "ARENA.zip/ARENA/Darksteel Ingot.full.jpg"); +// singleLinks.put("arena/59.jpg", "ARENA.zip/ARENA/Serum Visions.full.jpg"); +// singleLinks.put("arena/6.jpg", "ARENA.zip/ARENA/Disenchant.full.jpg"); +// singleLinks.put("arena/60.jpg", "ARENA.zip/ARENA/Glacial Ray.full.jpg"); +// singleLinks.put("arena/61.jpg", "ARENA.zip/ARENA/Circle of Protection Art.full.jpg"); +// singleLinks.put("arena/62.jpg", "ARENA.zip/ARENA/Mise.full.jpg"); +// singleLinks.put("arena/63.jpg", "ARENA.zip/ARENA/Booster Tutor.full.jpg"); +// singleLinks.put("arena/64.jpg", "ARENA.zip/ARENA/Goblin Mime.full.jpg"); +// singleLinks.put("arena/65.jpg", "ARENA.zip/ARENA/Granny's Payback.full.jpg"); +// singleLinks.put("arena/66.jpg", "ARENA.zip/ARENA/Ashnod's Coupon.full.jpg"); +// singleLinks.put("arena/67.jpg", "ARENA.zip/ARENA/Plains.67.full.jpg"); +// singleLinks.put("arena/68.jpg", "ARENA.zip/ARENA/Island.68.full.jpg"); +// singleLinks.put("arena/69.jpg", "ARENA.zip/ARENA/Swamp.69.full.jpg"); +// singleLinks.put("arena/7.jpg", "ARENA.zip/ARENA/Fireball.full.jpg"); +// singleLinks.put("arena/70.jpg", "ARENA.zip/ARENA/Mountain.70.full.jpg"); +// singleLinks.put("arena/71.jpg", "ARENA.zip/ARENA/Forest.71.full.jpg"); +// singleLinks.put("arena/72.jpg", "ARENA.zip/ARENA/Genju of the Spires.full.jpg"); +// singleLinks.put("arena/73.jpg", "ARENA.zip/ARENA/Okina Nightwatch.full.jpg"); +// singleLinks.put("arena/74.jpg", "ARENA.zip/ARENA/Skyknight Legionnaire.full.jpg"); +// singleLinks.put("arena/75.jpg", "ARENA.zip/ARENA/Plains.75.full.jpg"); +// singleLinks.put("arena/76.jpg", "ARENA.zip/ARENA/Island.76.full.jpg"); +// singleLinks.put("arena/77.jpg", "ARENA.zip/ARENA/Swamp.77.full.jpg"); +// singleLinks.put("arena/78.jpg", "ARENA.zip/ARENA/Mountain.78.full.jpg"); +// singleLinks.put("arena/8.jpg", "ARENA.zip/ARENA/Plains.8.full.jpg"); +// singleLinks.put("arena/80.jpg", "ARENA.zip/ARENA/Castigate.full.jpg"); +// singleLinks.put("arena/81.jpg", "ARENA.zip/ARENA/Wee Dragonauts.full.jpg"); +// singleLinks.put("arena/82.jpg", "ARENA.zip/ARENA/Coiling Oracle.full.jpg"); +// singleLinks.put("arena/83.jpg", "ARENA.zip/ARENA/Surging Flame.full.jpg"); +// singleLinks.put("arena/9.jpg", "ARENA.zip/ARENA/Island.9.full.jpg"); +// singleLinks.put("euro/1.jpg", "EURO.zip/EURO/Forest.1.full.jpg"); +// singleLinks.put("euro/10.jpg", "EURO.zip/EURO/Swamp.10.full.jpg"); +// singleLinks.put("euro/11.jpg", "EURO.zip/EURO/Forest.11.full.jpg"); +// singleLinks.put("euro/12.jpg", "EURO.zip/EURO/Island.12.full.jpg"); +// singleLinks.put("euro/13.jpg", "EURO.zip/EURO/Mountain.13.full.jpg"); +// singleLinks.put("euro/14.jpg", "EURO.zip/EURO/Plains.14.full.jpg"); +// singleLinks.put("euro/15.jpg", "EURO.zip/EURO/Swamp.15.full.jpg"); +// singleLinks.put("euro/2.jpg", "EURO.zip/EURO/Island.2.full.jpg"); +// singleLinks.put("euro/3.jpg", "EURO.zip/EURO/Mountain.3.full.jpg"); +// singleLinks.put("euro/4.jpg", "EURO.zip/EURO/Plains.4.full.jpg"); +// singleLinks.put("euro/5.jpg", "EURO.zip/EURO/Swamp.5.full.jpg"); +// singleLinks.put("euro/6.jpg", "EURO.zip/EURO/Forest.6.full.jpg"); +// singleLinks.put("euro/7.jpg", "EURO.zip/EURO/Island.7.full.jpg"); +// singleLinks.put("euro/8.jpg", "EURO.zip/EURO/Mountain.8.full.jpg"); +// singleLinks.put("euro/9.jpg", "EURO.zip/EURO/Plains.9.full.jpg"); +// singleLinks.put("exp/1.jpg", "EXP.zip/EXP/Prairie Stream.full.jpg"); +// singleLinks.put("exp/10.jpg", "EXP.zip/EXP/Temple Garden.full.jpg"); +// singleLinks.put("exp/11.jpg", "EXP.zip/EXP/Godless Shrine.full.jpg"); +// singleLinks.put("exp/12.jpg", "EXP.zip/EXP/Steam Vents.full.jpg"); +// singleLinks.put("exp/13.jpg", "EXP.zip/EXP/Overgrown Tomb.full.jpg"); +// singleLinks.put("exp/14.jpg", "EXP.zip/EXP/Sacred Foundry.full.jpg"); +// singleLinks.put("exp/15.jpg", "EXP.zip/EXP/Breeding Pool.full.jpg"); +// singleLinks.put("exp/16.jpg", "EXP.zip/EXP/Flooded Strand.full.jpg"); +// singleLinks.put("exp/17.jpg", "EXP.zip/EXP/Polluted Delta.full.jpg"); +// singleLinks.put("exp/18.jpg", "EXP.zip/EXP/Bloodstained Mire.full.jpg"); +// singleLinks.put("exp/19.jpg", "EXP.zip/EXP/Wooded Foothills.full.jpg"); +// singleLinks.put("exp/2.jpg", "EXP.zip/EXP/Sunken Hollow.full.jpg"); +// singleLinks.put("exp/20.jpg", "EXP.zip/EXP/Windswept Heath.full.jpg"); +// singleLinks.put("exp/21.jpg", "EXP.zip/EXP/Marsh Flats.full.jpg"); +// singleLinks.put("exp/22.jpg", "EXP.zip/EXP/Scalding Tarn.full.jpg"); +// singleLinks.put("exp/23.jpg", "EXP.zip/EXP/Verdant Catacombs.full.jpg"); +// singleLinks.put("exp/24.jpg", "EXP.zip/EXP/Arid Mesa.full.jpg"); +// singleLinks.put("exp/25.jpg", "EXP.zip/EXP/Misty Rainforest.full.jpg"); +// singleLinks.put("exp/3.jpg", "EXP.zip/EXP/Smoldering Marsh.full.jpg"); +// singleLinks.put("exp/4.jpg", "EXP.zip/EXP/Cinder Glade.full.jpg"); +// singleLinks.put("exp/5.jpg", "EXP.zip/EXP/Canopy Vista.full.jpg"); +// singleLinks.put("exp/6.jpg", "EXP.zip/EXP/Hallowed Fountain.full.jpg"); +// singleLinks.put("exp/7.jpg", "EXP.zip/EXP/Watery Grave.full.jpg"); +// singleLinks.put("exp/8.jpg", "EXP.zip/EXP/Blood Crypt.full.jpg"); +// singleLinks.put("exp/9.jpg", "EXP.zip/EXP/Stomping Ground.full.jpg"); +// singleLinks.put("fnmp/1.jpg", "FNMP.zip/FNMP/River Boa.full.jpg"); +// singleLinks.put("fnmp/10.jpg", "FNMP.zip/FNMP/Stone Rain.full.jpg"); +// singleLinks.put("fnmp/100.jpg", "FNMP.zip/FNMP/Thirst for Knowledge.full.jpg"); +// singleLinks.put("fnmp/101.jpg", "FNMP.zip/FNMP/Serrated Arrows.full.jpg"); +// singleLinks.put("fnmp/102.jpg", "FNMP.zip/FNMP/Isochron Scepter.full.jpg"); +// singleLinks.put("fnmp/103.jpg", "FNMP.zip/FNMP/Shrapnel Blast.full.jpg"); +// singleLinks.put("fnmp/104.jpg", "FNMP.zip/FNMP/Magma Jet.full.jpg"); +// singleLinks.put("fnmp/105.jpg", "FNMP.zip/FNMP/Myr Enforcer.full.jpg"); +// singleLinks.put("fnmp/106.jpg", "FNMP.zip/FNMP/Kitchen Finks.full.jpg"); +// singleLinks.put("fnmp/107.jpg", "FNMP.zip/FNMP/Merrow Reejerey.full.jpg"); +// singleLinks.put("fnmp/108.jpg", "FNMP.zip/FNMP/Wren's Run Vanquisher.full.jpg"); +// singleLinks.put("fnmp/109.jpg", "FNMP.zip/FNMP/Mulldrifter.full.jpg"); +// singleLinks.put("fnmp/11.jpg", "FNMP.zip/FNMP/Llanowar Elves.full.jpg"); +// singleLinks.put("fnmp/110.jpg", "FNMP.zip/FNMP/Murderous Redcap.full.jpg"); +// singleLinks.put("fnmp/111.jpg", "FNMP.zip/FNMP/Lightning Greaves.full.jpg"); +// singleLinks.put("fnmp/112.jpg", "FNMP.zip/FNMP/Watchwolf.full.jpg"); +// singleLinks.put("fnmp/113.jpg", "FNMP.zip/FNMP/Browbeat.full.jpg"); +// singleLinks.put("fnmp/114.jpg", "FNMP.zip/FNMP/Oblivion Ring.full.jpg"); +// singleLinks.put("fnmp/115.jpg", "FNMP.zip/FNMP/Sakura-Tribe Elder.full.jpg"); +// singleLinks.put("fnmp/116.jpg", "FNMP.zip/FNMP/Tidehollow Sculler.full.jpg"); +// singleLinks.put("fnmp/117.jpg", "FNMP.zip/FNMP/Ghostly Prison.full.jpg"); +// singleLinks.put("fnmp/118.jpg", "FNMP.zip/FNMP/Ancient Ziggurat.full.jpg"); +// singleLinks.put("fnmp/119.jpg", "FNMP.zip/FNMP/Bloodbraid Elf.full.jpg"); +// singleLinks.put("fnmp/12.jpg", "FNMP.zip/FNMP/Swords to Plowshares.full.jpg"); +// singleLinks.put("fnmp/120.jpg", "FNMP.zip/FNMP/Cloudpost.full.jpg"); +// singleLinks.put("fnmp/121.jpg", "FNMP.zip/FNMP/Elvish Visionary.full.jpg"); +// singleLinks.put("fnmp/122.jpg", "FNMP.zip/FNMP/Anathemancer.full.jpg"); +// singleLinks.put("fnmp/123.jpg", "FNMP.zip/FNMP/Krosan Grip.full.jpg"); +// singleLinks.put("fnmp/124.jpg", "FNMP.zip/FNMP/Qasali Pridemage.full.jpg"); +// singleLinks.put("fnmp/125.jpg", "FNMP.zip/FNMP/Rift Bolt.full.jpg"); +// singleLinks.put("fnmp/126.jpg", "FNMP.zip/FNMP/Gatekeeper of Malakir.full.jpg"); +// singleLinks.put("fnmp/127.jpg", "FNMP.zip/FNMP/Wild Nacatl.full.jpg"); +// singleLinks.put("fnmp/128.jpg", "FNMP.zip/FNMP/Everflowing Chalice.full.jpg"); +// singleLinks.put("fnmp/129.jpg", "FNMP.zip/FNMP/Spellstutter Sprite.full.jpg"); +// singleLinks.put("fnmp/13.jpg", "FNMP.zip/FNMP/Ophidian.full.jpg"); +// singleLinks.put("fnmp/130.jpg", "FNMP.zip/FNMP/Wall of Omens.full.jpg"); +// singleLinks.put("fnmp/131.jpg", "FNMP.zip/FNMP/Artisan of Kozilek.full.jpg"); +// singleLinks.put("fnmp/132.jpg", "FNMP.zip/FNMP/Squadron Hawk.full.jpg"); +// singleLinks.put("fnmp/133.jpg", "FNMP.zip/FNMP/Rhox War Monk.full.jpg"); +// singleLinks.put("fnmp/134.jpg", "FNMP.zip/FNMP/Jace's Ingenuity.full.jpg"); +// singleLinks.put("fnmp/135.jpg", "FNMP.zip/FNMP/Cultivate.full.jpg"); +// singleLinks.put("fnmp/136.jpg", "FNMP.zip/FNMP/Teetering Peaks.full.jpg"); +// singleLinks.put("fnmp/137.jpg", "FNMP.zip/FNMP/Contagion Clasp.full.jpg"); +// singleLinks.put("fnmp/138.jpg", "FNMP.zip/FNMP/Go for the Throat.full.jpg"); +// singleLinks.put("fnmp/139.jpg", "FNMP.zip/FNMP/Savage Lands.full.jpg"); +// singleLinks.put("fnmp/14.jpg", "FNMP.zip/FNMP/Jackal Pup.full.jpg"); +// singleLinks.put("fnmp/140.jpg", "FNMP.zip/FNMP/Glistener Elf.full.jpg"); +// singleLinks.put("fnmp/141.jpg", "FNMP.zip/FNMP/Despise.full.jpg"); +// singleLinks.put("fnmp/142.jpg", "FNMP.zip/FNMP/Tectonic Edge.full.jpg"); +// singleLinks.put("fnmp/143.jpg", "FNMP.zip/FNMP/Dismember.full.jpg"); +// singleLinks.put("fnmp/144.jpg", "FNMP.zip/FNMP/Ancient Grudge.full.jpg"); +// singleLinks.put("fnmp/145.jpg", "FNMP.zip/FNMP/Acidic Slime.full.jpg"); +// singleLinks.put("fnmp/146.jpg", "FNMP.zip/FNMP/Forbidden Alchemy.full.jpg"); +// singleLinks.put("fnmp/147.jpg", "FNMP.zip/FNMP/Avacyn's Pilgrim.full.jpg"); +// singleLinks.put("fnmp/148.jpg", "FNMP.zip/FNMP/Lingering Souls.full.jpg"); +// singleLinks.put("fnmp/149.jpg", "FNMP.zip/FNMP/Evolving Wilds.full.jpg"); +// singleLinks.put("fnmp/15.jpg", "FNMP.zip/FNMP/Quirion Ranger.full.jpg"); +// singleLinks.put("fnmp/150.jpg", "FNMP.zip/FNMP/Pillar of Flame.full.jpg"); +// singleLinks.put("fnmp/151.jpg", "FNMP.zip/FNMP/Gitaxian Probe.full.jpg"); +// singleLinks.put("fnmp/152.jpg", "FNMP.zip/FNMP/Searing Spear.full.jpg"); +// singleLinks.put("fnmp/153.jpg", "FNMP.zip/FNMP/Reliquary Tower.full.jpg"); +// singleLinks.put("fnmp/154.jpg", "FNMP.zip/FNMP/Farseek.full.jpg"); +// singleLinks.put("fnmp/155.jpg", "FNMP.zip/FNMP/Call of the Conclave.full.jpg"); +// singleLinks.put("fnmp/156.jpg", "FNMP.zip/FNMP/Judge's Familiar.full.jpg"); +// singleLinks.put("fnmp/157.jpg", "FNMP.zip/FNMP/Izzet Charm.full.jpg"); +// singleLinks.put("fnmp/158.jpg", "FNMP.zip/FNMP/Rakdos Cackler.full.jpg"); +// singleLinks.put("fnmp/159.jpg", "FNMP.zip/FNMP/Dimir Charm.full.jpg"); +// singleLinks.put("fnmp/16.jpg", "FNMP.zip/FNMP/Carnophage.full.jpg"); +// singleLinks.put("fnmp/160.jpg", "FNMP.zip/FNMP/Experiment One.full.jpg"); +// singleLinks.put("fnmp/161.jpg", "FNMP.zip/FNMP/Ghor-Clan Rampager.full.jpg"); +// singleLinks.put("fnmp/162.jpg", "FNMP.zip/FNMP/Grisly Salvage.full.jpg"); +// singleLinks.put("fnmp/163.jpg", "FNMP.zip/FNMP/Sin Collector.full.jpg"); +// singleLinks.put("fnmp/164.jpg", "FNMP.zip/FNMP/Warleader's Helix.full.jpg"); +// singleLinks.put("fnmp/165.jpg", "FNMP.zip/FNMP/Elvish Mystic.full.jpg"); +// singleLinks.put("fnmp/166.jpg", "FNMP.zip/FNMP/Banisher Priest.full.jpg"); +// singleLinks.put("fnmp/167.jpg", "FNMP.zip/FNMP/Encroaching Wastes.full.jpg"); +// singleLinks.put("fnmp/168.jpg", "FNMP.zip/FNMP/Tormented Hero.full.jpg"); +// singleLinks.put("fnmp/169.jpg", "FNMP.zip/FNMP/Dissolve.full.jpg"); +// singleLinks.put("fnmp/17.jpg", "FNMP.zip/FNMP/Impulse.full.jpg"); +// singleLinks.put("fnmp/170.jpg", "FNMP.zip/FNMP/Magma Spray.full.jpg"); +// singleLinks.put("fnmp/171.jpg", "FNMP.zip/FNMP/Bile Blight.full.jpg"); +// singleLinks.put("fnmp/172.jpg", "FNMP.zip/FNMP/Banishing Light.full.jpg"); +// singleLinks.put("fnmp/173.jpg", "FNMP.zip/FNMP/Fanatic of Xenagos.full.jpg"); +// singleLinks.put("fnmp/174.jpg", "FNMP.zip/FNMP/Brain Maggot.full.jpg"); +// singleLinks.put("fnmp/175.jpg", "FNMP.zip/FNMP/Stoke the Flames.full.jpg"); +// singleLinks.put("fnmp/176.jpg", "FNMP.zip/FNMP/Frenzied Goblin.full.jpg"); +// singleLinks.put("fnmp/177.jpg", "FNMP.zip/FNMP/Disdainful Stroke.full.jpg"); +// singleLinks.put("fnmp/178.jpg", "FNMP.zip/FNMP/Hordeling Outburst.full.jpg"); +// singleLinks.put("fnmp/179.jpg", "FNMP.zip/FNMP/Suspension Field.full.jpg"); +// singleLinks.put("fnmp/18.jpg", "FNMP.zip/FNMP/Fireblast.full.jpg"); +// singleLinks.put("fnmp/180.jpg", "FNMP.zip/FNMP/Abzan Beastmaster.full.jpg"); +// singleLinks.put("fnmp/181.jpg", "FNMP.zip/FNMP/Frost Walker.full.jpg"); +// singleLinks.put("fnmp/182.jpg", "FNMP.zip/FNMP/Path to Exile.full.jpg"); +// singleLinks.put("fnmp/183.jpg", "FNMP.zip/FNMP/Serum Visions.full.jpg"); +// singleLinks.put("fnmp/184.jpg", "FNMP.zip/FNMP/Orator of Ojutai.full.jpg"); +// singleLinks.put("fnmp/186.jpg", "FNMP.zip/FNMP/Roast.full.jpg"); +// singleLinks.put("fnmp/187.jpg", "FNMP.zip/FNMP/Anticipate.full.jpg"); +// singleLinks.put("fnmp/188.jpg", "FNMP.zip/FNMP/Nissa's Pilgrimage.full.jpg"); +// singleLinks.put("fnmp/189.jpg", "FNMP.zip/FNMP/Clash of Wills.full.jpg"); +// singleLinks.put("fnmp/19.jpg", "FNMP.zip/FNMP/Soltari Priest.full.jpg"); +// singleLinks.put("fnmp/190.jpg", "FNMP.zip/FNMP/Smash to Smithereens.full.jpg"); +// singleLinks.put("fnmp/191.jpg", "FNMP.zip/FNMP/Blighted Fen.full.jpg"); +// singleLinks.put("fnmp/2.jpg", "FNMP.zip/FNMP/Terror.full.jpg"); +// singleLinks.put("fnmp/20.jpg", "FNMP.zip/FNMP/Albino Troll.full.jpg"); +// singleLinks.put("fnmp/21.jpg", "FNMP.zip/FNMP/Dissipate.full.jpg"); +// singleLinks.put("fnmp/22.jpg", "FNMP.zip/FNMP/Black Knight.full.jpg"); +// singleLinks.put("fnmp/23.jpg", "FNMP.zip/FNMP/Wall of Blossoms.full.jpg"); +// singleLinks.put("fnmp/24.jpg", "FNMP.zip/FNMP/Fireslinger.full.jpg"); +// singleLinks.put("fnmp/25.jpg", "FNMP.zip/FNMP/Drain Life.full.jpg"); +// singleLinks.put("fnmp/26.jpg", "FNMP.zip/FNMP/Aura of Silence.full.jpg"); +// singleLinks.put("fnmp/27.jpg", "FNMP.zip/FNMP/Forbid.full.jpg"); +// singleLinks.put("fnmp/28.jpg", "FNMP.zip/FNMP/Spike Feeder.full.jpg"); +// singleLinks.put("fnmp/29.jpg", "FNMP.zip/FNMP/Mogg Fanatic.full.jpg"); +// singleLinks.put("fnmp/3.jpg", "FNMP.zip/FNMP/Longbow Archer.full.jpg"); +// singleLinks.put("fnmp/30.jpg", "FNMP.zip/FNMP/White Knight.full.jpg"); +// singleLinks.put("fnmp/31.jpg", "FNMP.zip/FNMP/Disenchant.full.jpg"); +// singleLinks.put("fnmp/32.jpg", "FNMP.zip/FNMP/Bottle Gnomes.full.jpg"); +// singleLinks.put("fnmp/33.jpg", "FNMP.zip/FNMP/Muscle Sliver.full.jpg"); +// singleLinks.put("fnmp/34.jpg", "FNMP.zip/FNMP/Crystalline Sliver.full.jpg"); +// singleLinks.put("fnmp/35.jpg", "FNMP.zip/FNMP/Capsize.full.jpg"); +// singleLinks.put("fnmp/36.jpg", "FNMP.zip/FNMP/Priest of Titania.full.jpg"); +// singleLinks.put("fnmp/37.jpg", "FNMP.zip/FNMP/Goblin Bombardment.full.jpg"); +// singleLinks.put("fnmp/38.jpg", "FNMP.zip/FNMP/Scragnoth.full.jpg"); +// singleLinks.put("fnmp/39.jpg", "FNMP.zip/FNMP/Smother.full.jpg"); +// singleLinks.put("fnmp/4.jpg", "FNMP.zip/FNMP/Volcanic Geyser.full.jpg"); +// singleLinks.put("fnmp/40.jpg", "FNMP.zip/FNMP/Whipcorder.full.jpg"); +// singleLinks.put("fnmp/41.jpg", "FNMP.zip/FNMP/Sparksmith.full.jpg"); +// singleLinks.put("fnmp/42.jpg", "FNMP.zip/FNMP/Krosan Tusker.full.jpg"); +// singleLinks.put("fnmp/43.jpg", "FNMP.zip/FNMP/Withered Wretch.full.jpg"); +// singleLinks.put("fnmp/44.jpg", "FNMP.zip/FNMP/Willbender.full.jpg"); +// singleLinks.put("fnmp/45.jpg", "FNMP.zip/FNMP/Slice and Dice.full.jpg"); +// singleLinks.put("fnmp/46.jpg", "FNMP.zip/FNMP/Silver Knight.full.jpg"); +// singleLinks.put("fnmp/47.jpg", "FNMP.zip/FNMP/Krosan Warchief.full.jpg"); +// singleLinks.put("fnmp/48.jpg", "FNMP.zip/FNMP/Lightning Rift.full.jpg"); +// singleLinks.put("fnmp/49.jpg", "FNMP.zip/FNMP/Carrion Feeder.full.jpg"); +// singleLinks.put("fnmp/5.jpg", "FNMP.zip/FNMP/Mind Warp.full.jpg"); +// singleLinks.put("fnmp/50.jpg", "FNMP.zip/FNMP/Treetop Village.full.jpg"); +// singleLinks.put("fnmp/51.jpg", "FNMP.zip/FNMP/Accumulated Knowledge.full.jpg"); +// singleLinks.put("fnmp/52.jpg", "FNMP.zip/FNMP/Avalanche Riders.full.jpg"); +// singleLinks.put("fnmp/53.jpg", "FNMP.zip/FNMP/Reanimate.full.jpg"); +// singleLinks.put("fnmp/54.jpg", "FNMP.zip/FNMP/Mother of Runes.full.jpg"); +// singleLinks.put("fnmp/55.jpg", "FNMP.zip/FNMP/Brainstorm.full.jpg"); +// singleLinks.put("fnmp/56.jpg", "FNMP.zip/FNMP/Rancor.full.jpg"); +// singleLinks.put("fnmp/57.jpg", "FNMP.zip/FNMP/Seal of Cleansing.full.jpg"); +// singleLinks.put("fnmp/58.jpg", "FNMP.zip/FNMP/Flametongue Kavu.full.jpg"); +// singleLinks.put("fnmp/59.jpg", "FNMP.zip/FNMP/Blastoderm.full.jpg"); +// singleLinks.put("fnmp/6.jpg", "FNMP.zip/FNMP/Shock.full.jpg"); +// singleLinks.put("fnmp/60.jpg", "FNMP.zip/FNMP/Cabal Therapy.full.jpg"); +// singleLinks.put("fnmp/61.jpg", "FNMP.zip/FNMP/Fact or Fiction.full.jpg"); +// singleLinks.put("fnmp/62.jpg", "FNMP.zip/FNMP/Juggernaut.full.jpg"); +// singleLinks.put("fnmp/63.jpg", "FNMP.zip/FNMP/Circle of Protection Red.full.jpg"); +// singleLinks.put("fnmp/64.jpg", "FNMP.zip/FNMP/Kird Ape.full.jpg"); +// singleLinks.put("fnmp/65.jpg", "FNMP.zip/FNMP/Duress.full.jpg"); +// singleLinks.put("fnmp/66.jpg", "FNMP.zip/FNMP/Counterspell.full.jpg"); +// singleLinks.put("fnmp/67.jpg", "FNMP.zip/FNMP/Icy Manipulator.full.jpg"); +// singleLinks.put("fnmp/68.jpg", "FNMP.zip/FNMP/Elves of Deep Shadow.full.jpg"); +// singleLinks.put("fnmp/69.jpg", "FNMP.zip/FNMP/Armadillo Cloak.full.jpg"); +// singleLinks.put("fnmp/7.jpg", "FNMP.zip/FNMP/Staunch Defenders.full.jpg"); +// singleLinks.put("fnmp/70.jpg", "FNMP.zip/FNMP/Terminate.full.jpg"); +// singleLinks.put("fnmp/71.jpg", "FNMP.zip/FNMP/Lobotomy.full.jpg"); +// singleLinks.put("fnmp/72.jpg", "FNMP.zip/FNMP/Goblin Warchief.full.jpg"); +// singleLinks.put("fnmp/73.jpg", "FNMP.zip/FNMP/Wild Mongrel.full.jpg"); +// singleLinks.put("fnmp/74.jpg", "FNMP.zip/FNMP/Chainer's Edict.full.jpg"); +// singleLinks.put("fnmp/75.jpg", "FNMP.zip/FNMP/Circular Logic.full.jpg"); +// singleLinks.put("fnmp/76.jpg", "FNMP.zip/FNMP/Astral Slide.full.jpg"); +// singleLinks.put("fnmp/77.jpg", "FNMP.zip/FNMP/Arrogant Wurm.full.jpg"); +// singleLinks.put("fnmp/78a.jpg", "FNMP.zip/FNMP/Life (Life/Death.full.jpg"); +// singleLinks.put("fnmp/78b.jpg", "FNMP.zip/FNMP/Death (Life/Death).full.jpg"); +// singleLinks.put("fnmp/79a.jpg", "FNMP.zip/FNMP/Fire (Fire/Ice).full.jpg"); +// singleLinks.put("fnmp/79b.jpg", "FNMP.zip/FNMP/Ice (Fire/Ice).full.jpg"); +// singleLinks.put("fnmp/8.jpg", "FNMP.zip/FNMP/Giant Growth.full.jpg"); +// singleLinks.put("fnmp/80.jpg", "FNMP.zip/FNMP/Firebolt.full.jpg"); +// singleLinks.put("fnmp/81.jpg", "FNMP.zip/FNMP/Deep Analysis.full.jpg"); +// singleLinks.put("fnmp/82.jpg", "FNMP.zip/FNMP/Gerrard's Verdict.full.jpg"); +// singleLinks.put("fnmp/83.jpg", "FNMP.zip/FNMP/Basking Rootwalla.full.jpg"); +// singleLinks.put("fnmp/84.jpg", "FNMP.zip/FNMP/Wonder.full.jpg"); +// singleLinks.put("fnmp/85.jpg", "FNMP.zip/FNMP/Goblin Legionnaire.full.jpg"); +// singleLinks.put("fnmp/86.jpg", "FNMP.zip/FNMP/Engineered Plague.full.jpg"); +// singleLinks.put("fnmp/87.jpg", "FNMP.zip/FNMP/Goblin Ringleader.full.jpg"); +// singleLinks.put("fnmp/88.jpg", "FNMP.zip/FNMP/Wing Shards.full.jpg"); +// singleLinks.put("fnmp/89.jpg", "FNMP.zip/FNMP/Cabal Coffers.full.jpg"); +// singleLinks.put("fnmp/9.jpg", "FNMP.zip/FNMP/Prodigal Sorcerer.full.jpg"); +// singleLinks.put("fnmp/90.jpg", "FNMP.zip/FNMP/Roar of the Wurm.full.jpg"); +// singleLinks.put("fnmp/91.jpg", "FNMP.zip/FNMP/Force Spike.full.jpg"); +// singleLinks.put("fnmp/92.jpg", "FNMP.zip/FNMP/Remand.full.jpg"); +// singleLinks.put("fnmp/93.jpg", "FNMP.zip/FNMP/Tormod's Crypt.full.jpg"); +// singleLinks.put("fnmp/94.jpg", "FNMP.zip/FNMP/Eternal Witness.full.jpg"); +// singleLinks.put("fnmp/95.jpg", "FNMP.zip/FNMP/Tendrils of Agony.full.jpg"); +// singleLinks.put("fnmp/96.jpg", "FNMP.zip/FNMP/Pendelhaven.full.jpg"); +// singleLinks.put("fnmp/97.jpg", "FNMP.zip/FNMP/Resurrection.full.jpg"); +// singleLinks.put("fnmp/98.jpg", "FNMP.zip/FNMP/Wall of Roots.full.jpg"); +// singleLinks.put("fnmp/99.jpg", "FNMP.zip/FNMP/Desert.full.jpg"); +// singleLinks.put("gpx/1.jpg", "GPX.zip/GPX/Spiritmonger.full.jpg"); +// singleLinks.put("gpx/10.jpg", "GPX.zip/GPX/Batterskull.full.jpg"); +// singleLinks.put("gpx/11.jpg", "GPX.zip/GPX/Griselbrand.full.jpg"); +// singleLinks.put("gpx/12.jpg", "GPX.zip/GPX/Stoneforge Mystic.full.jpg"); +// singleLinks.put("gpx/2.jpg", "GPX.zip/GPX/Call of the Herd.full.jpg"); +// singleLinks.put("gpx/3.jpg", "GPX.zip/GPX/Chrome Mox.full.jpg"); +// singleLinks.put("gpx/4.jpg", "GPX.zip/GPX/Umezawa's Jitte.full.jpg"); +// singleLinks.put("gpx/5.jpg", "GPX.zip/GPX/Maelstrom Pulse.full.jpg"); +// singleLinks.put("gpx/6.jpg", "GPX.zip/GPX/Goblin Guide.full.jpg"); +// singleLinks.put("gpx/7.jpg", "GPX.zip/GPX/Lotus Cobra.full.jpg"); +// singleLinks.put("gpx/8.jpg", "GPX.zip/GPX/Primeval Titan.full.jpg"); +// singleLinks.put("gpx/9.jpg", "GPX.zip/GPX/All Is Dust.full.jpg"); +// singleLinks.put("grc/1.jpg", "GRC.zip/GRC/Wood Elves.full.jpg"); +// singleLinks.put("grc/10.jpg", "GRC.zip/GRC/Mogg Fanatic.full.jpg"); +// singleLinks.put("grc/11.jpg", "GRC.zip/GRC/Mind Stone.full.jpg"); +// singleLinks.put("grc/12.jpg", "GRC.zip/GRC/Dauntless Dourbark.full.jpg"); +// singleLinks.put("grc/13.jpg", "GRC.zip/GRC/Lava Axe.full.jpg"); +// singleLinks.put("grc/14.jpg", "GRC.zip/GRC/Cenn's Tactician.full.jpg"); +// singleLinks.put("grc/15.jpg", "GRC.zip/GRC/Oona's Blackguard.full.jpg"); +// singleLinks.put("grc/16.jpg", "GRC.zip/GRC/Gravedigger.full.jpg"); +// singleLinks.put("grc/17.jpg", "GRC.zip/GRC/Boggart Ram-Gang.full.jpg"); +// singleLinks.put("grc/18.jpg", "GRC.zip/GRC/Wilt-Leaf Cavaliers.full.jpg"); +// singleLinks.put("grc/19.jpg", "GRC.zip/GRC/Duergar Hedge-Mage.full.jpg"); +// singleLinks.put("grc/2.jpg", "GRC.zip/GRC/Icatian Javelineers.full.jpg"); +// singleLinks.put("grc/20.jpg", "GRC.zip/GRC/Selkie Hedge-Mage.full.jpg"); +// singleLinks.put("grc/21.jpg", "GRC.zip/GRC/Sprouting Thrinax.full.jpg"); +// singleLinks.put("grc/22.jpg", "GRC.zip/GRC/Woolly Thoctar.full.jpg"); +// singleLinks.put("grc/24.jpg", "GRC.zip/GRC/Path to Exile.full.jpg"); +// singleLinks.put("grc/25.jpg", "GRC.zip/GRC/Hellspark Elemental.full.jpg"); +// singleLinks.put("grc/26.jpg", "GRC.zip/GRC/Marisi's Twinclaws.full.jpg"); +// singleLinks.put("grc/27.jpg", "GRC.zip/GRC/Slave of Bolas.full.jpg"); +// singleLinks.put("grc/28.jpg", "GRC.zip/GRC/Mycoid Shepherd.full.jpg"); +// singleLinks.put("grc/29.jpg", "GRC.zip/GRC/Naya Sojourners.full.jpg"); +// singleLinks.put("grc/3.jpg", "GRC.zip/GRC/Fiery Temper.full.jpg"); +// singleLinks.put("grc/30.jpg", "GRC.zip/GRC/Mind Control.full.jpg"); +// singleLinks.put("grc/31.jpg", "GRC.zip/GRC/Rise from the Grave.full.jpg"); +// singleLinks.put("grc/32.jpg", "GRC.zip/GRC/Kor Duelist.full.jpg"); +// singleLinks.put("grc/33.jpg", "GRC.zip/GRC/Vampire Nighthawk.full.jpg"); +// singleLinks.put("grc/34.jpg", "GRC.zip/GRC/Nissa's Chosen.full.jpg"); +// singleLinks.put("grc/35.jpg", "GRC.zip/GRC/Emeria Angel.full.jpg"); +// singleLinks.put("grc/36.jpg", "GRC.zip/GRC/Kor Firewalker.full.jpg"); +// singleLinks.put("grc/37.jpg", "GRC.zip/GRC/Leatherback Baloth.full.jpg"); +// singleLinks.put("grc/38.jpg", "GRC.zip/GRC/Hada Freeblade.full.jpg"); +// singleLinks.put("grc/39.jpg", "GRC.zip/GRC/Kalastria Highborn.full.jpg"); +// singleLinks.put("grc/4.jpg", "GRC.zip/GRC/Boomerang.full.jpg"); +// singleLinks.put("grc/40.jpg", "GRC.zip/GRC/Syphon Mind.full.jpg"); +// singleLinks.put("grc/46.jpg", "GRC.zip/GRC/Pathrazer of Ulamog.full.jpg"); +// singleLinks.put("grc/47.jpg", "GRC.zip/GRC/Curse of Wizardry.full.jpg"); +// singleLinks.put("grc/48.jpg", "GRC.zip/GRC/Staggershock.full.jpg"); +// singleLinks.put("grc/49.jpg", "GRC.zip/GRC/Deathless Angel.full.jpg"); +// singleLinks.put("grc/5.jpg", "GRC.zip/GRC/Calciderm.full.jpg"); +// singleLinks.put("grc/50.jpg", "GRC.zip/GRC/Fling.full.jpg"); +// singleLinks.put("grc/51.jpg", "GRC.zip/GRC/Sylvan Ranger.full.jpg"); +// singleLinks.put("grc/59.jpg", "GRC.zip/GRC/Plague Stinger.full.jpg"); +// singleLinks.put("grc/6.jpg", "GRC.zip/GRC/Reckless Wurm.full.jpg"); +// singleLinks.put("grc/60.jpg", "GRC.zip/GRC/Golem's Heart.full.jpg"); +// singleLinks.put("grc/63.jpg", "GRC.zip/GRC/Skinrender.full.jpg"); +// singleLinks.put("grc/64.jpg", "GRC.zip/GRC/Master's Call.full.jpg"); +// singleLinks.put("grc/65.jpg", "GRC.zip/GRC/Plague Myr.full.jpg"); +// singleLinks.put("grc/66.jpg", "GRC.zip/GRC/Signal Pest.full.jpg"); +// singleLinks.put("grc/69.jpg", "GRC.zip/GRC/Fling.full.jpg"); +// singleLinks.put("grc/7.jpg", "GRC.zip/GRC/Yixlid Jailer.full.jpg"); +// singleLinks.put("grc/70.jpg", "GRC.zip/GRC/Sylvan Ranger.full.jpg"); +// singleLinks.put("grc/71.jpg", "GRC.zip/GRC/Vault Skirge.full.jpg"); +// singleLinks.put("grc/72.jpg", "GRC.zip/GRC/Maul Splicer.full.jpg"); +// singleLinks.put("grc/73.jpg", "GRC.zip/GRC/Shrine of Burning Rage.full.jpg"); +// singleLinks.put("grc/76.jpg", "GRC.zip/GRC/Tormented Soul.full.jpg"); +// singleLinks.put("grc/77.jpg", "GRC.zip/GRC/Auramancer.full.jpg"); +// singleLinks.put("grc/78.jpg", "GRC.zip/GRC/Circle of Flame.full.jpg"); +// singleLinks.put("grc/79.jpg", "GRC.zip/GRC/Gather the Townsfolk.full.jpg"); +// singleLinks.put("grc/8.jpg", "GRC.zip/GRC/Zoetic Cavern.full.jpg"); +// singleLinks.put("grc/80.jpg", "GRC.zip/GRC/Curse of the Bloody Tome.full.jpg"); +// singleLinks.put("grc/81.jpg", "GRC.zip/GRC/Curse of Thirst.full.jpg"); +// singleLinks.put("grc/82.jpg", "GRC.zip/GRC/Nearheath Stalker.full.jpg"); +// singleLinks.put("grc/83.jpg", "GRC.zip/GRC/Bloodcrazed Neonate.full.jpg"); +// singleLinks.put("grc/84.jpg", "GRC.zip/GRC/Boneyard Wurm.full.jpg"); +// singleLinks.put("grc/9.jpg", "GRC.zip/GRC/Llanowar Elves.full.jpg"); +// singleLinks.put("jr/1.jpg", "JP.zip/JP/Lightning Bolt.full.jpg"); +// singleLinks.put("jr/10.jpg", "JP.zip/JP/Tradewind Rider.full.jpg"); +// singleLinks.put("jr/100.jpg", "JP.zip/JP/Feldon of the Third Path.full.jpg"); +// singleLinks.put("jr/101.jpg", "JP.zip/JP/Wasteland.full.jpg"); +// singleLinks.put("jr/103.jpg", "JP.zip/JP/Mana Drain.full.jpg"); +// singleLinks.put("jr/105.jpg", "JP.zip/JP/Command Beacon.full.jpg"); +// singleLinks.put("jr/11.jpg", "JP.zip/JP/Intuition.full.jpg"); +// singleLinks.put("jr/12.jpg", "JP.zip/JP/Argothian Enchantress.full.jpg"); +// singleLinks.put("jr/13.jpg", "JP.zip/JP/Living Death.full.jpg"); +// singleLinks.put("jr/14.jpg", "JP.zip/JP/Armageddon.full.jpg"); +// singleLinks.put("jr/15.jpg", "JP.zip/JP/Balance.full.jpg"); +// singleLinks.put("jr/16.jpg", "JP.zip/JP/Time Warp.full.jpg"); +// singleLinks.put("jr/17.jpg", "JP.zip/JP/Phyrexian Negator.full.jpg"); +// singleLinks.put("jr/18.jpg", "JP.zip/JP/Deranged Hermit.full.jpg"); +// singleLinks.put("jr/19.jpg", "JP.zip/JP/Hermit Druid.full.jpg"); +// singleLinks.put("jr/2.jpg", "JP.zip/JP/Stroke of Genius.full.jpg"); +// singleLinks.put("jr/20.jpg", "JP.zip/JP/Gemstone Mine.full.jpg"); +// singleLinks.put("jr/21.jpg", "JP.zip/JP/Regrowth.full.jpg"); +// singleLinks.put("jr/22.jpg", "JP.zip/JP/Sol Ring.full.jpg"); +// singleLinks.put("jr/23.jpg", "JP.zip/JP/Mishra's Factory.full.jpg"); +// singleLinks.put("jr/24.jpg", "JP.zip/JP/Exalted Angel.full.jpg"); +// singleLinks.put("jr/25.jpg", "JP.zip/JP/Grim Lavamancer.full.jpg"); +// singleLinks.put("jr/26.jpg", "JP.zip/JP/Meddling Mage.full.jpg"); +// singleLinks.put("jr/27.jpg", "JP.zip/JP/Pernicious Deed.full.jpg"); +// singleLinks.put("jr/28.jpg", "JP.zip/JP/Ravenous Baloth.full.jpg"); +// singleLinks.put("jr/29.jpg", "JP.zip/JP/Cunning Wish.full.jpg"); +// singleLinks.put("jr/3.jpg", "JP.zip/JP/Gaea's Cradle.full.jpg"); +// singleLinks.put("jr/30.jpg", "JP.zip/JP/Yawgmoth's Will.full.jpg"); +// singleLinks.put("jr/31.jpg", "JP.zip/JP/Vindicate.full.jpg"); +// singleLinks.put("jr/32.jpg", "JP.zip/JP/Decree of Justice.full.jpg"); +// singleLinks.put("jr/33.jpg", "JP.zip/JP/Orim's Chant.full.jpg"); +// singleLinks.put("jr/34.jpg", "JP.zip/JP/Mind's Desire.full.jpg"); +// singleLinks.put("jr/35.jpg", "JP.zip/JP/Demonic Tutor.full.jpg"); +// singleLinks.put("jr/36.jpg", "JP.zip/JP/Goblin Piledriver.full.jpg"); +// singleLinks.put("jr/37.jpg", "JP.zip/JP/Living Wish.full.jpg"); +// singleLinks.put("jr/38.jpg", "JP.zip/JP/Dark Ritual.full.jpg"); +// singleLinks.put("jr/39.jpg", "JP.zip/JP/Maze of Ith.full.jpg"); +// singleLinks.put("jr/4.jpg", "JP.zip/JP/Memory Lapse.full.jpg"); +// singleLinks.put("jr/40.jpg", "JP.zip/JP/Stifle.full.jpg"); +// singleLinks.put("jr/41.jpg", "JP.zip/JP/Survival of the Fittest.full.jpg"); +// singleLinks.put("jr/42.jpg", "JP.zip/JP/Burning Wish.full.jpg"); +// singleLinks.put("jr/43.jpg", "JP.zip/JP/Bloodstained Mire.full.jpg"); +// singleLinks.put("jr/44.jpg", "JP.zip/JP/Flooded Strand.full.jpg"); +// singleLinks.put("jr/45.jpg", "JP.zip/JP/Polluted Delta.full.jpg"); +// singleLinks.put("jr/46.jpg", "JP.zip/JP/Windswept Heath.full.jpg"); +// singleLinks.put("jr/47.jpg", "JP.zip/JP/Wooded Foothills.full.jpg"); +// singleLinks.put("jr/48.jpg", "JP.zip/JP/Sinkhole.full.jpg"); +// singleLinks.put("jr/49.jpg", "JP.zip/JP/Natural Order.full.jpg"); +// singleLinks.put("jr/5.jpg", "JP.zip/JP/Counterspell.full.jpg"); +// singleLinks.put("jr/50.jpg", "JP.zip/JP/Phyrexian Dreadnought.full.jpg"); +// singleLinks.put("jr/51.jpg", "JP.zip/JP/Thawing Glaciers.full.jpg"); +// singleLinks.put("jr/52.jpg", "JP.zip/JP/Land Tax.full.jpg"); +// singleLinks.put("jr/53.jpg", "JP.zip/JP/Morphling.full.jpg"); +// singleLinks.put("jr/54.jpg", "JP.zip/JP/Wheel of Fortune.full.jpg"); +// singleLinks.put("jr/55.jpg", "JP.zip/JP/Wasteland.full.jpg"); +// singleLinks.put("jr/56.jpg", "JP.zip/JP/Entomb.full.jpg"); +// singleLinks.put("jr/57.jpg", "JP.zip/JP/Sword of Fire and Ice.full.jpg"); +// singleLinks.put("jr/58.jpg", "JP.zip/JP/Vendilion Clique.full.jpg"); +// singleLinks.put("jr/59.jpg", "JP.zip/JP/Bitterblossom.full.jpg"); +// singleLinks.put("jr/6.jpg", "JP.zip/JP/Vampiric Tutor.full.jpg"); +// singleLinks.put("jr/60.jpg", "JP.zip/JP/Mana Crypt.full.jpg"); +// singleLinks.put("jr/61.jpg", "JP.zip/JP/Dark Confidant.full.jpg"); +// singleLinks.put("jr/62.jpg", "JP.zip/JP/Doubling Season.full.jpg"); +// singleLinks.put("jr/63.jpg", "JP.zip/JP/Goblin Welder.full.jpg"); +// singleLinks.put("jr/64.jpg", "JP.zip/JP/Xiahou Dun, the One-Eyed.full.jpg"); +// singleLinks.put("jr/65.jpg", "JP.zip/JP/Flusterstorm.full.jpg"); +// singleLinks.put("jr/66.jpg", "JP.zip/JP/Noble Hierarch.full.jpg"); +// singleLinks.put("jr/67.jpg", "JP.zip/JP/Karmic Guide.full.jpg"); +// singleLinks.put("jr/68.jpg", "JP.zip/JP/Sneak Attack.full.jpg"); +// singleLinks.put("jr/69.jpg", "JP.zip/JP/Karakas.full.jpg"); +// singleLinks.put("jr/7.jpg", "JP.zip/JP/Ball Lightning.full.jpg"); +// singleLinks.put("jr/70.jpg", "JP.zip/JP/Sword of Light and Shadow.full.jpg"); +// singleLinks.put("jr/71.jpg", "JP.zip/JP/Command Tower.full.jpg"); +// singleLinks.put("jr/72.jpg", "JP.zip/JP/Swords to Plowshares.full.jpg"); +// singleLinks.put("jr/73.jpg", "JP.zip/JP/Bribery.full.jpg"); +// singleLinks.put("jr/74.jpg", "JP.zip/JP/Imperial Recruiter.full.jpg"); +// singleLinks.put("jr/75.jpg", "JP.zip/JP/Crucible of Worlds.full.jpg"); +// singleLinks.put("jr/76.jpg", "JP.zip/JP/Overwhelming Forces.full.jpg"); +// singleLinks.put("jr/77.jpg", "JP.zip/JP/Show and Tell.full.jpg"); +// singleLinks.put("jr/78.jpg", "JP.zip/JP/Vindicate.full.jpg"); +// singleLinks.put("jr/79.jpg", "JP.zip/JP/Genesis.full.jpg"); +// singleLinks.put("jr/8.jpg", "JP.zip/JP/Oath of Druids.full.jpg"); +// singleLinks.put("jr/80.jpg", "JP.zip/JP/Karador, Ghost Chieftain.full.jpg"); +// singleLinks.put("jr/81.jpg", "JP.zip/JP/Greater Good.full.jpg"); +// singleLinks.put("jr/82.jpg", "JP.zip/JP/Riku of Two Reflections.full.jpg"); +// singleLinks.put("jr/83.jpg", "JP.zip/JP/Force of Will.full.jpg"); +// singleLinks.put("jr/84.jpg", "JP.zip/JP/Hanna, Ship's Navigator.full.jpg"); +// singleLinks.put("jr/85.jpg", "JP.zip/JP/Sword of Feast and Famine.full.jpg"); +// singleLinks.put("jr/86.jpg", "JP.zip/JP/Nekusar, the Mindrazer.full.jpg"); +// singleLinks.put("jr/87.jpg", "JP.zip/JP/Elesh Norn, Grand Cenobite.full.jpg"); +// singleLinks.put("jr/88.jpg", "JP.zip/JP/Oloro, Ageless Ascetic.full.jpg"); +// singleLinks.put("jr/89.jpg", "JP.zip/JP/Plains.full.jpg"); +// singleLinks.put("jr/9.jpg", "JP.zip/JP/Hammer of Bogardan.full.jpg"); +// singleLinks.put("jr/90.jpg", "JP.zip/JP/Island.full.jpg"); +// singleLinks.put("jr/91.jpg", "JP.zip/JP/Swamp.full.jpg"); +// singleLinks.put("jr/92.jpg", "JP.zip/JP/Mountain.full.jpg"); +// singleLinks.put("jr/93.jpg", "JP.zip/JP/Forest.full.jpg"); +// singleLinks.put("jr/97.jpg", "JP.zip/JP/Ravages of War.full.jpg"); +// singleLinks.put("jr/98.jpg", "JP.zip/JP/Damnation.full.jpg"); +// singleLinks.put("jr/99.jpg", "JP.zip/JP/Dualcaster Mage.full.jpg"); +// singleLinks.put("mbp/1.jpg", "MBP.zip/MBP/Arena.full.jpg"); +// singleLinks.put("mbp/10.jpg", "MBP.zip/MBP/Lightning Hounds.full.jpg"); +// singleLinks.put("mbp/100.jpg", "MBP.zip/MBP/Jace, the Living Guildpact.full.jpg"); +// singleLinks.put("mbp/101.jpg", "MBP.zip/MBP/Liliana Vess.full.jpg"); +// singleLinks.put("mbp/102.jpg", "MBP.zip/MBP/Chandra, Pyromaster.full.jpg"); +// singleLinks.put("mbp/103.jpg", "MBP.zip/MBP/Nissa, Worldwaker.full.jpg"); +// singleLinks.put("mbp/104.jpg", "MBP.zip/MBP/Garruk, Apex Predator.full.jpg"); +// singleLinks.put("mbp/105.jpg", "MBP.zip/MBP/Shamanic Revelation.full.jpg"); +// singleLinks.put("mbp/106.jpg", "MBP.zip/MBP/Ojutai's Command.full.jpg"); +// singleLinks.put("mbp/107.jpg", "MBP.zip/MBP/Dragonscale General.full.jpg"); +// singleLinks.put("mbp/108.jpg", "MBP.zip/MBP/Sage-Eye Avengers.full.jpg"); +// singleLinks.put("mbp/109.jpg", "MBP.zip/MBP/Archfiend of Depravity.full.jpg"); +// singleLinks.put("mbp/11.jpg", "MBP.zip/MBP/Spined Wurm.full.jpg"); +// singleLinks.put("mbp/110.jpg", "MBP.zip/MBP/Flamerush Rider.full.jpg"); +// singleLinks.put("mbp/111.jpg", "MBP.zip/MBP/Temur War Shaman.full.jpg"); +// singleLinks.put("mbp/112.jpg", "MBP.zip/MBP/Arashin Sovereign.full.jpg"); +// singleLinks.put("mbp/113.jpg", "MBP.zip/MBP/Pristine Skywise.full.jpg"); +// singleLinks.put("mbp/114.jpg", "MBP.zip/MBP/Necromaster Dragon.full.jpg"); +// singleLinks.put("mbp/115.jpg", "MBP.zip/MBP/Boltwing Marauder.full.jpg"); +// singleLinks.put("mbp/116.jpg", "MBP.zip/MBP/Harbinger of the Hunt.full.jpg"); +// singleLinks.put("mbp/117.jpg", "MBP.zip/MBP/Sultai Charm.full.jpg"); +// singleLinks.put("mbp/118.jpg", "MBP.zip/MBP/Aeronaut Tinkerer.full.jpg"); +// singleLinks.put("mbp/119.jpg", "MBP.zip/MBP/Dragon Fodder.full.jpg"); +// singleLinks.put("mbp/12.jpg", "MBP.zip/MBP/Warmonger.full.jpg"); +// singleLinks.put("mbp/120.jpg", "MBP.zip/MBP/Dragonlord's Servant.full.jpg"); +// singleLinks.put("mbp/121.jpg", "MBP.zip/MBP/Evolving Wilds.full.jpg"); +// singleLinks.put("mbp/122.jpg", "MBP.zip/MBP/Foe-Razer Regent.full.jpg"); +// singleLinks.put("mbp/123.jpg", "MBP.zip/MBP/Relic Seeker.full.jpg"); +// singleLinks.put("mbp/124.jpg", "MBP.zip/MBP/Alhammarret, High Arbiter.full.jpg"); +// singleLinks.put("mbp/125.jpg", "MBP.zip/MBP/Dwynen, Gilt-Leaf Daen.full.jpg"); +// singleLinks.put("mbp/126.jpg", "MBP.zip/MBP/Hixus, Prison Warden.full.jpg"); +// singleLinks.put("mbp/127.jpg", "MBP.zip/MBP/Kothophed, Soul Hoarder.full.jpg"); +// singleLinks.put("mbp/128.jpg", "MBP.zip/MBP/Pia and Kiran Nalaar.full.jpg"); +// singleLinks.put("mbp/129.jpg", "MBP.zip/MBP/Honored Hierarch.full.jpg"); +// singleLinks.put("mbp/13.jpg", "MBP.zip/MBP/Silver Drake.full.jpg"); +// singleLinks.put("mbp/130.jpg", "MBP.zip/MBP/Seeker of the Way.full.jpg"); +// singleLinks.put("mbp/131.jpg", "MBP.zip/MBP/Valorous Stance.full.jpg"); +// singleLinks.put("mbp/132.jpg", "MBP.zip/MBP/Dromoka, the Eternal.full.jpg"); +// singleLinks.put("mbp/133.jpg", "MBP.zip/MBP/Siege Rhino.full.jpg"); +// singleLinks.put("mbp/134.jpg", "MBP.zip/MBP/Sandsteppe Citadel.full.jpg"); +// singleLinks.put("mbp/135.jpg", "MBP.zip/MBP/Ruinous Path.full.jpg"); +// singleLinks.put("mbp/136.jpg", "MBP.zip/MBP/Hero of Goma Fada.full.jpg"); +// singleLinks.put("mbp/137.jpg", "MBP.zip/MBP/Drowner of Hope.full.jpg"); +// singleLinks.put("mbp/138.jpg", "MBP.zip/MBP/Defiant Bloodlord.full.jpg"); +// singleLinks.put("mbp/139.jpg", "MBP.zip/MBP/Barrage Tyrant.full.jpg"); +// singleLinks.put("mbp/14.jpg", "MBP.zip/MBP/Phyrexian Rager.full.jpg"); +// singleLinks.put("mbp/140.jpg", "MBP.zip/MBP/Oran-Rief Hydra.full.jpg"); +// singleLinks.put("mbp/141.jpg", "MBP.zip/MBP/Scythe Leopard.full.jpg"); +// singleLinks.put("mbp/142.jpg", "MBP.zip/MBP/Genesis Hydra.full.jpg"); +// singleLinks.put("mbp/143.jpg", "MBP.zip/MBP/Munda's Vanguard.full.jpg"); +// singleLinks.put("mbp/144.jpg", "MBP.zip/MBP/Deepfathom Skulker.full.jpg"); +// singleLinks.put("mbp/145.jpg", "MBP.zip/MBP/Dread Defiler.full.jpg"); +// singleLinks.put("mbp/146.jpg", "MBP.zip/MBP/Tyrant of Valakut.full.jpg"); +// singleLinks.put("mbp/147.jpg", "MBP.zip/MBP/Gladehart Cavalry.full.jpg"); +// singleLinks.put("mbp/148.jpg", "MBP.zip/MBP/Goblin Dark-Dwellers.full.jpg"); +// singleLinks.put("mbp/15.jpg", "MBP.zip/MBP/Jace Beleren.full.jpg"); +// singleLinks.put("mbp/16.jpg", "MBP.zip/MBP/Garruk Wildspeaker.full.jpg"); +// singleLinks.put("mbp/17.jpg", "MBP.zip/MBP/Brion Stoutarm.full.jpg"); +// singleLinks.put("mbp/18.jpg", "MBP.zip/MBP/Jaya Ballard, Task Mage.full.jpg"); +// singleLinks.put("mbp/19.jpg", "MBP.zip/MBP/Broodmate Dragon.full.jpg"); +// singleLinks.put("mbp/2.jpg", "MBP.zip/MBP/Sewers of Estark.full.jpg"); +// singleLinks.put("mbp/20.jpg", "MBP.zip/MBP/Honor of the Pure.full.jpg"); +// singleLinks.put("mbp/21.jpg", "MBP.zip/MBP/Steward of Valeron.full.jpg"); +// singleLinks.put("mbp/22.jpg", "MBP.zip/MBP/Day of Judgment.full.jpg"); +// singleLinks.put("mbp/23.jpg", "MBP.zip/MBP/Celestial Colonnade.full.jpg"); +// singleLinks.put("mbp/24.jpg", "MBP.zip/MBP/Retaliator Griffin.full.jpg"); +// singleLinks.put("mbp/25.jpg", "MBP.zip/MBP/Kor Skyfisher.full.jpg"); +// singleLinks.put("mbp/26.jpg", "MBP.zip/MBP/Guul Draz Assassin.full.jpg"); +// singleLinks.put("mbp/27.jpg", "MBP.zip/MBP/Nissa Revane.full.jpg"); +// singleLinks.put("mbp/28.jpg", "MBP.zip/MBP/Birds of Paradise.full.jpg"); +// singleLinks.put("mbp/29.jpg", "MBP.zip/MBP/Memoricide.full.jpg"); +// singleLinks.put("mbp/3.jpg", "MBP.zip/MBP/Nalathni Dragon.full.jpg"); +// singleLinks.put("mbp/30.jpg", "MBP.zip/MBP/Liliana Vess.full.jpg"); +// singleLinks.put("mbp/31.jpg", "MBP.zip/MBP/Bloodthrone Vampire.full.jpg"); +// singleLinks.put("mbp/32.jpg", "MBP.zip/MBP/Mirran Crusader.full.jpg"); +// singleLinks.put("mbp/33.jpg", "MBP.zip/MBP/Surgical Extraction.full.jpg"); +// singleLinks.put("mbp/34.jpg", "MBP.zip/MBP/Frost Titan.full.jpg"); +// singleLinks.put("mbp/35.jpg", "MBP.zip/MBP/Grave Titan.full.jpg"); +// singleLinks.put("mbp/36.jpg", "MBP.zip/MBP/Inferno Titan.full.jpg"); +// singleLinks.put("mbp/37.jpg", "MBP.zip/MBP/Chandra's Phoenix.full.jpg"); +// singleLinks.put("mbp/38.jpg", "MBP.zip/MBP/Treasure Hunt.full.jpg"); +// singleLinks.put("mbp/39.jpg", "MBP.zip/MBP/Faithless Looting.full.jpg"); +// singleLinks.put("mbp/4.jpg", "MBP.zip/MBP/Fireball.full.jpg"); +// singleLinks.put("mbp/40.jpg", "MBP.zip/MBP/Devil's Play.full.jpg"); +// singleLinks.put("mbp/41.jpg", "MBP.zip/MBP/Gravecrawler.full.jpg"); +// singleLinks.put("mbp/42.jpg", "MBP.zip/MBP/Electrolyze.full.jpg"); +// singleLinks.put("mbp/43.jpg", "MBP.zip/MBP/Feast of Blood.full.jpg"); +// singleLinks.put("mbp/44.jpg", "MBP.zip/MBP/Silverblade Paladin.full.jpg"); +// singleLinks.put("mbp/45.jpg", "MBP.zip/MBP/Merfolk Mesmerist.full.jpg"); +// singleLinks.put("mbp/46.jpg", "MBP.zip/MBP/Knight Exemplar.full.jpg"); +// singleLinks.put("mbp/47.jpg", "MBP.zip/MBP/Sunblast Angel.full.jpg"); +// singleLinks.put("mbp/48.jpg", "MBP.zip/MBP/Serra Avatar.full.jpg"); +// singleLinks.put("mbp/49.jpg", "MBP.zip/MBP/Primordial Hydra.full.jpg"); +// singleLinks.put("mbp/5.jpg", "MBP.zip/MBP/Blue Elemental Blast.full.jpg"); +// singleLinks.put("mbp/50.jpg", "MBP.zip/MBP/Vampire Nocturnus.full.jpg"); +// singleLinks.put("mbp/51.jpg", "MBP.zip/MBP/Cathedral of War.full.jpg"); +// singleLinks.put("mbp/52.jpg", "MBP.zip/MBP/Terastodon.full.jpg"); +// singleLinks.put("mbp/53.jpg", "MBP.zip/MBP/Arrest.full.jpg"); +// singleLinks.put("mbp/54.jpg", "MBP.zip/MBP/Consume Spirit.full.jpg"); +// singleLinks.put("mbp/55.jpg", "MBP.zip/MBP/Dreg Mangler.full.jpg"); +// singleLinks.put("mbp/56.jpg", "MBP.zip/MBP/Supreme Verdict.full.jpg"); +// singleLinks.put("mbp/57.jpg", "MBP.zip/MBP/Standstill.full.jpg"); +// singleLinks.put("mbp/58.jpg", "MBP.zip/MBP/Breath of Malfegor.full.jpg"); +// singleLinks.put("mbp/59.jpg", "MBP.zip/MBP/Angel of Glory's Rise.full.jpg"); +// singleLinks.put("mbp/6.jpg", "MBP.zip/MBP/Mana Crypt.full.jpg"); +// singleLinks.put("mbp/60.jpg", "MBP.zip/MBP/Turnabout.full.jpg"); +// singleLinks.put("mbp/61.jpg", "MBP.zip/MBP/Nightveil Specter.full.jpg"); +// singleLinks.put("mbp/62.jpg", "MBP.zip/MBP/Voidmage Husher.full.jpg"); +// singleLinks.put("mbp/63.jpg", "MBP.zip/MBP/Ogre Arsonist.full.jpg"); +// singleLinks.put("mbp/64.jpg", "MBP.zip/MBP/Corrupt.full.jpg"); +// singleLinks.put("mbp/65.jpg", "MBP.zip/MBP/Chandra's Fury.full.jpg"); +// singleLinks.put("mbp/66.jpg", "MBP.zip/MBP/Render Silent.full.jpg"); +// singleLinks.put("mbp/67.jpg", "MBP.zip/MBP/Ratchet Bomb.full.jpg"); +// singleLinks.put("mbp/68.jpg", "MBP.zip/MBP/Bonescythe Sliver.full.jpg"); +// singleLinks.put("mbp/69.jpg", "MBP.zip/MBP/Ogre Battledriver.full.jpg"); +// singleLinks.put("mbp/7.jpg", "MBP.zip/MBP/Windseeker Centaur.full.jpg"); +// singleLinks.put("mbp/70.jpg", "MBP.zip/MBP/Scavenging Ooze.full.jpg"); +// singleLinks.put("mbp/71.jpg", "MBP.zip/MBP/Hamletback Goliath.full.jpg"); +// singleLinks.put("mbp/72.jpg", "MBP.zip/MBP/Ajani, Caller of the Pride.full.jpg"); +// singleLinks.put("mbp/73.jpg", "MBP.zip/MBP/Jace, Memory Adept.full.jpg"); +// singleLinks.put("mbp/74.jpg", "MBP.zip/MBP/Liliana of the Dark Realms.full.jpg"); +// singleLinks.put("mbp/75.jpg", "MBP.zip/MBP/Chandra, Pyromaster.full.jpg"); +// singleLinks.put("mbp/76.jpg", "MBP.zip/MBP/Garruk, Caller of Beasts.full.jpg"); +// singleLinks.put("mbp/77.jpg", "MBP.zip/MBP/Sylvan Caryatid.full.jpg"); +// singleLinks.put("mbp/78.jpg", "MBP.zip/MBP/Karametra's Acolyte.full.jpg"); +// singleLinks.put("mbp/79.jpg", "MBP.zip/MBP/Fated Conflagration.full.jpg"); +// singleLinks.put("mbp/8.jpg", "MBP.zip/MBP/Giant Badger.full.jpg"); +// singleLinks.put("mbp/80.jpg", "MBP.zip/MBP/High Tide.full.jpg"); +// singleLinks.put("mbp/81.jpg", "MBP.zip/MBP/Gaze of Granite.full.jpg"); +// singleLinks.put("mbp/82.jpg", "MBP.zip/MBP/Wash Out.full.jpg"); +// singleLinks.put("mbp/83.jpg", "MBP.zip/MBP/Acquire.full.jpg"); +// singleLinks.put("mbp/84.jpg", "MBP.zip/MBP/Duress.full.jpg"); +// singleLinks.put("mbp/85.jpg", "MBP.zip/MBP/Eidolon of Blossoms.full.jpg"); +// singleLinks.put("mbp/86.jpg", "MBP.zip/MBP/Magister of Worth.full.jpg"); +// singleLinks.put("mbp/87.jpg", "MBP.zip/MBP/Soul of Ravnica.full.jpg"); +// singleLinks.put("mbp/88.jpg", "MBP.zip/MBP/Soul of Zendikar.full.jpg"); +// singleLinks.put("mbp/89.jpg", "MBP.zip/MBP/Stealer of Secrets.full.jpg"); +// singleLinks.put("mbp/9.jpg", "MBP.zip/MBP/Scent of Cinder.full.jpg"); +// singleLinks.put("mbp/90.jpg", "MBP.zip/MBP/Angelic Skirmisher.full.jpg"); +// singleLinks.put("mbp/91.jpg", "MBP.zip/MBP/Xathrid Necromancer.full.jpg"); +// singleLinks.put("mbp/92.jpg", "MBP.zip/MBP/Rattleclaw Mystic.full.jpg"); +// singleLinks.put("mbp/93.jpg", "MBP.zip/MBP/Ankle Shanker.full.jpg"); +// singleLinks.put("mbp/94.jpg", "MBP.zip/MBP/Avalanche Tusker.full.jpg"); +// singleLinks.put("mbp/95.jpg", "MBP.zip/MBP/Ivorytusk Fortress.full.jpg"); +// singleLinks.put("mbp/96.jpg", "MBP.zip/MBP/Rakshasa Vizier.full.jpg"); +// singleLinks.put("mbp/97.jpg", "MBP.zip/MBP/Sage of the Inward Eye.full.jpg"); +// singleLinks.put("mbp/98.jpg", "MBP.zip/MBP/Goblin Rabblemaster.full.jpg"); +// singleLinks.put("mbp/99.jpg", "MBP.zip/MBP/Ajani Steadfast.full.jpg"); +// singleLinks.put("mgdc/1.jpg", "MGDC.zip/MGDC/Reya Dawnbringer.full.jpg"); +// singleLinks.put("mgdc/10.jpg", "MGDC.zip/MGDC/Stormblood Berserker.full.jpg"); +// singleLinks.put("mgdc/11.jpg", "MGDC.zip/MGDC/Dungrove Elder.full.jpg"); +// singleLinks.put("mgdc/12.jpg", "MGDC.zip/MGDC/Diregraf Ghoul.full.jpg"); +// singleLinks.put("mgdc/13.jpg", "MGDC.zip/MGDC/Elite Inquisitor.full.jpg"); +// singleLinks.put("mgdc/14.jpg", "MGDC.zip/MGDC/Zombie Apocalypse.full.jpg"); +// singleLinks.put("mgdc/15.jpg", "MGDC.zip/MGDC/Strangleroot Geist.full.jpg"); +// singleLinks.put("mgdc/16.jpg", "MGDC.zip/MGDC/Suture Priest.full.jpg"); +// singleLinks.put("mgdc/17.jpg", "MGDC.zip/MGDC/Pristine Talisman.full.jpg"); +// singleLinks.put("mgdc/18.jpg", "MGDC.zip/MGDC/Latch Seeker.full.jpg"); +// singleLinks.put("mgdc/19.jpg", "MGDC.zip/MGDC/Killing Wave.full.jpg"); +// singleLinks.put("mgdc/2.jpg", "MGDC.zip/MGDC/Liliana's Specter.full.jpg"); +// singleLinks.put("mgdc/20.jpg", "MGDC.zip/MGDC/Magmaquake.full.jpg"); +// singleLinks.put("mgdc/21.jpg", "MGDC.zip/MGDC/Mwonvuli Beast Tracker.full.jpg"); +// singleLinks.put("mgdc/22.jpg", "MGDC.zip/MGDC/Cryptborn Horror.full.jpg"); +// singleLinks.put("mgdc/23.jpg", "MGDC.zip/MGDC/Dryad Militant.full.jpg"); +// singleLinks.put("mgdc/24.jpg", "MGDC.zip/MGDC/Firemane Avenger.full.jpg"); +// singleLinks.put("mgdc/25.jpg", "MGDC.zip/MGDC/Zameck Guildmage.full.jpg"); +// singleLinks.put("mgdc/26.jpg", "MGDC.zip/MGDC/Melek, Izzet Paragon.full.jpg"); +// singleLinks.put("mgdc/27.jpg", "MGDC.zip/MGDC/Trostani's Summoner.full.jpg"); +// singleLinks.put("mgdc/28.jpg", "MGDC.zip/MGDC/Hive Stirrings.full.jpg"); +// singleLinks.put("mgdc/29.jpg", "MGDC.zip/MGDC/Goblin Diplomats.full.jpg"); +// singleLinks.put("mgdc/3.jpg", "MGDC.zip/MGDC/Mitotic Slime.full.jpg"); +// singleLinks.put("mgdc/30.jpg", "MGDC.zip/MGDC/Phalanx Leader.full.jpg"); +// singleLinks.put("mgdc/31.jpg", "MGDC.zip/MGDC/Nighthowler.full.jpg"); +// singleLinks.put("mgdc/32.jpg", "MGDC.zip/MGDC/Pain Seer.full.jpg"); +// singleLinks.put("mgdc/33.jpg", "MGDC.zip/MGDC/Kiora's Follower.full.jpg"); +// singleLinks.put("mgdc/34.jpg", "MGDC.zip/MGDC/Squelching Leeches.full.jpg"); +// singleLinks.put("mgdc/35.jpg", "MGDC.zip/MGDC/Dictate of Kruphix.full.jpg"); +// singleLinks.put("mgdc/36.jpg", "MGDC.zip/MGDC/Hall of Triumph.full.jpg"); +// singleLinks.put("mgdc/37.jpg", "MGDC.zip/MGDC/Heir of the Wilds.full.jpg"); +// singleLinks.put("mgdc/38.jpg", "MGDC.zip/MGDC/Utter End.full.jpg"); +// singleLinks.put("mgdc/39.jpg", "MGDC.zip/MGDC/Reclamation Sage.full.jpg"); +// singleLinks.put("mgdc/4.jpg", "MGDC.zip/MGDC/Memnite.full.jpg"); +// singleLinks.put("mgdc/40.jpg", "MGDC.zip/MGDC/Chief Engineer.full.jpg"); +// singleLinks.put("mgdc/41.jpg", "MGDC.zip/MGDC/Mardu Shadowspear.full.jpg"); +// singleLinks.put("mgdc/42.jpg", "MGDC.zip/MGDC/Supplant Form.full.jpg"); +// singleLinks.put("mgdc/43.jpg", "MGDC.zip/MGDC/Thunderbreak Regent.full.jpg"); +// singleLinks.put("mgdc/44.jpg", "MGDC.zip/MGDC/Scaleguard Sentinels.full.jpg"); +// singleLinks.put("mgdc/45.jpg", "MGDC.zip/MGDC/Conclave Naturalists.full.jpg"); +// singleLinks.put("mgdc/46.jpg", "MGDC.zip/MGDC/Languish.full.jpg"); +// singleLinks.put("mgdc/47.jpg", "MGDC.zip/MGDC/Stasis Snare.full.jpg"); +// singleLinks.put("mgdc/48.jpg", "MGDC.zip/MGDC/Radiant Flames.full.jpg"); +// singleLinks.put("mgdc/49.jpg", "MGDC.zip/MGDC/Immolating Glare.full.jpg"); +// singleLinks.put("mgdc/5.jpg", "MGDC.zip/MGDC/Tempered Steel.full.jpg"); +// singleLinks.put("mgdc/50.jpg", "MGDC.zip/MGDC/Jori En, Ruin Diver.full.jpg"); +// singleLinks.put("mgdc/6.jpg", "MGDC.zip/MGDC/Treasure Mage.full.jpg"); +// singleLinks.put("mgdc/7.jpg", "MGDC.zip/MGDC/Black Sun's Zenith.full.jpg"); +// singleLinks.put("mgdc/8.jpg", "MGDC.zip/MGDC/Myr Superion.full.jpg"); +// singleLinks.put("mgdc/9.jpg", "MGDC.zip/MGDC/Priest of Urabrask.full.jpg"); +// singleLinks.put("mlp/1.jpg", "MLP.zip/MLP/Earwig Squad.full.jpg"); +// singleLinks.put("mlp/10.jpg", "MLP.zip/MLP/Lord of Shatterskull Pass.full.jpg"); +// singleLinks.put("mlp/11.jpg", "MLP.zip/MLP/Ancient Hellkite.full.jpg"); +// singleLinks.put("mlp/12.jpg", "MLP.zip/MLP/Steel Hellkite.full.jpg"); +// singleLinks.put("mlp/13.jpg", "MLP.zip/MLP/Thopter Assembly.full.jpg"); +// singleLinks.put("mlp/14.jpg", "MLP.zip/MLP/Phyrexian Metamorph.full.jpg"); +// singleLinks.put("mlp/15.jpg", "MLP.zip/MLP/Garruk's Horde.full.jpg"); +// singleLinks.put("mlp/16a.jpg", "MLP.zip/MLP/Ludevic's Test Subject.full.jpg"); +// singleLinks.put("mlp/16b.jpg", "MLP.zip/MLP/Ludevic's Abomination.full.jpg"); +// singleLinks.put("mlp/17a.jpg", "MLP.zip/MLP/Mondronen Shaman.full.jpg"); +// singleLinks.put("mlp/17b.jpg", "MLP.zip/MLP/Tovolar's Magehunter.full.jpg"); +// singleLinks.put("mlp/18.jpg", "MLP.zip/MLP/Restoration Angel.full.jpg"); +// singleLinks.put("mlp/19.jpg", "MLP.zip/MLP/Staff of Nin.full.jpg"); +// singleLinks.put("mlp/2.jpg", "MLP.zip/MLP/Vexing Shusher.full.jpg"); +// singleLinks.put("mlp/20.jpg", "MLP.zip/MLP/Deadbridge Goliath.full.jpg"); +// singleLinks.put("mlp/21.jpg", "MLP.zip/MLP/Skarrg Goliath.full.jpg"); +// singleLinks.put("mlp/22a.jpg", "MLP.zip/MLP/Breaking (Breaking/Entering).full.jpg"); +// singleLinks.put("mlp/22b.jpg", "MLP.zip/MLP/Entering (Breaking/Entering).full.jpg"); +// singleLinks.put("mlp/23.jpg", "MLP.zip/MLP/Colossal Whale.full.jpg"); +// singleLinks.put("mlp/24.jpg", "MLP.zip/MLP/Bident of Thassa.full.jpg"); +// singleLinks.put("mlp/25.jpg", "MLP.zip/MLP/Tromokratis.full.jpg"); +// singleLinks.put("mlp/26.jpg", "MLP.zip/MLP/Dictate of the Twin Gods.full.jpg"); +// singleLinks.put("mlp/27.jpg", "MLP.zip/MLP/Dragone Throne of Tarkir.full.jpg"); +// singleLinks.put("mlp/28.jpg", "MLP.zip/MLP/In Garruk's Wake.full.jpg"); +// singleLinks.put("mlp/29.jpg", "MLP.zip/MLP/Sandsteppe Mastodon.full.jpg"); +// singleLinks.put("mlp/3.jpg", "MLP.zip/MLP/Figure of Destiny.full.jpg"); +// singleLinks.put("mlp/31.jpg", "MLP.zip/MLP/Deathbringer Regent.full.jpg"); +// singleLinks.put("mlp/32.jpg", "MLP.zip/MLP/Mizzium Meddler.full.jpg"); +// singleLinks.put("mlp/33.jpg", "MLP.zip/MLP/Blight Herder.full.jpg"); +// singleLinks.put("mlp/34.jpg", "MLP.zip/MLP/Endbringer.full.jpg"); +// singleLinks.put("mlp/4.jpg", "MLP.zip/MLP/Ajani Vengeant.full.jpg"); +// singleLinks.put("mlp/5.jpg", "MLP.zip/MLP/Obelisk of Alara.full.jpg"); +// singleLinks.put("mlp/6.jpg", "MLP.zip/MLP/Knight of New Alara.full.jpg"); +// singleLinks.put("mlp/7.jpg", "MLP.zip/MLP/Ant Queen.full.jpg"); +// singleLinks.put("mlp/8.jpg", "MLP.zip/MLP/Valakut, the Molten Pinnacle.full.jpg"); +// singleLinks.put("mlp/9.jpg", "MLP.zip/MLP/Joraga Warcaller.full.jpg"); +// singleLinks.put("mprp/1.jpg", "MPRP.zip/MPRP/Wasteland.full.jpg"); +// singleLinks.put("mprp/10.jpg", "MPRP.zip/MPRP/Hypnotic Specter.full.jpg"); +// singleLinks.put("mprp/11.jpg", "MPRP.zip/MPRP/Hinder.full.jpg"); +// singleLinks.put("mprp/12.jpg", "MPRP.zip/MPRP/Pyroclasm.full.jpg"); +// singleLinks.put("mprp/13.jpg", "MPRP.zip/MPRP/Giant Growth.full.jpg"); +// singleLinks.put("mprp/14.jpg", "MPRP.zip/MPRP/Putrefy.full.jpg"); +// singleLinks.put("mprp/15.jpg", "MPRP.zip/MPRP/Zombify.full.jpg"); +// singleLinks.put("mprp/16.jpg", "MPRP.zip/MPRP/Lightning Helix.full.jpg"); +// singleLinks.put("mprp/17.jpg", "MPRP.zip/MPRP/Wrath of God.full.jpg"); +// singleLinks.put("mprp/18.jpg", "MPRP.zip/MPRP/Condemn.full.jpg"); +// singleLinks.put("mprp/19.jpg", "MPRP.zip/MPRP/Mortify.full.jpg"); +// singleLinks.put("mprp/2.jpg", "MPRP.zip/MPRP/Voidmage Prodigy.full.jpg"); +// singleLinks.put("mprp/20.jpg", "MPRP.zip/MPRP/Psionic Blast.full.jpg"); +// singleLinks.put("mprp/21.jpg", "MPRP.zip/MPRP/Cruel Edict.full.jpg"); +// singleLinks.put("mprp/22.jpg", "MPRP.zip/MPRP/Disenchant.full.jpg"); +// singleLinks.put("mprp/23.jpg", "MPRP.zip/MPRP/Recollect.full.jpg"); +// singleLinks.put("mprp/24.jpg", "MPRP.zip/MPRP/Damnation.full.jpg"); +// singleLinks.put("mprp/25.jpg", "MPRP.zip/MPRP/Tidings.full.jpg"); +// singleLinks.put("mprp/26.jpg", "MPRP.zip/MPRP/Incinerate.full.jpg"); +// singleLinks.put("mprp/27.jpg", "MPRP.zip/MPRP/Mana Tithe.full.jpg"); +// singleLinks.put("mprp/28.jpg", "MPRP.zip/MPRP/Harmonize.full.jpg"); +// singleLinks.put("mprp/29.jpg", "MPRP.zip/MPRP/Ponder.full.jpg"); +// singleLinks.put("mprp/3.jpg", "MPRP.zip/MPRP/Powder Keg.full.jpg"); +// singleLinks.put("mprp/30.jpg", "MPRP.zip/MPRP/Corrupt.full.jpg"); +// singleLinks.put("mprp/31.jpg", "MPRP.zip/MPRP/Cryptic Command.full.jpg"); +// singleLinks.put("mprp/32.jpg", "MPRP.zip/MPRP/Flame Javelin.full.jpg"); +// singleLinks.put("mprp/33.jpg", "MPRP.zip/MPRP/Unmake.full.jpg"); +// singleLinks.put("mprp/34.jpg", "MPRP.zip/MPRP/Nameless Inversion.full.jpg"); +// singleLinks.put("mprp/35.jpg", "MPRP.zip/MPRP/Remove Soul.full.jpg"); +// singleLinks.put("mprp/36.jpg", "MPRP.zip/MPRP/Blightning.full.jpg"); +// singleLinks.put("mprp/37.jpg", "MPRP.zip/MPRP/Rampant Growth.full.jpg"); +// singleLinks.put("mprp/38.jpg", "MPRP.zip/MPRP/Negate.full.jpg"); +// singleLinks.put("mprp/39.jpg", "MPRP.zip/MPRP/Terminate.full.jpg"); +// singleLinks.put("mprp/4.jpg", "MPRP.zip/MPRP/Psychatog.full.jpg"); +// singleLinks.put("mprp/40.jpg", "MPRP.zip/MPRP/Lightning Bolt.full.jpg"); +// singleLinks.put("mprp/41.jpg", "MPRP.zip/MPRP/Cancel.full.jpg"); +// singleLinks.put("mprp/42.jpg", "MPRP.zip/MPRP/Sign in Blood.full.jpg"); +// singleLinks.put("mprp/43.jpg", "MPRP.zip/MPRP/Infest.full.jpg"); +// singleLinks.put("mprp/44.jpg", "MPRP.zip/MPRP/Volcanic Fallout.full.jpg"); +// singleLinks.put("mprp/45.jpg", "MPRP.zip/MPRP/Celestial Purge.full.jpg"); +// singleLinks.put("mprp/46.jpg", "MPRP.zip/MPRP/Bituminous Blast.full.jpg"); +// singleLinks.put("mprp/47.jpg", "MPRP.zip/MPRP/Burst Lightning.full.jpg"); +// singleLinks.put("mprp/48.jpg", "MPRP.zip/MPRP/Harrow.full.jpg"); +// singleLinks.put("mprp/49.jpg", "MPRP.zip/MPRP/Day of Judgment.full.jpg"); +// singleLinks.put("mprp/5.jpg", "MPRP.zip/MPRP/Terror.full.jpg"); +// singleLinks.put("mprp/50.jpg", "MPRP.zip/MPRP/Brave the Elements.full.jpg"); +// singleLinks.put("mprp/51.jpg", "MPRP.zip/MPRP/Doom Blade.full.jpg"); +// singleLinks.put("mprp/52.jpg", "MPRP.zip/MPRP/Treasure Hunt.full.jpg"); +// singleLinks.put("mprp/53.jpg", "MPRP.zip/MPRP/Searing Blaze.full.jpg"); +// singleLinks.put("mprp/6.jpg", "MPRP.zip/MPRP/Fireball.full.jpg"); +// singleLinks.put("mprp/7.jpg", "MPRP.zip/MPRP/Oxidize.full.jpg"); +// singleLinks.put("mprp/8.jpg", "MPRP.zip/MPRP/Mana Leak.full.jpg"); +// singleLinks.put("mprp/9.jpg", "MPRP.zip/MPRP/Reciprocate.full.jpg"); +// singleLinks.put("mpskld/1.jpg", "MPS.zip/MPS/Cataclysmic Gearhulk.full.jpg"); +// singleLinks.put("mpskld/10.jpg", "MPS.zip/MPS/Cloudstone Curio.full.jpg"); +// singleLinks.put("mpskld/11.jpg", "MPS.zip/MPS/Crucible of Worlds.full.jpg"); +// singleLinks.put("mpskld/12.jpg", "MPS.zip/MPS/Gauntlet of Power.full.jpg"); +// singleLinks.put("mpskld/13.jpg", "MPS.zip/MPS/Hangarback Walker.full.jpg"); +// singleLinks.put("mpskld/14.jpg", "MPS.zip/MPS/Lightning Greaves.full.jpg"); +// singleLinks.put("mpskld/15.jpg", "MPS.zip/MPS/Lotus Petal.full.jpg"); +// singleLinks.put("mpskld/16.jpg", "MPS.zip/MPS/Mana Crypt.full.jpg"); +// singleLinks.put("mpskld/17.jpg", "MPS.zip/MPS/Mana Vault.full.jpg"); +// singleLinks.put("mpskld/18.jpg", "MPS.zip/MPS/Mind's Eye.full.jpg"); +// singleLinks.put("mpskld/19.jpg", "MPS.zip/MPS/Mox Opal.full.jpg"); +// singleLinks.put("mpskld/2.jpg", "MPS.zip/MPS/Torrential Gearhulk.full.jpg"); +// singleLinks.put("mpskld/20.jpg", "MPS.zip/MPS/Painter's Servant.full.jpg"); +// singleLinks.put("mpskld/21.jpg", "MPS.zip/MPS/Rings of Brighthearth.full.jpg"); +// singleLinks.put("mpskld/22.jpg", "MPS.zip/MPS/Scroll Rack.full.jpg"); +// singleLinks.put("mpskld/23.jpg", "MPS.zip/MPS/Sculpting Steel.full.jpg"); +// singleLinks.put("mpskld/24.jpg", "MPS.zip/MPS/Sol Ring.full.jpg"); +// singleLinks.put("mpskld/25.jpg", "MPS.zip/MPS/Solemn Simulacrum.full.jpg"); +// singleLinks.put("mpskld/26.jpg", "MPS.zip/MPS/Static Orb.full.jpg"); +// singleLinks.put("mpskld/27.jpg", "MPS.zip/MPS/Steel Overseer.full.jpg"); +// singleLinks.put("mpskld/28.jpg", "MPS.zip/MPS/Sword of Feast and Famine.full.jpg"); +// singleLinks.put("mpskld/29.jpg", "MPS.zip/MPS/Sword of Fire and Ice.full.jpg"); +// singleLinks.put("mpskld/3.jpg", "MPS.zip/MPS/Noxious Gearhulk.full.jpg"); +// singleLinks.put("mpskld/30.jpg", "MPS.zip/MPS/Sword of Light and Shadow.full.jpg"); +// singleLinks.put("mpskld/4.jpg", "MPS.zip/MPS/Combustible Gearhulk.full.jpg"); +// singleLinks.put("mpskld/5.jpg", "MPS.zip/MPS/Verdurous Gearhulk.full.jpg"); +// singleLinks.put("mpskld/6.jpg", "MPS.zip/MPS/Aether Vial.full.jpg"); +// singleLinks.put("mpskld/7.jpg", "MPS.zip/MPS/Champion's Helm.full.jpg"); +// singleLinks.put("mpskld/8.jpg", "MPS.zip/MPS/Chromatic Lantern.full.jpg"); +// singleLinks.put("mpskld/9.jpg", "MPS.zip/MPS/Chrome Mox.full.jpg"); +// singleLinks.put("ptc/1.jpg", "PTC.zip/PTC/Dirtcowl Wurm.full.jpg"); +// singleLinks.put("ptc/10.jpg", "PTC.zip/PTC/Rathi Assassin.full.jpg"); +// singleLinks.put("ptc/100.jpg", "PTC.zip/PTC/Flying Crane Technique.full.jpg"); +// singleLinks.put("ptc/101.jpg", "PTC.zip/PTC/Grim Haruspex.full.jpg"); +// singleLinks.put("ptc/102.jpg", "PTC.zip/PTC/Hardened Scales.full.jpg"); +// singleLinks.put("ptc/103.jpg", "PTC.zip/PTC/Herald of Anafenza.full.jpg"); +// singleLinks.put("ptc/104.jpg", "PTC.zip/PTC/High Sentinels of Arashin.full.jpg"); +// singleLinks.put("ptc/105.jpg", "PTC.zip/PTC/Icy Blast.full.jpg"); +// singleLinks.put("ptc/106.jpg", "PTC.zip/PTC/Ivorytusk Fortress.full.jpg"); +// singleLinks.put("ptc/107.jpg", "PTC.zip/PTC/Jeering Instigator.full.jpg"); +// singleLinks.put("ptc/108.jpg", "PTC.zip/PTC/Jeskai Ascendancy.full.jpg"); +// singleLinks.put("ptc/109.jpg", "PTC.zip/PTC/Kheru Lich Lord.full.jpg"); +// singleLinks.put("ptc/11.jpg", "PTC.zip/PTC/Avatar of Hope.full.jpg"); +// singleLinks.put("ptc/110.jpg", "PTC.zip/PTC/Mardu Ascendancy.full.jpg"); +// singleLinks.put("ptc/111.jpg", "PTC.zip/PTC/Master of Pearls.full.jpg"); +// singleLinks.put("ptc/112.jpg", "PTC.zip/PTC/Narset, Enlightened Master.full.jpg"); +// singleLinks.put("ptc/113.jpg", "PTC.zip/PTC/Necropolis Fiend.full.jpg"); +// singleLinks.put("ptc/114.jpg", "PTC.zip/PTC/Rakshasa Vizier.full.jpg"); +// singleLinks.put("ptc/115.jpg", "PTC.zip/PTC/Rattleclaw Mystic.full.jpg"); +// singleLinks.put("ptc/116.jpg", "PTC.zip/PTC/Sage of the Inward Eye.full.jpg"); +// singleLinks.put("ptc/117.jpg", "PTC.zip/PTC/Sidisi, Brood Tyrant.full.jpg"); +// singleLinks.put("ptc/118.jpg", "PTC.zip/PTC/Siege Rhino.full.jpg"); +// singleLinks.put("ptc/119.jpg", "PTC.zip/PTC/Sultai Ascendacy.full.jpg"); +// singleLinks.put("ptc/12.jpg", "PTC.zip/PTC/Raging Kavu.full.jpg"); +// singleLinks.put("ptc/120.jpg", "PTC.zip/PTC/Surrak Dragonclaw.full.jpg"); +// singleLinks.put("ptc/121.jpg", "PTC.zip/PTC/Temur Ascendancy.full.jpg"); +// singleLinks.put("ptc/122.jpg", "PTC.zip/PTC/Thousand Winds.full.jpg"); +// singleLinks.put("ptc/123.jpg", "PTC.zip/PTC/Trail of Mystery.full.jpg"); +// singleLinks.put("ptc/124.jpg", "PTC.zip/PTC/Trap Essence.full.jpg"); +// singleLinks.put("ptc/125.jpg", "PTC.zip/PTC/Utter End.full.jpg"); +// singleLinks.put("ptc/126.jpg", "PTC.zip/PTC/Villainous Wealth.full.jpg"); +// singleLinks.put("ptc/127.jpg", "PTC.zip/PTC/Zurgo Helmsmasher.full.jpg"); +// singleLinks.put("ptc/128.jpg", "PTC.zip/PTC/Alesha, Who Smiles at Death.full.jpg"); +// singleLinks.put("ptc/129.jpg", "PTC.zip/PTC/Arcbond.full.jpg"); +// singleLinks.put("ptc/13.jpg", "PTC.zip/PTC/Questing Phelddagrif.full.jpg"); +// singleLinks.put("ptc/130.jpg", "PTC.zip/PTC/Archfiend of Depravity.full.jpg"); +// singleLinks.put("ptc/131.jpg", "PTC.zip/PTC/Atarka, World Render.full.jpg"); +// singleLinks.put("ptc/132.jpg", "PTC.zip/PTC/Brutal Hordechief.full.jpg"); +// singleLinks.put("ptc/133.jpg", "PTC.zip/PTC/Daghatar the Adamant.full.jpg"); +// singleLinks.put("ptc/134.jpg", "PTC.zip/PTC/Dragonscale General.full.jpg"); +// singleLinks.put("ptc/135.jpg", "PTC.zip/PTC/Dromoka, the Eternal.full.jpg"); +// singleLinks.put("ptc/136.jpg", "PTC.zip/PTC/Flamerush Rider.full.jpg"); +// singleLinks.put("ptc/137.jpg", "PTC.zip/PTC/Flamewake Phoenix.full.jpg"); +// singleLinks.put("ptc/138.jpg", "PTC.zip/PTC/Jeskai Infiltrator.full.jpg"); +// singleLinks.put("ptc/14.jpg", "PTC.zip/PTC/Fungal Shambler.full.jpg"); +// singleLinks.put("ptc/141.jpg", "PTC.zip/PTC/Mastery of the Unseen.full.jpg"); +// singleLinks.put("ptc/142.jpg", "PTC.zip/PTC/Ojutai, Soul of Winter.full.jpg"); +// singleLinks.put("ptc/143.jpg", "PTC.zip/PTC/Rally the Ancestors.full.jpg"); +// singleLinks.put("ptc/145.jpg", "PTC.zip/PTC/Sandsteppe Mastodon.full.jpg"); +// singleLinks.put("ptc/147.jpg", "PTC.zip/PTC/Shamanic Revelation.full.jpg"); +// singleLinks.put("ptc/15.jpg", "PTC.zip/PTC/Stone-Tongue Basilisk.full.jpg"); +// singleLinks.put("ptc/150.jpg", "PTC.zip/PTC/Soulfire Grand Master.full.jpg"); +// singleLinks.put("ptc/151.jpg", "PTC.zip/PTC/Soulflayer.full.jpg"); +// singleLinks.put("ptc/152.jpg", "PTC.zip/PTC/Supplant Form.full.jpg"); +// singleLinks.put("ptc/153.jpg", "PTC.zip/PTC/Tasigur, the Golden Fang.full.jpg"); +// singleLinks.put("ptc/154.jpg", "PTC.zip/PTC/Torrent Elemental.full.jpg"); +// singleLinks.put("ptc/157.jpg", "PTC.zip/PTC/Yasova Dragonclaw.full.jpg"); +// singleLinks.put("ptc/16.jpg", "PTC.zip/PTC/Laquatus's Champion.full.jpg"); +// singleLinks.put("ptc/166.jpg", "PTC.zip/PTC/Crater Elemental.full.jpg"); +// singleLinks.put("ptc/168.jpg", "PTC.zip/PTC/Deathbringer Regent.full.jpg"); +// singleLinks.put("ptc/17.jpg", "PTC.zip/PTC/Glory.full.jpg"); +// singleLinks.put("ptc/18.jpg", "PTC.zip/PTC/Silent Specter.full.jpg"); +// singleLinks.put("ptc/181.jpg", "PTC.zip/PTC/Kolaghan's Command.full.jpg"); +// singleLinks.put("ptc/183.jpg", "PTC.zip/PTC/Myth Realized.full.jpg"); +// singleLinks.put("ptc/185.jpg", "PTC.zip/PTC/Ojutai's Command.full.jpg"); +// singleLinks.put("ptc/19.jpg", "PTC.zip/PTC/Feral Throwback.full.jpg"); +// singleLinks.put("ptc/196.jpg", "PTC.zip/PTC/Volcanic Vision.full.jpg"); +// singleLinks.put("ptc/198.jpg", "PTC.zip/PTC/Abbot of Keral Keep.full.jpg"); +// singleLinks.put("ptc/2.jpg", "PTC.zip/PTC/Revenant.full.jpg"); +// singleLinks.put("ptc/20.jpg", "PTC.zip/PTC/Soul Collector.full.jpg"); +// singleLinks.put("ptc/21.jpg", "PTC.zip/PTC/Sword of Kaldra.full.jpg"); +// singleLinks.put("ptc/210.jpg", "PTC.zip/PTC/Gilt-Leaf Winnower.full.jpg"); +// singleLinks.put("ptc/212.jpg", "PTC.zip/PTC/Graveblade Marauder.full.jpg"); +// singleLinks.put("ptc/216.jpg", "PTC.zip/PTC/Jace, Vryn's Prodigy.full.jpg"); +// singleLinks.put("ptc/22.jpg", "PTC.zip/PTC/Shield of Kaldra.full.jpg"); +// singleLinks.put("ptc/225.jpg", "PTC.zip/PTC/Nissa's Revelation.full.jpg"); +// singleLinks.put("ptc/227.jpg", "PTC.zip/PTC/Outland Colossus.full.jpg"); +// singleLinks.put("ptc/23.jpg", "PTC.zip/PTC/Helm of Kaldra.full.jpg"); +// singleLinks.put("ptc/238.jpg", "PTC.zip/PTC/Akoum Firebird.full.jpg"); +// singleLinks.put("ptc/239.jpg", "PTC.zip/PTC/Akoum Hellkite.full.jpg"); +// singleLinks.put("ptc/24.jpg", "PTC.zip/PTC/Ryusei, the Falling Star.full.jpg"); +// singleLinks.put("ptc/240.jpg", "PTC.zip/PTC/Aligned Hedron Network.full.jpg"); +// singleLinks.put("ptc/241.jpg", "PTC.zip/PTC/Ally Encampment.full.jpg"); +// singleLinks.put("ptc/242.jpg", "PTC.zip/PTC/Angelic Captain.full.jpg"); +// singleLinks.put("ptc/243.jpg", "PTC.zip/PTC/Barrage Tyrant.full.jpg"); +// singleLinks.put("ptc/244.jpg", "PTC.zip/PTC/Beastcaller Savant.full.jpg"); +// singleLinks.put("ptc/245.jpg", "PTC.zip/PTC/Blight Herder.full.jpg"); +// singleLinks.put("ptc/246.jpg", "PTC.zip/PTC/Bring to Light.full.jpg"); +// singleLinks.put("ptc/247.jpg", "PTC.zip/PTC/Brood Butcher.full.jpg"); +// singleLinks.put("ptc/248.jpg", "PTC.zip/PTC/Brutal Expulsion.full.jpg"); +// singleLinks.put("ptc/249.jpg", "PTC.zip/PTC/Canopy Vista.full.jpg"); +// singleLinks.put("ptc/25.jpg", "PTC.zip/PTC/Ink-Eyes, Servant of Oni.full.jpg"); +// singleLinks.put("ptc/250.jpg", "PTC.zip/PTC/Cinder Glade.full.jpg"); +// singleLinks.put("ptc/251.jpg", "PTC.zip/PTC/Conduit of Ruin.full.jpg"); +// singleLinks.put("ptc/252.jpg", "PTC.zip/PTC/Defiant Bloodlord.full.jpg"); +// singleLinks.put("ptc/253.jpg", "PTC.zip/PTC/Desolation Twin.full.jpg"); +// singleLinks.put("ptc/254.jpg", "PTC.zip/PTC/Dragonmaster Outcast.full.jpg"); +// singleLinks.put("ptc/255.jpg", "PTC.zip/PTC/Drana, Liberator of Malakir.full.jpg"); +// singleLinks.put("ptc/256.jpg", "PTC.zip/PTC/Drowner of Hope.full.jpg"); +// singleLinks.put("ptc/257.jpg", "PTC.zip/PTC/Dust Stalker.full.jpg"); +// singleLinks.put("ptc/258.jpg", "PTC.zip/PTC/Emeria Shepherd.full.jpg"); +// singleLinks.put("ptc/259.jpg", "PTC.zip/PTC/Endless One.full.jpg"); +// singleLinks.put("ptc/26.jpg", "PTC.zip/PTC/Kiyomaro, First to Stand.full.jpg"); +// singleLinks.put("ptc/260.jpg", "PTC.zip/PTC/Exert Influence.full.jpg"); +// singleLinks.put("ptc/261.jpg", "PTC.zip/PTC/Fathom Feeder.full.jpg"); +// singleLinks.put("ptc/262.jpg", "PTC.zip/PTC/Felidar Sovereign.full.jpg"); +// singleLinks.put("ptc/263.jpg", "PTC.zip/PTC/From Beyond.full.jpg"); +// singleLinks.put("ptc/264.jpg", "PTC.zip/PTC/Gideon, Ally of Zendikar.full.jpg"); +// singleLinks.put("ptc/265.jpg", "PTC.zip/PTC/Greenwarden of Murasa.full.jpg"); +// singleLinks.put("ptc/266.jpg", "PTC.zip/PTC/Gruesome Slaughter.full.jpg"); +// singleLinks.put("ptc/267.jpg", "PTC.zip/PTC/Guardian of Tazeem.full.jpg"); +// singleLinks.put("ptc/268.jpg", "PTC.zip/PTC/Guul Draz Overseer.full.jpg"); +// singleLinks.put("ptc/27.jpg", "PTC.zip/PTC/Gleancrawler.full.jpg"); +// singleLinks.put("ptc/271.jpg", "PTC.zip/PTC/Lantern Scout.full.jpg"); +// singleLinks.put("ptc/272.jpg", "PTC.zip/PTC/Lumbering Falls.full.jpg"); +// singleLinks.put("ptc/273.jpg", "PTC.zip/PTC/March from the Tomb.full.jpg"); +// singleLinks.put("ptc/274.jpg", "PTC.zip/PTC/Munda, Ambush Leader.full.jpg"); +// singleLinks.put("ptc/275.jpg", "PTC.zip/PTC/Nissa's Renewal.full.jpg"); +// singleLinks.put("ptc/276.jpg", "PTC.zip/PTC/Noyan Dar, Roil Shaper.full.jpg"); +// singleLinks.put("ptc/277.jpg", "PTC.zip/PTC/Ob Nixilis Reignited.full.jpg"); +// singleLinks.put("ptc/278.jpg", "PTC.zip/PTC/Oblivion Sower.full.jpg"); +// singleLinks.put("ptc/279.jpg", "PTC.zip/PTC/Omnath, Locus of Rage.full.jpg"); +// singleLinks.put("ptc/28.jpg", "PTC.zip/PTC/Djinn Illuminatus.full.jpg"); +// singleLinks.put("ptc/280.jpg", "PTC.zip/PTC/Oran-Rief Hydra.full.jpg"); +// singleLinks.put("ptc/281.jpg", "PTC.zip/PTC/Painful Truths.full.jpg"); +// singleLinks.put("ptc/282.jpg", "PTC.zip/PTC/Part the Waterveil.full.jpg"); +// singleLinks.put("ptc/283.jpg", "PTC.zip/PTC/Planar Outburst.full.jpg"); +// singleLinks.put("ptc/284.jpg", "PTC.zip/PTC/Prairie Stream.full.jpg"); +// singleLinks.put("ptc/285.jpg", "PTC.zip/PTC/Prism Array.full.jpg"); +// singleLinks.put("ptc/286.jpg", "PTC.zip/PTC/Quarantine Field.full.jpg"); +// singleLinks.put("ptc/287.jpg", "PTC.zip/PTC/Radiant Flames.full.jpg"); +// singleLinks.put("ptc/288.jpg", "PTC.zip/PTC/Ruinous Path.full.jpg"); +// singleLinks.put("ptc/289.jpg", "PTC.zip/PTC/Sanctum of Ugin.full.jpg"); +// singleLinks.put("ptc/29.jpg", "PTC.zip/PTC/Avatar of Discord.full.jpg"); +// singleLinks.put("ptc/290.jpg", "PTC.zip/PTC/Scatter to the Winds.full.jpg"); +// singleLinks.put("ptc/291.jpg", "PTC.zip/PTC/Serpentine Spike.full.jpg"); +// singleLinks.put("ptc/292.jpg", "PTC.zip/PTC/Shambling Vent.full.jpg"); +// singleLinks.put("ptc/293.jpg", "PTC.zip/PTC/Shrine of the Forsaken Gods.full.jpg"); +// singleLinks.put("ptc/294.jpg", "PTC.zip/PTC/Sire of Stagnation.full.jpg"); +// singleLinks.put("ptc/295.jpg", "PTC.zip/PTC/Smoldering Marsh.full.jpg"); +// singleLinks.put("ptc/296.jpg", "PTC.zip/PTC/Smothering Abomination.full.jpg"); +// singleLinks.put("ptc/297.jpg", "PTC.zip/PTC/Sunken Hollow.full.jpg"); +// singleLinks.put("ptc/298.jpg", "PTC.zip/PTC/Ugin's Insight.full.jpg"); +// singleLinks.put("ptc/299.jpg", "PTC.zip/PTC/Ulamog, the Ceaseless Hunger.full.jpg"); +// singleLinks.put("ptc/3.jpg", "PTC.zip/PTC/Monstrous Hound.full.jpg"); +// singleLinks.put("ptc/30.jpg", "PTC.zip/PTC/Allosaurus Rider.full.jpg"); +// singleLinks.put("ptc/300.jpg", "PTC.zip/PTC/Undergrowth Champion.full.jpg"); +// singleLinks.put("ptc/301.jpg", "PTC.zip/PTC/Veteran Warleader.full.jpg"); +// singleLinks.put("ptc/302.jpg", "PTC.zip/PTC/Void Winnower.full.jpg"); +// singleLinks.put("ptc/303.jpg", "PTC.zip/PTC/Wasteland Strangler.full.jpg"); +// singleLinks.put("ptc/304.jpg", "PTC.zip/PTC/Woodland Wanderer.full.jpg"); +// singleLinks.put("ptc/305.jpg", "PTC.zip/PTC/Zada, Hedron Grinder.full.jpg"); +// singleLinks.put("ptc/31.jpg", "PTC.zip/PTC/Lotus Bloom.full.jpg"); +// singleLinks.put("ptc/32.jpg", "PTC.zip/PTC/Oros, the Avenger.full.jpg"); +// singleLinks.put("ptc/33.jpg", "PTC.zip/PTC/Korlash, Heir to Blackblade.full.jpg"); +// singleLinks.put("ptc/34.jpg", "PTC.zip/PTC/Wren's Run Packmaster.full.jpg"); +// singleLinks.put("ptc/35.jpg", "PTC.zip/PTC/Door of Destinies.full.jpg"); +// singleLinks.put("ptc/36.jpg", "PTC.zip/PTC/Demigod of Revenge.full.jpg"); +// singleLinks.put("ptc/37.jpg", "PTC.zip/PTC/Overbeing of Myth.full.jpg"); +// singleLinks.put("ptc/38.jpg", "PTC.zip/PTC/Ajani Vengeant.full.jpg"); +// singleLinks.put("ptc/39.jpg", "PTC.zip/PTC/Malfegor.full.jpg"); +// singleLinks.put("ptc/4.jpg", "PTC.zip/PTC/Lightning Dragon.full.jpg"); +// singleLinks.put("ptc/40.jpg", "PTC.zip/PTC/Dragon Broodmother.full.jpg"); +// singleLinks.put("ptc/41.jpg", "PTC.zip/PTC/Vampire Nocturnus.full.jpg"); +// singleLinks.put("ptc/42.jpg", "PTC.zip/PTC/Rampaging Baloths.full.jpg"); +// singleLinks.put("ptc/43.jpg", "PTC.zip/PTC/Comet Storm.full.jpg"); +// singleLinks.put("ptc/44.jpg", "PTC.zip/PTC/Emrakul, the Aeons Torn.full.jpg"); +// singleLinks.put("ptc/45.jpg", "PTC.zip/PTC/Sun Titan.full.jpg"); +// singleLinks.put("ptc/46.jpg", "PTC.zip/PTC/Wurmcoil Engine.full.jpg"); +// singleLinks.put("ptc/47.jpg", "PTC.zip/PTC/Hero of Bladehold.full.jpg"); +// singleLinks.put("ptc/48.jpg", "PTC.zip/PTC/Glissa, the Traitor.full.jpg"); +// singleLinks.put("ptc/49.jpg", "PTC.zip/PTC/Sheoldred, Whispering One.full.jpg"); +// singleLinks.put("ptc/5.jpg", "PTC.zip/PTC/Beast of Burden.full.jpg"); +// singleLinks.put("ptc/50.jpg", "PTC.zip/PTC/Bloodlord of Vaasgoth.full.jpg"); +// singleLinks.put("ptc/51a.jpg", "PTC.zip/PTC/Mayor of Avabruck.full.jpg"); +// singleLinks.put("ptc/51b.jpg", "PTC.zip/PTC/Howlpack Alpha.full.jpg"); +// singleLinks.put("ptc/52a.jpg", "PTC.zip/PTC/Ravenous Demon.full.jpg"); +// singleLinks.put("ptc/52b.jpg", "PTC.zip/PTC/Archdemon of Greed.full.jpg"); +// singleLinks.put("ptc/53.jpg", "PTC.zip/PTC/Moonsilver Spear.full.jpg"); +// singleLinks.put("ptc/54.jpg", "PTC.zip/PTC/Xathrid Gorgon.full.jpg"); +// singleLinks.put("ptc/55.jpg", "PTC.zip/PTC/Archon of the Triumvirate.full.jpg"); +// singleLinks.put("ptc/56.jpg", "PTC.zip/PTC/Hypersonic Dragon.full.jpg"); +// singleLinks.put("ptc/57.jpg", "PTC.zip/PTC/Carnival Hellsteed.full.jpg"); +// singleLinks.put("ptc/58.jpg", "PTC.zip/PTC/Corpsejack Menace.full.jpg"); +// singleLinks.put("ptc/59.jpg", "PTC.zip/PTC/Grove of the Guardian.full.jpg"); +// singleLinks.put("ptc/6.jpg", "PTC.zip/PTC/Lu Bu, Master-at-Arms.full.jpg"); +// singleLinks.put("ptc/60.jpg", "PTC.zip/PTC/Consuming Aberration.full.jpg"); +// singleLinks.put("ptc/61.jpg", "PTC.zip/PTC/Fathom Mage.full.jpg"); +// singleLinks.put("ptc/62.jpg", "PTC.zip/PTC/Foundry Champion.full.jpg"); +// singleLinks.put("ptc/63.jpg", "PTC.zip/PTC/Rubblehulk.full.jpg"); +// singleLinks.put("ptc/64.jpg", "PTC.zip/PTC/Treasury Thrull.full.jpg"); +// singleLinks.put("ptc/65.jpg", "PTC.zip/PTC/Maze's End.full.jpg"); +// singleLinks.put("ptc/66.jpg", "PTC.zip/PTC/Plains.66.full.jpg"); +// singleLinks.put("ptc/67.jpg", "PTC.zip/PTC/Megantic Sliver.full.jpg"); +// singleLinks.put("ptc/68.jpg", "PTC.zip/PTC/Celestial Archon.full.jpg"); +// singleLinks.put("ptc/69.jpg", "PTC.zip/PTC/Shipbreaker Kraken.full.jpg"); +// singleLinks.put("ptc/7.jpg", "PTC.zip/PTC/False Prophet.full.jpg"); +// singleLinks.put("ptc/70.jpg", "PTC.zip/PTC/Abhorrent Overlord.full.jpg"); +// singleLinks.put("ptc/71.jpg", "PTC.zip/PTC/Ember Swallower.full.jpg"); +// singleLinks.put("ptc/72.jpg", "PTC.zip/PTC/Anthousa, Setessan Hero.full.jpg"); +// singleLinks.put("ptc/73.jpg", "PTC.zip/PTC/Silent Sentinel.full.jpg"); +// singleLinks.put("ptc/74.jpg", "PTC.zip/PTC/Arbiter of the Ideal.full.jpg"); +// singleLinks.put("ptc/75.jpg", "PTC.zip/PTC/Eater of Hope.full.jpg"); +// singleLinks.put("ptc/76.jpg", "PTC.zip/PTC/Forgestoker Dragon.full.jpg"); +// singleLinks.put("ptc/77.jpg", "PTC.zip/PTC/Nessian Wilds Ravager.full.jpg"); +// singleLinks.put("ptc/78.jpg", "PTC.zip/PTC/Dawnbringer Charioteers.full.jpg"); +// singleLinks.put("ptc/79.jpg", "PTC.zip/PTC/Scourge of Fleets.full.jpg"); +// singleLinks.put("ptc/8.jpg", "PTC.zip/PTC/Lu Bu, Master-at-Arms.full.jpg"); +// singleLinks.put("ptc/80.jpg", "PTC.zip/PTC/Doomwake Giant.full.jpg"); +// singleLinks.put("ptc/81.jpg", "PTC.zip/PTC/Spawn of Thraxes.full.jpg"); +// singleLinks.put("ptc/82.jpg", "PTC.zip/PTC/Heroes' Bane.full.jpg"); +// singleLinks.put("ptc/83.jpg", "PTC.zip/PTC/Resolute Archangel.full.jpg"); +// singleLinks.put("ptc/84.jpg", "PTC.zip/PTC/Mercurial Pretender.full.jpg"); +// singleLinks.put("ptc/85.jpg", "PTC.zip/PTC/Indulgent Tormentor.full.jpg"); +// singleLinks.put("ptc/86.jpg", "PTC.zip/PTC/Siege Dragon.full.jpg"); +// singleLinks.put("ptc/87.jpg", "PTC.zip/PTC/Phytotitan.full.jpg"); +// singleLinks.put("ptc/88.jpg", "PTC.zip/PTC/Abzan Ascendancy.full.jpg"); +// singleLinks.put("ptc/89.jpg", "PTC.zip/PTC/Anafenza, the Foremost.full.jpg"); +// singleLinks.put("ptc/9.jpg", "PTC.zip/PTC/Overtaker.full.jpg"); +// singleLinks.put("ptc/90.jpg", "PTC.zip/PTC/Ankle Shanker.full.jpg"); +// singleLinks.put("ptc/91.jpg", "PTC.zip/PTC/Avalanche Tusker.full.jpg"); +// singleLinks.put("ptc/92.jpg", "PTC.zip/PTC/Bloodsoaked Champion.full.jpg"); +// singleLinks.put("ptc/93.jpg", "PTC.zip/PTC/Butcher of the Horde.full.jpg"); +// singleLinks.put("ptc/94.jpg", "PTC.zip/PTC/Crackling Doom.full.jpg"); +// singleLinks.put("ptc/95.jpg", "PTC.zip/PTC/Crater's Claws.full.jpg"); +// singleLinks.put("ptc/96.jpg", "PTC.zip/PTC/Deflecting Palm.full.jpg"); +// singleLinks.put("ptc/97.jpg", "PTC.zip/PTC/Dig Through Time.full.jpg"); +// singleLinks.put("ptc/98.jpg", "PTC.zip/PTC/Dragon-Style Twins.full.jpg"); +// singleLinks.put("ptc/99.jpg", "PTC.zip/PTC/Duneblast.full.jpg"); +// singleLinks.put("sus/1.jpg", "SUS.zip/SUS/Thran Quarry.full.jpg"); +// singleLinks.put("sus/10.jpg", "SUS.zip/SUS/Slith Firewalker.full.jpg"); +// singleLinks.put("sus/11.jpg", "SUS.zip/SUS/Royal Assassin.full.jpg"); +// singleLinks.put("sus/12.jpg", "SUS.zip/SUS/Sakura-Tribe Elder.full.jpg"); +// singleLinks.put("sus/13.jpg", "SUS.zip/SUS/Shard Phoenix.full.jpg"); +// singleLinks.put("sus/14.jpg", "SUS.zip/SUS/Soltari Priest.full.jpg"); +// singleLinks.put("sus/15.jpg", "SUS.zip/SUS/Whirling Dervish.full.jpg"); +// singleLinks.put("sus/16.jpg", "SUS.zip/SUS/Glorious Anthem.full.jpg"); +// singleLinks.put("sus/17.jpg", "SUS.zip/SUS/Elvish Champion.full.jpg"); +// singleLinks.put("sus/18.jpg", "SUS.zip/SUS/Mad Auntie.full.jpg"); +// singleLinks.put("sus/19.jpg", "SUS.zip/SUS/Slith Firewalker.full.jpg"); +// singleLinks.put("sus/2.jpg", "SUS.zip/SUS/Serra Avatar.full.jpg"); +// singleLinks.put("sus/20.jpg", "SUS.zip/SUS/Royal Assassin.full.jpg"); +// singleLinks.put("sus/21.jpg", "SUS.zip/SUS/Sakura-Tribe Elder.full.jpg"); +// singleLinks.put("sus/22.jpg", "SUS.zip/SUS/Shard Phoenix.full.jpg"); +// singleLinks.put("sus/23.jpg", "SUS.zip/SUS/Soltari Priest.full.jpg"); +// singleLinks.put("sus/24.jpg", "SUS.zip/SUS/Whirling Dervish.full.jpg"); +// singleLinks.put("sus/25.jpg", "SUS.zip/SUS/Glorious Anthem.full.jpg"); +// singleLinks.put("sus/26.jpg", "SUS.zip/SUS/Elvish Champion.full.jpg"); +// singleLinks.put("sus/27.jpg", "SUS.zip/SUS/Sakura-Tribe Elder.full.jpg"); +// singleLinks.put("sus/28.jpg", "SUS.zip/SUS/Shard Phoenix.full.jpg"); +// singleLinks.put("sus/29.jpg", "SUS.zip/SUS/Soltari Priest.full.jpg"); +// singleLinks.put("sus/3.jpg", "SUS.zip/SUS/Lord of Atlantis.full.jpg"); +// singleLinks.put("sus/30.jpg", "SUS.zip/SUS/Whirling Dervish.full.jpg"); +// singleLinks.put("sus/31.jpg", "SUS.zip/SUS/Glorious Anthem.full.jpg"); +// singleLinks.put("sus/32.jpg", "SUS.zip/SUS/Elvish Champion.full.jpg"); +// singleLinks.put("sus/4.jpg", "SUS.zip/SUS/Crusade.full.jpg"); +// singleLinks.put("sus/5.jpg", "SUS.zip/SUS/Elvish Lyrist.full.jpg"); +// singleLinks.put("sus/6.jpg", "SUS.zip/SUS/City of Brass.full.jpg"); +// singleLinks.put("sus/7.jpg", "SUS.zip/SUS/Volcanic Hammer.full.jpg"); +// singleLinks.put("sus/8.jpg", "SUS.zip/SUS/Giant Growth.full.jpg"); +// singleLinks.put("sus/9.jpg", "SUS.zip/SUS/Two-Headed Dragon.full.jpg"); +// singleLinks.put("ugin/1.jpg", "UGIN.zip/UGIN/Ugin, the Spirit Dragon.full.jpg"); +// singleLinks.put("ugin/113.jpg", "UGIN.zip/UGIN/Jeering Instigator.full.jpg"); +// singleLinks.put("ugin/123.jpg", "UGIN.zip/UGIN/Arashin War Beast.full.jpg"); +// singleLinks.put("ugin/129.jpg", "UGIN.zip/UGIN/Formless Nurturing.full.jpg"); +// singleLinks.put("ugin/131.jpg", "UGIN.zip/UGIN/Dragonscale Boon.full.jpg"); +// singleLinks.put("ugin/146.jpg", "UGIN.zip/UGIN/Wildcall.full.jpg"); +// singleLinks.put("ugin/161.jpg", "UGIN.zip/UGIN/Hewed Stone Retainers.full.jpg"); +// singleLinks.put("ugin/164.jpg", "UGIN.zip/UGIN/Ugin's Construct.full.jpg"); +// singleLinks.put("ugin/19.jpg", "UGIN.zip/UGIN/Mastery of the Unseen.full.jpg"); +// singleLinks.put("ugin/216.jpg", "UGIN.zip/UGIN/Altar of the Brood.full.jpg"); +// singleLinks.put("ugin/217.jpg", "UGIN.zip/UGIN/Briber's Purse.full.jpg"); +// singleLinks.put("ugin/220.jpg", "UGIN.zip/UGIN/Ghostfire Blade.full.jpg"); +// singleLinks.put("ugin/24.jpg", "UGIN.zip/UGIN/Smite the Monstrous.full.jpg"); +// singleLinks.put("ugin/26.jpg", "UGIN.zip/UGIN/Soul Summons.full.jpg"); +// singleLinks.put("ugin/30.jpg", "UGIN.zip/UGIN/Watcher of the Roost.full.jpg"); +// singleLinks.put("ugin/36.jpg", "UGIN.zip/UGIN/Jeskai Infiltrator.full.jpg"); +// singleLinks.put("ugin/46.jpg", "UGIN.zip/UGIN/Reality Shift.full.jpg"); +// singleLinks.put("ugin/48.jpg", "UGIN.zip/UGIN/Mystic of the Hidden Way.full.jpg"); +// singleLinks.put("ugin/59.jpg", "UGIN.zip/UGIN/Write into Being.full.jpg"); +// singleLinks.put("ugin/68.jpg", "UGIN.zip/UGIN/Debilitating Injury.full.jpg"); +// singleLinks.put("ugin/73.jpg", "UGIN.zip/UGIN/Grim Haruspex.full.jpg"); +// singleLinks.put("ugin/85.jpg", "UGIN.zip/UGIN/Sultai Emissary.full.jpg"); +// singleLinks.put("ugin/88.jpg", "UGIN.zip/UGIN/Ruthless Ripper.full.jpg"); +// singleLinks.put("ugin/96.jpg", "UGIN.zip/UGIN/Ainok Tracker.full.jpg"); +// singleLinks.put("ugin/97.jpg", "UGIN.zip/UGIN/Arc Lightning.full.jpg"); +// singleLinks.put("ugin/98.jpg", "UGIN.zip/UGIN/Fierce Invocation.full.jpg"); +// singleLinks.put("wmcq/1.jpg", "WMCQ.zip/WMCQ/Vengevine.full.jpg"); +// singleLinks.put("wmcq/2.jpg", "WMCQ.zip/WMCQ/Geist of Saint Traft.full.jpg"); +// singleLinks.put("wmcq/3.jpg", "WMCQ.zip/WMCQ/Thalia, Guardian of Thraben.full.jpg"); +// singleLinks.put("wmcq/4.jpg", "WMCQ.zip/WMCQ/Liliana of the Veil.full.jpg"); +// singleLinks.put("wmcq/5.jpg", "WMCQ.zip/WMCQ/Snapcaster Mage.full.jpg"); } @Override @@ -1697,11 +1958,11 @@ public enum GrabbagImageSource implements CardImageSource { @Override public int getTotalImages() { - if (copyUrlToImage == null) { + if (singleLinks == null) { setupLinks(); } - if (copyUrlToImage != null) { - return copyImageToUrl.size(); + if (singleLinks != null) { + return singleLinks.size(); } return -1; } @@ -1711,9 +1972,11 @@ public enum GrabbagImageSource implements CardImageSource { return false; } - private String getSourceName(String httpImageUrl) { - if (httpImageUrl.startsWith("MTG")) { + private String getSourceName(CardDownloadData card, String httpImageUrl) { + if (card.getSet().equals("MTG")) { return "http://static.starcitygames.com/sales/cardscans/"; + } else if (card.getSet().equals("SWS")) { + return "http://i.imgur.com/"; } else { return "http://magiccards.info/scans/en/"; } @@ -1735,4 +1998,18 @@ public enum GrabbagImageSource implements CardImageSource { } } } + + @Override + public boolean isImageProvided(String setCode, String cardName) { + if (singleLinks == null) { + setupLinks(); + } + return singleLinks.containsKey(setCode + "/" + cardName); + } + + @Override + public boolean isSetSupportedComplete(String setCode) { + return false; + } + } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index be4345dadf..ee30aa0f71 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -294,7 +294,9 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab for (CardDownloadData data : allCardsMissingImage) { if ((data.isToken() && tokens) || (!data.isToken() && selectedSetCodes != null && selectedSetCodes.contains(data.getSet()))) { - cardsToDownload.add(data); + if (cardImageSource.isSetSupportedComplete(data.getSet()) || cardImageSource.isImageProvided(data.getSet(), data.getName())) { + cardsToDownload.add(data); + } } } int numberTokenImagesAvailable = 0; From 96034c4c2b267e8ddbcaeca5dfedab65a18d1e77 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 8 Sep 2017 15:22:09 +0200 Subject: [PATCH 005/182] Updated some logic. --- .../card/dl/sources/GrabbagImageSource.java | 23 ++- .../dl/sources/MythicspoilerComSource.java | 173 +++++++++++++++++- 2 files changed, 189 insertions(+), 7 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java index 501b1c61e9..ef5fa334df 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java @@ -33,6 +33,7 @@ import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; import org.apache.log4j.Logger; import org.mage.plugins.card.images.CardDownloadData; @@ -415,6 +416,21 @@ public enum GrabbagImageSource implements CardImageSource { singleLinks.put("SWS/Yoda, Jedi Master", "6arN1Hl.png"); singleLinks.put("SWS/Y-Wing", "aQQ5zwA.jpg"); singleLinks.put("SWS/Zam Wesell", "ToG0C1r.jpg"); + // Emblems + singleLinks.put("SWS/Obi-Wan Kenobi", "Qyc10aT.png"); + singleLinks.put("SWS/Aurra Sing", "BLWbVJC.png"); + singleLinks.put("SWS/Yoda", "zH0sYxg.png"); + // Tokens + singleLinks.put("SWS/Ewok", "N2MvJyr.png"); + singleLinks.put("SWS/B-Wing", "oH62AUD.png"); + singleLinks.put("SWS/Hunter", "oJiawFA.png"); + singleLinks.put("SWS/TIE Fighter", "CLOuJ05.png"); + singleLinks.put("SWS/Trooper", "2XKqdX5.png"); + singleLinks.put("SWS/AT-AT", "Tv5b7h1.png"); + singleLinks.put("SWS/Rebel", "pVoShnF.png"); + singleLinks.put("SWS/Royal Guard", "9tqE8vL.png"); + singleLinks.put("SWS/Tusken Raider", "gPMiSmP.png"); + singleLinks.put("SWS/Droid", "4PRrWFF.png"); // singleLinks.put("MTG/FRF/en/promo/prerelease/AleshaWhoSmilesAtDeath.jpg", "PTC.zip/PTC/Alesha, Who Smiles at Death.full.jpg"); // singleLinks.put("MTG/FRF/en/promo/prerelease/Arcbond.jpg", "PTC.zip/PTC/Arcbond.full.jpg"); @@ -1953,6 +1969,11 @@ public enum GrabbagImageSource implements CardImageSource { @Override public String generateTokenUrl(CardDownloadData card) throws IOException { + try { + return generateURL(card); + } catch (Exception ex) { + java.util.logging.Logger.getLogger(GrabbagImageSource.class.getName()).log(Level.SEVERE, null, ex); + } return null; } @@ -1969,7 +1990,7 @@ public enum GrabbagImageSource implements CardImageSource { @Override public boolean isTokenSource() { - return false; + return true; } private String getSourceName(CardDownloadData card, String httpImageUrl) { diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java index cf81ee5957..93bd2a6d11 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java @@ -72,24 +72,185 @@ public enum MythicspoilerComSource implements CardImageSource { MythicspoilerComSource() { supportedSets = new LinkedHashSet<>(); - supportedSets.add("V16"); +// supportedSets.add("LEA"); + supportedSets.add("LEB"); +// supportedSets.add("2ED"); + supportedSets.add("ARN"); + supportedSets.add("ATQ"); + supportedSets.add("3ED"); + supportedSets.add("LEG"); + supportedSets.add("DRK"); + supportedSets.add("FEM"); +// supportedSets.add("4ED"); + supportedSets.add("ICE"); + supportedSets.add("CHR"); + supportedSets.add("HML"); + supportedSets.add("ALL"); + supportedSets.add("MIR"); + supportedSets.add("VIS"); +// supportedSets.add("5ED"); +// supportedSets.add("POR"); + supportedSets.add("WTH"); + supportedSets.add("TMP"); + supportedSets.add("STH"); + supportedSets.add("EXO"); +// supportedSets.add("P02"); +// supportedSets.add("UGL"); + supportedSets.add("USG"); +// supportedSets.add("DD3DVD"); +// supportedSets.add("DD3EVG"); +// supportedSets.add("DD3GVL"); +// supportedSets.add("DD3JVC"); + +// supportedSets.add("ULG"); +// supportedSets.add("6ED"); + supportedSets.add("UDS"); + supportedSets.add("PTK"); +// supportedSets.add("S99"); + supportedSets.add("MMQ"); + // supportedSets.add("BRB");Battle Royale Box Set + supportedSets.add("NEM"); +// supportedSets.add("S00"); + supportedSets.add("PCY"); + supportedSets.add("INV"); + // supportedSets.add("BTD"); // Beatdown Boxset + supportedSets.add("PLS"); + supportedSets.add("7ED"); + supportedSets.add("APC"); + supportedSets.add("ODY"); + // supportedSets.add("DKM"); // Deckmasters 2001 + supportedSets.add("TOR"); + supportedSets.add("JUD"); + supportedSets.add("ONS"); + supportedSets.add("LGN"); + supportedSets.add("SCG"); + supportedSets.add("8ED"); + supportedSets.add("MRD"); + supportedSets.add("DST"); + supportedSets.add("5DN"); + supportedSets.add("CHK"); + supportedSets.add("UNH"); + supportedSets.add("BOK"); + supportedSets.add("SOK"); + supportedSets.add("9ED"); + supportedSets.add("RAV"); + supportedSets.add("GPT"); + supportedSets.add("DIS"); + supportedSets.add("CSP"); + supportedSets.add("TSP"); + supportedSets.add("TSB"); + supportedSets.add("PLC"); + supportedSets.add("FUT"); + supportedSets.add("10E"); + supportedSets.add("MED"); + supportedSets.add("LRW"); + supportedSets.add("EVG"); + supportedSets.add("MOR"); + supportedSets.add("SHM"); + supportedSets.add("EVE"); + supportedSets.add("DRB"); +// supportedSets.add("ME2"); + supportedSets.add("ALA"); +// supportedSets.add("DD2"); + supportedSets.add("CON"); +// supportedSets.add("DDC"); + supportedSets.add("ARB"); + supportedSets.add("M10"); + // supportedSets.add("TD0"); // Magic Online Deck Series +// supportedSets.add("V09"); + supportedSets.add("HOP"); +// supportedSets.add("ME3"); + supportedSets.add("ZEN"); +// supportedSets.add("DDD"); + supportedSets.add("H09"); + supportedSets.add("WWK"); +// supportedSets.add("DDE"); + supportedSets.add("ROE"); + supportedSets.add("DPA"); + supportedSets.add("ARC"); + supportedSets.add("M11"); +// supportedSets.add("V10"); +// supportedSets.add("DDF"); + supportedSets.add("SOM"); +// supportedSets.add("TD0"); // Commander Theme Decks +// supportedSets.add("PD2"); +// supportedSets.add("ME4"); + supportedSets.add("MBS"); +// supportedSets.add("DDG"); + supportedSets.add("NPH"); + supportedSets.add("CMD"); + supportedSets.add("M12"); + supportedSets.add("V11"); +// supportedSets.add("DDH"); + supportedSets.add("ISD"); + supportedSets.add("PD3"); + supportedSets.add("DKA"); +// supportedSets.add("DDI"); + supportedSets.add("AVR"); +// supportedSets.add("PC2"); + supportedSets.add("M13"); +// supportedSets.add("V12"); +// supportedSets.add("DDJ"); + supportedSets.add("RTR"); +// supportedSets.add("CM1"); + // supportedSets.add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia + supportedSets.add("GTC"); +// supportedSets.add("DDK"); + supportedSets.add("DGM"); +// supportedSets.add("MMA"); + supportedSets.add("M14"); + supportedSets.add("V13"); +// supportedSets.add("DDL"); + supportedSets.add("THS"); + supportedSets.add("C13"); + supportedSets.add("BNG"); +// supportedSets.add("DDM"); + supportedSets.add("JOU"); + // supportedSets.add("MD1"); // Modern Event Deck +// supportedSets.add("CNS"); +// supportedSets.add("VMA"); + supportedSets.add("M15"); + supportedSets.add("V14"); + supportedSets.add("DDN"); + supportedSets.add("KTK"); + supportedSets.add("C14"); + // supportedSets.add("DD3"); // Duel Decks Anthology + supportedSets.add("FRF"); +// supportedSets.add("DDO"); +// supportedSets.add("DTK"); +// supportedSets.add("TPR"); + supportedSets.add("MM2"); + supportedSets.add("ORI"); +// supportedSets.add("V15"); +// supportedSets.add("DDP"); + supportedSets.add("BFZ"); +// supportedSets.add("EXP"); + supportedSets.add("C15"); + // supportedSets.add("PZ1"); // Legendary Cube + supportedSets.add("OGW"); +// supportedSets.add("DDQ"); +// supportedSets.add("W16"); + supportedSets.add("SOI"); + supportedSets.add("EMA"); + supportedSets.add("EMN"); +// supportedSets.add("V16"); supportedSets.add("CN2"); - supportedSets.add("DDR"); +// supportedSets.add("DDR"); supportedSets.add("KLD"); - supportedSets.add("MPS"); +// supportedSets.add("MPS"); // supportedSets.add("PZ2"); supportedSets.add("C16"); - supportedSets.add("PCA"); +// supportedSets.add("PCA"); supportedSets.add("AER"); supportedSets.add("MM3"); - supportedSets.add("DDS"); - supportedSets.add("W17"); +// supportedSets.add("W17"); supportedSets.add("AKH"); supportedSets.add("MPS"); supportedSets.add("CMA"); supportedSets.add("E01"); supportedSets.add("HOU"); supportedSets.add("C17"); + supportedSets.add("XLN"); sets = new LinkedHashMap<>(); setsAliases = new HashMap<>(); From a2806055917e82c6c42c22e3a8f665ba8e9aa1fd Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 10 Sep 2017 10:19:14 +0200 Subject: [PATCH 006/182] Some updates. --- .../card/dl/sources/TokensMtgImageSource.java | 101 +++++++++++------- .../plugins/card/images/DownloadPictures.java | 51 ++++----- .../main/resources/tokens-mtg-onl-list.csv | 23 +++- .../game/permanent/token/HellionToken.java | 3 +- 4 files changed, 112 insertions(+), 66 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java index 7f932f3536..95f4294a05 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java @@ -36,6 +36,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.logging.Level; import org.apache.log4j.Logger; import org.mage.plugins.card.images.CardDownloadData; @@ -48,7 +49,8 @@ public enum TokensMtgImageSource implements CardImageSource { instance; private static final Logger logger = Logger.getLogger(TokensMtgImageSource.class); - private List tokensData; + // [[EXP/Name, TokenData> + private HashMap> tokensData; private final Object tokensDataSync = new Object(); @@ -98,7 +100,12 @@ public enum TokensMtgImageSource implements CardImageSource { "Sorin", "Tamiyo", "Teferi", - "Venser",}; + "Venser", + // Custom Emblems + "Yoda", + "Obi-Wan Kenobi", + "Aurra Sing" + }; private static final Map SET_NAMES_REPLACEMENT = new HashMap() { { @@ -132,38 +139,31 @@ public enum TokensMtgImageSource implements CardImageSource { // e.g. http://tokens.mtg.onl/tokens/ORI_010-Thopter.jpg -- token number 010 // We don't know these numbers, but we can take them from a file // with tokens information that can be downloaded from the site. - List newTokensData = getTokensData(); - - if (newTokensData.isEmpty()) { + if (tokensData.isEmpty()) { logger.info("Source " + getSourceName() + " provides no token data."); return null; } - List matchedTokens = new ArrayList<>(); - for (TokenData token : newTokensData) { - if (name.equalsIgnoreCase(token.getName()) && set.equalsIgnoreCase(token.getExpansionSetCode())) { - matchedTokens.add(token); - } - } - - if (matchedTokens.isEmpty()) { + String key = set + "/" + name; + List list = tokensData.get(key); + if (list == null) { logger.info("Could not find data for token " + name + ", set " + set + "."); return null; } TokenData tokenData; if (type == 0) { - if (matchedTokens.size() > 1) { + if (list.size() > 1) { logger.info("Multiple images were found for token " + name + ", set " + set + '.'); } logger.info("Token found: " + name + ", set " + set + '.'); - tokenData = matchedTokens.get(0); + tokenData = list.get(0); } else { - if (type > matchedTokens.size()) { + if (type > list.size()) { logger.warn("Not enough images for token with type " + type + ", name " + name + ", set " + set + '.'); return null; } - tokenData = matchedTokens.get(card.getType() - 1); + tokenData = list.get(card.getType() - 1); } String url = "http://tokens.mtg.onl/tokens/" + tokenData.getExpansionSetCode().trim() + '_' @@ -172,15 +172,24 @@ public enum TokensMtgImageSource implements CardImageSource { return url; } - private List getTokensData() throws IOException { + private HashMap> getTokensData() throws IOException { synchronized (tokensDataSync) { if (tokensData == null) { - tokensData = new ArrayList<>(); + tokensData = new HashMap<>(); // get tokens data from resource file try (InputStream inputStream = this.getClass().getResourceAsStream("/tokens-mtg-onl-list.csv")) { List fileTokensData = parseTokensData(inputStream); - tokensData.addAll(fileTokensData); + for (TokenData tokenData : fileTokensData) { + String key = tokenData.getExpansionSetCode() + "/" + tokenData.getName(); + ArrayList list = tokensData.get(key); + if (list == null) { + list = new ArrayList<>(); + tokensData.put(key, list); + logger.info("Added key: " + key); + } + list.add(tokenData); + } } catch (Exception exception) { logger.warn("Failed to get tokens description from resource file tokens-mtg-onl-list.csv", exception); } @@ -190,23 +199,26 @@ public enum TokensMtgImageSource implements CardImageSource { URL url = new URL("http://tokens.mtg.onl/data/SetsWithTokens.csv"); try (InputStream inputStream = url.openStream()) { List siteTokensData = parseTokensData(inputStream); - List newTokensData = new ArrayList<>(); for (TokenData siteData : siteTokensData) { - boolean isNew = true; - for (TokenData fileData : tokensData) { - if (siteData.getName().equalsIgnoreCase(fileData.getName()) - && siteData.getNumber().equalsIgnoreCase(fileData.getNumber()) - && siteData.getExpansionSetCode().equalsIgnoreCase(fileData.getExpansionSetCode())) { - isNew = false; - break; + String key = siteData.getExpansionSetCode() + "/" + siteData.getName(); + ArrayList list = tokensData.get(key); + if (list == null) { + list = new ArrayList<>(); + tokensData.put(key, list); + list.add(siteData); + } else { + boolean newToken = true; + for (TokenData tokenData : list) { + if (siteData.getNumber().equals(tokenData.number)) { + newToken = false; + break; + } + } + if (newToken) { + list.add(siteData); } } - if (isNew) { - newTokensData.add(siteData); - } } - - tokensData.addAll(newTokensData); } catch (Exception exception) { logger.warn("Failed to get tokens description from tokens.mtg.onl", exception); } @@ -290,14 +302,12 @@ public enum TokensMtgImageSource implements CardImageSource { @Override public int getTokenImages() { - int number = 0; try { - List newTokensData = getTokensData(); - number = newTokensData.size(); + getTokensData(); } catch (IOException ex) { logger.error(getSourceName() + ": Loading available data failed. " + ex.getMessage()); } - return number; + return tokensData.size(); } @Override @@ -308,4 +318,21 @@ public enum TokensMtgImageSource implements CardImageSource { @Override public void doPause(String httpImageUrl) { } + + @Override + public boolean isImageProvided(String setCode, String cardName) { + try { + getTokensData(); + } catch (IOException ex) { + java.util.logging.Logger.getLogger(TokensMtgImageSource.class.getName()).log(Level.SEVERE, null, ex); + } + String key = setCode + "/" + cardName; + return (tokensData.containsKey(key)); + } + + @Override + public boolean isSetSupportedComplete(String setCode) { + return false; + } + } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index ee30aa0f71..2e81ebd36c 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -46,9 +46,9 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab private static final Logger logger = Logger.getLogger(DownloadPictures.class); - public static final String ALL_CARDS = "- All cards from that source"; - public static final String ALL_STANDARD_CARDS = "- All cards from standard from that source"; - public static final String ALL_TOKENS = "- All token images from that source"; + public static final String ALL_IMAGES = "- All images from that source"; + public static final String ALL_STANDARD_IMAGES = "- All images from standard from that source"; + public static final String ALL_TOKENS = "- Only all token images from that source"; private final JProgressBar bar; private final JOptionPane dlg; @@ -204,7 +204,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab bar.setStringPainted(true); Dimension d = bar.getPreferredSize(); - d.width = 300; + d.width = 400; bar.setPreferredSize(d); // JOptionPane @@ -232,8 +232,8 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab ArrayList supportedSets = cardImageSource.getSupportedSets(); List setNames = new ArrayList<>(); if (supportedSets != null) { - setNames.add(ALL_CARDS); - setNames.add(ALL_STANDARD_CARDS); + setNames.add(ALL_IMAGES); + setNames.add(ALL_STANDARD_IMAGES); } if (cardImageSource.isTokenSource()) { setNames.add(ALL_TOKENS); @@ -258,16 +258,15 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab private void updateCardsToDownload(String itemText) { selectedSetCodes.clear(); - boolean tokens = false; switch (itemText) { - case ALL_CARDS: + case ALL_IMAGES: if (cardImageSource.getSupportedSets() == null) { selectedSetCodes = cardImageSource.getSupportedSets(); } else { selectedSetCodes.addAll(cardImageSource.getSupportedSets()); } break; - case ALL_STANDARD_CARDS: + case ALL_STANDARD_IMAGES: List standardSets = ConstructedFormats.getSetsByFormat(ConstructedFormats.STANDARD); for (String setCode : cardImageSource.getSupportedSets()) { if (standardSets.contains(setCode)) { @@ -277,9 +276,6 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } } break; - case ALL_TOKENS: - tokens = true; - break; default: int nonSetEntries = 0; if (cardImageSource.getSupportedSets() != null) { @@ -291,19 +287,24 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab selectedSetCodes.add(cardImageSource.getSupportedSets().get(jComboBoxSet.getSelectedIndex() - nonSetEntries)); } cardsToDownload.clear(); + int numberTokenImagesAvailable = 0; + int numberCardImagesAvailable = 0; for (CardDownloadData data : allCardsMissingImage) { - if ((data.isToken() && tokens) - || (!data.isToken() && selectedSetCodes != null && selectedSetCodes.contains(data.getSet()))) { - if (cardImageSource.isSetSupportedComplete(data.getSet()) || cardImageSource.isImageProvided(data.getSet(), data.getName())) { + if (data.isToken() && cardImageSource.isTokenSource()) { + if (cardImageSource.isImageProvided(data.getSet(), data.getName())) { + numberTokenImagesAvailable++; cardsToDownload.add(data); } + } else { + if (selectedSetCodes != null && selectedSetCodes.contains(data.getSet())) { + if (cardImageSource.isSetSupportedComplete(data.getSet()) || cardImageSource.isImageProvided(data.getSet(), data.getName())) { + numberCardImagesAvailable++; + cardsToDownload.add(data); + } + } } } - int numberTokenImagesAvailable = 0; - if (tokens) { - cardImageSource.getTokenImages(); - } - updateProgressText(cardsToDownload.size() + numberTokenImagesAvailable); + updateProgressText(numberCardImagesAvailable, numberTokenImagesAvailable); } private void comboBoxSetItemSelected(ItemEvent event) { @@ -311,7 +312,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab updateCardsToDownload(event.getItem().toString()); } - private void updateProgressText(int cardCount) { + private void updateProgressText(int cardCount, int tokenCount) { missingTokens = 0; for (CardDownloadData card : allCardsMissingImage) { if (card.isToken()) { @@ -320,10 +321,10 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } missingCards = allCardsMissingImage.size() - missingTokens; jLabelAllMissing.setText("Missing: " + missingCards + " card images / " + missingTokens + " token images"); - - float mb = (cardCount * cardImageSource.getAverageSize()) / 1024; - bar.setString(String.format(cardIndex == cardCount ? "%d of %d image downloads finished! Please close!" - : "%d of %d image downloads finished! Please wait! [%.1f Mb]", 0, cardCount, mb)); + int imageSum = cardCount + tokenCount; + float mb = (imageSum * cardImageSource.getAverageSize()) / 1024; + bar.setString(String.format(cardIndex == imageSum ? "%d of %d (%d cards/%d tokens) image downloads finished! Please close!" + : "%d of %d (%d cards/%d tokens) image downloads finished! Please wait! [%.1f Mb]", 0, imageSum, cardCount, tokenCount, mb)); } private static String createDownloadName(CardInfo card) { diff --git a/Mage.Client/src/main/resources/tokens-mtg-onl-list.csv b/Mage.Client/src/main/resources/tokens-mtg-onl-list.csv index 1d2ea50d5c..4343e5257e 100644 --- a/Mage.Client/src/main/resources/tokens-mtg-onl-list.csv +++ b/Mage.Client/src/main/resources/tokens-mtg-onl-list.csv @@ -222,7 +222,7 @@ Eldrazi Spawn, 1a, -, -, -, Creature - Eldrazi Spawn, Aleksi Briclot, Sacrifice Eldrazi Spawn, 1b, -, -, -, Creature - Eldrazi Spawn, Mark Tedin, Sacrifice this creature: Add {1} to your mana pool. Eldrazi Spawn, 1c, -, -, -, Creature - Eldrazi Spawn, Veronique Meignaud, Sacrifice this creature: Add {1} to your mana pool. Elemental, 2, R, *|*, -, Creature - Elemental, Jung Park, - -Hellion, 3, R, 4|4, -, Creature - Hellion, Anthony Francisco, - +Hellion, 1, R, 4|4, -, Creature - Hellion, Anthony Francisco, - Ooze, 4, G, *|*, -, Creature - Ooze, Daniel Ljunggren, - Tuktuk The Returned, 5, -, 5|5, -, Legendary Artifact Creature - Goblin Golem, Franz Vohwinkel, - @@ -344,7 +344,7 @@ Soldier, 3, W, 1|1, -, Creature - Soldier, Greg Staples, - Drake, 4, U, 2|2, -, Creature - Drake, Svetlin Velinov, Flying Zombie, 5, B, 2|2, -, Creature - Zombie, Lucas Graciano, - Goblin, 6, R, 1|1, -, Creature - Goblin, Karl Kopinski, - -Hellion, 7, R, 4|4, -, Creature - Hellion, Anthony Francisco, - +Hellion, 1, R, 4|4, -, Creature - Hellion, Anthony Francisco, - Beast, 8, G, 3|3, -, Creature - Beast, John Donahue, - Saproling, 9, G, 1|1, -, Creature - Saproling, Brad Rigney, - Wurm, 10, G, 6|6, -, Creature - Wurm, Anthony Francisco, - @@ -664,7 +664,7 @@ DDP - Duel Decks: Zendikar vs. Eldrazi (2015-08-28) Eldrazi Spawn, 076, -, -, -, Creature - Eldrazi Spawn, Aleksi Briclot, Sacrifice this creature: Add {1} to your mana pool. Eldrazi Spawn, 077, -, -, -, Creature - Eldrazi Spawn, Veronique Meignaud, Sacrifice this creature: Add {1} to your mana pool. Eldrazi Spawn, 078, -, -, -, Creature - Eldrazi Spawn, Mark Tedin, Sacrifice this creature: Add {1} to your mana pool. -Hellion, 079, R, 4|4, -, Creature - Hellion, Anthony Francisco, - +Hellion, 1, R, 4|4, -, Creature - Hellion, Anthony Francisco, - Plant, 080, G, -, -, Creature - Plant, Daren Bader, - BFZ - Battle for Zendikar (2015-10-09) @@ -745,3 +745,20 @@ Clue, 015, -, -, -, Artifact - Clue, James Paick, {2}‚ Sacrifice this Artifact Clue, 016, -, -, -, Artifact - Clue, Franz Vohwinkel, {2}‚ Sacrifice this Artifact: Draw a card. Jace Emblem, 017, -, -, -, Emblem - Jace, Tyler Jacobson, Whenever an opponent casts his or her first spell each turn� counter that spell. Arlinn Emblem, 018, -, -, -, Emblem - Arlinn, Winona Nelson, Creatures you control have haste and '{T}: This creature deals damage equal to its power to target creature or player.' + + +SWS - Star Wars Custom set + +Rebel, 001, W, 1|1, -, Creature - Rebel, Alex Konstad, - +Trooper, 002, W, 1|1, -, Creature - Trooper, Darren Tan, - +Tusken Raider, 003, W, 1|1, -, Creature - Tusken Raider, William O'Connor, - +Ewok, 004, G, 1|1, -, Creature - Ewok, Chris NG, - +Hunter, 005, R, 4|4, -, Creature - Hunter, Steve Argyle, - +Royal Guard, 006, R, 2|2, -, Creature - Soldier, Aldo Katayanagi, First Strike +AT-AT, 007, -, 5|5, -, Artifact Creature - AT-AT, Prokhoda, When this creature dies� create two 1/1 white Trooper creature tokens. +B-Wing, 008, -, 1|1, -, Artifact Creature - Rebel Starship, Anthony Devine, Spaceflight +Droid, 009, -, 1|1, -, Artifact Creature - Droid, PeetuGee, - +TIE Fighter, 010, -, 1|1, -, Artifact Creature - Starship, Darren Tan, Spaceflight +Yoda Emblem, 011, -, -, -, Emblem - Yoda, Jerry Vanderstelt, Hexproof� you and your creatures have. +Obi-Wan Kenobi Emblem, 012, -, -, -, Emblem - Obi-Wan Kenobi, Jerry Vanderstelt, Creatures you control get +1/+1 and have vigilance� first strike� and lifelink. +Aurra Sing Emblem, 013, -, -, -, Emblem - Aurra Sing, Willman1701, Whenever a nontoken creature you control leaves the battlefield� discard a card. diff --git a/Mage/src/main/java/mage/game/permanent/token/HellionToken.java b/Mage/src/main/java/mage/game/permanent/token/HellionToken.java index a4672fb64e..31eed72112 100644 --- a/Mage/src/main/java/mage/game/permanent/token/HellionToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/HellionToken.java @@ -29,6 +29,7 @@ package mage.game.permanent.token; import mage.MageInt; import mage.constants.CardType; +import mage.constants.SubType; /** * @@ -40,7 +41,7 @@ public class HellionToken extends Token { super("Hellion", "4/4 red Hellion creature token"); cardType.add(CardType.CREATURE); color.setRed(true); - subtype.add("Hellion"); + subtype.add(SubType.HELLION); power = new MageInt(4); toughness = new MageInt(4); } From 650f184ee682ffd0d8122dadbaa5cd60720d41d8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 11 Sep 2017 16:26:30 -0400 Subject: [PATCH 007/182] Begin Mairsil fix --- .../src/mage/cards/m/MairsilThePretender.java | 288 +++++++++--------- .../mage/abilities/ActivatedAbilityImpl.java | 62 ++++ .../ActivateIfConditionActivatedAbility.java | 32 +- .../LimitedTimesPerTurnActivatedAbility.java | 62 ---- 4 files changed, 203 insertions(+), 241 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MairsilThePretender.java b/Mage.Sets/src/mage/cards/m/MairsilThePretender.java index 4e4b5cb050..ca79b17b9d 100644 --- a/Mage.Sets/src/mage/cards/m/MairsilThePretender.java +++ b/Mage.Sets/src/mage/cards/m/MairsilThePretender.java @@ -27,21 +27,14 @@ */ package mage.cards.m; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.ActivatedAbility; +import mage.abilities.ActivatedAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -54,7 +47,6 @@ import mage.constants.Outcome; import mage.constants.SubLayer; import mage.constants.SuperType; import mage.constants.TargetController; -import mage.constants.WatcherScope; import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.FilterCard; @@ -63,15 +55,11 @@ import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.other.CounterCardPredicate; import mage.filter.predicate.other.OwnerPredicate; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; -import mage.game.stack.StackAbility; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInYourGraveyard; -import mage.watchers.Watcher; /** * @@ -93,8 +81,9 @@ public class MairsilThePretender extends CardImpl { // Mairsil, the Pretender has all activated abilities of all cards you own in exile with cage counters on them. You may activate each of those abilities only once each turn. Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new MairsilThePretenderGainAbilitiesEffect()); - ability.addEffect(new MairsilThePretenderRuleModifyingEffect()); - this.addAbility(ability, new MairsilThePretenderWatcher()); + this.addAbility(ability); +// ability.addEffect(new MairsilThePretenderRuleModifyingEffect()); +// this.addAbility(ability, new MairsilThePretenderWatcher()); } public MairsilThePretender(final MairsilThePretender card) { @@ -182,11 +171,8 @@ class MairsilThePretenderGainAbilitiesEffect extends ContinuousEffectImpl { if (filter.match(card, game)) { for (Ability ability : card.getAbilities()) { if (ability instanceof ActivatedAbility) { - UUID originaId = ability.getId(); - ActivatedAbility copyAbility = (ActivatedAbility) ability.copy(); - Effect effect = new DoNothingEffect(); - effect.setValue("key", originaId); - copyAbility.addEffect(effect); + ActivatedAbilityImpl copyAbility = (ActivatedAbilityImpl) ability.copy(); + copyAbility.setMaxActivationsPerTurn(1); perm.addAbility(copyAbility, card.getId(), game); } } @@ -203,134 +189,134 @@ class MairsilThePretenderGainAbilitiesEffect extends ContinuousEffectImpl { } } -class MairsilThePretenderWatcher extends Watcher { - - public final Map> activatedThisTurnAbilities = new HashMap<>(); - - public MairsilThePretenderWatcher() { - super(MairsilThePretenderWatcher.class.getSimpleName(), WatcherScope.GAME); - } - - public MairsilThePretenderWatcher(final MairsilThePretenderWatcher watcher) { - super(watcher); - for (Entry> entry : watcher.activatedThisTurnAbilities.entrySet()) { - activatedThisTurnAbilities.put(entry.getKey(), entry.getValue()); - } - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event instanceof ZoneChangeEvent) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getFromZone() == Zone.BATTLEFIELD) { - Permanent permanent = zEvent.getTarget(); - if (permanent != null) { - this.activatedThisTurnAbilities.remove(permanent.getId()); - } - } - } - if (event.getType() == GameEvent.EventType.ACTIVATED_ABILITY) { - Set permAbilities; - if (activatedThisTurnAbilities.keySet().contains(event.getSourceId())) { - permAbilities = activatedThisTurnAbilities.get(event.getSourceId()); - } else { - permAbilities = new HashSet<>(); - } - StackAbility ability = (StackAbility) game.getStack().getStackObject(event.getSourceId()); - if (ability != null && ability.getStackAbility().isActivated()) { - for (Effect effect : ability.getAllEffects()) { - if (effect instanceof DoNothingEffect) { - permAbilities.add((UUID) effect.getValue("key")); - this.activatedThisTurnAbilities.put(event.getSourceId(), permAbilities); - } - } - } - } - } - - @Override - public void reset() { - activatedThisTurnAbilities.clear(); - } - - public Map> getActivatedThisTurnAbilities() { - return this.activatedThisTurnAbilities; - } - - @Override - public MairsilThePretenderWatcher copy() { - return new MairsilThePretenderWatcher(this); - } - -} - -class MairsilThePretenderRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl { - - public MairsilThePretenderRuleModifyingEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); - } - - public MairsilThePretenderRuleModifyingEffect(final MairsilThePretenderRuleModifyingEffect effect) { - super(effect); - } - - @Override - public MairsilThePretenderRuleModifyingEffect copy() { - return new MairsilThePretenderRuleModifyingEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ACTIVATE_ABILITY; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); - MairsilThePretenderWatcher watcher = (MairsilThePretenderWatcher) game.getState().getWatchers().get(MairsilThePretenderWatcher.class.getSimpleName()); - if (watcher != null && ability != null && ability.isPresent()) { - for (Effect effect : ability.get().getAllEffects()) { - if (effect instanceof DoNothingEffect) { - UUID originalID = (UUID) effect.getValue("key"); - if (watcher.getActivatedThisTurnAbilities().keySet().contains(event.getSourceId())) { - if (watcher.getActivatedThisTurnAbilities().get(event.getSourceId()).contains(originalID)) { - return true; - } - } - } - } - } - return false; - } - - @Override - public String getInfoMessage(Ability source, GameEvent event, Game game) { - return "This ability can only be activated once each turn."; - } -} - -class DoNothingEffect extends OneShotEffect { - - DoNothingEffect() { - super(Outcome.Neutral); - } - - DoNothingEffect(final DoNothingEffect effect) { - super(effect); - } - - @Override - public DoNothingEffect copy() { - return new DoNothingEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } -} +//class MairsilThePretenderWatcher extends Watcher { +// +// public final Map> activatedThisTurnAbilities = new HashMap<>(); +// +// public MairsilThePretenderWatcher() { +// super(MairsilThePretenderWatcher.class.getSimpleName(), WatcherScope.GAME); +// } +// +// public MairsilThePretenderWatcher(final MairsilThePretenderWatcher watcher) { +// super(watcher); +// for (Entry> entry : watcher.activatedThisTurnAbilities.entrySet()) { +// activatedThisTurnAbilities.put(entry.getKey(), entry.getValue()); +// } +// } +// +// @Override +// public void watch(GameEvent event, Game game) { +// if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event instanceof ZoneChangeEvent) { +// ZoneChangeEvent zEvent = (ZoneChangeEvent) event; +// if (zEvent.getFromZone() == Zone.BATTLEFIELD) { +// Permanent permanent = zEvent.getTarget(); +// if (permanent != null) { +// this.activatedThisTurnAbilities.remove(permanent.getId()); +// } +// } +// } +// if (event.getType() == GameEvent.EventType.ACTIVATED_ABILITY) { +// Set permAbilities; +// if (activatedThisTurnAbilities.keySet().contains(event.getSourceId())) { +// permAbilities = activatedThisTurnAbilities.get(event.getSourceId()); +// } else { +// permAbilities = new HashSet<>(); +// } +// StackAbility ability = (StackAbility) game.getStack().getStackObject(event.getSourceId()); +// if (ability != null && ability.getStackAbility().isActivated()) { +// for (Effect effect : ability.getAllEffects()) { +// if (effect instanceof DoNothingEffect) { +// permAbilities.add((UUID) effect.getValue("key")); +// this.activatedThisTurnAbilities.put(event.getSourceId(), permAbilities); +// } +// } +// } +// } +// } +// +// @Override +// public void reset() { +// activatedThisTurnAbilities.clear(); +// } +// +// public Map> getActivatedThisTurnAbilities() { +// return this.activatedThisTurnAbilities; +// } +// +// @Override +// public MairsilThePretenderWatcher copy() { +// return new MairsilThePretenderWatcher(this); +// } +// +//} +// +//class MairsilThePretenderRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl { +// +// public MairsilThePretenderRuleModifyingEffect() { +// super(Duration.WhileOnBattlefield, Outcome.Detriment); +// } +// +// public MairsilThePretenderRuleModifyingEffect(final MairsilThePretenderRuleModifyingEffect effect) { +// super(effect); +// } +// +// @Override +// public MairsilThePretenderRuleModifyingEffect copy() { +// return new MairsilThePretenderRuleModifyingEffect(this); +// } +// +// @Override +// public boolean apply(Game game, Ability source) { +// return true; +// } +// +// @Override +// public boolean checksEventType(GameEvent event, Game game) { +// return event.getType() == GameEvent.EventType.ACTIVATE_ABILITY; +// } +// +// @Override +// public boolean applies(GameEvent event, Ability source, Game game) { +// Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); +// MairsilThePretenderWatcher watcher = (MairsilThePretenderWatcher) game.getState().getWatchers().get(MairsilThePretenderWatcher.class.getSimpleName()); +// if (watcher != null && ability != null && ability.isPresent()) { +// for (Effect effect : ability.get().getAllEffects()) { +// if (effect instanceof DoNothingEffect) { +// UUID originalID = (UUID) effect.getValue("key"); +// if (watcher.getActivatedThisTurnAbilities().keySet().contains(event.getSourceId())) { +// if (watcher.getActivatedThisTurnAbilities().get(event.getSourceId()).contains(originalID)) { +// return true; +// } +// } +// } +// } +// } +// return false; +// } +// +// @Override +// public String getInfoMessage(Ability source, GameEvent event, Game game) { +// return "This ability can only be activated once each turn."; +// } +//} +// +//class DoNothingEffect extends OneShotEffect { +// +// DoNothingEffect() { +// super(Outcome.Neutral); +// } +// +// DoNothingEffect(final DoNothingEffect effect) { +// super(effect); +// } +// +// @Override +// public DoNothingEffect copy() { +// return new DoNothingEffect(this); +// } +// +// @Override +// public boolean apply(Game game, Ability source) { +// return true; +// } +//} diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java index 5021a83896..0bbca8ccfd 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java @@ -29,6 +29,7 @@ package mage.abilities; import java.util.UUID; import mage.MageObject; +import mage.abilities.condition.Condition; import mage.abilities.costs.Cost; import mage.abilities.costs.Costs; import mage.abilities.costs.mana.ManaCosts; @@ -45,6 +46,7 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.command.Emblem; import mage.game.permanent.Permanent; +import mage.util.CardUtil; /** * @@ -52,6 +54,19 @@ import mage.game.permanent.Permanent; */ public abstract class ActivatedAbilityImpl extends AbilityImpl implements ActivatedAbility { + static class ActivationInfo { + + public int turnNum; + public int activationCounter; + + public ActivationInfo(int turnNum, int activationCounter) { + this.turnNum = turnNum; + this.activationCounter = activationCounter; + } + } + + protected int maxActivationsPerTurn = Integer.MAX_VALUE; + protected Condition condition; protected TimingRule timing = TimingRule.INSTANT; protected TargetController mayActivate = TargetController.YOU; protected UUID activatorId; @@ -68,6 +83,8 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa mayActivate = ability.mayActivate; activatorId = ability.activatorId; checkPlayableMode = ability.checkPlayableMode; + maxActivationsPerTurn = ability.maxActivationsPerTurn; + condition = ability.condition; } public ActivatedAbilityImpl(Zone zone) { @@ -161,6 +178,9 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa @Override public boolean canActivate(UUID playerId, Game game) { //20091005 - 602.2 + if (!(hasMoreActivationsThisTurn(game) && (condition == null || condition.apply(game, this)))) { + return false; + } switch (mayActivate) { case ANY: break; @@ -255,4 +275,46 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa return checkPlayableMode; } + private boolean hasMoreActivationsThisTurn(Game game) { + ActivationInfo activationInfo = getActivationInfo(game); + return activationInfo == null || activationInfo.turnNum != game.getTurnNum() || activationInfo.activationCounter < maxActivationsPerTurn; + } + + @Override + public boolean activate(Game game, boolean noMana) { + if (hasMoreActivationsThisTurn(game)) { + if (super.activate(game, noMana)) { + ActivationInfo activationInfo = getActivationInfo(game); + if (activationInfo == null) { + activationInfo = new ActivationInfo(game.getTurnNum(), 1); + } else if (activationInfo.turnNum != game.getTurnNum()) { + activationInfo.turnNum = game.getTurnNum(); + activationInfo.activationCounter = 1; + } else { + activationInfo.activationCounter++; + } + setActivationInfo(activationInfo, game); + return true; + } + } + return false; + } + + public void setMaxActivationsPerTurn(int maxActivationsPerTurn) { + this.maxActivationsPerTurn = maxActivationsPerTurn; + } + + private ActivationInfo getActivationInfo(Game game) { + Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game)); + Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount", sourceId, game)); + if (turnNum == null || activationCount == null) { + return null; + } + return new ActivationInfo(turnNum, activationCount); + } + + private void setActivationInfo(ActivationInfo activationInfo, Game game) { + game.getState().setValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game), activationInfo.turnNum); + game.getState().setValue(CardUtil.getCardZoneString("activationsCount", sourceId, game), activationInfo.activationCounter); + } } diff --git a/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java b/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java index 1e0753ce92..c44fe6cb16 100644 --- a/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java +++ b/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java @@ -25,10 +25,8 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.common; -import java.util.UUID; import mage.abilities.ActivatedAbilityImpl; import mage.abilities.condition.Condition; import mage.abilities.condition.InvertCondition; @@ -43,8 +41,6 @@ import mage.game.Game; */ public class ActivateIfConditionActivatedAbility extends ActivatedAbilityImpl { - private final Condition condition; - public ActivateIfConditionActivatedAbility(Zone zone, Effect effect, Cost cost, Condition condition) { super(zone, effect, cost); this.condition = condition; @@ -52,31 +48,11 @@ public class ActivateIfConditionActivatedAbility extends ActivatedAbilityImpl { public ActivateIfConditionActivatedAbility(ActivateIfConditionActivatedAbility ability) { super(ability); - this.condition = ability.condition; - } - - @Override - public boolean canActivate(UUID playerId, Game game) { - if (condition.apply(game, this)) { - return super.canActivate(playerId, game); - } - return false; - } - - @Override - public boolean activate(Game game, boolean noMana) { - if (canActivate(this.controllerId, game)) { - return super.activate(game, noMana); - } - return false; } @Override public boolean resolve(Game game) { - if (super.resolve(game)) { - return true; - } - return false; + return super.resolve(game); } @Override @@ -88,15 +64,15 @@ public class ActivateIfConditionActivatedAbility extends ActivatedAbilityImpl { sb.append(" Activate this ability only "); } if (condition.toString() != null) { - if (!condition.toString().startsWith("during") && - !condition.toString().startsWith("before")) { + if (!condition.toString().startsWith("during") + && !condition.toString().startsWith("before")) { sb.append("if "); } sb.append(condition.toString()).append('.'); } else { sb.append(" [Condition toString() == null] "); } - return sb.toString() ; + return sb.toString(); } @Override diff --git a/Mage/src/main/java/mage/abilities/common/LimitedTimesPerTurnActivatedAbility.java b/Mage/src/main/java/mage/abilities/common/LimitedTimesPerTurnActivatedAbility.java index 4e42a1678c..3358d9dd9f 100644 --- a/Mage/src/main/java/mage/abilities/common/LimitedTimesPerTurnActivatedAbility.java +++ b/Mage/src/main/java/mage/abilities/common/LimitedTimesPerTurnActivatedAbility.java @@ -36,28 +36,12 @@ import mage.constants.Zone; import mage.game.Game; import mage.util.CardUtil; -import java.util.UUID; - /** * * @author BetaSteward_at_googlemail.com */ public class LimitedTimesPerTurnActivatedAbility extends ActivatedAbilityImpl { - static class ActivationInfo { - - public int turnNum; - public int activationCounter; - - public ActivationInfo(int turnNum, int activationCounter) { - this.turnNum = turnNum; - this.activationCounter = activationCounter; - } - } - - private int maxActivationsPerTurn; - private Condition condition; - public LimitedTimesPerTurnActivatedAbility(Zone zone, Effect effect, Cost cost) { this(zone, effect, cost, 1); } @@ -78,38 +62,6 @@ public class LimitedTimesPerTurnActivatedAbility extends ActivatedAbilityImpl { this.condition = ability.condition; } - @Override - public boolean canActivate(UUID playerId, Game game) { - return super.canActivate(playerId, game) - && hasMoreActivationsThisTurn(game) - && (condition == null || condition.apply(game, this)); - } - - private boolean hasMoreActivationsThisTurn(Game game) { - ActivationInfo activationInfo = getActivationInfo(game); - return activationInfo == null || activationInfo.turnNum != game.getTurnNum() || activationInfo.activationCounter < maxActivationsPerTurn; - } - - @Override - public boolean activate(Game game, boolean noMana) { - if (hasMoreActivationsThisTurn(game)) { - if (super.activate(game, noMana)) { - ActivationInfo activationInfo = getActivationInfo(game); - if (activationInfo == null) { - activationInfo = new ActivationInfo(game.getTurnNum(), 1); - } else if (activationInfo.turnNum != game.getTurnNum()) { - activationInfo.turnNum = game.getTurnNum(); - activationInfo.activationCounter = 1; - } else { - activationInfo.activationCounter++; - } - setActivationInfo(activationInfo, game); - return true; - } - } - return false; - } - @Override public boolean resolve(Game game) { return super.resolve(game); @@ -142,18 +94,4 @@ public class LimitedTimesPerTurnActivatedAbility extends ActivatedAbilityImpl { public LimitedTimesPerTurnActivatedAbility copy() { return new LimitedTimesPerTurnActivatedAbility(this); } - - private ActivationInfo getActivationInfo(Game game) { - Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game)); - Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount", sourceId, game)); - if (turnNum == null || activationCount == null) { - return null; - } - return new ActivationInfo(turnNum, activationCount); - } - - private void setActivationInfo(ActivationInfo activationInfo, Game game) { - game.getState().setValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game), activationInfo.turnNum); - game.getState().setValue(CardUtil.getCardZoneString("activationsCount", sourceId, game), activationInfo.activationCounter); - } } From 9b25dd0e393bfb47a3cf8ba19883b62f40677ec2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 12 Sep 2017 09:33:12 -0400 Subject: [PATCH 008/182] revamped how conditional and limited-use activated abilities are implemented --- .../mage/cards/q/QuicksilverElemental.java | 45 ++++++++++++-- .../mage/abilities/ActivatedAbilityImpl.java | 10 +-- .../ConditionalActivatedAbility.java | 10 --- .../mana/ActivateIfConditionManaAbility.java | 16 +---- .../mana/ActivateOncePerTurnManaAbility.java | 62 ++----------------- .../mana/ActivatedManaAbilityImpl.java | 5 +- 6 files changed, 55 insertions(+), 93 deletions(-) diff --git a/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java b/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java index 5c5cefc1f9..293843fd05 100644 --- a/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java +++ b/Mage.Sets/src/mage/cards/q/QuicksilverElemental.java @@ -37,6 +37,8 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughManaEffect; import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AsThoughEffectType; @@ -89,14 +91,14 @@ public class QuicksilverElemental extends CardImpl { } } -class QuicksilverElementalEffect extends ContinuousEffectImpl { +class QuicksilverElementalEffect extends OneShotEffect { - public QuicksilverElementalEffect() { - super(Duration.EndOfTurn, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); + QuicksilverElementalEffect() { + super(Outcome.Benefit); staticText = "{this} gains all activated abilities of target creature until end of turn"; } - public QuicksilverElementalEffect(final QuicksilverElementalEffect effect) { + QuicksilverElementalEffect(final QuicksilverElementalEffect effect) { super(effect); } @@ -112,13 +114,46 @@ class QuicksilverElementalEffect extends ContinuousEffectImpl { if (permanent != null && creature != null) { for (ActivatedAbility ability : creature.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) { - permanent.addAbility(ability, source.getSourceId(), game); + Ability newAbility = ability.copy(); + newAbility.newOriginalId(); + game.addEffect(new GainAbilitySourceEffect(newAbility, Duration.EndOfTurn), source); } + return true; } return false; } } +//class QuicksilverElementalEffect extends ContinuousEffectImpl { +// +// public QuicksilverElementalEffect() { +// super(Duration.EndOfTurn, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); +// staticText = "{this} gains all activated abilities of target creature until end of turn"; +// } +// +// public QuicksilverElementalEffect(final QuicksilverElementalEffect effect) { +// super(effect); +// } +// +// @Override +// public QuicksilverElementalEffect copy() { +// return new QuicksilverElementalEffect(this); +// } +// +// @Override +// public boolean apply(Game game, Ability source) { +// Permanent permanent = game.getPermanent(source.getSourceId()); +// Permanent creature = game.getPermanent(source.getTargets().getFirstTarget()); +// +// if (permanent != null && creature != null) { +// for (ActivatedAbility ability : creature.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) { +// permanent.addAbility(ability, source.getSourceId(), game); +// } +// } +// return false; +// } +//} + class QuickSilverElementalBlueManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect { public QuickSilverElementalBlueManaEffect() { diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java index 0bbca8ccfd..32c3728ee9 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java @@ -275,7 +275,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa return checkPlayableMode; } - private boolean hasMoreActivationsThisTurn(Game game) { + protected boolean hasMoreActivationsThisTurn(Game game) { ActivationInfo activationInfo = getActivationInfo(game); return activationInfo == null || activationInfo.turnNum != game.getTurnNum() || activationInfo.activationCounter < maxActivationsPerTurn; } @@ -305,8 +305,8 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa } private ActivationInfo getActivationInfo(Game game) { - Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game)); - Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount", sourceId, game)); + Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn" + originalId, sourceId, game)); + Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount" + originalId, sourceId, game)); if (turnNum == null || activationCount == null) { return null; } @@ -314,7 +314,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa } private void setActivationInfo(ActivationInfo activationInfo, Game game) { - game.getState().setValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game), activationInfo.turnNum); - game.getState().setValue(CardUtil.getCardZoneString("activationsCount", sourceId, game), activationInfo.activationCounter); + game.getState().setValue(CardUtil.getCardZoneString("activationsTurn" + originalId, sourceId, game), activationInfo.turnNum); + game.getState().setValue(CardUtil.getCardZoneString("activationsCount" + originalId, sourceId, game), activationInfo.activationCounter); } } diff --git a/Mage/src/main/java/mage/abilities/decorator/ConditionalActivatedAbility.java b/Mage/src/main/java/mage/abilities/decorator/ConditionalActivatedAbility.java index 38339c569d..0e159549ff 100644 --- a/Mage/src/main/java/mage/abilities/decorator/ConditionalActivatedAbility.java +++ b/Mage/src/main/java/mage/abilities/decorator/ConditionalActivatedAbility.java @@ -4,7 +4,6 @@ */ package mage.abilities.decorator; -import java.util.UUID; import mage.abilities.ActivatedAbilityImpl; import mage.abilities.condition.Condition; import mage.abilities.costs.Cost; @@ -24,7 +23,6 @@ public class ConditionalActivatedAbility extends ActivatedAbilityImpl { private static final Effects emptyEffects = new Effects(); - private final Condition condition; private String ruleText = null; public ConditionalActivatedAbility(Zone zone, Effect effect, Cost cost, Condition condition) { @@ -64,14 +62,6 @@ public class ConditionalActivatedAbility extends ActivatedAbilityImpl { return super.getEffects(game, effectType); } - @Override - public boolean canActivate(UUID playerId, Game game) { - if (!condition.apply(game, this)) { - return false; - } - return super.canActivate(playerId, game); - } - @Override public ConditionalActivatedAbility copy() { return new ConditionalActivatedAbility(this); diff --git a/Mage/src/main/java/mage/abilities/mana/ActivateIfConditionManaAbility.java b/Mage/src/main/java/mage/abilities/mana/ActivateIfConditionManaAbility.java index f12d8e5565..d851810563 100644 --- a/Mage/src/main/java/mage/abilities/mana/ActivateIfConditionManaAbility.java +++ b/Mage/src/main/java/mage/abilities/mana/ActivateIfConditionManaAbility.java @@ -27,7 +27,6 @@ */ package mage.abilities.mana; -import java.util.UUID; import mage.abilities.condition.Condition; import mage.abilities.costs.Cost; import mage.abilities.effects.common.AddConditionalColorlessManaEffect; @@ -37,8 +36,6 @@ import mage.game.Game; public class ActivateIfConditionManaAbility extends ActivatedManaAbilityImpl { - private final Condition condition; - public ActivateIfConditionManaAbility(Zone zone, BasicManaEffect effect, Cost cost, Condition condition) { super(zone, effect, cost); this.netMana.add(effect.getMana()); @@ -56,20 +53,9 @@ public class ActivateIfConditionManaAbility extends ActivatedManaAbilityImpl { this.condition = ability.condition; } - @Override - public boolean canActivate(UUID playerId, Game game) { - if (condition.apply(game, this)) { - return super.canActivate(playerId, game); - } - return false; - } - @Override public boolean activate(Game game, boolean noMana) { - if (canActivate(this.controllerId, game)) { - return super.activate(game, noMana); - } - return false; + return super.activate(game, noMana); } @Override diff --git a/Mage/src/main/java/mage/abilities/mana/ActivateOncePerTurnManaAbility.java b/Mage/src/main/java/mage/abilities/mana/ActivateOncePerTurnManaAbility.java index 56ec6843b0..dc5f46335a 100644 --- a/Mage/src/main/java/mage/abilities/mana/ActivateOncePerTurnManaAbility.java +++ b/Mage/src/main/java/mage/abilities/mana/ActivateOncePerTurnManaAbility.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.abilities.mana; import mage.Mana; @@ -34,9 +33,6 @@ import mage.abilities.effects.common.AddManaOfAnyColorEffect; import mage.abilities.effects.common.BasicManaEffect; import mage.constants.Zone; import mage.game.Game; -import mage.util.CardUtil; - -import java.util.UUID; /** * @@ -44,60 +40,26 @@ import java.util.UUID; */ public class ActivateOncePerTurnManaAbility extends ActivatedManaAbilityImpl { - static class ActivationInfo { - - public int turnNum; - public int activationCounter; - - public ActivationInfo(int turnNum, int activationCounter) { - this.turnNum = turnNum; - this.activationCounter = activationCounter; - } - } - public ActivateOncePerTurnManaAbility(Zone zone, BasicManaEffect effect, Cost cost) { super(zone, effect, cost); this.netMana.add(effect.getMana()); + this.maxActivationsPerTurn = 1; } public ActivateOncePerTurnManaAbility(Zone zone, AddManaOfAnyColorEffect effect, Cost cost) { super(zone, effect, cost); - this.netMana.add(new Mana(0,0,0,0,0,0,effect.getAmount(), 0)); + this.netMana.add(new Mana(0, 0, 0, 0, 0, 0, effect.getAmount(), 0)); + this.maxActivationsPerTurn = 1; } public ActivateOncePerTurnManaAbility(ActivateOncePerTurnManaAbility ability) { super(ability); } - @Override - public boolean canActivate(UUID playerId, Game game) { - if (super.canActivate(playerId, game)) { - ActivationInfo activationInfo = getActivationInfo(game); - if (activationInfo == null || activationInfo.turnNum != game.getTurnNum() || activationInfo.activationCounter < 1) { - return true; - } - } - return false; - } - @Override public boolean activate(Game game, boolean noMana) { if (canActivate(this.controllerId, game)) { - if (super.activate(game, noMana)) { - ActivationInfo activationInfo = getActivationInfo(game); - if (activationInfo == null) { - activationInfo = new ActivationInfo(game.getTurnNum(), 1); - } else { - if (activationInfo.turnNum != game.getTurnNum()) { - activationInfo.turnNum = game.getTurnNum(); - activationInfo.activationCounter = 1; - } else { - activationInfo.activationCounter++; - } - } - setActivationInfo(activationInfo, game); - return true; - } + return super.activate(game, noMana); } return false; } @@ -112,18 +74,4 @@ public class ActivateOncePerTurnManaAbility extends ActivatedManaAbilityImpl { return new ActivateOncePerTurnManaAbility(this); } - private ActivationInfo getActivationInfo(Game game) { - Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game)); - Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount", sourceId, game)); - if (turnNum == null || activationCount == null) { - return null; - } - return new ActivationInfo(turnNum, activationCount); - } - - private void setActivationInfo(ActivationInfo activationInfo, Game game) { - game.getState().setValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game), activationInfo.turnNum); - game.getState().setValue(CardUtil.getCardZoneString("activationsCount", sourceId, game), activationInfo.activationCounter); - } - } diff --git a/Mage/src/main/java/mage/abilities/mana/ActivatedManaAbilityImpl.java b/Mage/src/main/java/mage/abilities/mana/ActivatedManaAbilityImpl.java index fef2dd0eb6..61da85343a 100644 --- a/Mage/src/main/java/mage/abilities/mana/ActivatedManaAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/mana/ActivatedManaAbilityImpl.java @@ -69,10 +69,13 @@ public abstract class ActivatedManaAbilityImpl extends ActivatedAbilityImpl impl @Override public boolean canActivate(UUID playerId, Game game) { + if (!super.hasMoreActivationsThisTurn(game) || !(condition == null || condition.apply(game, this))) { + return false; + } if (!controlsAbility(playerId, game)) { return false; } - if (timing == TimingRule.SORCERY + if (timing == TimingRule.SORCERY && !game.canPlaySorcery(playerId) && !game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_AS_INSTANT, this, controllerId, game)) { return false; From 786a62befa08e21f2a44c8f757d3e63281d9cdaa Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 12 Sep 2017 10:10:18 -0400 Subject: [PATCH 009/182] updated various activated abilities --- .../src/mage/cards/c/CabalInquisitor.java | 16 +----- .../src/mage/cards/c/ChronatogTotem.java | 17 ++---- Mage.Sets/src/mage/cards/e/EvolvingWilds.java | 36 ++++--------- .../src/mage/cards/g/GargoyleCastle.java | 36 ++++--------- .../src/mage/cards/g/GroundlingPouncer.java | 12 +---- Mage.Sets/src/mage/cards/k/KyrenToy.java | 4 +- .../src/mage/cards/m/MulDayaChannelers.java | 52 +------------------ .../src/mage/cards/t/TerramorphicExpanse.java | 36 ++++--------- .../src/mage/cards/w/WellOfKnowledge.java | 3 -- 9 files changed, 40 insertions(+), 172 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CabalInquisitor.java b/Mage.Sets/src/mage/cards/c/CabalInquisitor.java index ded5d90a14..43f4de72c2 100644 --- a/Mage.Sets/src/mage/cards/c/CabalInquisitor.java +++ b/Mage.Sets/src/mage/cards/c/CabalInquisitor.java @@ -52,11 +52,10 @@ import mage.target.common.TargetCardInYourGraveyard; * * @author cbt33 */ - public class CabalInquisitor extends CardImpl { public CabalInquisitor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.MINION); @@ -82,11 +81,8 @@ public class CabalInquisitor extends CardImpl { } } - class ActivateAsSorceryConditionalActivatedAbility extends ActivatedAbilityImpl { - private Condition condition; - private static final Effects emptyEffects = new Effects(); public ActivateAsSorceryConditionalActivatedAbility(Zone zone, Effect effect, ManaCosts cost, Condition condition) { @@ -95,10 +91,8 @@ class ActivateAsSorceryConditionalActivatedAbility extends ActivatedAbilityImpl timing = TimingRule.SORCERY; } - public ActivateAsSorceryConditionalActivatedAbility(final ActivateAsSorceryConditionalActivatedAbility ability) { super(ability); - this.condition = ability.condition; } @Override @@ -109,14 +103,6 @@ class ActivateAsSorceryConditionalActivatedAbility extends ActivatedAbilityImpl return super.getEffects(game, effectType); } - @Override - public boolean canActivate(UUID playerId, Game game) { - if (!condition.apply(game, this)) { - return false; - } - return super.canActivate(playerId, game); - } - @Override public ActivateAsSorceryConditionalActivatedAbility copy() { return new ActivateAsSorceryConditionalActivatedAbility(this); diff --git a/Mage.Sets/src/mage/cards/c/ChronatogTotem.java b/Mage.Sets/src/mage/cards/c/ChronatogTotem.java index 3633454e29..2cb60a672e 100644 --- a/Mage.Sets/src/mage/cards/c/ChronatogTotem.java +++ b/Mage.Sets/src/mage/cards/c/ChronatogTotem.java @@ -59,14 +59,14 @@ import mage.game.permanent.token.Token; public class ChronatogTotem extends CardImpl { public ChronatogTotem(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // {tap}: Add {U} to your mana pool. this.addAbility(new BlueManaAbility()); - + // {1}{U}: Chronatog Totem becomes a 1/2 blue Atog artifact creature until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new ChronatogTotemToken(), "", Duration.EndOfTurn), new ManaCostsImpl<>("{1}{U}"))); - + // {0}: Chronatog Totem gets +3/+3 until end of turn. You skip your next turn. Activate this ability only once each turn and only if Chronatog Totem is a creature. Ability ability = new ChronatogTotemAbility( Zone.BATTLEFIELD, @@ -91,8 +91,6 @@ class ChronatogTotemAbility extends LimitedTimesPerTurnActivatedAbility { private static final Effects emptyEffects = new Effects(); - private final Condition condition; - public ChronatogTotemAbility(Zone zone, Effect effect, Cost cost, Condition condition) { super(zone, effect, cost); this.condition = condition; @@ -100,7 +98,6 @@ class ChronatogTotemAbility extends LimitedTimesPerTurnActivatedAbility { public ChronatogTotemAbility(ChronatogTotemAbility ability) { super(ability); - this.condition = ability.condition; } @Override @@ -111,14 +108,6 @@ class ChronatogTotemAbility extends LimitedTimesPerTurnActivatedAbility { return super.getEffects(game, effectType); } - @Override - public boolean canActivate(UUID playerId, Game game) { - if (!condition.apply(game, this)) { - return false; - } - return super.canActivate(playerId, game); - } - @Override public ChronatogTotemAbility copy() { return new ChronatogTotemAbility(this); diff --git a/Mage.Sets/src/mage/cards/e/EvolvingWilds.java b/Mage.Sets/src/mage/cards/e/EvolvingWilds.java index 69211f6845..13c09f8abd 100644 --- a/Mage.Sets/src/mage/cards/e/EvolvingWilds.java +++ b/Mage.Sets/src/mage/cards/e/EvolvingWilds.java @@ -27,19 +27,19 @@ */ package mage.cards.e; -import mage.abilities.ActivatedAbilityImpl; -import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.StaticFilters; import mage.target.common.TargetCardInLibrary; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; /** * @@ -48,10 +48,15 @@ import java.util.UUID; public class EvolvingWilds extends CardImpl { public EvolvingWilds(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); // {T}, Sacrifice Evolving Wilds: Search your library for a basic land card and put it onto the battlefield tapped. Then shuffle your library. - this.addAbility(new EvolvingWildsAbility()); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); } public EvolvingWilds(final EvolvingWilds card) { @@ -64,24 +69,3 @@ public class EvolvingWilds extends CardImpl { } } - -class EvolvingWildsAbility extends ActivatedAbilityImpl { - - public EvolvingWildsAbility() { - super(Zone.BATTLEFIELD, null); - addCost(new TapSourceCost()); - addCost(new SacrificeSourceCost()); - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); - addEffect(new SearchLibraryPutInPlayEffect(target, true, Outcome.PutLandInPlay)); - } - - public EvolvingWildsAbility(final EvolvingWildsAbility ability) { - super(ability); - } - - @Override - public EvolvingWildsAbility copy() { - return new EvolvingWildsAbility(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/g/GargoyleCastle.java b/Mage.Sets/src/mage/cards/g/GargoyleCastle.java index 69ab8a9efa..56ec46d63c 100644 --- a/Mage.Sets/src/mage/cards/g/GargoyleCastle.java +++ b/Mage.Sets/src/mage/cards/g/GargoyleCastle.java @@ -28,10 +28,11 @@ package mage.cards.g; import java.util.UUID; -import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; @@ -52,7 +53,13 @@ public class GargoyleCastle extends CardImpl { this.addAbility(new ColorlessManaAbility()); // {T}, {5}, Sacrifice Gargoyle Castle: Put a 3/4 colorless Gargoyle artifact creature token with flying onto the battlefield. - this.addAbility(new GargoyleCastleAbility()); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new CreateTokenEffect(new GargoyleToken()), + new ManaCostsImpl("{5}")); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); } public GargoyleCastle(final GargoyleCastle card) { @@ -64,25 +71,4 @@ public class GargoyleCastle extends CardImpl { return new GargoyleCastle(this); } -} - -class GargoyleCastleAbility extends ActivatedAbilityImpl { - - public GargoyleCastleAbility() { - super(Zone.BATTLEFIELD, null); - addCost(new TapSourceCost()); - addCost(new GenericManaCost(5)); - addCost(new SacrificeSourceCost()); - addEffect(new CreateTokenEffect(new GargoyleToken())); - } - - public GargoyleCastleAbility(final GargoyleCastleAbility ability) { - super(ability); - } - - @Override - public GargoyleCastleAbility copy() { - return new GargoyleCastleAbility(this); - } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GroundlingPouncer.java b/Mage.Sets/src/mage/cards/g/GroundlingPouncer.java index 41b3e883e1..c03cd462e1 100644 --- a/Mage.Sets/src/mage/cards/g/GroundlingPouncer.java +++ b/Mage.Sets/src/mage/cards/g/GroundlingPouncer.java @@ -65,7 +65,7 @@ public class GroundlingPouncer extends CardImpl { } public GroundlingPouncer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G/U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G/U}"); this.subtype.add(SubType.FAERIE); this.power = new MageInt(2); @@ -97,7 +97,6 @@ class GroundlingPouncerAbility extends LimitedTimesPerTurnActivatedAbility { private static final Effects emptyEffects = new Effects(); - private final Condition condition; private final String ruleText; public GroundlingPouncerAbility(Zone zone, Effect effect, Cost cost, Condition condition, String rule) { @@ -108,7 +107,6 @@ class GroundlingPouncerAbility extends LimitedTimesPerTurnActivatedAbility { public GroundlingPouncerAbility(GroundlingPouncerAbility ability) { super(ability); - this.condition = ability.condition; this.ruleText = ability.ruleText; } @@ -120,14 +118,6 @@ class GroundlingPouncerAbility extends LimitedTimesPerTurnActivatedAbility { return super.getEffects(game, effectType); } - @Override - public boolean canActivate(UUID playerId, Game game) { - if (!condition.apply(game, this)) { - return false; - } - return super.canActivate(playerId, game); - } - @Override public GroundlingPouncerAbility copy() { return new GroundlingPouncerAbility(this); diff --git a/Mage.Sets/src/mage/cards/k/KyrenToy.java b/Mage.Sets/src/mage/cards/k/KyrenToy.java index dd757a25c0..0dc4decc0c 100644 --- a/Mage.Sets/src/mage/cards/k/KyrenToy.java +++ b/Mage.Sets/src/mage/cards/k/KyrenToy.java @@ -53,7 +53,7 @@ import mage.players.Player; public class KyrenToy extends CardImpl { public KyrenToy(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // {1}, {T}: Put a charge counter on Kyren Toy. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.CHARGE.createInstance(1)), new GenericManaCost(1)); @@ -95,7 +95,7 @@ public class KyrenToy extends CardImpl { KyrenToyManaEffect() { super(); - staticText = "Add X mana of {C} to your mana pool, and then add {C} to your mana pool"; + staticText = "Add an amount of {C} to your mana pool equal to X plus one"; } KyrenToyManaEffect(final KyrenToyManaEffect effect) { diff --git a/Mage.Sets/src/mage/cards/m/MulDayaChannelers.java b/Mage.Sets/src/mage/cards/m/MulDayaChannelers.java index 5b84f8caa4..b03c18ee68 100644 --- a/Mage.Sets/src/mage/cards/m/MulDayaChannelers.java +++ b/Mage.Sets/src/mage/cards/m/MulDayaChannelers.java @@ -30,17 +30,13 @@ package mage.cards.m; import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; import mage.abilities.condition.common.TopLibraryCardTypeCondition; -import mage.abilities.costs.Cost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.AddManaOfAnyColorEffect; -import mage.abilities.effects.common.ManaEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.effects.common.continuous.PlayWithTheTopCardRevealedEffect; -import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.abilities.mana.SimpleManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -48,7 +44,6 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; -import mage.game.Game; /** * @@ -59,7 +54,7 @@ public class MulDayaChannelers extends CardImpl { private static final String rule1 = "As long as the top card of your library is a creature card, {this} gets +3/+3"; public MulDayaChannelers(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}"); this.subtype.add(SubType.ELF); this.subtype.add(SubType.DRUID); this.subtype.add(SubType.SHAMAN); @@ -81,7 +76,7 @@ public class MulDayaChannelers extends CardImpl { new TopLibraryCardTypeCondition(CardType.LAND), "As long as the top card of your library is a land card, Mul Daya Channelers has \"{T}: Add two mana of any one color to your mana pool.\""); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); - + } public MulDayaChannelers(final MulDayaChannelers card) { @@ -93,46 +88,3 @@ public class MulDayaChannelers extends CardImpl { return new MulDayaChannelers(this); } } - - -class MulDayaChannelersActivateIfConditionManaAbility extends ActivatedManaAbilityImpl { - - private Condition condition; - - public MulDayaChannelersActivateIfConditionManaAbility(Zone zone, ManaEffect effect, Cost cost, Condition condition) { - super(zone, effect, cost); - this.condition = condition; - } - - public MulDayaChannelersActivateIfConditionManaAbility(MulDayaChannelersActivateIfConditionManaAbility ability) { - super(ability); - this.condition = ability.condition; - } - - @Override - public boolean canActivate(UUID playerId, Game game) { - if (condition.apply(game, this)) { - return super.canActivate(playerId, game); - } - return false; - } - - @Override - public boolean activate(Game game, boolean noMana) { - if (canActivate(this.controllerId, game)) { - return super.activate(game, noMana); - } - return false; - } - - @Override - public String getRule() { - return "As long as the top card of your library is a land card, {this} has \"{T}: Add two mana of any one color to your mana pool."; - } - - @Override - public MulDayaChannelersActivateIfConditionManaAbility copy() { - return new MulDayaChannelersActivateIfConditionManaAbility(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/t/TerramorphicExpanse.java b/Mage.Sets/src/mage/cards/t/TerramorphicExpanse.java index 1038660daf..5a4239c092 100644 --- a/Mage.Sets/src/mage/cards/t/TerramorphicExpanse.java +++ b/Mage.Sets/src/mage/cards/t/TerramorphicExpanse.java @@ -25,22 +25,21 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.t; -import mage.abilities.ActivatedAbilityImpl; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.StaticFilters; import mage.target.common.TargetCardInLibrary; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; /** * @@ -49,8 +48,14 @@ import java.util.UUID; public class TerramorphicExpanse extends CardImpl { public TerramorphicExpanse(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},null); - this.addAbility(new TerramorphicExpanseAbility()); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); + + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); } public TerramorphicExpanse(final TerramorphicExpanse card) { @@ -63,24 +68,3 @@ public class TerramorphicExpanse extends CardImpl { } } - -class TerramorphicExpanseAbility extends ActivatedAbilityImpl { - - public TerramorphicExpanseAbility() { - super(Zone.BATTLEFIELD, null); - addCost(new TapSourceCost()); - addCost(new SacrificeSourceCost()); - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); - addEffect(new SearchLibraryPutInPlayEffect(target, true, Outcome.PutLandInPlay)); - } - - public TerramorphicExpanseAbility(final TerramorphicExpanseAbility ability) { - super(ability); - } - - @Override - public TerramorphicExpanseAbility copy() { - return new TerramorphicExpanseAbility(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java b/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java index 22afc30cae..d735337165 100644 --- a/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java +++ b/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java @@ -30,7 +30,6 @@ package mage.cards.w; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.ActivatedAbilityImpl; -import mage.abilities.condition.Condition; import mage.abilities.condition.common.IsStepCondition; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.Effects; @@ -71,8 +70,6 @@ public class WellOfKnowledge extends CardImpl { class WellOfKnowledgeConditionalActivatedAbility extends ActivatedAbilityImpl { - private final Condition condition; - public WellOfKnowledgeConditionalActivatedAbility() { super(Zone.BATTLEFIELD, new WellOfKnowledgeEffect(), new GenericManaCost(2)); condition = new IsStepCondition(PhaseStep.DRAW, false); From d95a3e470ce3b4d72ae58326fd5225d2029c6e51 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 12 Sep 2017 17:25:18 +0200 Subject: [PATCH 010/182] Updated some logic. --- .../card/dl/sources/TokensMtgImageSource.java | 19 ++- .../plugins/card/images/DownloadPictures.java | 123 ++++++++++++++---- 2 files changed, 117 insertions(+), 25 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java index 95f4294a05..f04dad377e 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java @@ -34,11 +34,14 @@ import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.logging.Level; import org.apache.log4j.Logger; import org.mage.plugins.card.images.CardDownloadData; +import org.mage.plugins.card.images.DownloadPictures; /** * @@ -51,6 +54,7 @@ public enum TokensMtgImageSource implements CardImageSource { // [[EXP/Name, TokenData> private HashMap> tokensData; + private static final Set supportedSets = new LinkedHashSet(); private final Object tokensDataSync = new Object(); @@ -175,6 +179,7 @@ public enum TokensMtgImageSource implements CardImageSource { private HashMap> getTokensData() throws IOException { synchronized (tokensDataSync) { if (tokensData == null) { + DownloadPictures.getInstance().updateAndViewMessage("Creating token data..."); tokensData = new HashMap<>(); // get tokens data from resource file @@ -186,6 +191,7 @@ public enum TokensMtgImageSource implements CardImageSource { if (list == null) { list = new ArrayList<>(); tokensData.put(key, list); + supportedSets.add(tokenData.getExpansionSetCode()); logger.info("Added key: " + key); } list.add(tokenData); @@ -219,8 +225,10 @@ public enum TokensMtgImageSource implements CardImageSource { } } } - } catch (Exception exception) { - logger.warn("Failed to get tokens description from tokens.mtg.onl", exception); + DownloadPictures.getInstance().updateAndViewMessage(""); + } catch (Exception ex) { + logger.warn("Failed to get tokens description from tokens.mtg.onl", ex); + DownloadPictures.getInstance().updateAndViewMessage(ex.getMessage()); } } } @@ -319,6 +327,13 @@ public enum TokensMtgImageSource implements CardImageSource { public void doPause(String httpImageUrl) { } + @Override + public ArrayList getSupportedSets() { + ArrayList supportedSetsCopy = new ArrayList<>(); + supportedSetsCopy.addAll(supportedSets); + return supportedSetsCopy; + } + @Override public boolean isImageProvided(String setCode, String cardName) { try { diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index 2e81ebd36c..92e0d20c1a 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -26,6 +26,7 @@ import mage.cards.Sets; import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; +import mage.client.MageFrame; import mage.client.constants.Constants; import mage.client.dialog.PreferencesDialog; import mage.client.util.sets.ConstructedFormats; @@ -44,12 +45,15 @@ import org.mage.plugins.card.utils.CardImageUtils; public class DownloadPictures extends DefaultBoundedRangeModel implements Runnable { + private static DownloadPictures instance; + private static final Logger logger = Logger.getLogger(DownloadPictures.class); public static final String ALL_IMAGES = "- All images from that source"; public static final String ALL_STANDARD_IMAGES = "- All images from standard from that source"; public static final String ALL_TOKENS = "- Only all token images from that source"; + private JDialog dialog; private final JProgressBar bar; private final JOptionPane dlg; private boolean cancel; @@ -57,7 +61,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab private final JButton startDownloadButton; private int cardIndex; private List allCardsMissingImage; - List cardsToDownload = new ArrayList<>(); + private List cardsToDownload; private int missingCards = 0; private int missingTokens = 0; @@ -65,6 +69,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab List selectedSetCodes = new ArrayList<>(); private final JComboBox jComboBoxServer; + private final JLabel jLabelMessage; private final JLabel jLabelAllMissing; private final JLabel jLabelServer; @@ -107,6 +112,10 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } + public static DownloadPictures getInstance() { + return instance; + } + public static void main(String[] args) { startDownload(); } @@ -118,18 +127,15 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab * JOptionPane.showMessageDialog(null, * "All card pictures have been downloaded."); return; } */ - DownloadPictures download = new DownloadPictures(); - JDialog dlg = download.getDlg(null); - dlg.setVisible(true); - dlg.dispose(); - download.cancel = true; + instance = new DownloadPictures(MageFrame.getInstance()); + Thread t1 = new Thread(new LoadMissingCardData(instance)); + t1.start(); + instance.getDlg().setVisible(true); + instance.getDlg().dispose(); + instance.cancel = true; } - public JDialog getDlg(JFrame frame) { - String title = "Downloading images"; - - final JDialog dialog = this.dlg.createDialog(frame, title); - closeButton.addActionListener(e -> dialog.setVisible(false)); + public JDialog getDlg() { return dialog; } @@ -137,12 +143,23 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab this.cancel = cancel; } - public DownloadPictures() { + static int WIDTH = 400; + + public DownloadPictures(JFrame frame) { + + cardsToDownload = new ArrayList<>(); + JPanel p0 = new JPanel(); p0.setLayout(new BoxLayout(p0, BoxLayout.Y_AXIS)); p0.add(Box.createVerticalStrut(5)); + jLabelMessage = new JLabel(); + jLabelMessage.setAlignmentX(Component.CENTER_ALIGNMENT); + jLabelMessage.setText("Initializing image download..."); + p0.add(jLabelMessage); + p0.add(Box.createVerticalStrut(5)); + jLabelAllMissing = new JLabel(); jLabelAllMissing.setAlignmentX(Component.LEFT_ALIGNMENT); @@ -153,6 +170,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab jLabelServer = new JLabel(); jLabelServer.setText("Please select image source:"); jLabelServer.setAlignmentX(Component.LEFT_ALIGNMENT); + jLabelServer.setVisible(false); p0.add(jLabelServer); p0.add(Box.createVerticalStrut(5)); @@ -160,12 +178,18 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab jComboBoxServer = new JComboBox(); jComboBoxServer.setModel(new DefaultComboBoxModel(DownloadSources.values())); jComboBoxServer.setAlignmentX(Component.LEFT_ALIGNMENT); + jComboBoxServer.setAlignmentY(Component.LEFT_ALIGNMENT); jComboBoxServer.addItemListener((ItemEvent event) -> { if (event.getStateChange() == ItemEvent.SELECTED) { comboBoxServerItemSelected(event); } }); + Dimension d = jComboBoxServer.getPreferredSize(); + d.width = WIDTH; + jComboBoxServer.setPreferredSize(d); p0.add(jComboBoxServer); + jComboBoxServer.setVisible(false); + // set the first source as default cardImageSource = WizardCardsImageSource.instance; @@ -175,10 +199,11 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab jLabelSet = new JLabel(); jLabelSet.setText("Please select sets to download the images for:"); jLabelSet.setAlignmentX(Component.LEFT_ALIGNMENT); + jLabelSet.setVisible(false); p0.add(jLabelSet); jComboBoxSet = new JComboBox(); - jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); +// jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); jComboBoxSet.setAlignmentX(Component.LEFT_ALIGNMENT); jComboBoxSet.addItemListener((ItemEvent event) -> { if (event.getStateChange() == ItemEvent.SELECTED) { @@ -187,6 +212,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab }); p0.add(jComboBoxSet); + jComboBoxSet.setVisible(false); p0.add(Box.createVerticalStrut(5)); @@ -203,28 +229,58 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab p0.add(bar); bar.setStringPainted(true); - Dimension d = bar.getPreferredSize(); - d.width = 400; + d = bar.getPreferredSize(); + d.width = WIDTH; bar.setPreferredSize(d); + bar.setVisible(false); // JOptionPane Object[] options = {startDownloadButton, closeButton = new JButton("Cancel")}; - dlg = new JOptionPane(p0, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null, options, options[1]); + startDownloadButton.setVisible(false); + closeButton.addActionListener(e -> dialog.setVisible(false)); + closeButton.setVisible(false); - setAllMissingCards(); + dlg = new JOptionPane(p0, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null, options, options[1]); + dialog = this.dlg.createDialog(frame, "Downloading images"); } public void setAllMissingCards() { + updateAndViewMessage("Get all available cards from the repository..."); List cards = CardRepository.instance.findCards(new CardCriteria()); + updateAndViewMessage("Check which images are missing ..."); this.allCardsMissingImage = getNeededCards(cards); + updateAndViewMessage("Check which images the current source is providing ..."); + jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); + updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); + + jComboBoxServer.setVisible(true); + jLabelServer.setVisible(true); + jComboBoxSet.setVisible(true); + jLabelSet.setVisible(true); + bar.setVisible(true); + startDownloadButton.setVisible(true); + closeButton.setVisible(true); + + updateAndViewMessage(""); } private void comboBoxServerItemSelected(ItemEvent evt) { - cardImageSource = ((DownloadSources) evt.getItem()).getSource(); - // update the available sets / token comboBox - jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); - updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); + if (jComboBoxServer.isEnabled()) { + cardImageSource = ((DownloadSources) evt.getItem()).getSource(); + // update the available sets / token comboBox + jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); + updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); + } + } + + public void updateAndViewMessage(String text) { + jLabelMessage.setText(text); + if (dialog != null) { + dialog.pack(); + dialog.validate(); + dialog.repaint(); + } } private Object[] getSetsForCurrentImageSource() { @@ -290,8 +346,8 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab int numberTokenImagesAvailable = 0; int numberCardImagesAvailable = 0; for (CardDownloadData data : allCardsMissingImage) { - if (data.isToken() && cardImageSource.isTokenSource()) { - if (cardImageSource.isImageProvided(data.getSet(), data.getName())) { + if (data.isToken()) { + if (cardImageSource.isTokenSource() && cardImageSource.isImageProvided(data.getSet(), data.getName())) { numberTokenImagesAvailable++; cardsToDownload.add(data); } @@ -809,4 +865,25 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } private static final long serialVersionUID = 1L; + +} + +class LoadMissingCardData implements Runnable { + + private static DownloadPictures downloadPictures; + + public LoadMissingCardData(DownloadPictures downloadPictures) { + LoadMissingCardData.downloadPictures = downloadPictures; + } + + @Override + public void run() { + downloadPictures.setAllMissingCards(); + } + + public static void main() { + + (new Thread(new LoadMissingCardData(downloadPictures))).start(); + } + } From a26c5a509ff88f9ba8ca63d5215e2aa442d945e3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 12 Sep 2017 12:14:01 -0400 Subject: [PATCH 011/182] updated various activated abilities --- .../src/mage/cards/a/AncientHellkite.java | 100 ++++-------------- .../src/mage/cards/b/BrutalDeceiver.java | 52 ++++----- .../src/mage/cards/c/CallousDeceiver.java | 2 +- Mage.Sets/src/mage/cards/c/CruelDeceiver.java | 27 +++-- Mage.Sets/src/mage/cards/f/FeralDeceiver.java | 54 ++++++++-- Mage.Sets/src/mage/cards/h/HarshDeceiver.java | 55 ++++++++-- .../common/FeralDeceiverAbility.java | 50 --------- .../ConditionalActivatedAbility.java | 1 - .../ConditionalGainActivatedAbility.java | 2 - .../mana/ActivateIfConditionManaAbility.java | 1 - 10 files changed, 163 insertions(+), 181 deletions(-) delete mode 100644 Mage/src/main/java/mage/abilities/common/FeralDeceiverAbility.java diff --git a/Mage.Sets/src/mage/cards/a/AncientHellkite.java b/Mage.Sets/src/mage/cards/a/AncientHellkite.java index a44e3c9817..bb830ed973 100644 --- a/Mage.Sets/src/mage/cards/a/AncientHellkite.java +++ b/Mage.Sets/src/mage/cards/a/AncientHellkite.java @@ -25,28 +25,24 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.a; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.ActivatedAbilityImpl; -import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; -import mage.abilities.costs.mana.ColoredManaCost; +import mage.abilities.condition.common.SourceAttackingCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.ColoredManaSymbol; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; /** @@ -55,19 +51,37 @@ import mage.target.common.TargetCreaturePermanent; */ public class AncientHellkite extends CardImpl { + private final UUID originalId; + public AncientHellkite(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}{R}"); this.subtype.add(SubType.DRAGON); this.power = new MageInt(6); this.toughness = new MageInt(6); this.addAbility(FlyingAbility.getInstance()); - this.addAbility(new AncientHellkiteAbility()); + Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{R}"), SourceAttackingCondition.instance); + ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls"))); + originalId = ability.getOriginalId(); + this.addAbility(ability); } public AncientHellkite(final AncientHellkite card) { super(card); + this.originalId = card.originalId; + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if (ability.getOriginalId().equals(originalId)) { + ability.getTargets().clear(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); + UUID defenderId = game.getCombat().getDefenderId(ability.getSourceId()); + filter.add(new ControllerIdPredicate(defenderId)); + TargetCreaturePermanent target = new TargetCreaturePermanent(filter); + ability.addTarget(target); + } } @Override @@ -76,71 +90,3 @@ public class AncientHellkite extends CardImpl { } } - -class AncientHellkiteAbility extends ActivatedAbilityImpl { - - private static final FilterCreaturePermanent filterTemplate = new FilterCreaturePermanent("creature defending player controls"); - - public AncientHellkiteAbility() { - super(Zone.BATTLEFIELD, new DamageTargetEffect(1)); - addCost(new AncientHellkiteCost()); - addManaCost(new ColoredManaCost(ColoredManaSymbol.R)); - addTarget(new TargetCreaturePermanent(filterTemplate)); - } - - public AncientHellkiteAbility(final AncientHellkiteAbility ability) { - super(ability); - } - - @Override - public AncientHellkiteAbility copy() { - return new AncientHellkiteAbility(this); - } - - @Override - public boolean activate(Game game, boolean noMana) { - UUID defenderId = game.getCombat().getDefenderId(sourceId); - if (defenderId != null) { - FilterCreaturePermanent filter = filterTemplate.copy(); - filter.add(new ControllerIdPredicate(defenderId)); - - this.getTargets().clear(); - TargetCreaturePermanent target = new TargetCreaturePermanent(filter); - this.addTarget(target); - return super.activate(game, noMana); - } - return false; - } -} - -class AncientHellkiteCost extends CostImpl { - - public AncientHellkiteCost() { - this.text = "Activate this ability only if Ancient Hellkite is attacking"; - } - - public AncientHellkiteCost(final AncientHellkiteCost cost) { - super(cost); - } - - @Override - public AncientHellkiteCost copy() { - return new AncientHellkiteCost(this); - } - - @Override - public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { - Permanent permanent = game.getPermanent(sourceId); - if (permanent != null && permanent.isAttacking()) { - return true; - } - return false; - } - - @Override - public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { - this.paid = true; - return paid; - } - -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/BrutalDeceiver.java b/Mage.Sets/src/mage/cards/b/BrutalDeceiver.java index 0ff4dc4091..e443ace2d9 100644 --- a/Mage.Sets/src/mage/cards/b/BrutalDeceiver.java +++ b/Mage.Sets/src/mage/cards/b/BrutalDeceiver.java @@ -29,13 +29,13 @@ package mage.cards.b; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.Cost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.LookLibraryControllerEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; @@ -43,6 +43,7 @@ import mage.abilities.keyword.FirstStrikeAbility; import mage.cards.*; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; @@ -55,7 +56,7 @@ import mage.players.Player; public class BrutalDeceiver extends CardImpl { public BrutalDeceiver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(2); @@ -65,9 +66,7 @@ public class BrutalDeceiver extends CardImpl { this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(), new GenericManaCost(1))); // {2}: Reveal the top card of your library. If it's a land card, {this} gets +1/+0 and gains first strike until end of turn. - Ability ability = new BrutalDeceiverAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{2}")); - ability.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn)); - this.addAbility(ability); + this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BrutalDeceiverEffect(), new ManaCostsImpl("{2}"))); } public BrutalDeceiver(final BrutalDeceiver card) { @@ -80,38 +79,39 @@ public class BrutalDeceiver extends CardImpl { } } -class BrutalDeceiverAbility extends LimitedTimesPerTurnActivatedAbility { +class BrutalDeceiverEffect extends OneShotEffect { - public BrutalDeceiverAbility(Zone zone, Effect effect, Cost cost) { - super(zone, effect, cost); + public BrutalDeceiverEffect() { + super(Outcome.BoostCreature); + this.staticText = "Reveal the top card of your library. If it's a land card, {this} gets +1/+0 and gains first strike until end of turn"; } - public BrutalDeceiverAbility(BrutalDeceiverAbility ability) { - super(ability); + public BrutalDeceiverEffect(final BrutalDeceiverEffect effect) { + super(effect); } @Override - public BrutalDeceiverAbility copy() { - return new BrutalDeceiverAbility(this); + public BrutalDeceiverEffect copy() { + return new BrutalDeceiverEffect(this); } @Override - public boolean checkIfClause(Game game) { - Player player = game.getPlayer(this.getControllerId()); - if (player != null) { + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { Cards cards = new CardsImpl(); - Card card = player.getLibrary().getFromTop(game); - cards.add(card); - player.revealCards("Brutal Deceiver", cards, game); - if (card != null && card.isLand()) { - return true; + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + cards.add(card); + controller.revealCards(sourceObject.getIdName(), cards, game); + if (card.isLand()) { + game.addEffect(new BoostSourceEffect(1, 0, Duration.EndOfTurn), source); + game.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn), source); + } } + return true; } return false; } - - @Override - public String getRule() { - return "{2}: Reveal the top card of your library. If it's a land card, {this} gets +1/+0 and gains first strike until end of turn. Activate this ability only once each turn."; - } } diff --git a/Mage.Sets/src/mage/cards/c/CallousDeceiver.java b/Mage.Sets/src/mage/cards/c/CallousDeceiver.java index 4aa3f68801..03c905e245 100644 --- a/Mage.Sets/src/mage/cards/c/CallousDeceiver.java +++ b/Mage.Sets/src/mage/cards/c/CallousDeceiver.java @@ -56,7 +56,7 @@ import mage.players.Player; public class CallousDeceiver extends CardImpl { public CallousDeceiver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/c/CruelDeceiver.java b/Mage.Sets/src/mage/cards/c/CruelDeceiver.java index ed6b1ef8e3..95bab5f5e9 100644 --- a/Mage.Sets/src/mage/cards/c/CruelDeceiver.java +++ b/Mage.Sets/src/mage/cards/c/CruelDeceiver.java @@ -29,16 +29,18 @@ package mage.cards.c; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToACreatureTriggeredAbility; import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.LookLibraryControllerEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.keyword.TrampleAbility; import mage.cards.*; import mage.constants.CardType; import mage.constants.SubType; @@ -55,7 +57,7 @@ import mage.players.Player; public class CruelDeceiver extends CardImpl { public CruelDeceiver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(2); @@ -82,7 +84,7 @@ class CruelDeceiverEffect extends OneShotEffect { public CruelDeceiverEffect() { super(Outcome.AddAbility); - this.staticText = "Reveal the top card of your library. If it's a land card, {this} gets +2/+2 and gains trample until end of turn"; + this.staticText = "Reveal the top card of your library. If it's a land card, Cruel Deceiver gains \"Whenever Cruel Deceiver deals damage to a creature, destroy that creature\" until end of turn"; } public CruelDeceiverEffect(final CruelDeceiverEffect effect) { @@ -96,15 +98,18 @@ class CruelDeceiverEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { Cards cards = new CardsImpl(); - Card card = player.getLibrary().getFromTop(game); - cards.add(card); - player.revealCards("Cruel Deceiver", cards, game); - if (card != null && card.isLand()) { - game.addEffect(new BoostSourceEffect(2,2,Duration.EndOfTurn), source); - game.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(),Duration.EndOfTurn), source); + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + cards.add(card); + controller.revealCards(sourceObject.getIdName(), cards, game); + if (card.isLand()) { + game.addEffect(new BoostSourceEffect(1, 0, Duration.EndOfTurn), source); + game.addEffect(new GainAbilitySourceEffect(new DealsDamageToACreatureTriggeredAbility(new DestroyTargetEffect(true), false, false, true), Duration.EndOfTurn), source); + } } return true; } diff --git a/Mage.Sets/src/mage/cards/f/FeralDeceiver.java b/Mage.Sets/src/mage/cards/f/FeralDeceiver.java index c590aced71..5bde2e76fc 100644 --- a/Mage.Sets/src/mage/cards/f/FeralDeceiver.java +++ b/Mage.Sets/src/mage/cards/f/FeralDeceiver.java @@ -29,21 +29,29 @@ package mage.cards.f; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.common.FeralDeceiverAbility; +import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.LookLibraryControllerEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.keyword.TrampleAbility; +import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; /** * @@ -52,19 +60,17 @@ import mage.constants.Zone; public class FeralDeceiver extends CardImpl { public FeralDeceiver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(3); this.toughness = new MageInt(2); // {1}: Look at the top card of your library. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(), new GenericManaCost(1))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(), new GenericManaCost(1))); // {2}: Reveal the top card of your library. If it's a land card, {this} gets +2/+2 and gains trample until end of turn. - Ability ability = new FeralDeceiverAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2,2,Duration.EndOfTurn), new ManaCostsImpl("{2}")); - ability.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(),Duration.EndOfTurn)); - this.addAbility(ability); + this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new FeralDeceiverEffect(), new ManaCostsImpl("{2}"))); } public FeralDeceiver(final FeralDeceiver card) { @@ -77,3 +83,39 @@ public class FeralDeceiver extends CardImpl { } } +class FeralDeceiverEffect extends OneShotEffect { + + public FeralDeceiverEffect() { + super(Outcome.BoostCreature); + this.staticText = "Reveal the top card of your library. If it's a land card, {this} gets +2/+2 and gains trample until end of turn"; + } + + public FeralDeceiverEffect(final FeralDeceiverEffect effect) { + super(effect); + } + + @Override + public FeralDeceiverEffect copy() { + return new FeralDeceiverEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { + Cards cards = new CardsImpl(); + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + cards.add(card); + controller.revealCards(sourceObject.getIdName(), cards, game); + if (card.isLand()) { + game.addEffect(new BoostSourceEffect(2, 2, Duration.EndOfTurn), source); + game.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn), source); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/h/HarshDeceiver.java b/Mage.Sets/src/mage/cards/h/HarshDeceiver.java index 6debef53fa..af887e3e3b 100644 --- a/Mage.Sets/src/mage/cards/h/HarshDeceiver.java +++ b/Mage.Sets/src/mage/cards/h/HarshDeceiver.java @@ -29,20 +29,28 @@ package mage.cards.h; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.common.FeralDeceiverAbility; +import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.LookLibraryControllerEffect; import mage.abilities.effects.common.UntapSourceEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; /** * @@ -51,19 +59,17 @@ import mage.constants.Zone; public class HarshDeceiver extends CardImpl { public HarshDeceiver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(1); this.toughness = new MageInt(4); // {1}: Look at the top card of your library. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(), new GenericManaCost(1))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryControllerEffect(), new GenericManaCost(1))); // {2}: Reveal the top card of your library. If it's a land card, untap {this} and it gets +1/+1 until end of turn. - Ability ability = new FeralDeceiverAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new ManaCostsImpl("{2}")); - ability.addEffect(new BoostSourceEffect(1,1,Duration.EndOfTurn)); - this.addAbility(ability); + this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new HarshDeceiverEffect(), new ManaCostsImpl("{2}"))); } public HarshDeceiver(final HarshDeceiver card) { @@ -75,3 +81,40 @@ public class HarshDeceiver extends CardImpl { return new HarshDeceiver(this); } } + +class HarshDeceiverEffect extends OneShotEffect { + + public HarshDeceiverEffect() { + super(Outcome.BoostCreature); + this.staticText = "Reveal the top card of your library. If it's a land card, untap {this} and it gets +1/+1 until end of turn"; + } + + public HarshDeceiverEffect(final HarshDeceiverEffect effect) { + super(effect); + } + + @Override + public HarshDeceiverEffect copy() { + return new HarshDeceiverEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { + Cards cards = new CardsImpl(); + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + cards.add(card); + controller.revealCards(sourceObject.getIdName(), cards, game); + if (card.isLand()) { + new UntapSourceEffect().apply(game, source); + game.addEffect(new BoostSourceEffect(1, 1, Duration.EndOfTurn), source); + } + } + return true; + } + return false; + } +} diff --git a/Mage/src/main/java/mage/abilities/common/FeralDeceiverAbility.java b/Mage/src/main/java/mage/abilities/common/FeralDeceiverAbility.java deleted file mode 100644 index 49c73bb613..0000000000 --- a/Mage/src/main/java/mage/abilities/common/FeralDeceiverAbility.java +++ /dev/null @@ -1,50 +0,0 @@ -package mage.abilities.common; - -import mage.abilities.costs.Cost; -import mage.abilities.effects.Effect; -import mage.cards.Card; -import mage.cards.Cards; -import mage.cards.CardsImpl; -import mage.constants.CardType; -import mage.constants.Zone; -import mage.game.Game; -import mage.players.Player; - -/** - * Created by Eric on 9/24/2016. - */ -public class FeralDeceiverAbility extends LimitedTimesPerTurnActivatedAbility { - - public FeralDeceiverAbility(Zone zone, Effect effect, Cost cost) { - super(zone, effect, cost); - } - - public FeralDeceiverAbility(FeralDeceiverAbility ability) { - super(ability); - } - - @Override - public FeralDeceiverAbility copy() { - return new FeralDeceiverAbility(this); - } - - @Override - public boolean checkIfClause(Game game) { - Player player = game.getPlayer(this.getControllerId()); - if (player != null) { - Cards cards = new CardsImpl(); - Card card = player.getLibrary().getFromTop(game); - cards.add(card); - player.revealCards("Feral Deceiver", cards, game); - if (card != null && card.isLand()) { - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "{2}: Reveal the top card of your library. If it's a land card, {this} gets +2/+2 and gains trample until end of turn. Activate this ability only once each turn."; - } -} diff --git a/Mage/src/main/java/mage/abilities/decorator/ConditionalActivatedAbility.java b/Mage/src/main/java/mage/abilities/decorator/ConditionalActivatedAbility.java index 0e159549ff..86186e4b01 100644 --- a/Mage/src/main/java/mage/abilities/decorator/ConditionalActivatedAbility.java +++ b/Mage/src/main/java/mage/abilities/decorator/ConditionalActivatedAbility.java @@ -50,7 +50,6 @@ public class ConditionalActivatedAbility extends ActivatedAbilityImpl { public ConditionalActivatedAbility(final ConditionalActivatedAbility ability) { super(ability); - this.condition = ability.condition; this.ruleText = ability.ruleText; } diff --git a/Mage/src/main/java/mage/abilities/decorator/ConditionalGainActivatedAbility.java b/Mage/src/main/java/mage/abilities/decorator/ConditionalGainActivatedAbility.java index 9fe5123f83..41660dda3e 100644 --- a/Mage/src/main/java/mage/abilities/decorator/ConditionalGainActivatedAbility.java +++ b/Mage/src/main/java/mage/abilities/decorator/ConditionalGainActivatedAbility.java @@ -46,7 +46,6 @@ import mage.game.Game; */ public class ConditionalGainActivatedAbility extends ActivatedAbilityImpl { - private final Condition condition; private String staticText = ""; private static final Effects emptyEffects = new Effects(); @@ -71,7 +70,6 @@ public class ConditionalGainActivatedAbility extends ActivatedAbilityImpl { public ConditionalGainActivatedAbility(ConditionalGainActivatedAbility ability) { super(ability); - this.condition = ability.condition; this.staticText = ability.staticText; } diff --git a/Mage/src/main/java/mage/abilities/mana/ActivateIfConditionManaAbility.java b/Mage/src/main/java/mage/abilities/mana/ActivateIfConditionManaAbility.java index d851810563..f6c63bc2d4 100644 --- a/Mage/src/main/java/mage/abilities/mana/ActivateIfConditionManaAbility.java +++ b/Mage/src/main/java/mage/abilities/mana/ActivateIfConditionManaAbility.java @@ -50,7 +50,6 @@ public class ActivateIfConditionManaAbility extends ActivatedManaAbilityImpl { public ActivateIfConditionManaAbility(ActivateIfConditionManaAbility ability) { super(ability); - this.condition = ability.condition; } @Override From 155329ad0f20c11fc1660d1279d439ac8340c02e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 12 Sep 2017 15:42:34 -0400 Subject: [PATCH 012/182] small change --- .../src/mage/cards/m/MairsilThePretender.java | 134 ------------------ 1 file changed, 134 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MairsilThePretender.java b/Mage.Sets/src/mage/cards/m/MairsilThePretender.java index ca79b17b9d..1265793027 100644 --- a/Mage.Sets/src/mage/cards/m/MairsilThePretender.java +++ b/Mage.Sets/src/mage/cards/m/MairsilThePretender.java @@ -82,8 +82,6 @@ public class MairsilThePretender extends CardImpl { // Mairsil, the Pretender has all activated abilities of all cards you own in exile with cage counters on them. You may activate each of those abilities only once each turn. Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new MairsilThePretenderGainAbilitiesEffect()); this.addAbility(ability); -// ability.addEffect(new MairsilThePretenderRuleModifyingEffect()); -// this.addAbility(ability, new MairsilThePretenderWatcher()); } public MairsilThePretender(final MairsilThePretender card) { @@ -188,135 +186,3 @@ class MairsilThePretenderGainAbilitiesEffect extends ContinuousEffectImpl { return new MairsilThePretenderGainAbilitiesEffect(this); } } - -//class MairsilThePretenderWatcher extends Watcher { -// -// public final Map> activatedThisTurnAbilities = new HashMap<>(); -// -// public MairsilThePretenderWatcher() { -// super(MairsilThePretenderWatcher.class.getSimpleName(), WatcherScope.GAME); -// } -// -// public MairsilThePretenderWatcher(final MairsilThePretenderWatcher watcher) { -// super(watcher); -// for (Entry> entry : watcher.activatedThisTurnAbilities.entrySet()) { -// activatedThisTurnAbilities.put(entry.getKey(), entry.getValue()); -// } -// } -// -// @Override -// public void watch(GameEvent event, Game game) { -// if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event instanceof ZoneChangeEvent) { -// ZoneChangeEvent zEvent = (ZoneChangeEvent) event; -// if (zEvent.getFromZone() == Zone.BATTLEFIELD) { -// Permanent permanent = zEvent.getTarget(); -// if (permanent != null) { -// this.activatedThisTurnAbilities.remove(permanent.getId()); -// } -// } -// } -// if (event.getType() == GameEvent.EventType.ACTIVATED_ABILITY) { -// Set permAbilities; -// if (activatedThisTurnAbilities.keySet().contains(event.getSourceId())) { -// permAbilities = activatedThisTurnAbilities.get(event.getSourceId()); -// } else { -// permAbilities = new HashSet<>(); -// } -// StackAbility ability = (StackAbility) game.getStack().getStackObject(event.getSourceId()); -// if (ability != null && ability.getStackAbility().isActivated()) { -// for (Effect effect : ability.getAllEffects()) { -// if (effect instanceof DoNothingEffect) { -// permAbilities.add((UUID) effect.getValue("key")); -// this.activatedThisTurnAbilities.put(event.getSourceId(), permAbilities); -// } -// } -// } -// } -// } -// -// @Override -// public void reset() { -// activatedThisTurnAbilities.clear(); -// } -// -// public Map> getActivatedThisTurnAbilities() { -// return this.activatedThisTurnAbilities; -// } -// -// @Override -// public MairsilThePretenderWatcher copy() { -// return new MairsilThePretenderWatcher(this); -// } -// -//} -// -//class MairsilThePretenderRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl { -// -// public MairsilThePretenderRuleModifyingEffect() { -// super(Duration.WhileOnBattlefield, Outcome.Detriment); -// } -// -// public MairsilThePretenderRuleModifyingEffect(final MairsilThePretenderRuleModifyingEffect effect) { -// super(effect); -// } -// -// @Override -// public MairsilThePretenderRuleModifyingEffect copy() { -// return new MairsilThePretenderRuleModifyingEffect(this); -// } -// -// @Override -// public boolean apply(Game game, Ability source) { -// return true; -// } -// -// @Override -// public boolean checksEventType(GameEvent event, Game game) { -// return event.getType() == GameEvent.EventType.ACTIVATE_ABILITY; -// } -// -// @Override -// public boolean applies(GameEvent event, Ability source, Game game) { -// Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); -// MairsilThePretenderWatcher watcher = (MairsilThePretenderWatcher) game.getState().getWatchers().get(MairsilThePretenderWatcher.class.getSimpleName()); -// if (watcher != null && ability != null && ability.isPresent()) { -// for (Effect effect : ability.get().getAllEffects()) { -// if (effect instanceof DoNothingEffect) { -// UUID originalID = (UUID) effect.getValue("key"); -// if (watcher.getActivatedThisTurnAbilities().keySet().contains(event.getSourceId())) { -// if (watcher.getActivatedThisTurnAbilities().get(event.getSourceId()).contains(originalID)) { -// return true; -// } -// } -// } -// } -// } -// return false; -// } -// -// @Override -// public String getInfoMessage(Ability source, GameEvent event, Game game) { -// return "This ability can only be activated once each turn."; -// } -//} -// -//class DoNothingEffect extends OneShotEffect { -// -// DoNothingEffect() { -// super(Outcome.Neutral); -// } -// -// DoNothingEffect(final DoNothingEffect effect) { -// super(effect); -// } -// -// @Override -// public DoNothingEffect copy() { -// return new DoNothingEffect(this); -// } -// -// @Override -// public boolean apply(Game game, Ability source) { -// return true; -// } -//} From 98c2332b3c1bdb1398e47e22088b60ab664b297a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 07:04:44 -0400 Subject: [PATCH 013/182] a few small changes --- Mage.Sets/src/mage/cards/c/CruelDeceiver.java | 4 +--- Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CruelDeceiver.java b/Mage.Sets/src/mage/cards/c/CruelDeceiver.java index 95bab5f5e9..dd515075b0 100644 --- a/Mage.Sets/src/mage/cards/c/CruelDeceiver.java +++ b/Mage.Sets/src/mage/cards/c/CruelDeceiver.java @@ -39,7 +39,6 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.LookLibraryControllerEffect; -import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.cards.*; import mage.constants.CardType; @@ -84,7 +83,7 @@ class CruelDeceiverEffect extends OneShotEffect { public CruelDeceiverEffect() { super(Outcome.AddAbility); - this.staticText = "Reveal the top card of your library. If it's a land card, Cruel Deceiver gains \"Whenever Cruel Deceiver deals damage to a creature, destroy that creature\" until end of turn"; + this.staticText = "Reveal the top card of your library. If it's a land card, {this} gains \"Whenever Cruel Deceiver deals damage to a creature, destroy that creature\" until end of turn"; } public CruelDeceiverEffect(final CruelDeceiverEffect effect) { @@ -107,7 +106,6 @@ class CruelDeceiverEffect extends OneShotEffect { cards.add(card); controller.revealCards(sourceObject.getIdName(), cards, game); if (card.isLand()) { - game.addEffect(new BoostSourceEffect(1, 0, Duration.EndOfTurn), source); game.addEffect(new GainAbilitySourceEffect(new DealsDamageToACreatureTriggeredAbility(new DestroyTargetEffect(true), false, false, true), Duration.EndOfTurn), source); } } diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java index 32c3728ee9..cb8d83d483 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java @@ -276,6 +276,9 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa } protected boolean hasMoreActivationsThisTurn(Game game) { + if (maxActivationsPerTurn == Integer.MAX_VALUE) { + return true; + } ActivationInfo activationInfo = getActivationInfo(game); return activationInfo == null || activationInfo.turnNum != game.getTurnNum() || activationInfo.activationCounter < maxActivationsPerTurn; } From e401bebb4ecc69a00ee604b169b93913583a507b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 06:57:43 -0400 Subject: [PATCH 014/182] fixed Sword-Point Diplomacy --- Mage.Sets/src/mage/cards/s/SwordPointDiplomacy.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SwordPointDiplomacy.java b/Mage.Sets/src/mage/cards/s/SwordPointDiplomacy.java index 7dd227bed8..75d9e44712 100644 --- a/Mage.Sets/src/mage/cards/s/SwordPointDiplomacy.java +++ b/Mage.Sets/src/mage/cards/s/SwordPointDiplomacy.java @@ -72,7 +72,7 @@ class SwordPointDiplomacyEffect extends OneShotEffect { SwordPointDiplomacyEffect() { super(Outcome.Benefit); - this.staticText = ""; + this.staticText = "Reveal the top three cards of your library. For each of those cards, put that card into your hand unless any opponent pays 3 life. Then exile the rest."; } SwordPointDiplomacyEffect(final SwordPointDiplomacyEffect effect) { @@ -102,10 +102,10 @@ class SwordPointDiplomacyEffect extends OneShotEffect { Cost cost = new PayLifeCost(3); for (UUID oppId : game.getOpponents(controller.getId())) { Player opponent = game.getPlayer(oppId); - if (!(opponent != null + if (opponent != null && cost.canPay(source, source.getSourceId(), opponent.getId(), game) && opponent.chooseUse(Outcome.Neutral, "Pay 3 life to prevent " + controller.getLogName() + " from getting " + card.getLogName() + "?", source, game) - && cost.pay(source, game, source.getSourceId(), opponent.getId(), true))) { + && cost.pay(source, game, source.getSourceId(), opponent.getId(), true)) { keepIt = false; } } From 1ae29e900a9953fa0bfe114a790b793e833d4de1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 10:02:32 -0400 Subject: [PATCH 015/182] Implemented Guided Passage --- Mage.Sets/src/mage/cards/g/GuidedPassage.java | 149 ++++++++++++++++++ Mage.Sets/src/mage/sets/Apocalypse.java | 1 + .../common/DoUnlessAnyPlayerPaysEffect.java | 1 - 3 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/g/GuidedPassage.java diff --git a/Mage.Sets/src/mage/cards/g/GuidedPassage.java b/Mage.Sets/src/mage/cards/g/GuidedPassage.java new file mode 100644 index 0000000000..fb04a3237b --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GuidedPassage.java @@ -0,0 +1,149 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.Set; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; +import mage.filter.common.FilterLandCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetCard; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class GuidedPassage extends CardImpl { + + public GuidedPassage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}{R}{G}"); + + // Reveal the cards in your library. An opponent chooses from among them a creature card, a land card, and a noncreature, nonland card. You put the chosen cards into your hand. Then shuffle your library. + this.getSpellAbility().addEffect(new GuidedPassageEffect()); + } + + public GuidedPassage(final GuidedPassage card) { + super(card); + } + + @Override + public GuidedPassage copy() { + return new GuidedPassage(this); + } +} + +class GuidedPassageEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard("noncreature, nonland card"); + + static { + filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); + filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); + } + + GuidedPassageEffect() { + super(Outcome.Benefit); + this.staticText = "Reveal the cards in your library. An opponent chooses from among them a creature card, a land card, and a noncreature, nonland card. You put the chosen cards into your hand. Then shuffle your library."; + } + + GuidedPassageEffect(final GuidedPassageEffect effect) { + super(effect); + } + + @Override + public GuidedPassageEffect copy() { + return new GuidedPassageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { + return false; + } + int libSize = controller.getLibrary().size(); + if (libSize == 0) { + controller.shuffleLibrary(source, game); + return true; + } + CardsImpl cards = new CardsImpl(); + cards.addAll(controller.getLibrary().getTopCards(game, libSize)); + controller.revealCards(sourceObject.getIdName(), cards, game); + + Player opponent; + Set opponents = game.getOpponents(controller.getId()); + if (opponents.size() == 1) { + opponent = game.getPlayer(opponents.iterator().next()); + } else { + Target target = new TargetOpponent(true); + controller.chooseTarget(Outcome.Detriment, target, source, game); + opponent = game.getPlayer(target.getFirstTarget()); + } + TargetCard target1 = new TargetCard(1, Zone.LIBRARY, new FilterCreatureCard()); + TargetCard target2 = new TargetCard(1, Zone.LIBRARY, new FilterLandCard()); + TargetCard target3 = new TargetCard(1, Zone.LIBRARY, new FilterCard(filter)); + opponent.chooseTarget(Outcome.Detriment, cards, target1, source, game); + opponent.chooseTarget(Outcome.Detriment, cards, target2, source, game); + opponent.chooseTarget(Outcome.Detriment, cards, target3, source, game); + Cards cardsToHand = new CardsImpl(); + Card cardToHand; + cardToHand = game.getCard(target1.getFirstTarget()); + if (cardToHand != null) { + cardsToHand.add(cardToHand); + } + cardToHand = game.getCard(target2.getFirstTarget()); + if (cardToHand != null) { + cardsToHand.add(cardToHand); + } + cardToHand = game.getCard(target3.getFirstTarget()); + if (cardToHand != null) { + cardsToHand.add(cardToHand); + } + controller.moveCards(cardsToHand, Zone.HAND, source, game); + controller.shuffleLibrary(source, game); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Apocalypse.java b/Mage.Sets/src/mage/sets/Apocalypse.java index 8dd861e76e..122dc92c5c 100644 --- a/Mage.Sets/src/mage/sets/Apocalypse.java +++ b/Mage.Sets/src/mage/sets/Apocalypse.java @@ -70,6 +70,7 @@ public class Apocalypse extends ExpansionSet { cards.add(new SetCardInfo("Goblin Ringleader", 62, Rarity.UNCOMMON, mage.cards.g.GoblinRingleader.class)); cards.add(new SetCardInfo("Goblin Trenches", 104, Rarity.RARE, mage.cards.g.GoblinTrenches.class)); cards.add(new SetCardInfo("Grave Defiler", 40, Rarity.UNCOMMON, mage.cards.g.GraveDefiler.class)); + cards.add(new SetCardInfo("Guided Passage", 105, Rarity.RARE, mage.cards.g.GuidedPassage.class)); cards.add(new SetCardInfo("Haunted Angel", 12, Rarity.UNCOMMON, mage.cards.h.HauntedAngel.class)); cards.add(new SetCardInfo("Helionaut", 13, Rarity.COMMON, mage.cards.h.Helionaut.class)); cards.add(new SetCardInfo("Ice Cave", 24, Rarity.RARE, mage.cards.i.IceCave.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/DoUnlessAnyPlayerPaysEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessAnyPlayerPaysEffect.java index 15bff45982..b05f8501cf 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DoUnlessAnyPlayerPaysEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DoUnlessAnyPlayerPaysEffect.java @@ -98,7 +98,6 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect { game.informPlayers(player.getLogName() + " pays the cost to prevent the effect"); } doEffect = false; - break; } } } From 6a9770030b6e2cc062a35d9ba970e5f2ddcbba5a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 10:59:02 -0400 Subject: [PATCH 016/182] updated XLN spoiler --- Utils/mtg-cards-data.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index e65553aad7..bec858c9f8 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32334,6 +32334,7 @@ Axis of Mortality|Ixalan|3|M|{4}{W}{W}|Enchantment|||At the beginning of your up Bellowing Aegisaur|Ixalan|4|U|{5}{W}|Creature - Dinosaur|3|5|Enrage - Whenever Bellowing Aegisaur is dealt damage, put a +1/+1 counter on each other creature you control.| Bishop of Rebirth|Ixalan|5|R|Creature - Vampire Cleric|3|4|Vigilance$Whenever Bishop of Rebirth attacks, you may return target creature card with converted mana cost 3 or less from your graveyard to the battlefield.| Duskborne Skymarcher|Ixalan|9|U|{W}|Creature - Vampire Cleric|1|1|Flying${W}, {T}: Target attacking vampire gets +1/+1 until end of turn.| +Emissary of Sunrise|Ixalan|10|U|{2}{W}|Creature - Human Cleric|2|1|First strike$When Emissary of Sunrise enters the battlefield, it explores. (Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on this creature, then put the card back or put it into your graveyard.)| Goring Ceratops|Ixalan|13|R|Creature - Dinosaur|3|3|Double strike$Whenever Goring Ceratops attacks, other creatures you control gain double strike until end of turn.| Imperial Lancer|Ixalan|15|U|{W}|Creature - Human Knight|1|1|Imperial Lancer has double strike as long as you control a Dinosaur.| Ixalan's Binding|Ixalan|17|U|{3}{W}|Enchantment|||When Ixalan's Binding enters the battlefield, exile target nonland permanent an opponent controls until Ixalan's Binding leaves the battlefield.$Your opponents can't cast spells with the same name as the exiled card.| @@ -32474,6 +32475,7 @@ Pirate's Cutlass|Ixalan|242|C|{3}|Artifact - Equipment|||When Pirate's Cutlass e Primal Amulet|Ixalan|243a|R|{4}|Artifact|||Instant and sorcery spells you cast cost {1} less to cast.$Whenever you cast an instant or sorcery spell, put a charge counter on Primal Amulet. Then if there are four or more charge counters on it, you may remove those counters and transform it.| Primal Wellspring|Ixalan|243b|R||Land|||Add one mana of any color to your mana pool. When that mana is spent to cast an instant or sorcery spell, copy that spell and you may choose new targets for the copy.| Sentinel Totem|Ixalan|245|U|{1}|Artifact|||When Sentinel Totem enters the battlefield, scry 1.${T}, Exile Sentinel Totem: Exile all cards from all graveyards.| +Shadowed Caravel|Ixalan|246|R|{2}|Artifact - Vehicle|2|2|Whenever a creature you control explores, put a +1/+1 counter on Shadowed Caravel.$Crew 2| Sleek Schooner|Ixalan|247|U|{3}|Artifact - Vehicle|4|3|Crew 1| Sorcerous Spyglass|Ixalan|248|R|{2}|Artifact|||As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name.$Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.| Spires of Orazca|Ixalan|249b|R||Land|||{T}: Add {C} to your mana pool.${T}: Untap target attacking creature an opponent controls and remove it from combat.| @@ -32483,6 +32485,7 @@ Treasure Map|Ixalan|250a|R|{2}|Artifact|||{1}, {T}: Scry 1. Put a landmark count Vanquisher's Banner|Ixalan|251|R|{5}|Artifact|||As Vanquisher's Banner enters the battlefield, choose a creature type.$Creatures you control of the chosen type get +1/+1.$Whenever you cast a creature spell of the chosen type, draw a card.| Dragonskull Summit|Ixalan|252|R||Land|||Dragonskull Summit enters the battlefield tapped unless you control a Swamp or a Mountain.${T}: Add {B} or {R} to your mana pool.| Drowned Catacomb|Ixalan|253|R||Land|||Drowned Catacomb enters the battlefield tapped unless you control an Island or a Swamp.${T}: Add {U} or {B} to your mana pool.| +Field of Ruin|Ixalan|254|U||Land|||{T}: Add {C} to your mana pool.${2}, {T}, Sacrifice Field of Ruin: Destroy target nonbasic land an opponent controls. Each player searches his or her library for a basic land card, puts it onto the battlefield, then shuffles his or her library.| Glacial Fortress|Ixalan|255|R||Land|||Glacial Fortress enters the battlefield tapped unless you control a Plains or an Island.${T}: Add {W} or {U} to your mana pool.| Rootbound Crag|Ixalan|256|R||Land|||Rootbound Crag enters the battlefield tapped unless you control a Mountain or a Forest.${T}: Add {R} or {G} to your mana pool.| Sunpetal Grove|Ixalan|257|R||Land|||Sunpetal Grove enters the battlefield tapped unless you control a Forest or a Plains.${T}: Add {G} or {W} to your mana pool.| From ceaf2bdde771ddb2e0a0be6ef092deb0f2f145c0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 11:03:57 -0400 Subject: [PATCH 017/182] updated XLN spoiler --- Utils/mtg-cards-data.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index bec858c9f8..9d507cc389 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32427,6 +32427,7 @@ Unfriendly Fire|Ixalan|172|C|{4}{R}|Instant|||Unfriendly Fire deals 4 damage to Wily Goblin|Ixalan|174|U|{R}{R}|Creature - Goblin Pirate|1|1|When Wily Goblin enters the battlefield, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| Carnage Tyrant|Ixalan|179|M|{4}{G}{G}|Creature - Dinosaur|7|6|Carnage Tyrant can't be countered.$Trample, hexproof| Commune with Dinosaurs|Ixalan|181|C|{G}|Sorcery|||| +Deathgorge Scavenger|Ixalan|184|R|{2}{G}|Creature - Dinosaur|3|2|Whenever Deathgorge Scavenger enters the battlefield or attacks, you may exile target card from a graveyard. If a creature card is exiled this way, you gain 2 life. If a noncreature card is exiled this way, Deathgorge Scavenger gets +1/+1 until end of turn.| Deeproot Champion|Ixalan|185|R|{1}{G}|Creature - Merfolk Shaman|1|1|Whenever you cast a noncreature spell, put a +1/+1 counter on Deeproot Champion.| Drover of the Mighty|Ixalan|187|U|{1}{G}|Creature - Human Druid|1|1|Drover of the Mighty gets +2/+2 as long as you control a Dinosaur.${T}: Add one mana of any color to your mana pool.| Emperor's Vanguard|Ixalan|189|R|{3}{G}|Creature - Human Scout|4|3|Whenever Emperor's Vanguard deals combat damage to a player, it explores.| From dff87b11637a45ffc1fc4dd88dae5a96e054816e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 11:08:45 -0400 Subject: [PATCH 018/182] Implemented Emissary of Sunrise --- .../src/mage/cards/e/EmissaryOfSunrise.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EmissaryOfSunrise.java diff --git a/Mage.Sets/src/mage/cards/e/EmissaryOfSunrise.java b/Mage.Sets/src/mage/cards/e/EmissaryOfSunrise.java new file mode 100644 index 0000000000..0587f17b36 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EmissaryOfSunrise.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.e; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.keyword.ExploreSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class EmissaryOfSunrise extends CardImpl { + + public EmissaryOfSunrise(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // When Emissary of Sunrise enters the battlefield, it explores. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExploreSourceEffect())); + } + + public EmissaryOfSunrise(final EmissaryOfSunrise card) { + super(card); + } + + @Override + public EmissaryOfSunrise copy() { + return new EmissaryOfSunrise(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 4af16f8659..9db95b74e6 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -79,6 +79,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Duress", 105, Rarity.COMMON, mage.cards.d.Duress.class)); cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.d.DuskLegionDreadnought.class)); cards.add(new SetCardInfo("Duskborne Skymarcher", 9, Rarity.UNCOMMON, mage.cards.d.DuskborneSkymarcher.class)); + cards.add(new SetCardInfo("Emissary of Sunrise", 10, Rarity.UNCOMMON, mage.cards.e.EmissaryOfSunrise.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); cards.add(new SetCardInfo("Fathom Fleet Captain", 106, Rarity.RARE, mage.cards.f.FathomFleetCaptain.class)); From 68a42726a88a0fa4cca1ffe42850632c72689202 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 11:19:29 -0400 Subject: [PATCH 019/182] Implemented Shadowed Caravel, generalized explore triggers --- .../src/mage/cards/l/LurkingChupacabra.java | 46 +----------- .../src/mage/cards/s/ShadowedCaravel.java | 74 +++++++++++++++++++ .../src/mage/cards/w/WildgrowthWalker.java | 45 +---------- Mage.Sets/src/mage/sets/Ixalan.java | 1 + .../CreatureExploresTriggeredAbility.java | 43 +++++++++++ 5 files changed, 124 insertions(+), 85 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/s/ShadowedCaravel.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/CreatureExploresTriggeredAbility.java diff --git a/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java b/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java index 6c011ea8f0..7f607f32f9 100644 --- a/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java +++ b/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java @@ -30,8 +30,7 @@ package mage.cards.l; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreatureExploresTriggeredAbility; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.constants.SubType; import mage.cards.CardImpl; @@ -39,12 +38,8 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.TargetController; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; /** @@ -53,7 +48,7 @@ import mage.target.common.TargetCreaturePermanent; */ public class LurkingChupacabra extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); @@ -68,7 +63,7 @@ public class LurkingChupacabra extends CardImpl { this.toughness = new MageInt(3); // Whenever a creature you control explores, target creature an opponent controls gets -2/-2 until end of turn - Ability ability = new LurkingChupacabraTriggeredAbility(new BoostTargetEffect(-2, -2, Duration.EndOfTurn)); + Ability ability = new CreatureExploresTriggeredAbility(new BoostTargetEffect(-2, -2, Duration.EndOfTurn)); ability.addTarget(new TargetCreaturePermanent(filter)); } @@ -81,38 +76,3 @@ public class LurkingChupacabra extends CardImpl { return new LurkingChupacabra(this); } } - -class LurkingChupacabraTriggeredAbility extends TriggeredAbilityImpl { - - LurkingChupacabraTriggeredAbility(Effect effect) { - super(Zone.BATTLEFIELD, effect, false); - } - - LurkingChupacabraTriggeredAbility(final LurkingChupacabraTriggeredAbility effect) { - super(effect); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.EXPLORED; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (creature != null) { - return creature.getControllerId().equals(controllerId); - } - return false; - } - - @Override - public LurkingChupacabraTriggeredAbility copy() { - return new LurkingChupacabraTriggeredAbility(this); - } - - @Override - public String getRule() { - return "Whenever a creature you control explores, target creature an opponent controls gets -2/-2 until end of turn"; - } -} diff --git a/Mage.Sets/src/mage/cards/s/ShadowedCaravel.java b/Mage.Sets/src/mage/cards/s/ShadowedCaravel.java new file mode 100644 index 0000000000..ab340946d0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShadowedCaravel.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreatureExploresTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.CrewAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; + +/** + * + * @author TheElk801 + */ +public class ShadowedCaravel extends CardImpl { + + public ShadowedCaravel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + this.subtype.add(SubType.VEHICLE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever a creature you control explores, put a +1/+1 counter on Shadowed Caravel. + Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance()); + Ability ability = new CreatureExploresTriggeredAbility(effect); + this.addAbility(ability); + + // Crew 2 + this.addAbility(new CrewAbility(2)); + + } + + public ShadowedCaravel(final ShadowedCaravel card) { + super(card); + } + + @Override + public ShadowedCaravel copy() { + return new ShadowedCaravel(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WildgrowthWalker.java b/Mage.Sets/src/mage/cards/w/WildgrowthWalker.java index 8066b2dad3..7830ef9d03 100644 --- a/Mage.Sets/src/mage/cards/w/WildgrowthWalker.java +++ b/Mage.Sets/src/mage/cards/w/WildgrowthWalker.java @@ -30,20 +30,15 @@ package mage.cards.w; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreatureExploresTriggeredAbility; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; /** * @@ -60,8 +55,9 @@ public class WildgrowthWalker extends CardImpl { // Whenever a creature you control explores, put a +1/+1 counter on Wildgrowth Walker and you gain 3 life. Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance()); - Ability ability = new WildgrowthWalkerTriggeredAbility(effect); + Ability ability = new CreatureExploresTriggeredAbility(effect); effect = new GainLifeEffect(3); + effect.setText("and you gain 3 life"); ability.addEffect(effect); this.addAbility(ability); } @@ -75,38 +71,3 @@ public class WildgrowthWalker extends CardImpl { return new WildgrowthWalker(this); } } - -class WildgrowthWalkerTriggeredAbility extends TriggeredAbilityImpl { - - WildgrowthWalkerTriggeredAbility(Effect effect) { - super(Zone.BATTLEFIELD, effect, false); - } - - WildgrowthWalkerTriggeredAbility(final WildgrowthWalkerTriggeredAbility effect) { - super(effect); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.EXPLORED; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (creature != null) { - return creature.getControllerId().equals(controllerId); - } - return false; - } - - @Override - public WildgrowthWalkerTriggeredAbility copy() { - return new WildgrowthWalkerTriggeredAbility(this); - } - - @Override - public String getRule() { - return "Whenever a creature you control explores, put a +1/+1 counter on {this} and you gain 3 life"; - } -} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 9db95b74e6..751beb6597 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -169,6 +169,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Search for Azcanta", 74, Rarity.RARE, mage.cards.s.SearchForAzcanta.class)); cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); cards.add(new SetCardInfo("Settle the Wreckage", 34, Rarity.RARE, mage.cards.s.SettleTheWreckage.class)); + cards.add(new SetCardInfo("Shadowed Caravel", 246, Rarity.RARE, mage.cards.s.ShadowedCaravel.class)); cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Siren Stormtamer", 79, Rarity.UNCOMMON, mage.cards.s.SirenStormtamer.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreatureExploresTriggeredAbility.java b/Mage/src/main/java/mage/abilities/effects/common/CreatureExploresTriggeredAbility.java new file mode 100644 index 0000000000..e78b559cc4 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/CreatureExploresTriggeredAbility.java @@ -0,0 +1,43 @@ +package mage.abilities.effects.common; + +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +public class CreatureExploresTriggeredAbility extends TriggeredAbilityImpl { + + public CreatureExploresTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect, false); + } + + public CreatureExploresTriggeredAbility(final CreatureExploresTriggeredAbility effect) { + super(effect); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.EXPLORED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (creature != null) { + return creature.getControllerId().equals(controllerId); + } + return false; + } + + @Override + public CreatureExploresTriggeredAbility copy() { + return new CreatureExploresTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever a creature you control explores, " + super.getRule(); + } +} From d9c601dd26e7f6943998bc8fa5ac930beebf9d05 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 14 Sep 2017 17:50:00 +0200 Subject: [PATCH 020/182] Trove of Temptation - Basic some changes to Combat and Human --- .../src/mage/player/human/HumanPlayer.java | 137 +++++++++++++----- .../src/mage/cards/t/TroveOfTemptation.java | 109 ++++++++++++++ .../abilities/effects/ContinuousEffects.java | 22 +-- .../abilities/effects/RequirementEffect.java | 49 ++++++- .../main/java/mage/game/combat/Combat.java | 12 +- .../java/mage/game/combat/CombatGroup.java | 4 + 6 files changed, 271 insertions(+), 62 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/t/TroveOfTemptation.java diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index bff6dea4ea..762c5408e7 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -46,6 +46,7 @@ import mage.choices.ChoiceImpl; import mage.constants.*; import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL; import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL; +import mage.filter.StaticFilters; import mage.filter.common.FilterAttackingCreature; import mage.filter.common.FilterBlockingCreature; import mage.filter.common.FilterCreatureForCombat; @@ -1055,6 +1056,7 @@ public class HumanPlayer extends PlayerImpl { updateGameStatePriority("selectAttackers", game); FilterCreatureForCombat filter = filterCreatureForCombat.copy(); filter.add(new ControllerIdPredicate(attackingPlayerId)); + while (!abort) { if (passedAllTurns || passedUntilEndStepBeforeMyTurn @@ -1063,7 +1065,9 @@ public class HumanPlayer extends PlayerImpl { || passedTurnSkipStack || passedUntilEndOfTurn || passedUntilNextMain))) { - return; + if (checkIfAttackersValid(game)) { + return; + } } Map options = new HashMap<>(); @@ -1108,46 +1112,12 @@ public class HumanPlayer extends PlayerImpl { // attack selected default defender declareAttacker(attacker.getId(), attackedDefender, game, false); } - } else if (response.getBoolean() != null) { - // check if enough attackers are declared - if (!game.getCombat().getCreaturesForcedToAttack().isEmpty()) { - if (!game.getCombat().getAttackers().containsAll(game.getCombat().getCreaturesForcedToAttack().keySet())) { - int forcedAttackers = 0; - StringBuilder sb = new StringBuilder(); - for (UUID creatureId : game.getCombat().getCreaturesForcedToAttack().keySet()) { - boolean validForcedAttacker = false; - if (game.getCombat().getAttackers().contains(creatureId)) { - Set possibleDefender = game.getCombat().getCreaturesForcedToAttack().get(creatureId); - if (possibleDefender.isEmpty() - || possibleDefender.contains(game.getCombat().getDefenderId(creatureId))) { - validForcedAttacker = true; - } - } - if (validForcedAttacker) { - forcedAttackers++; - } else { - Permanent creature = game.getPermanent(creatureId); - if (creature != null) { - sb.append(creature.getIdName()).append(' '); - } - } +// } else if (response.getInteger() != null) { // Ok or F-Key - } - if (game.getCombat().getMaxAttackers() > forcedAttackers) { - int requireToAttack = Math.min(game.getCombat().getMaxAttackers() - forcedAttackers, game.getCombat().getCreaturesForcedToAttack().size() - forcedAttackers); - String message = (requireToAttack == 1 ? " more attacker that is " : " more attackers that are ") - + "forced to attack.\nCreature" - + (requireToAttack == 1 ? "" : "s") + " forced to attack: "; - game.informPlayer(this, sb.insert(0, message) - .insert(0, requireToAttack) - .insert(0, "You have to attack with ").toString()); - continue; - } - } + } else if (response.getBoolean() != null) { // ok button + if (checkIfAttackersValid(game)) { + return; } - return; - } else if (response.getInteger() != null) { - return; } else if (response.getUUID() != null) { Permanent attacker = game.getPermanent(response.getUUID()); if (attacker != null) { @@ -1161,8 +1131,95 @@ public class HumanPlayer extends PlayerImpl { } } + private boolean checkIfAttackersValid(Game game) { + if (!game.getCombat().getCreaturesForcedToAttack().isEmpty()) { + if (!game.getCombat().getAttackers().containsAll(game.getCombat().getCreaturesForcedToAttack().keySet())) { + int forcedAttackers = 0; + StringBuilder sb = new StringBuilder(); + for (UUID creatureId : game.getCombat().getCreaturesForcedToAttack().keySet()) { + boolean validForcedAttacker = false; + if (game.getCombat().getAttackers().contains(creatureId)) { + Set possibleDefender = game.getCombat().getCreaturesForcedToAttack().get(creatureId); + if (possibleDefender.isEmpty() + || possibleDefender.contains(game.getCombat().getDefenderId(creatureId))) { + validForcedAttacker = true; + } + } + if (validForcedAttacker) { + forcedAttackers++; + } else { + Permanent creature = game.getPermanent(creatureId); + if (creature != null) { + sb.append(creature.getIdName()).append(' '); + } + } + + } + if (game.getCombat().getMaxAttackers() > forcedAttackers) { + int requireToAttack = Math.min(game.getCombat().getMaxAttackers() - forcedAttackers, game.getCombat().getCreaturesForcedToAttack().size() - forcedAttackers); + String message = (requireToAttack == 1 ? " more attacker that is " : " more attackers that are ") + + "forced to attack.\nCreature" + + (requireToAttack == 1 ? "" : "s") + " forced to attack: "; + game.informPlayer(this, sb.insert(0, message) + .insert(0, requireToAttack) + .insert(0, "You have to attack with ").toString()); + return false; + } + } + } + // check if enough attackers are declared + // check if players have to be attacked + Set playersToAttackIfAble = new HashSet<>(); + for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(null, true, game).entrySet()) { + RequirementEffect effect = entry.getKey(); + for (Ability ability : entry.getValue()) { + UUID playerToAttack = effect.playerMustBeAttackedIfAble(ability, game); + if (playerToAttack != null) { + playersToAttackIfAble.add(playerToAttack); + } + } + } + if (!playersToAttackIfAble.isEmpty()) { + Set checkPlayersToAttackIfAble = new HashSet<>(playersToAttackIfAble); + for (CombatGroup combatGroup : game.getCombat().getGroups()) { + checkPlayersToAttackIfAble.remove(combatGroup.getDefendingPlayerId()); + } + + for (UUID forcedToAttackId : checkPlayersToAttackIfAble) { + Player forcedToAttack = game.getPlayer(forcedToAttackId); + + for (Permanent attacker : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, getId(), game)) { + + if (game.getContinuousEffects().checkIfThereArePayCostToAttackBlockEffects( + GameEvent.getEvent(GameEvent.EventType.DECLARE_ATTACKER, + forcedToAttackId, attacker.getId(), attacker.getControllerId()), game)) { + continue; + } + // if attacker needs a specific defender to attack so select that one instead + if (game.getCombat().getCreaturesForcedToAttack().containsKey(attacker.getId())) { + Set possibleDefenders = game.getCombat().getCreaturesForcedToAttack().get(attacker.getId()); + if (!possibleDefenders.isEmpty() && !possibleDefenders.contains(forcedToAttackId)) { + continue; + } + } + UUID defendingPlayerId = game.getCombat().getDefendingPlayerId(attacker.getId(), game); + if (playersToAttackIfAble.contains(defendingPlayerId)) { + // already attacks other player taht has to be attacked + continue; + } + if (defendingPlayerId != null || attacker.canAttack(forcedToAttackId, game)) { + game.informPlayer(this, "You are forced to attack " + forcedToAttack.getName() + " or a controlled planeswalker e.g. with " + attacker.getIdName() + "."); + return false; + } + } + } + } + + return true; + } + private void removeAttackerIfPossible(Game game, Permanent attacker) { - for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(attacker, game).entrySet()) { + for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(attacker, false, game).entrySet()) { RequirementEffect effect = (RequirementEffect) entry.getKey(); if (effect.mustAttack(game)) { if (game.getCombat().getMaxAttackers() >= game.getCombat().getCreaturesForcedToAttack().size() diff --git a/Mage.Sets/src/mage/cards/t/TroveOfTemptation.java b/Mage.Sets/src/mage/cards/t/TroveOfTemptation.java new file mode 100644 index 0000000000..70ad58d291 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TroveOfTemptation.java @@ -0,0 +1,109 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.RequirementEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.TreasureToken; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class TroveOfTemptation extends CardImpl { + + public TroveOfTemptation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); + + // Each opponent must attack you or a planeswalker you control with at least one creature each combat if able. + addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TroveOfTemptationForceAttackEffect(Duration.WhileOnBattlefield))); + + // At the beginning of your end step, create a colorless Treasure artifact token with "{t}, Sacrifice this artifact: Add one mana of any color to your mana pool.” + addAbility(new BeginningOfYourEndStepTriggeredAbility(new CreateTokenEffect(new TreasureToken()), false)); + } + + public TroveOfTemptation(final TroveOfTemptation card) { + super(card); + } + + @Override + public TroveOfTemptation copy() { + return new TroveOfTemptation(this); + } +} + +class TroveOfTemptationForceAttackEffect extends RequirementEffect { + + public TroveOfTemptationForceAttackEffect(Duration duration) { + super(duration, true); + staticText = "Each opponent must attack you or a planeswalker you control with at least one creature each combat if able"; + } + + public TroveOfTemptationForceAttackEffect(final TroveOfTemptationForceAttackEffect effect) { + super(effect); + } + + @Override + public TroveOfTemptationForceAttackEffect copy() { + return new TroveOfTemptationForceAttackEffect(this); + } + + @Override + public boolean mustAttack(Game game) { + return false; + } + + @Override + public boolean mustBlock(Game game) { + return false; + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + return controller != null && controller.hasOpponent(game.getActivePlayerId(), game); + } + + @Override + public UUID playerMustBeAttackedIfAble(Ability source, Game game) { + return source.getControllerId(); + } + +} diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java index e1ac2ffa00..f7933a870f 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java @@ -243,20 +243,22 @@ public class ContinuousEffects implements Serializable { return effects.stream().filter(effect -> effect.hasLayer(layer)).collect(Collectors.toList()); } - public Map> getApplicableRequirementEffects(Permanent permanent, Game game) { + public Map> getApplicableRequirementEffects(Permanent permanent, boolean playerRealted, Game game) { Map> effects = new HashMap<>(); for (RequirementEffect effect : requirementEffects) { - Set abilities = requirementEffects.getAbility(effect.getId()); - Set applicableAbilities = new HashSet<>(); - for (Ability ability : abilities) { - if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, ability instanceof MageSingleton ? permanent : null, null)) { - if (effect.applies(permanent, ability, game)) { - applicableAbilities.add(ability); + if (playerRealted == effect.isPlayerRelated()) { + Set abilities = requirementEffects.getAbility(effect.getId()); + Set applicableAbilities = new HashSet<>(); + for (Ability ability : abilities) { + if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, ability instanceof MageSingleton ? permanent : null, null)) { + if (effect.applies(permanent, ability, game)) { + applicableAbilities.add(ability); + } } } - } - if (!applicableAbilities.isEmpty()) { - effects.put(effect, abilities); + if (!applicableAbilities.isEmpty()) { + effects.put(effect, abilities); + } } } return effects; diff --git a/Mage/src/main/java/mage/abilities/effects/RequirementEffect.java b/Mage/src/main/java/mage/abilities/effects/RequirementEffect.java index 93a34bd5ff..89afa2bd49 100644 --- a/Mage/src/main/java/mage/abilities/effects/RequirementEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/RequirementEffect.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects; import java.util.UUID; @@ -36,20 +35,33 @@ import mage.constants.Outcome; import mage.game.Game; import mage.game.permanent.Permanent; - /** * * @author BetaSteward_at_googlemail.com */ public abstract class RequirementEffect extends ContinuousEffectImpl { + boolean playerRelated; // defines a requirement that is more related to a player than a single creature + public RequirementEffect(Duration duration) { + this(duration, false); + } + + /** + * + * @param duration + * @param playerRelated defines a requirement that is more related to a + * player than a single creature + */ + public RequirementEffect(Duration duration, boolean playerRelated) { super(duration, Outcome.Detriment); this.effectType = EffectType.REQUIREMENT; + this.playerRelated = playerRelated; } public RequirementEffect(final RequirementEffect effect) { super(effect); + this.playerRelated = effect.playerRelated; } @Override @@ -67,6 +79,13 @@ public abstract class RequirementEffect extends ContinuousEffectImpl { return false; } + /** + * Defines the defender a attacker has to attack + * + * @param source + * @param game + * @return + */ public UUID mustAttackDefender(Ability source, Game game) { return null; } @@ -79,4 +98,20 @@ public abstract class RequirementEffect extends ContinuousEffectImpl { return null; } + /** + * Player related check The player returned or controlled planeswalker must + * be attacked with at least one attacker + * + * @param source + * @param game + * @return + */ + public UUID playerMustBeAttackedIfAble(Ability source, Game game) { + return null; + } + + public boolean isPlayerRelated() { + return playerRelated; + } + } diff --git a/Mage/src/main/java/mage/game/combat/Combat.java b/Mage/src/main/java/mage/game/combat/Combat.java index 496520ed0c..1ad1948a1b 100644 --- a/Mage/src/main/java/mage/game/combat/Combat.java +++ b/Mage/src/main/java/mage/game/combat/Combat.java @@ -306,7 +306,9 @@ public class Combat implements Serializable, Copyable { for (Permanent creature : player.getAvailableAttackers(game)) { boolean mustAttack = false; Set defendersForcedToAttack = new HashSet<>(); - for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).entrySet()) { + + // check if a creature has to attack + for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, false, game).entrySet()) { RequirementEffect effect = entry.getKey(); if (effect.mustAttack(game)) { mustAttack = true; @@ -379,6 +381,7 @@ public class Combat implements Serializable, Copyable { boolean check = true; int numberOfChecks = 0; UUID attackerToRemove = null; + Player attackingPlayer = game.getPlayer(attackingPlayerId); Check: while (check) { check = false; @@ -387,7 +390,6 @@ public class Combat implements Serializable, Copyable { for (CombatGroup group : groups) { numberAttackers += group.getAttackers().size(); } - Player attackingPlayer = game.getPlayer(attackingPlayerId); if (attackerToRemove != null) { removeAttacker(attackerToRemove, game); } @@ -579,7 +581,7 @@ public class Combat implements Serializable, Copyable { return; } for (Permanent possibleBlocker : game.getBattlefield().getActivePermanents(filterBlockers, attackingPlayer.getId(), game)) { - for (Map.Entry> requirementEntry : game.getContinuousEffects().getApplicableRequirementEffects(possibleBlocker, game).entrySet()) { + for (Map.Entry> requirementEntry : game.getContinuousEffects().getApplicableRequirementEffects(possibleBlocker, false, game).entrySet()) { if (requirementEntry.getKey().mustBlock(game)) { for (Ability ability : requirementEntry.getValue()) { UUID attackingCreatureId = requirementEntry.getKey().mustBlockAttacker(ability, game); @@ -656,7 +658,7 @@ public class Combat implements Serializable, Copyable { // Creature is already blocking but not forced to do so if (creature.getBlocking() > 0) { // get all requirement effects that apply to the creature (e.g. is able to block attacker) - for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).entrySet()) { + for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, false, game).entrySet()) { RequirementEffect effect = entry.getKey(); // get possible mustBeBlockedByAtLeastOne blocker for (Ability ability : entry.getValue()) { @@ -678,7 +680,7 @@ public class Combat implements Serializable, Copyable { // Creature is not blocking yet if (creature.getBlocking() == 0) { // get all requirement effects that apply to the creature - for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).entrySet()) { + for (Map.Entry> entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, false, game).entrySet()) { RequirementEffect effect = entry.getKey(); // get possible mustBeBlockedByAtLeastOne blocker for (Ability ability : entry.getValue()) { diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index 3b900692b7..3bab5e6305 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -105,6 +105,10 @@ public class CombatGroup implements Serializable, Copyable { return defenderId; } + public UUID getDefendingPlayerId() { + return defendingPlayerId; + } + public List getAttackers() { return attackers; } From 73a8d64d5c58fd375ebfa7b52cecf741235a416e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 13:36:17 -0400 Subject: [PATCH 021/182] fixed Thraben Sentry --- Mage.Sets/src/mage/cards/t/ThrabenSentry.java | 13 +++---------- Mage.Sets/src/mage/sets/Ixalan.java | 1 + .../common/DiesCreatureTriggeredAbility.java | 11 ++++++----- Mage/src/main/java/mage/filter/StaticFilters.java | 2 +- .../common/FilterControlledCreaturePermanent.java | 10 ++++++---- 5 files changed, 17 insertions(+), 20 deletions(-) diff --git a/Mage.Sets/src/mage/cards/t/ThrabenSentry.java b/Mage.Sets/src/mage/cards/t/ThrabenSentry.java index 335871c031..cf553d5504 100644 --- a/Mage.Sets/src/mage/cards/t/ThrabenSentry.java +++ b/Mage.Sets/src/mage/cards/t/ThrabenSentry.java @@ -37,22 +37,15 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.common.FilterControlledCreaturePermanent; /** * @author nantuko */ public class ThrabenSentry extends CardImpl { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature"); - - static { - filter.add(new AnotherPredicate()); - } public ThrabenSentry(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); @@ -66,7 +59,7 @@ public class ThrabenSentry extends CardImpl { // Whenever another creature you control dies, you may transform Thraben Sentry. this.addAbility(new TransformAbility()); - this.addAbility(new DiesCreatureTriggeredAbility(new TransformSourceEffect(true), true, filter)); + this.addAbility(new DiesCreatureTriggeredAbility(new TransformSourceEffect(true), true, new FilterControlledCreaturePermanent())); } public ThrabenSentry(final ThrabenSentry card) { diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 751beb6597..623026e62d 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -155,6 +155,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Ravenous Daggertooth", 202, Rarity.COMMON, mage.cards.r.RavenousDaggertooth.class)); cards.add(new SetCardInfo("Regisaur Alpha", 227, Rarity.RARE, mage.cards.r.RegisaurAlpha.class)); cards.add(new SetCardInfo("Revel in Riches", 117, Rarity.RARE, mage.cards.r.RevelInRiches.class)); + cards.add(new SetCardInfo("Rigging Runner", 157, Rarity.UNCOMMON, mage.cards.r.RiggingRunner.class)); cards.add(new SetCardInfo("Rile", 158, Rarity.COMMON, mage.cards.r.Rile.class)); cards.add(new SetCardInfo("Ripjaw Raptor", 203, Rarity.RARE, mage.cards.r.RipjawRaptor.class)); cards.add(new SetCardInfo("River Sneak", 70, Rarity.UNCOMMON, mage.cards.r.RiverSneak.class)); diff --git a/Mage/src/main/java/mage/abilities/common/DiesCreatureTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DiesCreatureTriggeredAbility.java index 6e160f7020..671945e5f9 100644 --- a/Mage/src/main/java/mage/abilities/common/DiesCreatureTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DiesCreatureTriggeredAbility.java @@ -3,6 +3,7 @@ package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; import mage.constants.Zone; +import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.AnotherPredicate; import mage.game.Game; @@ -15,7 +16,7 @@ import mage.target.targetpointer.FixedTarget; */ public class DiesCreatureTriggeredAbility extends TriggeredAbilityImpl { - protected FilterCreaturePermanent filter; + protected FilterPermanent filter; private boolean setTargetPointer; public DiesCreatureTriggeredAbility(Effect effect, boolean optional) { @@ -34,15 +35,15 @@ public class DiesCreatureTriggeredAbility extends TriggeredAbilityImpl { this.setTargetPointer = setTargetPointer; } - public DiesCreatureTriggeredAbility(Effect effect, boolean optional, FilterCreaturePermanent filter) { + public DiesCreatureTriggeredAbility(Effect effect, boolean optional, FilterPermanent filter) { this(effect, optional, filter, false); } - public DiesCreatureTriggeredAbility(Effect effect, boolean optional, FilterCreaturePermanent filter, boolean setTargetPointer) { + public DiesCreatureTriggeredAbility(Effect effect, boolean optional, FilterPermanent filter, boolean setTargetPointer) { this(Zone.BATTLEFIELD, effect, optional, filter, setTargetPointer); } - public DiesCreatureTriggeredAbility(Zone zone, Effect effect, boolean optional, FilterCreaturePermanent filter, boolean setTargetPointer) { + public DiesCreatureTriggeredAbility(Zone zone, Effect effect, boolean optional, FilterPermanent filter, boolean setTargetPointer) { super(zone, effect, optional); this.filter = filter; this.setTargetPointer = setTargetPointer; @@ -68,7 +69,7 @@ public class DiesCreatureTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { - if (filter.match(zEvent.getTarget(), sourceId, controllerId, game)) { + if (filter.match(zEvent.getTarget(), sourceId, controllerId, game) && zEvent.getTarget().isCreature()) { if (setTargetPointer) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getTargetId())); diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 620c7582d5..05a02cc488 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -41,7 +41,7 @@ public final class StaticFilters { public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_ARTIFACT = new FilterControlledArtifactPermanent(); public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_ARTIFACT_OR_CREATURE = new FilterControlledPermanent("artifact or creature you control"); - public static final FilterControlledPermanent FILTER_CONTROLLED_A_CREATURE = new FilterControlledCreaturePermanent("a creature you control"); + public static final FilterPermanent FILTER_CONTROLLED_A_CREATURE = new FilterControlledCreaturePermanent("a creature you control"); public static final FilterControlledCreaturePermanent FILTER_CONTROLLED_ANOTHER_CREATURE = new FilterControlledCreaturePermanent("another creature"); public static final FilterControlledPermanent FILTER_CONTROLLED_PERMANENT_NON_LAND = new FilterControlledPermanent("nonland permanent"); public static final FilterLandPermanent FILTER_LAND = new FilterLandPermanent(); diff --git a/Mage/src/main/java/mage/filter/common/FilterControlledCreaturePermanent.java b/Mage/src/main/java/mage/filter/common/FilterControlledCreaturePermanent.java index f8fcd1a77c..a10d4b7b73 100644 --- a/Mage/src/main/java/mage/filter/common/FilterControlledCreaturePermanent.java +++ b/Mage/src/main/java/mage/filter/common/FilterControlledCreaturePermanent.java @@ -25,19 +25,21 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.filter.common; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; /** * * @author BetaSteward_at_googlemail.com */ -public class FilterControlledCreaturePermanent extends FilterControlledPermanent { +public class FilterControlledCreaturePermanent extends FilterPermanent { public FilterControlledCreaturePermanent() { this("creature you control"); @@ -46,8 +48,8 @@ public class FilterControlledCreaturePermanent extends FilterControlledPermanent public FilterControlledCreaturePermanent(String name) { super(name); this.add(new CardTypePredicate(CardType.CREATURE)); - } - + this.add(new ControllerPredicate(TargetController.YOU)); + } public FilterControlledCreaturePermanent(SubType subtype, String name) { super(name); From 4f4950b7ed6c6c231c1b5e010fc2764cb163cae2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 13:52:58 -0400 Subject: [PATCH 022/182] Implemented Perilous Voyage --- .../src/mage/cards/p/PerilousVoyage.java | 107 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + Utils/mtg-cards-data.txt | 1 + 3 files changed, 109 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PerilousVoyage.java diff --git a/Mage.Sets/src/mage/cards/p/PerilousVoyage.java b/Mage.Sets/src/mage/cards/p/PerilousVoyage.java new file mode 100644 index 0000000000..78313865e1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PerilousVoyage.java @@ -0,0 +1,107 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; + +/** + * + * @author TheElk801 + */ +public class PerilousVoyage extends CardImpl { + + private static final FilterNonlandPermanent filter = new FilterNonlandPermanent("nonland permanent you don't control"); + + static { + filter.add(new ControllerPredicate(TargetController.NOT_YOU)); + } + + public PerilousVoyage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + // Return target nonland permanent you don't control to its owner's hand. If its converted mana cost was 2 or less, scry 2. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addEffect(new PerilousVoyageEffect()); + this.getSpellAbility().addTarget(new TargetPermanent()); + } + + public PerilousVoyage(final PerilousVoyage card) { + super(card); + } + + @Override + public PerilousVoyage copy() { + return new PerilousVoyage(this); + } +} + +class PerilousVoyageEffect extends OneShotEffect { + + PerilousVoyageEffect() { + super(Outcome.Benefit); + this.staticText = "Return target nonland permanent you don't control to its owner's hand. If its converted mana cost was 2 or less, scry 2"; + } + + PerilousVoyageEffect(final PerilousVoyageEffect effect) { + super(effect); + } + + @Override + public PerilousVoyageEffect copy() { + return new PerilousVoyageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent != null) { + boolean isLittle = permanent.getConvertedManaCost() < 3; + permanent.moveToZone(Zone.HAND, source.getSourceId(), game, true); + if (isLittle && player != null) { + player.scry(2, source, game); + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 623026e62d..fdd7c29524 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -136,6 +136,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); cards.add(new SetCardInfo("Otepec Huntmaster", 153, Rarity.UNCOMMON, mage.cards.o.OtepecHuntmaster.class)); cards.add(new SetCardInfo("Overflowing Insight", 64, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); + cards.add(new SetCardInfo("Perilous Voyage", 67, Rarity.UNCOMMON, mage.cards.p.PerilousVoyage.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); cards.add(new SetCardInfo("Pirate's Cutlass", 242, Rarity.COMMON, mage.cards.p.PiratesCutlass.class)); cards.add(new SetCardInfo("Plains", 260, Rarity.LAND, mage.cards.basiclands.Plains.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 9d507cc389..dac7f4d4ab 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32364,6 +32364,7 @@ Kopala, Warden of Waves|Ixalan|61|R|{1}{U}{U}|Legendary Creature - Merfolk Wizar Lookout's Dispersal|Ixalan|62|U|{2}{U}|Instant|||Lookout's Dispersal costs {1} less to cast if you control a Pirate.$Counter target spell unless its controller pays {4}.| Overflowing Insight|Ixalan|64|M|{4}{U}{U}{U}|Sorcery|||Target player draws seven cards.| Opt|Ixalan|65|C|{U}|Instant|||Scry 1.$Draw a card.| +Perilous Voyage|Ixalan|67|U|{1}{U}|Instant|||Return target nonland permanent you don't control to its owner's hand. If its converted mana cost was 2 or less, scry 2.| Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperous Pirates enters the battlefield, create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| River Sneak|Ixalan|70|U|{1}{U}|Creature - Merfolk Warrior|1|1|River Sneak can't be blocked.$Whenever another Merfolk enters the battlefield under your control, River sneak gets +1/+1 until end of turn.| River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| From 9fa7729133779a89c6e5324f5eccf771ee46ba2e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 13:55:00 -0400 Subject: [PATCH 023/182] Implemented Perilous Voyage --- Mage.Sets/src/mage/cards/p/PerilousVoyage.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/p/PerilousVoyage.java b/Mage.Sets/src/mage/cards/p/PerilousVoyage.java index 78313865e1..a20473e1ad 100644 --- a/Mage.Sets/src/mage/cards/p/PerilousVoyage.java +++ b/Mage.Sets/src/mage/cards/p/PerilousVoyage.java @@ -30,7 +30,6 @@ package mage.cards.p; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -60,9 +59,8 @@ public class PerilousVoyage extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Return target nonland permanent you don't control to its owner's hand. If its converted mana cost was 2 or less, scry 2. - this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); this.getSpellAbility().addEffect(new PerilousVoyageEffect()); - this.getSpellAbility().addTarget(new TargetPermanent()); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); } public PerilousVoyage(final PerilousVoyage card) { From ec9a198d0a4efb9b3c9d9efd5eee71f84a7b5632 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 14:20:20 -0400 Subject: [PATCH 024/182] Implemented Deathgorge Scavenger --- .../src/mage/cards/d/DeathgorgeScavenger.java | 109 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 110 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java diff --git a/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java b/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java new file mode 100644 index 0000000000..13b6ae13b3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java @@ -0,0 +1,109 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.Card; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInGraveyard; + +/** + * + * @author TheElk801 + */ +public class DeathgorgeScavenger extends CardImpl { + + public DeathgorgeScavenger(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Whenever Deathgorge Scavenger enters the battlefield or attacks, you may exile target card from a graveyard. If a creature card is exiled this way, you gain 2 life. If a noncreature card is exiled this way, Deathgorge Scavenger gets +1/+1 until end of turn. + Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new DeathgorgeScavengerEffect(), true); + ability.addTarget(new TargetCardInGraveyard()); + this.addAbility(ability); + } + + public DeathgorgeScavenger(final DeathgorgeScavenger card) { + super(card); + } + + @Override + public DeathgorgeScavenger copy() { + return new DeathgorgeScavenger(this); + } +} + +class DeathgorgeScavengerEffect extends OneShotEffect { + + public DeathgorgeScavengerEffect() { + super(Outcome.Benefit); + this.staticText = "exile target card from a graveyard. If a creature card is exiled this way, you gain 2 life. If a noncreature card is exiled this way, {this} gets +1/+1 until end of turn"; + } + + public DeathgorgeScavengerEffect(final DeathgorgeScavengerEffect effect) { + super(effect); + } + + @Override + public DeathgorgeScavengerEffect copy() { + return new DeathgorgeScavengerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Card card = game.getCard(getTargetPointer().getFirst(game, source)); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && card != null) { + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true); + if (card.isCreature()) { + controller.gainLife(2, game); + } else { + new BoostSourceEffect(1, 1, Duration.EndOfTurn).apply(game, source); + } + return true; + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index fdd7c29524..9ca5f5b349 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -63,6 +63,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Deadeye Quartermaster", 50, Rarity.UNCOMMON, mage.cards.d.DeadeyeQuartermaster.class)); cards.add(new SetCardInfo("Deadeye Tormentor", 98, Rarity.COMMON, mage.cards.d.DeadeyeTormentor.class)); cards.add(new SetCardInfo("Deadeye Tracker", 99, Rarity.RARE, mage.cards.d.DeadeyeTracker.class)); + cards.add(new SetCardInfo("Deathgorge Scavenger", 184, Rarity.RARE, mage.cards.d.DeathgorgeScavenger.class)); cards.add(new SetCardInfo("Deathless Ancient", 100, Rarity.UNCOMMON, mage.cards.d.DeathlessAncient.class)); cards.add(new SetCardInfo("Deeproot Champion", 185, Rarity.RARE, mage.cards.d.DeeprootChampion.class)); cards.add(new SetCardInfo("Deeproot Waters", 51, Rarity.UNCOMMON, mage.cards.d.DeeprootWaters.class)); From 1cdc8d31778b65f7f039dbda8c746d7e4587569f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 14:47:07 -0400 Subject: [PATCH 025/182] Implemented Field of Ruin --- Mage.Sets/src/mage/cards/f/FieldOfRuin.java | 134 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + Utils/mtg-cards-data.txt | 1 + 3 files changed, 136 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FieldOfRuin.java diff --git a/Mage.Sets/src/mage/cards/f/FieldOfRuin.java b/Mage.Sets/src/mage/cards/f/FieldOfRuin.java new file mode 100644 index 0000000000..45e3c514be --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FieldOfRuin.java @@ -0,0 +1,134 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author TheElk801 + */ +public class FieldOfRuin extends CardImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent("nonbasic land an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + filter.add(Predicates.not(new SupertypePredicate(SuperType.BASIC))); + } + + public FieldOfRuin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + // {T}: Add {C} to your mana pool. + this.addAbility(new ColorlessManaAbility()); + + // {2}, {T}, Sacrifice Field of Ruin: Destroy target nonbasic land an opponent controls. Each player searches his or her library for a basic land card, puts it onto the battlefield, then shuffles his or her library. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new TapSourceCost()); + ability.addCost(new ManaCostsImpl("{2}")); + ability.addCost(new SacrificeSourceCost()); + ability.addEffect(new FieldOfRuinEffect()); + ability.addTarget(new TargetLandPermanent(filter)); + } + + public FieldOfRuin(final FieldOfRuin card) { + super(card); + } + + @Override + public FieldOfRuin copy() { + return new FieldOfRuin(this); + } +} + +class FieldOfRuinEffect extends OneShotEffect { + + FieldOfRuinEffect() { + super(Outcome.Benefit); + this.staticText = "Each player searches his or her library for a basic land card, puts it onto the battlefield, then shuffles his or her library."; + } + + FieldOfRuinEffect(final FieldOfRuinEffect effect) { + super(effect); + } + + @Override + public FieldOfRuinEffect copy() { + return new FieldOfRuinEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD); + if (player.searchLibrary(target, game)) { + for (UUID cardId : target.getTargets()) { + Card card = player.getLibrary().getCard(cardId, game); + if (card != null) { + card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId(), true); + } + + } + player.shuffleLibrary(source, game); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 9ca5f5b349..fd1e610dd8 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -86,6 +86,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Fathom Fleet Captain", 106, Rarity.RARE, mage.cards.f.FathomFleetCaptain.class)); cards.add(new SetCardInfo("Favorable Winds", 56, Rarity.UNCOMMON, mage.cards.f.FavorableWinds.class)); cards.add(new SetCardInfo("Fell Flagship", 238, Rarity.RARE, mage.cards.f.FellFlagship.class)); + cards.add(new SetCardInfo("Field of Ruin", 254, Rarity.UNCOMMON, mage.cards.f.FieldOfRuin.class)); cards.add(new SetCardInfo("Forest", 276, Rarity.LAND, mage.cards.basiclands.Forest.class)); cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class)); cards.add(new SetCardInfo("Forest", 278, Rarity.LAND, mage.cards.basiclands.Forest.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index dac7f4d4ab..b375b744a0 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32372,6 +32372,7 @@ Azcanta, The Sunken Ruin|Ixalan|74b|R||Legendary Land|||(Transforms from Search Search for Azcanta|Ixalan|74a|R|{1}{U}|Legendary Enchantment|||| Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|1|1|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| Spell Pierce|Ixalan|81|C|{U}|Instant|||Counter target noncreature spell unless its controller pays {2}.| +Spell Swindle|Ixalan|82|R|{3}{U}{U}|Instant|||Counter target spell. Create X colorless Treasure artifact tokens, where X is that spell's converted mana cost. They have "T, Sacrifice this artifact: Add one mana of any color to your mana pool."| Storm Fleet Aerialist|Ixalan|83|U|{1}{U}|Creature - Human Pirate|1|2|Flying$Raid - Storm Fleet Aerialist enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.| Storm Fleet Spy|Ixalan|84|U|{2}{U}|Creature - Human Pirate|2|2|Raid - When Storm Fleet Spy enters the battlefield, if you attacked with a creature this turn, draw a card.| Arguel's Blood Fast|Ixalan|90a|R|{1}{B}|Legendary Enchantment|||{1}{B}, Pay 2 life: Draw a card.$At the beginning of your upkeep, if you have 5 or less life, you may transform Arguel's Blood Fast.| From 75ce112a5df025fe6769b2ba5cc06657464ffb73 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 14:54:42 -0400 Subject: [PATCH 026/182] Implemented Spell Swindle --- Mage.Sets/src/mage/cards/s/SpellSwindle.java | 93 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 94 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SpellSwindle.java diff --git a/Mage.Sets/src/mage/cards/s/SpellSwindle.java b/Mage.Sets/src/mage/cards/s/SpellSwindle.java new file mode 100644 index 0000000000..6745cc8009 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpellSwindle.java @@ -0,0 +1,93 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.token.TreasureToken; +import mage.game.stack.StackObject; +import mage.target.TargetSpell; + +/** + * + * @author TheElk801 + */ +public class SpellSwindle extends CardImpl { + + public SpellSwindle(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{U}"); + + // Counter target spell. Create X colorless Treasure artifact tokens, where X is that spell's converted mana cost. They have "T, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.getSpellAbility().addTarget(new TargetSpell()); + this.getSpellAbility().addEffect(new SpellSwindleEffect()); + } + + public SpellSwindle(final SpellSwindle card) { + super(card); + } + + @Override + public SpellSwindle copy() { + return new SpellSwindle(this); + } +} + +class SpellSwindleEffect extends OneShotEffect { + + public SpellSwindleEffect() { + super(Outcome.Detriment); + staticText = "Counter target spell. Create X colorless Treasure artifact tokens, where X is that spell's converted mana cost. " + + "They have \"{T}, Sacrifice this artifact: Add one mana of any color to your mana pool"; + } + + public SpellSwindleEffect(final SpellSwindleEffect effect) { + super(effect); + } + + @Override + public SpellSwindleEffect copy() { + return new SpellSwindleEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + StackObject stackObject = game.getStack().getStackObject(targetPointer.getFirst(game, source)); + if (stackObject != null) { + game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game); + return new CreateTokenEffect(new TreasureToken(), stackObject.getConvertedManaCost()).apply(game, source); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index fd1e610dd8..9395a410cd 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -185,6 +185,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Snapping Sailback", 208, Rarity.UNCOMMON, mage.cards.s.SnappingSailback.class)); cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); cards.add(new SetCardInfo("Spell Pierce", 81, Rarity.RARE, mage.cards.s.SpellPierce.class)); + cards.add(new SetCardInfo("Spell Swindle", 82, Rarity.RARE, mage.cards.s.SpellSwindle.class)); cards.add(new SetCardInfo("Spires of Orazca", 249, Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); From 90cd60150d0acaed148f9e9b33bd201876a3e673 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 17:11:37 -0400 Subject: [PATCH 027/182] Implemented Vineshaper Mystic --- .../src/mage/cards/v/VineshaperMystic.java | 84 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + Utils/mtg-cards-data.txt | 3 + 3 files changed, 88 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VineshaperMystic.java diff --git a/Mage.Sets/src/mage/cards/v/VineshaperMystic.java b/Mage.Sets/src/mage/cards/v/VineshaperMystic.java new file mode 100644 index 0000000000..28471aa8fc --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VineshaperMystic.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.TargetPermanent; + +/** + * + * @author TheElk801 + */ +public class VineshaperMystic extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("Merfolk you control"); + + static { + filter.add(new SubtypePredicate(SubType.MERFOLK)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public VineshaperMystic(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.SHAMAN); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // When Vineshaper Mystic enters the battlefield, put a +1/+1 counter on each of up to two target Merfolk you control. + Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); + effect.setText("put a +1/+1 counter on each of up to two target Merfolk you control"); + Ability ability = new EntersBattlefieldTriggeredAbility(effect, false); + ability.addTarget(new TargetPermanent(0, 2, filter, false)); + this.addAbility(ability); + } + + public VineshaperMystic(final VineshaperMystic card) { + super(card); + } + + @Override + public VineshaperMystic copy() { + return new VineshaperMystic(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 9395a410cd..752e9defbd 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -216,6 +216,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Vanquisher's Banner", 251, Rarity.RARE, mage.cards.v.VanquishersBanner.class)); cards.add(new SetCardInfo("Verdant Sun's Avatar", 213, Rarity.RARE, mage.cards.v.VerdantSunsAvatar.class)); cards.add(new SetCardInfo("Vicious Conquistador", 128, Rarity.UNCOMMON, mage.cards.v.ViciousConquistador.class)); + cards.add(new SetCardInfo("Vineshaper Mystic", 214, Rarity.UNCOMMON, mage.cards.v.VineshaperMystic.class)); cards.add(new SetCardInfo("Vona, Butcher of Magan", 231, Rarity.MYTHIC, mage.cards.v.VonaButcherOfMagan.class)); cards.add(new SetCardInfo("Vraska's Contempt", 129, Rarity.RARE, mage.cards.v.VraskasContempt.class)); cards.add(new SetCardInfo("Vraska, Relic Seeker", 232, Rarity.MYTHIC, mage.cards.v.VraskaRelicSeeker.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index b375b744a0..d59d306d67 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32426,6 +32426,8 @@ Tilonalli's Knight|Ixalan|169|C|{1}{R}|Creature - Human Knight|2|2|Whenever Tilo Tilonalli's Skinshifter|Ixalan|170|R|{2}{R}|Creature - Human Shaman|0|1|Whenever Tilonalli's Skinshifter attacks, it becomes a copy of another target nonlegendary attacking creature until end of turn.| Trove of Temptation|Ixalan|171|U|{3}{R}|Enchantment|||Each opponent must attack you or a planeswalker you control with at least one creature each combat if able.$At the beginning of your end step, create a colorless Treasure artifact token with "t, Sacrifice this artifact: Add one mana of any color to your mana pool.”| Unfriendly Fire|Ixalan|172|C|{4}{R}|Instant|||Unfriendly Fire deals 4 damage to target creature or player.| +Vance's Blasting Cannons|Ixalan|173a|R|{3}{R}|Legendary Enchantment|||At the beginning of your upkeep, exile the top card of your library. If it's a nonland card, you may cast that card this turn.$Whenever you cast your third spell in a turn, transform Vance's Blasting Cannons.| +Spitfire Bastion|Ixalan|173b|R||Legendary Land|||{t}: Add {r} to your mana pool.${2}{r}, {t}: Spitfire Bastion deals 3 damage to target creature or player.| Wily Goblin|Ixalan|174|U|{R}{R}|Creature - Goblin Pirate|1|1|When Wily Goblin enters the battlefield, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| Carnage Tyrant|Ixalan|179|M|{4}{G}{G}|Creature - Dinosaur|7|6|Carnage Tyrant can't be countered.$Trample, hexproof| Commune with Dinosaurs|Ixalan|181|C|{G}|Sorcery|||| @@ -32449,6 +32451,7 @@ Snapping Sailback|Ixalan|208|U|{4}{G}|Creature - Dinosaur|4|4|Flash$Enrage — W Thundering Spineback|Ixalan|210|U|{5}{G}{G}|Creature - Dinosaur|5|5|Other Dinosaurs you control get +1/+1.${5}{G}: Create a 3/3 green Dinosaur creature token with trample.| Tishana's Wayfinder|Ixalan|211|C|{2}{G}|Creature - Merfolk Scout|2|2|When Tishana's Wayfinder enters the battlefield, it explores.| Verdant Sun's Avatar|Ixalan|213|R|{5}{G}{G}|Creature - Dinosaur Avatar|5|5|When Verdant Sun's Avatar or another creature enters the battlefield under your control, you gain life equal to that creature's toughness.| +Vineshaper Mystic|Ixalan|214|U|{2}{G}|Creature - Merfolk Shaman|1|3|When Vineshaper Mystic enters the battlefield, put a +1/+1 counter on each of up to two target Merfolk you control.| Waker of the Wilds|Ixalan|215|R|{2}{G}{G}|Creature - Merfolk Shaman|3|3|{X}{G}{G}: Put X +1/+1 counters on target land you control. That land becomes a 0/0 Elemental creature with haste. It's still a land.| Wildgrowth Walker|Ixalan|216|U|{1}{G}|Creature - Elemental|1|3|Whenever a creature you control explores, put a +1/+1 counter on Wildgrowth Walker and you gain 3 life.| Admiral Beckett Brass|Ixalan|217|M|{1}{U}{B}{R}|Legendary Creature - Human Pirate|3|3|Other Pirates you control get +1/+1.$At the beginning of your end step, gain control of target nonland permanent controlled by a player who was dealt damage by three or more Pirates this turn.| From c54ddefed54c12946ca258d664892c2454b7f7b4 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 14 Sep 2017 23:43:33 +0200 Subject: [PATCH 028/182] Fixed bug of Scarwood Bandits. --- .../src/mage/cards/s/ScarwoodBandits.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/ScarwoodBandits.java b/Mage.Sets/src/mage/cards/s/ScarwoodBandits.java index d6fd2a6c25..09c803e225 100644 --- a/Mage.Sets/src/mage/cards/s/ScarwoodBandits.java +++ b/Mage.Sets/src/mage/cards/s/ScarwoodBandits.java @@ -31,20 +31,20 @@ import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.Mode; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.common.SourceOnBattlefieldCondition; -import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.Cost; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalContinuousEffect; -import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.abilities.keyword.ForestwalkAbility; -import mage.abilities.Mode; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -53,7 +53,6 @@ import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetArtifactPermanent; import mage.util.CardUtil; @@ -65,7 +64,7 @@ import mage.util.CardUtil; public class ScarwoodBandits extends CardImpl { public ScarwoodBandits(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ROGUE); this.power = new MageInt(2); @@ -73,16 +72,16 @@ public class ScarwoodBandits extends CardImpl { // Forestwalk this.addAbility(new ForestwalkAbility()); - + // {2}{G}, {tap}: Unless an opponent pays {2}, gain control of target artifact for as long as Scarwood Bandits remains on the battlefield. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new DoUnlessAnyOpponentPaysEffect( - new ConditionalContinuousEffect( - new GainControlTargetEffect(Duration.Custom, true), - new SourceOnBattlefieldCondition(), - "gain control of target artifact for as long as {this} remains on the battlefield"), - new GenericManaCost(2)), - new ManaCostsImpl("{2}{G}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new DoUnlessAnyOpponentPaysEffect( + new ConditionalContinuousEffect( + new GainControlTargetEffect(Duration.Custom, true), + SourceOnBattlefieldCondition.instance, + "gain control of target artifact for as long as {this} remains on the battlefield"), + new GenericManaCost(2)), + new ManaCostsImpl("{2}{G}")); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetArtifactPermanent()); this.addAbility(ability); From d0dfd46c5f6c4aadf0014dca7d3794279c9214d1 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 14 Sep 2017 23:45:48 +0200 Subject: [PATCH 029/182] Fixed problem that prevented project generation. --- .../FilterControlledCreaturePermanent.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/Mage/src/main/java/mage/filter/common/FilterControlledCreaturePermanent.java b/Mage/src/main/java/mage/filter/common/FilterControlledCreaturePermanent.java index a10d4b7b73..34e81d3e43 100644 --- a/Mage/src/main/java/mage/filter/common/FilterControlledCreaturePermanent.java +++ b/Mage/src/main/java/mage/filter/common/FilterControlledCreaturePermanent.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,7 +20,7 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. @@ -29,17 +29,14 @@ package mage.filter.common; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.TargetController; -import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; -import mage.filter.predicate.permanent.ControllerPredicate; /** * * @author BetaSteward_at_googlemail.com */ -public class FilterControlledCreaturePermanent extends FilterPermanent { +public class FilterControlledCreaturePermanent extends FilterControlledPermanent { public FilterControlledCreaturePermanent() { this("creature you control"); @@ -48,7 +45,7 @@ public class FilterControlledCreaturePermanent extends FilterPermanent { public FilterControlledCreaturePermanent(String name) { super(name); this.add(new CardTypePredicate(CardType.CREATURE)); - this.add(new ControllerPredicate(TargetController.YOU)); + // this.add(new ControllerPredicate(TargetController.YOU)); } public FilterControlledCreaturePermanent(SubType subtype, String name) { From 7663827a30c4f6445cf63d3fc87eb041be453526 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 18:14:32 -0400 Subject: [PATCH 030/182] Implemented Vance's Blasting Cannons/Spitfire Bastion --- .../src/mage/cards/s/SpitfireBastion.java | 74 +++++++ .../mage/cards/v/VancesBlastingCannons.java | 194 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + .../abilities/keyword/ConspireAbility.java | 9 +- 4 files changed, 276 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/s/SpitfireBastion.java create mode 100644 Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java diff --git a/Mage.Sets/src/mage/cards/s/SpitfireBastion.java b/Mage.Sets/src/mage/cards/s/SpitfireBastion.java new file mode 100644 index 0000000000..5de16e5abe --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpitfireBastion.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.mana.RedManaAbility; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author TheElk801 + */ +public class SpitfireBastion extends CardImpl { + + public SpitfireBastion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.addSuperType(SuperType.LEGENDARY); + this.nightCard = true; + + // {T}: Add {R} to your mana pool. + this.addAbility(new RedManaAbility()); + + // {2}{R}, {T}: Spitfire Bastion deals 3 damage to target creature or player. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), new TapSourceCost()); + ability.addCost(new ManaCostsImpl("{2}{R}")); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public SpitfireBastion(final SpitfireBastion card) { + super(card); + } + + @Override + public SpitfireBastion copy() { + return new SpitfireBastion(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java new file mode 100644 index 0000000000..4444aa205b --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java @@ -0,0 +1,194 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.v; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.s.SpitfireBastion; +import mage.constants.AsThoughEffectType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.watchers.common.CastSpellLastTurnWatcher; + +/** + * + * @author TheElk801 + */ +public class VancesBlastingCannons extends CardImpl { + + public VancesBlastingCannons(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.transformable = true; + this.secondSideCardClazz = SpitfireBastion.class; + + // At the beginning of your upkeep, exile the top card of your library. If it's a nonland card, you may cast that card this turn. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new VancesBlastingCannonsExileEffect(), TargetController.YOU, false)); + + // Whenever you cast your third spell in a turn, transform Vance's Blasting Cannons. + this.addAbility(new TransformAbility()); + this.addAbility(new VancesBlastingCannonsFlipTrigger(), new CastSpellLastTurnWatcher()); + } + + public VancesBlastingCannons(final VancesBlastingCannons card) { + super(card); + } + + @Override + public VancesBlastingCannons copy() { + return new VancesBlastingCannons(this); + } +} + +class VancesBlastingCannonsExileEffect extends OneShotEffect { + + public VancesBlastingCannonsExileEffect() { + super(Outcome.Benefit); + this.staticText = "exile the top card of your library. If it's a nonland card, you may cast that card this turn"; + } + + public VancesBlastingCannonsExileEffect(final VancesBlastingCannonsExileEffect effect) { + super(effect); + } + + @Override + public VancesBlastingCannonsExileEffect copy() { + return new VancesBlastingCannonsExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (controller != null && sourcePermanent != null) { + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + String exileName = sourcePermanent.getIdName() + " Date: Thu, 14 Sep 2017 20:28:56 -0400 Subject: [PATCH 031/182] updated some mistakes --- Mage.Sets/src/mage/cards/f/FieldOfRuin.java | 2 +- Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/f/FieldOfRuin.java b/Mage.Sets/src/mage/cards/f/FieldOfRuin.java index 45e3c514be..ccd0cc0f34 100644 --- a/Mage.Sets/src/mage/cards/f/FieldOfRuin.java +++ b/Mage.Sets/src/mage/cards/f/FieldOfRuin.java @@ -119,7 +119,7 @@ class FieldOfRuinEffect extends OneShotEffect { for (UUID cardId : target.getTargets()) { Card card = player.getLibrary().getCard(cardId, game); if (card != null) { - card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId(), true); + card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId()); } } diff --git a/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java index 4444aa205b..4247174359 100644 --- a/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java +++ b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java @@ -108,7 +108,7 @@ class VancesBlastingCannonsExileEffect extends OneShotEffect { if (controller != null && sourcePermanent != null) { Card card = controller.getLibrary().getFromTop(game); if (card != null) { - String exileName = sourcePermanent.getIdName() + " Date: Thu, 14 Sep 2017 20:57:04 -0400 Subject: [PATCH 032/182] fixed Wasitora not forcing sacrifice of shroud creatures --- .../src/mage/cards/w/WasitoraNekoruQueen.java | 54 ++----------------- 1 file changed, 5 insertions(+), 49 deletions(-) diff --git a/Mage.Sets/src/mage/cards/w/WasitoraNekoruQueen.java b/Mage.Sets/src/mage/cards/w/WasitoraNekoruQueen.java index f825f37938..1a15867d24 100644 --- a/Mage.Sets/src/mage/cards/w/WasitoraNekoruQueen.java +++ b/Mage.Sets/src/mage/cards/w/WasitoraNekoruQueen.java @@ -30,8 +30,7 @@ package mage.cards.w; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.Effect; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.keyword.FlyingAbility; @@ -42,18 +41,13 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.SuperType; -import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.game.permanent.token.WasitoraCatDragonToken; import mage.players.Player; import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTarget; /** * @@ -77,7 +71,7 @@ public class WasitoraNekoruQueen extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Whenever Wasitora, Nekoru Queen deals combat damage to a player, that player sacrifices a creature. If the player can't, you create a 3/3 black, red, and green Cat Dragon creature token with flying - this.addAbility(new WasitoraNekoruQueenTriggeredAbility()); + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new WasitoraNekoruQueenEffect(), false, true)); } public WasitoraNekoruQueen(final WasitoraNekoruQueen card) { @@ -90,44 +84,6 @@ public class WasitoraNekoruQueen extends CardImpl { } } -class WasitoraNekoruQueenTriggeredAbility extends TriggeredAbilityImpl { - - public WasitoraNekoruQueenTriggeredAbility() { - super(Zone.BATTLEFIELD, new WasitoraNekoruQueenEffect()); - } - - public WasitoraNekoruQueenTriggeredAbility(final WasitoraNekoruQueenTriggeredAbility ability) { - super(ability); - } - - @Override - public WasitoraNekoruQueenTriggeredAbility copy() { - return new WasitoraNekoruQueenTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - if (damageEvent.isCombatDamage() && event.getSourceId().equals(this.getSourceId())) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getPlayerId())); - } - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, that player sacrifices a creature. If the player can't, you create a 3/3 black, red, and green Cat Dragon creature token with flying"; - } -} - class WasitoraNekoruQueenEffect extends OneShotEffect { public WasitoraNekoruQueenEffect() { @@ -151,11 +107,11 @@ class WasitoraNekoruQueenEffect extends OneShotEffect { if (damagedPlayer != null && controller != null) { FilterControlledPermanent filter = new FilterControlledPermanent("creature"); filter.add(new CardTypePredicate(CardType.CREATURE)); - TargetPermanent target = new TargetPermanent(filter); - if (damagedPlayer.choose(Outcome.Sacrifice, target, source.getId(), game)) { + TargetPermanent target = new TargetPermanent(1, 1, filter, true); + if (damagedPlayer.choose(Outcome.Sacrifice, target, source.getSourceId(), game)) { Permanent objectToBeSacrificed = game.getPermanent(target.getFirstTarget()); if (objectToBeSacrificed != null) { - if (objectToBeSacrificed.sacrifice(source.getId(), game)) { + if (objectToBeSacrificed.sacrifice(source.getSourceId(), game)) { return true; } } From 10a57b1594bbe678f6850e63cf25f3a2eadd16fd Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 21:12:25 -0400 Subject: [PATCH 033/182] Implemented Energy Storm --- Mage.Sets/src/mage/cards/e/EnergyStorm.java | 82 +++++++++++++++++++ Mage.Sets/src/mage/sets/IceAge.java | 1 + Mage.Sets/src/mage/sets/MastersEditionII.java | 1 + .../main/java/mage/filter/StaticFilters.java | 6 ++ 4 files changed, 90 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EnergyStorm.java diff --git a/Mage.Sets/src/mage/cards/e/EnergyStorm.java b/Mage.Sets/src/mage/cards/e/EnergyStorm.java new file mode 100644 index 0000000000..3bf51c4a3f --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EnergyStorm.java @@ -0,0 +1,82 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.e; + +import java.util.UUID; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DontUntapInControllersUntapStepAllEffect; +import mage.abilities.effects.common.PreventAllDamageByAllObjectsEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AbilityPredicate; + +/** + * + * @author TheElk801 + */ +public class EnergyStorm extends CardImpl { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with flying"); + + static { + filter.add(new AbilityPredicate(FlyingAbility.class)); + } + + public EnergyStorm(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); + + // Cumulative upkeep {1} + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}"))); + + // Prevent all damage that would be dealt by instant and sorcery spells. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new PreventAllDamageByAllObjectsEffect(StaticFilters.FILTER_INSTANT_OR_SORCERY_SPELLS, Duration.WhileOnBattlefield, false) + )); + + // Creatures with flying don't untap during their controllers' untap steps. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepAllEffect(Duration.WhileOnBattlefield, TargetController.ANY, filter))); + } + + public EnergyStorm(final EnergyStorm card) { + super(card); + } + + @Override + public EnergyStorm copy() { + return new EnergyStorm(this); + } +} diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 4f09b0c9a7..8aec080801 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -108,6 +108,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Elder Druid", 120, Rarity.RARE, mage.cards.e.ElderDruid.class)); cards.add(new SetCardInfo("Elemental Augury", 364, Rarity.RARE, mage.cards.e.ElementalAugury.class)); cards.add(new SetCardInfo("Enduring Renewal", 247, Rarity.RARE, mage.cards.e.EnduringRenewal.class)); + cards.add(new SetCardInfo("Energy Storm", 248, Rarity.RARE, mage.cards.e.EnergyStorm.class)); cards.add(new SetCardInfo("Enervate", 67, Rarity.COMMON, mage.cards.e.Enervate.class)); cards.add(new SetCardInfo("Errantry", 183, Rarity.COMMON, mage.cards.e.Errantry.class)); cards.add(new SetCardInfo("Fanatical Fever", 122, Rarity.UNCOMMON, mage.cards.f.FanaticalFever.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index dafcebca4f..88ddf68df4 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -114,6 +114,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Elvish Hunter", 157, Rarity.COMMON, ElvishHunter.class)); cards.add(new SetCardInfo("Elvish Ranger", 158, Rarity.COMMON, mage.cards.e.ElvishRanger.class)); cards.add(new SetCardInfo("Elvish Spirit Guide", 159, Rarity.UNCOMMON, mage.cards.e.ElvishSpiritGuide.class)); + cards.add(new SetCardInfo("Energy Storm", 11, Rarity.RARE, mage.cards.e.EnergyStorm.class)); cards.add(new SetCardInfo("Enervate", 47, Rarity.COMMON, mage.cards.e.Enervate.class)); cards.add(new SetCardInfo("Errantry", 124, Rarity.COMMON, mage.cards.e.Errantry.class)); cards.add(new SetCardInfo("Farrel's Mantle", 13, Rarity.UNCOMMON, mage.cards.f.FarrelsMantle.class)); diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 05a02cc488..462f267201 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -64,6 +64,7 @@ public final class StaticFilters { public static final FilterSpell FILTER_SPELL = new FilterSpell(); public static final FilterSpell FILTER_INSTANT_OR_SORCERY_SPELL = new FilterSpell("instant or sorcery spell"); + public static final FilterSpell FILTER_INSTANT_OR_SORCERY_SPELLS = new FilterSpell("instant or sorcery spells"); public static final FilterPermanent FILTER_CREATURE_TOKENS = new FilterCreaturePermanent("creature tokens"); @@ -125,6 +126,11 @@ public final class StaticFilters { new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY) )); + + FILTER_INSTANT_OR_SORCERY_SPELLS.add(Predicates.or( + new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY) + )); } } From 96bd19f1ba9e6d06860447fbb469c6814904c76a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 21:26:19 -0400 Subject: [PATCH 034/182] Implemented An-Zerrin Ruins --- Mage.Sets/src/mage/cards/a/AnZerrinRuins.java | 110 ++++++++++++++++++ Mage.Sets/src/mage/sets/Homelands.java | 2 + Mage.Sets/src/mage/sets/MastersEditionII.java | 1 + 3 files changed, 113 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AnZerrinRuins.java diff --git a/Mage.Sets/src/mage/cards/a/AnZerrinRuins.java b/Mage.Sets/src/mage/cards/a/AnZerrinRuins.java new file mode 100644 index 0000000000..b7a26eccdc --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AnZerrinRuins.java @@ -0,0 +1,110 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; +import mage.abilities.effects.common.DontUntapInControllersUntapStepAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class AnZerrinRuins extends CardImpl { + + public AnZerrinRuins(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{R}"); + + // As An-Zerrin Ruins enters the battlefield, choose a creature type. + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.UnboostCreature))); + + // Creatures of the chosen type don't untap during their controllers' untap steps. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AnZerrinRuinsDontUntapEffect())); + } + + public AnZerrinRuins(final AnZerrinRuins card) { + super(card); + } + + @Override + public AnZerrinRuins copy() { + return new AnZerrinRuins(this); + } +} + +class AnZerrinRuinsDontUntapEffect extends DontUntapInControllersUntapStepAllEffect { + + public AnZerrinRuinsDontUntapEffect() { + super(Duration.WhileOnBattlefield, TargetController.ANY, new FilterCreaturePermanent()); + } + + public AnZerrinRuinsDontUntapEffect(final AnZerrinRuinsDontUntapEffect effect) { + super(effect); + } + + @Override + public AnZerrinRuinsDontUntapEffect copy() { + return new AnZerrinRuinsDontUntapEffect(this); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (super.applies(event, source, game)) { + Permanent sourcePerm = game.getPermanent(source.getSourceId()); + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent != null && sourcePerm != null) { + SubType subtype = (SubType) game.getState().getValue(sourcePerm.getId() + "_type"); + if (permanent.getSubtype(game).contains(subtype)) { + return true; + } + } + } + return false; + } + + @Override + public String getText(Mode mode) { + return "Creatures of the chosen type don't untap during their controllers' untap steps."; + } +} diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java index 26330b1180..6b41c9983f 100644 --- a/Mage.Sets/src/mage/sets/Homelands.java +++ b/Mage.Sets/src/mage/sets/Homelands.java @@ -73,6 +73,7 @@ public class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Ambush", 78, Rarity.COMMON, mage.cards.a.Ambush.class)); cards.add(new SetCardInfo("Ambush Party", 79, Rarity.COMMON, mage.cards.a.AmbushParty.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ambush Party", 80, Rarity.COMMON, mage.cards.a.AmbushParty.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("An-Zerrin Ruins", 87, Rarity.RARE, mage.cards.a.AnZerrinRuins.class)); cards.add(new SetCardInfo("Anaba Ancestor", 81, Rarity.RARE, mage.cards.a.AnabaAncestor.class)); cards.add(new SetCardInfo("Anaba Bodyguard", 82, Rarity.COMMON, mage.cards.a.AnabaBodyguard.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Anaba Bodyguard", 83, Rarity.COMMON, mage.cards.a.AnabaBodyguard.class, NON_FULL_USE_VARIOUS)); @@ -82,6 +83,7 @@ public class Homelands extends ExpansionSet { cards.add(new SetCardInfo("An-Havva Constable", 51, Rarity.RARE, mage.cards.a.AnHavvaConstable.class)); cards.add(new SetCardInfo("An-Havva Inn", 52, Rarity.UNCOMMON, mage.cards.a.AnHavvaInn.class)); cards.add(new SetCardInfo("An-Havva Township", 136, Rarity.UNCOMMON, mage.cards.a.AnHavvaTownship.class)); + cards.add(new SetCardInfo("An-Zerrin Ruins", 87, Rarity.RARE, mage.cards.a.AnZerrinRuins.class)); cards.add(new SetCardInfo("Aysen Abbey", 137, Rarity.UNCOMMON, mage.cards.a.AysenAbbey.class)); cards.add(new SetCardInfo("Aysen Bureaucrats", 104, Rarity.COMMON, mage.cards.a.AysenBureaucrats.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Aysen Bureaucrats", 105, Rarity.COMMON, mage.cards.a.AysenBureaucrats.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index 88ddf68df4..43b4d13976 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -69,6 +69,7 @@ public class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Adarkar Sentinel", 201, Rarity.COMMON, mage.cards.a.AdarkarSentinel.class)); cards.add(new SetCardInfo("Aeolipile", 202, Rarity.COMMON, mage.cards.a.Aeolipile.class)); cards.add(new SetCardInfo("Ambush Party", 115, Rarity.COMMON, mage.cards.a.AmbushParty.class)); + cards.add(new SetCardInfo("An-Zerrin Ruins", 117, Rarity.RARE, mage.cards.a.AnZerrinRuins.class)); cards.add(new SetCardInfo("Anarchy", 116, Rarity.RARE, mage.cards.a.Anarchy.class)); cards.add(new SetCardInfo("Angel of Fury", 2, Rarity.RARE, mage.cards.a.AngelOfFury.class)); cards.add(new SetCardInfo("Angel of Light", 3, Rarity.UNCOMMON, mage.cards.a.AngelOfLight.class)); From 0d43fcf7294e5bff992e79a52a93c445746d5708 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 21:57:13 -0400 Subject: [PATCH 035/182] Implemented Repeating Barrage --- .../src/mage/cards/r/RepeatingBarrage.java | 75 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + Utils/mtg-cards-data.txt | 1 + 3 files changed, 77 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RepeatingBarrage.java diff --git a/Mage.Sets/src/mage/cards/r/RepeatingBarrage.java b/Mage.Sets/src/mage/cards/r/RepeatingBarrage.java new file mode 100644 index 0000000000..315b5a02c3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RepeatingBarrage.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.target.common.TargetCreatureOrPlayer; +import mage.watchers.common.PlayerAttackedWatcher; + +/** + * + * @author TheElk801 + */ +public class RepeatingBarrage extends CardImpl { + + public RepeatingBarrage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}{R}"); + + // Repeating Barrage deals 3 damage to target creature or player. + this.getSpellAbility().addEffect(new DamageTargetEffect(3)); + this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); + + // Raid — {3}{R}{R}: Return Repeating Barrage from your graveyard to your hand. Activate this ability only if you attacked with a creature this turn. + Ability ability = new ConditionalActivatedAbility(Zone.GRAVEYARD, + new ReturnSourceFromGraveyardToHandEffect(), + new ManaCostsImpl("{3}{R}{R}"), + RaidCondition.instance); + ability.setAbilityWord(AbilityWord.RAID); + this.addAbility(ability, new PlayerAttackedWatcher()); + } + + public RepeatingBarrage(final RepeatingBarrage card) { + super(card); + } + + @Override + public RepeatingBarrage copy() { + return new RepeatingBarrage(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 6cdf8a3b5d..a579435115 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -157,6 +157,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Raptor Hatchling", 155, Rarity.UNCOMMON, mage.cards.r.RaptorHatchling.class)); cards.add(new SetCardInfo("Ravenous Daggertooth", 202, Rarity.COMMON, mage.cards.r.RavenousDaggertooth.class)); cards.add(new SetCardInfo("Regisaur Alpha", 227, Rarity.RARE, mage.cards.r.RegisaurAlpha.class)); + cards.add(new SetCardInfo("Repeating Barrage", 156, Rarity.RARE, mage.cards.r.RepeatingBarrage.class)); cards.add(new SetCardInfo("Revel in Riches", 117, Rarity.RARE, mage.cards.r.RevelInRiches.class)); cards.add(new SetCardInfo("Rigging Runner", 157, Rarity.UNCOMMON, mage.cards.r.RiggingRunner.class)); cards.add(new SetCardInfo("Rile", 158, Rarity.COMMON, mage.cards.r.Rile.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index d59d306d67..973b339b5a 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32416,6 +32416,7 @@ Makeshift Munitions|Ixalan|151|U|{1}{R}|Enchantment|||{1}, Sacrifice an artifact Otepec Huntmaster|Ixalan|153|U|{1}{R}|Creature - Human Shaman|1|2|Dinosaur spells you cast cost {1} less to cast.${T}: Target Dinosaur gains haste until end of turn.| Rampaging Ferocidon|Ixalan|154|R|{2}{R}|Creature - Dinosaur|3|3|Menace$Players can't gain life.$Whenever another creature enters the battlefield, Rampaging Ferocidon deals 1 damage to that creature's controller.| Raptor Hatchling|Ixalan|155|U|{1}{R}|Creature - Dinosaur|1|1|Enrage - Whenever Raptor Hatchling is dealt damage, create a 3/3 green Dinosaur creature token with trample.| +Repeating Barrage|Ixalan|156|R|{1}{R}{R}|Sorcery|||Repeating Barrage deals 3 damage to target creature or player.$Raid — {3}{R}{R}: Return Repeating Barrage from your graveyard to your hand. Activate this ability only if you attacked with a creature this turn.| Rigging Runner|Ixalan|157|U|{R}|Creature - Goblin Pirate|1|1|First strike$Raid/ — Rigging runner enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.|Rile|Ixalan|158|C|{R}|Sorcery|||Rile deals 1 damage to target creature you control. That creature gains trample until end of turn.$Draw a card.| Rowdy Crew|Ixalan|159|M|{2}{R}{R}|Creature - Human Pirate|3|3|Trample$When Rowdy Crew enters the battlefield, draw three cards, then discard two cards at random. If two cards that share a card type are discarded this way, put two +1/+1 counters on Rowdy Crew.| Star of Extinction|Ixalan|161|M|{5}{R}{R}|Sorcery|||Destroy target land. Star of Extinction deals 20 damage to each creature and each planeswalker.| From c9f03612d9fe57ded4b14e65f5d3e3db9bf3b130 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 22:08:15 -0400 Subject: [PATCH 036/182] Implemented Mind Harness --- Mage.Sets/src/mage/cards/m/MindHarness.java | 89 +++++++++++++++++++++ Mage.Sets/src/mage/sets/Mirage.java | 1 + 2 files changed, 90 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MindHarness.java diff --git a/Mage.Sets/src/mage/cards/m/MindHarness.java b/Mage.Sets/src/mage/cards/m/MindHarness.java new file mode 100644 index 0000000000..a0ef54b12a --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MindHarness.java @@ -0,0 +1,89 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import java.util.UUID; +import mage.ObjectColor; +import mage.constants.SubType; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.ControlEnchantedEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author TheElk801 + */ +public class MindHarness extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("red or green creature"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.RED), new ColorPredicate(ObjectColor.GREEN))); + } + + public MindHarness(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant red or green creature + TargetPermanent auraTarget = new TargetPermanent(filter); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Cumulative upkeep {1} + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}"))); + + // You control enchanted creature. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); + } + + public MindHarness(final MindHarness card) { + super(card); + } + + @Override + public MindHarness copy() { + return new MindHarness(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Mirage.java b/Mage.Sets/src/mage/sets/Mirage.java index 2bd04a2dd4..1106b3b3f1 100644 --- a/Mage.Sets/src/mage/sets/Mirage.java +++ b/Mage.Sets/src/mage/sets/Mirage.java @@ -194,6 +194,7 @@ public class Mirage extends ExpansionSet { cards.add(new SetCardInfo("Memory Lapse", 74, Rarity.COMMON, mage.cards.m.MemoryLapse.class)); cards.add(new SetCardInfo("Merfolk Raiders", 75, Rarity.COMMON, mage.cards.m.MerfolkRaiders.class)); cards.add(new SetCardInfo("Merfolk Seer", 76, Rarity.COMMON, mage.cards.m.MerfolkSeer.class)); + cards.add(new SetCardInfo("Mind Harness", 78, Rarity.UNCOMMON, mage.cards.m.MindHarness.class)); cards.add(new SetCardInfo("Mist Dragon", 79, Rarity.RARE, mage.cards.m.MistDragon.class)); cards.add(new SetCardInfo("Moss Diamond", 277, Rarity.UNCOMMON, mage.cards.m.MossDiamond.class)); cards.add(new SetCardInfo("Mountain", 301, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); From 94b7c07b33a3cd606da49b86d6d9820222a86dca Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 22:11:45 -0400 Subject: [PATCH 037/182] Implemented Inner Sanctum --- Mage.Sets/src/mage/cards/i/InnerSanctum.java | 68 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Weatherlight.java | 1 + 2 files changed, 69 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/InnerSanctum.java diff --git a/Mage.Sets/src/mage/cards/i/InnerSanctum.java b/Mage.Sets/src/mage/cards/i/InnerSanctum.java new file mode 100644 index 0000000000..4f9c90ffa6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InnerSanctum.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.effects.common.PreventAllDamageToAllEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreatureInPlay; + +/** + * + * @author TheElk801 + */ +public class InnerSanctum extends CardImpl { + + public InnerSanctum(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{W}"); + + // Cumulative upkeep-Pay 2 life. + this.addAbility(new CumulativeUpkeepAbility(new PayLifeCost(2))); + + // Prevent all damage that would be dealt to creatures you control. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, new FilterControlledCreatureInPlay("creatures you control")) + )); + } + + public InnerSanctum(final InnerSanctum card) { + super(card); + } + + @Override + public InnerSanctum copy() { + return new InnerSanctum(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Weatherlight.java b/Mage.Sets/src/mage/sets/Weatherlight.java index 1db6ab52f3..b3a5344f6a 100644 --- a/Mage.Sets/src/mage/sets/Weatherlight.java +++ b/Mage.Sets/src/mage/sets/Weatherlight.java @@ -125,6 +125,7 @@ public class Weatherlight extends ExpansionSet { cards.add(new SetCardInfo("Hidden Horror", 14, Rarity.UNCOMMON, mage.cards.h.HiddenHorror.class)); cards.add(new SetCardInfo("Hurloon Shaman", 108, Rarity.UNCOMMON, mage.cards.h.HurloonShaman.class)); cards.add(new SetCardInfo("Infernal Tribute", 15, Rarity.RARE, mage.cards.i.InfernalTribute.class)); + cards.add(new SetCardInfo("Inner Sanctum", 134, Rarity.RARE, mage.cards.i.InnerSanctum.class)); cards.add(new SetCardInfo("Jabari's Banner", 150, Rarity.UNCOMMON, mage.cards.j.JabarisBanner.class)); cards.add(new SetCardInfo("Lava Hounds", 109, Rarity.UNCOMMON, mage.cards.l.LavaHounds.class)); cards.add(new SetCardInfo("Llanowar Behemoth", 74, Rarity.UNCOMMON, mage.cards.l.LlanowarBehemoth.class)); From c611d71f30e8cc68b9653d3c27b999f6923943c8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 22:23:01 -0400 Subject: [PATCH 038/182] Implemented Spiritual Asylum --- .../src/mage/cards/s/SpiritualAsylum.java | 70 +++++++++++++++++++ Mage.Sets/src/mage/sets/Nemesis.java | 1 + ...cksCreatureYouControlTriggeredAbility.java | 8 ++- 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/s/SpiritualAsylum.java diff --git a/Mage.Sets/src/mage/cards/s/SpiritualAsylum.java b/Mage.Sets/src/mage/cards/s/SpiritualAsylum.java new file mode 100644 index 0000000000..ade45e5deb --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpiritualAsylum.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.ShroudAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class SpiritualAsylum extends CardImpl { + + public SpiritualAsylum(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); + + // Creatures and lands you control have shroud. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(ShroudAbility.getInstance(), + Duration.WhileOnBattlefield, new FilterCreaturePermanent()))); + + // When a creature you control attacks, sacrifice Spiritual Asylum. + AttacksCreatureYouControlTriggeredAbility ability = new AttacksCreatureYouControlTriggeredAbility(new SacrificeSourceEffect()); + ability.setOnce(true); + this.addAbility(ability); + } + + public SpiritualAsylum(final SpiritualAsylum card) { + super(card); + } + + @Override + public SpiritualAsylum copy() { + return new SpiritualAsylum(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Nemesis.java b/Mage.Sets/src/mage/sets/Nemesis.java index 34e3d6e696..9d737ef767 100644 --- a/Mage.Sets/src/mage/sets/Nemesis.java +++ b/Mage.Sets/src/mage/sets/Nemesis.java @@ -152,6 +152,7 @@ public class Nemesis extends ExpansionSet { cards.add(new SetCardInfo("Skyshroud Ridgeback", 120, Rarity.COMMON, mage.cards.s.SkyshroudRidgeback.class)); cards.add(new SetCardInfo("Sneaky Homunculus", 44, Rarity.COMMON, mage.cards.s.SneakyHomunculus.class)); cards.add(new SetCardInfo("Spineless Thug", 71, Rarity.COMMON, mage.cards.s.SpinelessThug.class)); + cards.add(new SetCardInfo("Spiritual Asylum", 23, Rarity.RARE, mage.cards.s.SpiritualAsylum.class)); cards.add(new SetCardInfo("Stampede Driver", 122, Rarity.UNCOMMON, mage.cards.s.StampedeDriver.class)); cards.add(new SetCardInfo("Stronghold Discipline", 73, Rarity.COMMON, mage.cards.s.StrongholdDiscipline.class)); cards.add(new SetCardInfo("Stronghold Gambit", 100, Rarity.RARE, mage.cards.s.StrongholdGambit.class)); diff --git a/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java index 1649cc3ab5..9ec48797fd 100644 --- a/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java @@ -44,6 +44,7 @@ public class AttacksCreatureYouControlTriggeredAbility extends TriggeredAbilityI protected FilterControlledCreaturePermanent filter; protected boolean setTargetPointer; + protected boolean once = false; public AttacksCreatureYouControlTriggeredAbility(Effect effect) { this(effect, false); @@ -73,6 +74,10 @@ public class AttacksCreatureYouControlTriggeredAbility extends TriggeredAbilityI this.setTargetPointer = ability.setTargetPointer; } + public void setOnce(boolean once) { + this.once = once; + } + @Override public boolean checkEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ATTACKER_DECLARED; @@ -97,7 +102,6 @@ public class AttacksCreatureYouControlTriggeredAbility extends TriggeredAbilityI @Override public String getRule() { - return "Whenever a" + (filter.getMessage().startsWith("a") ? "n " : " ") + " attacks, " + super.getRule(); + return "When" + (once ? "" : "ever") + " a" + (filter.getMessage().startsWith("a") ? "n " : " ") + " attacks, " + super.getRule(); } - } From 4b4214ba0f79c641f5a9c986fa9e4e334184a557 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 14 Sep 2017 22:29:33 -0400 Subject: [PATCH 039/182] Implemented Spiritual Asylum --- .../src/mage/cards/s/SpiritualAsylum.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SpiritualAsylum.java b/Mage.Sets/src/mage/cards/s/SpiritualAsylum.java index ade45e5deb..927439e493 100644 --- a/Mage.Sets/src/mage/cards/s/SpiritualAsylum.java +++ b/Mage.Sets/src/mage/cards/s/SpiritualAsylum.java @@ -37,8 +37,12 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.TargetController; import mage.constants.Zone; -import mage.filter.common.FilterCreaturePermanent; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; /** * @@ -46,12 +50,22 @@ import mage.filter.common.FilterCreaturePermanent; */ public class SpiritualAsylum extends CardImpl { + private static final FilterPermanent filter = new FilterPermanent("Creatures and lands you control"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.CREATURE), + new CardTypePredicate(CardType.LAND) + )); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + public SpiritualAsylum(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); // Creatures and lands you control have shroud. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(ShroudAbility.getInstance(), - Duration.WhileOnBattlefield, new FilterCreaturePermanent()))); + Duration.WhileOnBattlefield, filter))); // When a creature you control attacks, sacrifice Spiritual Asylum. AttacksCreatureYouControlTriggeredAbility ability = new AttacksCreatureYouControlTriggeredAbility(new SacrificeSourceEffect()); From 5996aa12e6f4de0abe595a9d99a3fb76ced9dc61 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 15 Sep 2017 17:51:54 +0200 Subject: [PATCH 040/182] Trove of Temptation working for Human. --- .../player/ai/ma/ArtificialScoringSystem.java | 7 +++-- .../java/mage/player/ai/CombatEvaluator.java | 27 +++++++++---------- .../java/mage/player/ai/ComputerPlayer.java | 2 +- .../src/mage/player/human/HumanPlayer.java | 4 +-- .../src/mage/cards/i/IllicitAuction.java | 11 ++++---- Mage.Sets/src/mage/sets/Ixalan.java | 1 + .../java/mage/game/permanent/Permanent.java | 21 ++++++++++----- .../mage/game/permanent/PermanentImpl.java | 10 +++---- 8 files changed, 45 insertions(+), 38 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/ArtificialScoringSystem.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/ArtificialScoringSystem.java index d322ec6c3b..379dadee6a 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/ArtificialScoringSystem.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/ArtificialScoringSystem.java @@ -1,18 +1,17 @@ package mage.player.ai.ma; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.Effect; import mage.abilities.keyword.HasteAbility; import mage.cards.Card; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; -import java.util.UUID; -import mage.constants.SubType; - /** * @author ubeefx, nantuko */ @@ -104,7 +103,7 @@ public final class ArtificialScoringSystem { } score += equipments * 50 + enchantments * 100; - if (!permanent.canAttack(game)) { + if (!permanent.canAttack(null, game)) { score -= 100; } diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/CombatEvaluator.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/CombatEvaluator.java index 12032f470b..62b13acd84 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/CombatEvaluator.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/CombatEvaluator.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,24 +20,22 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.player.ai; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.TrampleAbility; import mage.game.Game; import mage.game.permanent.Permanent; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - /** * * @author BetaSteward_at_googlemail.com @@ -50,15 +48,16 @@ public class CombatEvaluator { public int evaluate(Permanent creature, Game game) { if (!values.containsKey(creature.getId())) { int value = 0; - if (creature.canAttack(game)) + if (creature.canAttack(null, game)) { value += 2; + } value += creature.getPower().getValue(); value += creature.getToughness().getValue(); value += creature.getAbilities().getEvasionAbilities().size(); value += creature.getAbilities().getProtectionAbilities().size(); - value += creature.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId())?1:0; - value += creature.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId())?2:0; - value += creature.getAbilities().containsKey(TrampleAbility.getInstance().getId())?1:0; + value += creature.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId()) ? 1 : 0; + value += creature.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId()) ? 2 : 0; + value += creature.getAbilities().containsKey(TrampleAbility.getInstance().getId()) ? 1 : 0; values.put(creature.getId(), value); } return values.get(creature.getId()); diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java index 005158b651..84253863c6 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java @@ -1939,7 +1939,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { protected int combatPotential(Permanent creature, Game game) { log.debug("combatPotential"); - if (!creature.canAttack(game)) { + if (!creature.canAttack(null, game)) { return 0; } int potential = creature.getPower().getValue(); diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index 762c5408e7..751e1739d2 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -1073,7 +1073,7 @@ public class HumanPlayer extends PlayerImpl { List possibleAttackers = new ArrayList<>(); for (Permanent possibleAttacker : game.getBattlefield().getActivePermanents(filter, attackingPlayerId, game)) { - if (possibleAttacker.canAttack(game)) { + if (possibleAttacker.canAttack(null, game)) { possibleAttackers.add(possibleAttacker.getId()); } } @@ -1207,7 +1207,7 @@ public class HumanPlayer extends PlayerImpl { // already attacks other player taht has to be attacked continue; } - if (defendingPlayerId != null || attacker.canAttack(forcedToAttackId, game)) { + if (defendingPlayerId != null || attacker.canAttackInPrinciple(forcedToAttackId, game)) { game.informPlayer(this, "You are forced to attack " + forcedToAttack.getName() + " or a controlled planeswalker e.g. with " + attacker.getIdName() + "."); return false; } diff --git a/Mage.Sets/src/mage/cards/i/IllicitAuction.java b/Mage.Sets/src/mage/cards/i/IllicitAuction.java index 32b4742e69..bb87c8d63c 100644 --- a/Mage.Sets/src/mage/cards/i/IllicitAuction.java +++ b/Mage.Sets/src/mage/cards/i/IllicitAuction.java @@ -137,18 +137,19 @@ class CreatureEvaluator { public int evaluate(Permanent creature, Game game) { if (!values.containsKey(creature.getId())) { int value = 0; - if (creature.canAttack(game)) + if (creature.canAttack(null, game)) { value += 2; + } value += creature.getPower().getValue(); value += creature.getToughness().getValue(); value += creature.getAbilities().getEvasionAbilities().size(); value += creature.getAbilities().getProtectionAbilities().size(); - value += creature.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId())?1:0; - value += creature.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId())?2:0; - value += creature.getAbilities().containsKey(TrampleAbility.getInstance().getId())?1:0; + value += creature.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId()) ? 1 : 0; + value += creature.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId()) ? 2 : 0; + value += creature.getAbilities().containsKey(TrampleAbility.getInstance().getId()) ? 1 : 0; values.put(creature.getId(), value); } return values.get(creature.getId()); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index a579435115..67d0c43832 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -213,6 +213,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Tocatli Honor Guard", 42, Rarity.RARE, mage.cards.t.TocatliHonorGuard.class)); cards.add(new SetCardInfo("Treasure Cove", 1250, Rarity.RARE, mage.cards.t.TreasureCove.class)); cards.add(new SetCardInfo("Treasure Map", 250, Rarity.RARE, mage.cards.t.TreasureMap.class)); + cards.add(new SetCardInfo("Trove of Temptation", 171, Rarity.UNCOMMON, mage.cards.t.TroveOfTemptation.class)); cards.add(new SetCardInfo("Unclaimed Territory", 258, Rarity.UNCOMMON, mage.cards.u.UnclaimedTerritory.class)); cards.add(new SetCardInfo("Unfriendly Fire", 172, Rarity.COMMON, mage.cards.u.UnfriendlyFire.class)); cards.add(new SetCardInfo("Vance's Blasting Cannons", 173, Rarity.RARE, mage.cards.v.VancesBlastingCannons.class)); diff --git a/Mage/src/main/java/mage/game/permanent/Permanent.java b/Mage/src/main/java/mage/game/permanent/Permanent.java index c7d0a4c1d2..68efe807b6 100644 --- a/Mage/src/main/java/mage/game/permanent/Permanent.java +++ b/Mage/src/main/java/mage/game/permanent/Permanent.java @@ -27,6 +27,9 @@ */ package mage.game.permanent; +import java.util.List; +import java.util.Set; +import java.util.UUID; import mage.MageObject; import mage.MageObjectReference; import mage.abilities.Ability; @@ -37,10 +40,6 @@ import mage.game.Controllable; import mage.game.Game; import mage.game.GameState; -import java.util.List; -import java.util.Set; -import java.util.UUID; - public interface Permanent extends Card, Controllable { void setControllerId(UUID controllerId); @@ -223,16 +222,24 @@ public interface Permanent extends Card, Controllable { */ void setMaxBlockedBy(int maxBlockedBy); - boolean canAttack(Game game); - /** * - * @param defenderId id of planeswalker or player to attack + * @param defenderId id of planeswalker or player to attack - can be empty + * to check generally * @param game * @return */ boolean canAttack(UUID defenderId, Game game); + /** + * Checks if a creature can attack (also if it is tapped) + * + * @param defenderId + * @param game + * @return + */ + boolean canAttackInPrinciple(UUID defenderId, Game game); + boolean canBlock(UUID attackerId, Game game); boolean canBlockAny(Game game); diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index b0afa82a08..56dd77e916 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java @@ -1029,16 +1029,16 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { return game.replaceEvent(GameEvent.getEvent(eventType, this.objectId, ownerId));// controllerId seems to me more logical (LevelX2) } - @Override - public boolean canAttack(Game game) { - return canAttack(null, game); - } - @Override public boolean canAttack(UUID defenderId, Game game) { if (tapped) { return false; } + return canAttackInPrinciple(defenderId, game); + } + + @Override + public boolean canAttackInPrinciple(UUID defenderId, Game game) { if (hasSummoningSickness() && !game.getContinuousEffects().asThough(this.objectId, AsThoughEffectType.ATTACK_AS_HASTE, this.getControllerId(), game)) { return false; } From 98b5da0ec67e9fe44121e650aa029673504f16e0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 12:41:51 -0400 Subject: [PATCH 041/182] added full XLN spoiler --- Utils/mtg-cards-data.txt | 115 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 107 insertions(+), 8 deletions(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 973b339b5a..402456aa1e 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32333,96 +32333,171 @@ Ashes of the Abhorrent|Ixalan|2|R|{1}{W}|Enchantment|||Players can't cast spells Axis of Mortality|Ixalan|3|M|{4}{W}{W}|Enchantment|||At the beginning of your upkeep, you may have two target players exchange life totals.| Bellowing Aegisaur|Ixalan|4|U|{5}{W}|Creature - Dinosaur|3|5|Enrage - Whenever Bellowing Aegisaur is dealt damage, put a +1/+1 counter on each other creature you control.| Bishop of Rebirth|Ixalan|5|R|Creature - Vampire Cleric|3|4|Vigilance$Whenever Bishop of Rebirth attacks, you may return target creature card with converted mana cost 3 or less from your graveyard to the battlefield.| +Bishop's Soldier|Ixalan|6|C|{1}{W}|Creature - Vampire Soldier|2|2|Lifelink| +Bright Reprisal|Ixalan|7|U|{4}{W}|Instant|||Destroy target attacking creature.$Draw a card.| +Demystify|Ixalan|8|C|{W}|Instant|||Destroy target enchantment.| Duskborne Skymarcher|Ixalan|9|U|{W}|Creature - Vampire Cleric|1|1|Flying${W}, {T}: Target attacking vampire gets +1/+1 until end of turn.| Emissary of Sunrise|Ixalan|10|U|{2}{W}|Creature - Human Cleric|2|1|First strike$When Emissary of Sunrise enters the battlefield, it explores. (Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on this creature, then put the card back or put it into your graveyard.)| +Encampment Keeper|Ixalan|11|C|{W}|Creature - Hound|1|1|First strike${7}{W}, Sacrifice Encampment Keeper: Creatures you control get +2/+2 until end of turn.| +Glorifier of Dusk|Ixalan|12|U|{3}{W}{W}|Creature - Vampire Soldier|4|4|Pay 2 life: Glorifier of Dusk gains flying until end of turn.$Pay 2 life: Glorifier of Dusk gains vigilance until end of turn.| Goring Ceratops|Ixalan|13|R|Creature - Dinosaur|3|3|Double strike$Whenever Goring Ceratops attacks, other creatures you control gain double strike until end of turn.| +Imperial Aerosaur|Ixalan|14|U|{3}{W}|Creature - Dinosaur|3|3|Flying$When Imperial Aerosaur enters the battlefield, another target creature you control gets +1/+1 and gains flying until end of turn.| Imperial Lancer|Ixalan|15|U|{W}|Creature - Human Knight|1|1|Imperial Lancer has double strike as long as you control a Dinosaur.| +Inspiring Cleric|Ixalan|16|U|{2}{W}|Creature - Vampire Cleric|3|2|When Inspiring Cleric enters the battlefield, you gain 4 life.| Ixalan's Binding|Ixalan|17|U|{3}{W}|Enchantment|||When Ixalan's Binding enters the battlefield, exile target nonland permanent an opponent controls until Ixalan's Binding leaves the battlefield.$Your opponents can't cast spells with the same name as the exiled card.| Kinjalli's Caller|Ixalan|18|C|{W}|Creature - Human Cleric|0|3|Dinosaur spells you cast cost {1} less to cast.| Kinjalli's Sunwing|Ixalan|19|R|{2}{W}|Creature - Dinosaur|2|3|Flying$Creatures your opponents control enter the battlefield tapped.| Legion Conquistador|Ixalan|20|C|{2}{W}|Creature - Vampire Soldier|2|2|When Legion Conquistador enters the battlefield, you may search your library for any number of cards named Legion Conquistador, reveal them, put them into your hand, then shuffle your library| +Legion's Judgment|Ixalan|21|C|{2}{W}|Sorcery|||Destroy target creature with power 4 or greater.| Legion's Landing|Ixalan|22a|R|{W}|Legendary Enchantment|||When Legion's Landing enters the battlefield, create a 1/1 white Vampire creature token with lifelink.$When you attack with three or more creatures, transform Legion's Landing.| Adanto, the First Fort|Ixalan|22b|R||Legendary Land|||T: Add W to your mana pool.$2W, T: Create a 1/1 white Vampire creature token with lifelink.| +Looming Altisaur|Ixalan|23|C|{3}{W}|Creature - Dinosaur|1|7|| Mavren Fein, Dusk Apostle|Ixalan|24|R|{2}{W}|Legendary Creature - Vampire Cleric|2|2|Whenever one or more nontoken Vampires you control attack, create a 1/1 white Vampire creature token with lifelink.| +Paladin of the Bloodstained|Ixalan|25|C|{3}{W}|Creature - Vampire Knight|3|2|When Paladin of the Bloodstained enters the battlefield, create a 1/1 white Vampire creature token with lifelink.| +Pious Interdiction|Ixalan|26|C|{3}{W}|Enchantment - Aura|||Enchant creature$When Pious Interdiction enters the battlefield, you gain 2 life.$Enchanted creature can't attack or block.| Priest of the Wakening Sun|Ixalan|27|R|{W}|Creature - Human Cleric|1|1|At the beginning of your upkeep, you may reveal a Dinosaur card from your hand. If you do, you gain 2 life.${3}{W}{W}, Sacrifice Priest of the Wakening Sun: Search your library for a Dinosaur card, reveal it, put it into your hand, then shuffle your library.| +Pterodon Knight|Ixalan|28|C|{3}{W}|Creature - Human Knight|3|3|Pterodon Knight has flying as long as you control a Dinosaur.| +Queen's Commission|Ixalan|29|C|{2}{W}|Sorcery|||Create two 1/1 white Vampire creature tokens with lifelink.| +Rallying Roar|Ixalan|30|U|{2}{W}|Instant|||Creatures you control get +1/+1 until end of turn. Untap them.| +Raptor Companion|Ixalan|31|C|{1}{W}|Creature - Dinosaur|3|1|| +Ritual of Rejuvenation|Ixalan|32|C|{2}{W}|Instant|||You gain 4 life.$Draw a card.| Sanguine Sacrament|Ixalan|33|R|{X}{W}{W}|Instant|||You gain twice X life. Put Sanguine Sacrament on the bottom of its owner's library.| Settle the Wreckage|Ixalan|34|R|{2}{W}{W}|Instant|||Exile all attacking creatures target player controls. That player may search his or her library for that many basic land cards, put those cards onto the battlefield tapped, then shuffle his or her library.| +Sheltering Light|Ixalan|35|U|{W}|Instant|||Target creature gains indestructible until end of turn. Scry 1. | +Shining Aerosaur|Ixalan|36|C|{4}{W}|Creature - Dinosaur|3|4|Flying| +Skyblade of the Legion|Ixalan|37|C|{1}{W}|Creature - Vampire Soldier|1|3|Flying| +Slash of Talons|Ixalan|38|C|{W}|Instant|||Slash of Talons deals 2 damage to target attacking or blocking creature.| +Steadfast Armasaur|Ixalan|39|U|{3}{W}|Creature - Dinosaur|2|3|Vigilance${1}{W}, {T}: Steadfast Armasaur deals damage equal to its toughness to target creature blocking or blocked by it.| +Sunrise Seeker|Ixalan|40|C|{4}{W}|Creature - Human Scout|3|3|Vigilance$When Sunrise Seeker enters the battlefield, it explores. | +Territorial Hammerskull|Ixalan|41|C|{2}{W}|Creature - Dinosaur|2|3|Whenever Territorial Hammerskull attacks, tap target creature an opponent controls.| Tocatli Honor Guard|Ixalan|42|R|{1}{W}|Creature - Human Soldier|1|3|Creatures entering the battlefield don't cause abilities to trigger.| +Vampire's Zeal|Ixalan|43|C|{W}|Instant|||Target creature gets +2/+2 until end of turn. If it's a Vampire, it gains first strike until end of turn.| Wakening Sun's Avatar|Ixalan|44|M|{5}{W}{W}{W}|Creature - Dinosaur Avatar|7|7|When Wakening Sun's Avatar enters the battlefield, if you cast if from you hand, destroy all non-Dinosaur creatures.| +Air Elemental|Ixalan|45|U|{3}{U}{U}|Creature - Elemental|4|4|Flying| Arcane Adaptation|Ixalan|46|R|{2}{U}|Enchantment|||As Arcane Adaptation enters the battlefield, choose a creature type.$Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield.| +Cancel|Ixalan|47|C|{1}{U}{U}|Instant|||Counter target spell.| Chart a Course|Ixalan|48|U|{1}{U}|Sorcery|||| Daring Saboteur|Ixalan|49|R|{1}{U}|Creature - Human Pirate|2|1|{2}{U}: Daring Saboteur can't be blocked this turn.$Whenever Daring Saboteur deals combat damage to a player, you may draw a card. If you do, discard a card.| Deadeye Quartermaster|Ixalan|50|U|{3}{U}|Creature - Human Pirate|2|2|When Deadeye Quartermaster enters the battlefield, you may search your library for an Equipment or a Vehicle card and put it into your hand. If you do, shuffle your library.| Deeproot Waters|Ixalan|51|U|{2}{U}|Enchantment|||Whenever you cast a Merfolk spell, create a 1/1 blue Merfolk creature token with hexproof.| +Depths of Desire|Ixalan|52|C|{2}{U}|Instant|||Return target creature to its owner's hand. Create a colorless Treasure token with "{t}, Sacrifice this artifact: Add one mana of any color to your mana pool."| +Dive Down|Ixalan|53|C|{U}|Instant|||Target creature you control gets +0/+3 until end of turn. | Dreamcaller Siren|Ixalan|54|R|{2}{U}{U}|Creature - Siren Pirate|3|3|Flash$Flying$Dreamcaller Siren can only block creatures with flying.$When Dreamcaller Siren enters the battlefield, if you control another Pirate, tap up to two nonland permanents.| Entrancing Melody|Ixalan|55|R|{X}{U}{U}|Instant|||Gain control of target creature with converted mana cost X.| Favorable Winds|Ixalan|56|U|{1}{U}|Enchantment|||Creatures you control with flying get +1/+1.| +Fleet Swallower|Ixalan|57|R|{5}{U}{U}|Creature - Fish|6|6|Whenever Fleet Swallower attacks, target player puts the top half of his or her library, rounded up, into his or her graveyard.| Headwater Sentries|Ixalan|58|C|{3}{U}|Creature - Merfolk Warrior|2|5|| Herald of Secret Streams|Ixalan|59|R|{3}{U}|Creature - Merfolk Warrior|2|3|Creatures you control with +1/+1 counters on them can't be blocked.| Jace, Cunning Castaway|Ixalan|60|M|{1}{U}{U}|Legendary Planeswalker - Jace|||+1: Whenever one or more creatures you control deal combat damage to a player this turn, draw a card, then discard a card.$-2: Create a 2/2 blue Illusion creature token with "When this creature becomes the target of a spell, sacrifice it."$-5: Create two tokens that are copies of Jace, Cunning Castaway, except they're not legendary.| Kopala, Warden of Waves|Ixalan|61|R|{1}{U}{U}|Legendary Creature - Merfolk Wizard|2|2|Spells your opponents cast that target a Merfolk you control cost {2} more to cast.$Abilities your opponents activate that target a Merfolk you control cost {2} more to activate.| Lookout's Dispersal|Ixalan|62|U|{2}{U}|Instant|||Lookout's Dispersal costs {1} less to cast if you control a Pirate.$Counter target spell unless its controller pays {4}.| -Overflowing Insight|Ixalan|64|M|{4}{U}{U}{U}|Sorcery|||Target player draws seven cards.| +Navigator's Ruin|Ixalan|63|U|{2}{U}|Enchantment|||Raid/-- At the beginning of your end step, if you attacked with a creature this turm, target opponent puts the top four cards of his or her library into his or her graveyard.| +One with the Wind|Ixalan|64|C|{1}{U}|Enchantment - Aura|||Enchant Creature$Enchanted creature gets +2/+2 and has flying.| Opt|Ixalan|65|C|{U}|Instant|||Scry 1.$Draw a card.| +Overflowing Insight|Ixalan|66|M|{4}{U}{U}{U}|Sorcery|||Target player draws seven cards.| Perilous Voyage|Ixalan|67|U|{1}{U}|Instant|||Return target nonland permanent you don't control to its owner's hand. If its converted mana cost was 2 or less, scry 2.| +Pirate's Prize|Ixalan|68|C|{3}{U}|Sorcery|||Draw two cards. Create a colorless Treasure artifact token with "{t}, Sacrifice this artifact: Add one mana of any color to your mana pool."| Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperous Pirates enters the battlefield, create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| River Sneak|Ixalan|70|U|{1}{U}|Creature - Merfolk Warrior|1|1|River Sneak can't be blocked.$Whenever another Merfolk enters the battlefield under your control, River sneak gets +1/+1 until end of turn.| River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| -Azcanta, The Sunken Ruin|Ixalan|74b|R||Legendary Land|||(Transforms from Search for Azcanta)/${t} : Add {U} to your mana pool.${2U} , {t} : Look at the top four cards of your library. You may reveal a noncreature, nonland card from among them and put it into your hand. Put the rest on the bottom of your library in any order. | +Run Aground|Ixalan|72|C|{3}{U}|Instant|||Put target artifact or creature on top of it's owner's library.| +Sailor of Means|Ixalan|73|C|{2}{U}|Creature - Human Pirate|1|4|When Sailor of Means enters the battlefield, create a colorless Treasure artifact token with "{t}, Sacrifice this artifact: Add one mana of any color to your mana pool."| Search for Azcanta|Ixalan|74a|R|{1}{U}|Legendary Enchantment|||| +Azcanta, The Sunken Ruin|Ixalan|74b|R||Legendary Land|||(Transforms from Search for Azcanta)/${t} : Add {U} to your mana pool.${2U} , {t} : Look at the top four cards of your library. You may reveal a noncreature, nonland card from among them and put it into your hand. Put the rest on the bottom of your library in any order. | +Shaper Apprentice|Ixalan|75|C|{1}{U}|Creature - Merfolk Wizard|2|1|Shaper Apprentice has flying as long as you control another Merfolk.| +Shipwreck Looter|Ixalan|76|C|{1}{U}|Creature - Human Pirate|2|1|Raid/-- When Shipwreck Looter enters the battlefield,if you attacked with a creature this turn, you may draw a card. If you do, discard a card.| +Shore Keeper|Ixalan|77|C|{U}|Creature - Trilobite|0|3|{7u}, {t}, Sacrifice Shore Keeper: Draw three cards.| +Siren Lookout|Ixalan|78|C|{2}{U}|Creature - Siren Pirate|1|2|Flying$When Siren Lookout enters the battlefield, it explores. | Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|1|1|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| +Siren's Ruse|Ixalan|80|C|{1}{U}|Instant|||Exile target creature you control, then return that card to the battlefield under its owner's control. If a Pirate was exiled this way, draw a card.| Spell Pierce|Ixalan|81|C|{U}|Instant|||Counter target noncreature spell unless its controller pays {2}.| Spell Swindle|Ixalan|82|R|{3}{U}{U}|Instant|||Counter target spell. Create X colorless Treasure artifact tokens, where X is that spell's converted mana cost. They have "T, Sacrifice this artifact: Add one mana of any color to your mana pool."| Storm Fleet Aerialist|Ixalan|83|U|{1}{U}|Creature - Human Pirate|1|2|Flying$Raid - Storm Fleet Aerialist enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.| Storm Fleet Spy|Ixalan|84|U|{2}{U}|Creature - Human Pirate|2|2|Raid - When Storm Fleet Spy enters the battlefield, if you attacked with a creature this turn, draw a card.| +Storm Sculptor|Ixalan|85|C|{3}{U}|Creature - Merfolk Wizard|3|2|Storm Sculptor can't be blocked.$When Storm Sculptor enters the battlefield, return a creature you control to its owner's hand.| +Tempest Caller|Ixalan|86|U|{2}{U}{U}|Creature - Merfolk Wizard|2|3|When Tempest Caller enters the battlefield, tap all creatures target opponent controls.| +Watertrap Weaver|Ixalan|87|C|{2}{U}|Creature - Merfolk Wizard|2|2|When Watertrap Weaver enters the battlefield, tap target creature an opponent controls. That creature doesn't untap during its controller's next untap step.| +Wind Strider|Ixalan|88|C|{4}{U}|Creature - Merfolk Wizard|3|3|Flash$Flying| +Anointed Deacon|Ixalan|89|C|{4}{B}|Creature - Vampire Cleric|3|3|At the beginning of combat on your turn, you may have target Vampire get +2/+0 until end of turn.| Arguel's Blood Fast|Ixalan|90a|R|{1}{B}|Legendary Enchantment|||{1}{B}, Pay 2 life: Draw a card.$At the beginning of your upkeep, if you have 5 or less life, you may transform Arguel's Blood Fast.| Temple of Aclazotz|Ixalan|90b|R||Legendary Land|||{T}: Add {B} to your mana pool${T}, Sacrifice a creature: You gain life equal to the sacrificed creature's toughness.| Bishop of the Bloodstained|Ixalan|91|U|{3}{B}{B}|Creature - Vampire Cleric|3|3|When Bishop of the Bloodstained enters the battlefield, target player loses 1 life for each vampire you control.| +Blight Keeper|Ixalan|92|C|{B}|Creature - Bat Imp|1|1|Flying${7}{B}, {T}, Sacrifice Blight Keeper: Target opponent loses 4 life and you gain 4 life.| Bloodcrazed Paladin|Ixalan|93|R|{1}{B}|Creature - Vampire Knight|1|1|Flash$Bloodcrazed Paladin enters the battlefield with a +1/+1 counter on it for each creature that died this turn.| Boneyard Parley|Ixalan|94|M|{5}{B}{B}|Sorcery|||Exile up to five target creature cards from graveyards. An opponent separates those cards into two piles. Put all cards from the pile of your choice onto the battlefield under your control and the rest into their owners' graveyards.| +Contract Killing|Ixalan|95|C|{3}{B}{B}|Sorcery|||Destroy target creature. Create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| +Costly Plunder|Ixalan|96|C|{1}{B}|Instant|||As an additional cost to cast Costly Plunder, sacrifice an artifact or creature.$Draw two cards.| +Dark Nourishment|Ixalan|97|U|{9}{7}|Instant|||Dark Nourishment deals 3 damage to target creature or player. You gain 3 life.| Deadeye Tormentor|Ixalan|98|C|{2}{B}|Creature - Human Pirate|2|2|Raid — When Deadeye Tormentor enters the battlefield, if you attacked with a creature this turn, target opponent discards a card.| Deadeye Tracker|Ixalan|99|R|{B}|Creature - Human Pirate|1|1|{1}{B}, {T}: Exile two target cards from an opponent's graveyard. Deadeye Tracker explores.| Deathless Ancient|Ixalan|100|U|{4}{B}{B}|Creature - Vampire Knight|4|4|Flying$Tap three untapped Vampires you control: Return Deathless Ancient from your graveyard to your hand.| Desperate Castaways|Ixalan|101|C|{1}{B}|Creature - Human Pirate|2|3|Desperate Castaways can't attack unless you control an artifact.| Dire Fleet Hoarder|Ixalan|102|C|{1}{B}|Creature - Human Pirate|2|1|When Dire Fleet Hoarder dies, create a colorless Treasure artifact token with "{t}, Sacrifice this artifact: Add one mana of any color to your mana pool."| +Dire Fleet Interloper|Ixalan|103|C|{3}{B}|Creature - Human Pirate|2|2|Menace$When Dire Fleet Interloper enters the battlefield, it explores. | Dire Fleet Ravager|Ixalan|104|M|{3}{B}{B}|Creature - Orc Pirate Wizard|4|4|Menace, deathtouch$When Dire Fleet Ravager enters the battlefield, each player loses a third of his or her life, rounded up.| Duress|Ixalan|105|C|{B}|Sorcery|||Target opponent reveals his or her hand. You choose a noncreature, nonland card from it. That player discards that card.| Fathom Fleet Captain|Ixalan|106|R|{1}{B}|Creature - Human Pirate|2|1|Menace$Whenever Fathom Fleet Captain attacks, if you control another nontoken Pirate, you may pay {2}. If you do, creature a 2/2 black Pirate creature token with menace.| +Fathom Fleet Cutthroat|Ixalan|107|C|{3}{B}|Creature - Human Pirate|3|3|When Fathom Fleet Cutthroat enters the battlefield, destroy target creature an opponent controls that was dealt damage this turn.| +Grim Captain's Call|Ixalan|108|U|{2}{B}|Sorcery|||Return a Pirate card from your graveyard to your hand, then do the same for Vampire, Dinosaur, and Merfolk.| +Heartless Pillage|Ixalan|109|U|{2}{B}|Sorcery|||Target opponent discards two cards.$Raid/ — If you attacked with a creature this turn, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| Kitesail Freebooter|Ixalan|110|U|{1}{B}|Creature - Human Pirate|1|2|Flying$When Kitesail Freebooter enters the battlefield, target opponent reveals his or her hand. You choose a noncreature, nonland card from it. Exile that card until Kitesail Freebooter leaves the battlefield.| Lurking Chupacabra|Ixalan|111|U|{3}{B}|Creature - Beast Horror|2|3|Whenever a creature you control explores, target creature an opponent controls gets -2/-2 until end of turn| +March of the Drowned|Ixalan|112|C|{B}|Sorcery|||Choose one —$&bull; Return target creature card from your graveyard to your hand.$&bull; Return two target Pirate cards from your graveyard to your hand.| +Mark of the Vampire|Ixalan|113|C|{3}{B}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +2/+2 and has lifelink.| +Queen's Agent|Ixalan|114|C|{5}{B}|Creature - Vampire Scout|3|3|Lifelink$When Queen's Agent enters the battlefield, it explores. | Queen's Bay Soldier|Ixalan|115|C|{1}{B}|Creature - Vampire Soldier|2|2|| -Revel in Riches|Ixalan|117|R|{4}{B}|Enchantment|||Whenever a creature an opponent controls dies, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."$At the beginning of your upkeep, if you control ten or more Treasures, you win the game.| Raiders' Wake|Ixalan|116|U|{3}{B}|Enchantment|||Whenever an opponent discards a card, that player loses 2 life.$Raid — At the beginning of your end step, if you attacked with a creature this turn, target opponent discards a card.| +Revel in Riches|Ixalan|117|R|{4}{B}|Enchantment|||Whenever a creature an opponent controls dies, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."$At the beginning of your upkeep, if you control ten or more Treasures, you win the game.| Ruin Raider|Ixalan|118|R|{2}{B}|Creature - Orc Pirate|3|2|Raid — At the beginning of your end step, if you attacked with a creature this turn, reveal the top card of your library and put that card into your hand. You lose life equal to the card's converted mana cost.| Ruthless Knave|Ixalan|119|U|{2}{B}|Creature - Orc Pirate|3|2|{2}{B}, Sacrifice a creature: Create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."$Sacrifice three Treasures: Draw a card.| Sanctum Seeker|Ixalan|120|R|{2}{B}{B}|Creature - Vampire Knight|3|4|Whenever a Vampire you control attacks, each opponent loses 1 life and you gain 1 life.| +Seekers' Squire|Ixalan|121|U|{1}{B}|Creature - Human Scout|1|2|When Seekers' Squire enters the battlefield, it explores. | Skittering Heartstopper|Ixalan|122|C|{B}|Creature - Insect|1|2|{B}: Skittering Heartstopper gains deathtouch until end of turn.| Skulduggery|Ixalan|123|C|{B}|Instant|||Until end of turn, target creature you control gets +1/+1 and target creature an opponent controls gets -1/-1.| +Skymarch Bloodletter|Ixalan|124|C|{2}{B}|Creature - Vampire Soldier|2|2|Flying$When Skymarch Bloodletters enters the battlefield, target opponent loses 1 life and you gain 1 life.| +Spreading Rot|Ixalan|125|C|{4}{B}|Sorcery|||Destroy target land. Its controller loses 2 life.| Sword-Point Diplomacy|Ixalan|126|R|{2}{B}|Sorcery|||Reveal the top three cards of your library. For each of those cards, put that card into your hand unless any opponent pays 3 life. Then exile the rest.| +Vanquish the Weak|Ixalan|127|C|{2}{B}|Instant|||Destroy target creature with power 3 or less.| Vicious Conquistador|Ixalan|128|U|{B}|Creature - Vampire Soldier|1|2|Whenever Vicious Conquistador attacks, each opponent loses 1 life.| Vraska's Contempt|Ixalan|129|R|{2}{B}{B}|Instant|||Exile target creature or planeswalker. You gain 2 life.| Walk the Plank|Ixalan|130|U|{B}{B}|Sorcery|||Destroy target non-Merfolk creature.| Wanted Scoundrels|Ixalan|131|U|{1}{B}|Creature - Human Pirate|4|3|When Wanted Scoundrels dies, target opponent creates two colorless Treasure artifact tokens with "T, Sacrifice this artifact: Add one mana of any color to your mana pool."| Angrath's Marauders|Ixalan|132|R|{5}{R}{R}|Creature - Human Pirate|4|4|If a source you control would deal damage to a permanent or player, it deals double that damage to that permanent or player instead.| -Brazen Buccaneers|Ixalan|134|C|{3}{R}|Creature - Human Pirate|2|2|Haste$When Brazen Buccaneers enters the battlefield, it explores.| +Bonded Horncrest|Ixalan|133|U|{3}{R}|Creature - Dinosaur|5|5|Bonded Horncrest can't attack or block alone.|Brazen Buccaneers|Ixalan|134|C|{3}{R}|Creature - Human Pirate|2|2|Haste$When Brazen Buccaneers enters the battlefield, it explores.| Burning Sun's Avatar|Ixalan|135|R|{3}{R}{R}{R}|Creature - Dinosaur Avatar|6|6|When Burning Sun's Avatar enters the battlefield, it deals 3 damage to target opponent and 3 damage to up to one target creature.| Captain Lannery Storm|Ixalan|136|R|{2}{R}|Legendary Creature - Human Pirate|2|2|Haste$Whenever Captain lannery Storm attacks, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."$Whenever you sacrifice a Treasure, Captain Lannery Storm gets +1/+0 until end of turn.| Captivating Crew|Ixalan|137|R|{3}{R}|Creature - Human Pirate|4|3|{3}{R}: Gain control of target creature an opponent controls until end of turn. Untap that creature. It gains haste until end of turn. Activate this ability only any time you could cast a sorcery.| Charging Monstrosaur|Ixalan|138|U|{4}{R}|Creature - Dinosaur|5|5|Trample, haste| +Demolish|Ixalan|139|C|{3}{R}|Sorcery|||Destroy target artifact or land.| Dinosaur Stampede|Ixalan|140|U|{2}{R}|Instant|||| +Dual Shot|Ixalan|141|C|{R}|Instant|||Dual Shot deals 1 damage to each of up to two target creatures.| +Fathom Fleet Firebrand|Ixalan|142|C|{1}{R}|Creature - Human Pirate|2|2|{1}{r}: Fathom Fleet Firebrand gets +1/+0 until end of turn.| +Fiery Cannonade|Ixalan|143|U|{2}{R}|Instant|||Fiery Cannonade deals 2 damage to each non-Pirate creature.| +Fire Shrine Keeper|Ixalan|144|C|{R}|Creature - Elemental|1|1|Menace${7}{R}, {t}, Sacrifice Fire Shrine Keeper: It deals 3 damage to each of up to two target creatures.| +Firecannon Blast|Ixalan|145|C|{1}{R}{R}|Sorcery|||Firecannon Blast deals 3 damage to target creature.$Raid/ -- Firecannon Blast deals 6 damage to that creature instead if you attacked with a creature this turn.| +Frenzied Raptor|Ixalan|146|C|{2}{R}|Creature - Dinosaur|4|2|| +Headstrong Brute|Ixalan|147|C|{2}{R}|Creature - Orc Pirate|3|3|Headstrong Brute can't block.$Headstrong Brute has menace as long as you control another Pirate.| +Hijack|Ixalan|148|C|{1}{R}{R}|Sorcery|||Gain control of target artifact or creature until end of turn. Untap it. It gains haste until end of turn.| Lightning Strike|Ixalan|149|U|{1}{R}|Instant|||Lightning Strike deals 3 damage to target creature or player.| Lightning-Rig Crew|Ixalan|150|U|{2}{R}|Creature - Goblin Pirate|0|5|{T}: Lightning-Rig Crew deals 1 damage to each opponent.$Whenever you cast a Pirate spell, untap Lightning-Rig Crew.| Makeshift Munitions|Ixalan|151|U|{1}{R}|Enchantment|||{1}, Sacrifice an artifact or creature: Makeshift Munitions deals 1 damage to target creature or player.| +Nest Robber|Ixalan|152|C|{1}{R}|Creature - Dinosaur|2|1|Haste| Otepec Huntmaster|Ixalan|153|U|{1}{R}|Creature - Human Shaman|1|2|Dinosaur spells you cast cost {1} less to cast.${T}: Target Dinosaur gains haste until end of turn.| Rampaging Ferocidon|Ixalan|154|R|{2}{R}|Creature - Dinosaur|3|3|Menace$Players can't gain life.$Whenever another creature enters the battlefield, Rampaging Ferocidon deals 1 damage to that creature's controller.| Raptor Hatchling|Ixalan|155|U|{1}{R}|Creature - Dinosaur|1|1|Enrage - Whenever Raptor Hatchling is dealt damage, create a 3/3 green Dinosaur creature token with trample.| Repeating Barrage|Ixalan|156|R|{1}{R}{R}|Sorcery|||Repeating Barrage deals 3 damage to target creature or player.$Raid — {3}{R}{R}: Return Repeating Barrage from your graveyard to your hand. Activate this ability only if you attacked with a creature this turn.| -Rigging Runner|Ixalan|157|U|{R}|Creature - Goblin Pirate|1|1|First strike$Raid/ — Rigging runner enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.|Rile|Ixalan|158|C|{R}|Sorcery|||Rile deals 1 damage to target creature you control. That creature gains trample until end of turn.$Draw a card.| +Rigging Runner|Ixalan|157|U|{R}|Creature - Goblin Pirate|1|1|First strike$Raid/ — Rigging runner enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.| +Rile|Ixalan|158|C|{R}|Sorcery|||Rile deals 1 damage to target creature you control. That creature gains trample until end of turn.$Draw a card.| Rowdy Crew|Ixalan|159|M|{2}{R}{R}|Creature - Human Pirate|3|3|Trample$When Rowdy Crew enters the battlefield, draw three cards, then discard two cards at random. If two cards that share a card type are discarded this way, put two +1/+1 counters on Rowdy Crew.| +Rummaging Goblin|Ixalan|160|C|{2}{R}|Creature - Goblin Rogue|1|1|{t}, Discard a card: Draw a card.| Star of Extinction|Ixalan|161|M|{5}{R}{R}|Sorcery|||Destroy target land. Star of Extinction deals 20 damage to each creature and each planeswalker.| Storm Fleet Arsonist|Ixalan|162|U|{4}{R}|Creature - Orc Pirate|4|4|Raid - When Storm Fleet Arsonist enters the battlefield, if you attacked with a creature this turn, target opponent sacrifices a permanent.| +Storm Fleet Pyromancer|Ixalan|163|C|{4}{R}|Creature - Human Pirate Wizard|3|2|Raid/ -- When Storm Fleet Pyromancer enters the battlefield, if you attacked with a creature this turn, Storm Fleet Pyromancer deals 2 damage to target creature or player.| Sun-Crowned Hunters|Ixalan|164|C|{4}{R}{R}|Creature - Dinosaur|5|4|Enrage — Whenever Sun-Crowned Hunters is dealt damage, it deals 3 damage to target opponent.| Sunbird's Invocation|Ixalan|165|R|{5}{R}|Enchantment|||Whenever you cast a spell from your hand, reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order.| +Sure Strike|Ixalan|166|C|{1}{R}|Instant|||Target creature gets +3/+0 and gains first strike until end of turn.| +Swashbuckling|Ixalan|167|C|{1}{R}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +2/+2 and has haste.| +Thrash of Raptors|Ixalan|168|C|{3}{R}|Creature - Dinosaur|3|3|As long as you control another Dinosaur, Thrash of Raptors gets +2/+0 and has trample.| Tilonalli's Knight|Ixalan|169|C|{1}{R}|Creature - Human Knight|2|2|Whenever Tilonalli's Knight attacks, if you control a Dinosaur, Tilonalli's Knight gets +1/+1 until end of turn.| Tilonalli's Skinshifter|Ixalan|170|R|{2}{R}|Creature - Human Shaman|0|1|Whenever Tilonalli's Skinshifter attacks, it becomes a copy of another target nonlegendary attacking creature until end of turn.| Trove of Temptation|Ixalan|171|U|{3}{R}|Enchantment|||Each opponent must attack you or a planeswalker you control with at least one creature each combat if able.$At the beginning of your end step, create a colorless Treasure artifact token with "t, Sacrifice this artifact: Add one mana of any color to your mana pool.”| @@ -32430,27 +32505,45 @@ Unfriendly Fire|Ixalan|172|C|{4}{R}|Instant|||Unfriendly Fire deals 4 damage to Vance's Blasting Cannons|Ixalan|173a|R|{3}{R}|Legendary Enchantment|||At the beginning of your upkeep, exile the top card of your library. If it's a nonland card, you may cast that card this turn.$Whenever you cast your third spell in a turn, transform Vance's Blasting Cannons.| Spitfire Bastion|Ixalan|173b|R||Legendary Land|||{t}: Add {r} to your mana pool.${2}{r}, {t}: Spitfire Bastion deals 3 damage to target creature or player.| Wily Goblin|Ixalan|174|U|{R}{R}|Creature - Goblin Pirate|1|1|When Wily Goblin enters the battlefield, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| +Ancient Brontodon|Ixalan|175|C|{6}{G}{G}|Creature - Dinosaur|9|9|| +Atzocan Archer|Ixalan|176|U|{2}{G}|Creature - Human Archer|1|4|Reach$When Atzocan Archer enters the battlefield, you may have it fight another target creature.| +Blinding Fog|Ixalan|177|C|{2}{G}|Instant|||Prevent all damage that would be dealt to creatures this turn. Creatures you control gain hexproof until end of turn.| +Blossom Dryad|Ixalan|178|C|{2}{G}|Creature - Dryad|2|2|{t}: Untap target land.| Carnage Tyrant|Ixalan|179|M|{4}{G}{G}|Creature - Dinosaur|7|6|Carnage Tyrant can't be countered.$Trample, hexproof| +Colossal Dreadmaw|Ixalan|180|C|{4}{G}{G}|Creature - Dinosaur|6|6|Trample| Commune with Dinosaurs|Ixalan|181|C|{G}|Sorcery|||| +Crash the Ramparts|Ixalan|182|C|{2}{G}|Instant|||Target creature gets +3/+3 and gains trample until end of turn.| +Crushing Canopy|Ixalan|183|C|{2}{G}|Instant|||Choose one --$* Destroy target creature with flying.$* Destroy target enchantment.| Deathgorge Scavenger|Ixalan|184|R|{2}{G}|Creature - Dinosaur|3|2|Whenever Deathgorge Scavenger enters the battlefield or attacks, you may exile target card from a graveyard. If a creature card is exiled this way, you gain 2 life. If a noncreature card is exiled this way, Deathgorge Scavenger gets +1/+1 until end of turn.| Deeproot Champion|Ixalan|185|R|{1}{G}|Creature - Merfolk Shaman|1|1|Whenever you cast a noncreature spell, put a +1/+1 counter on Deeproot Champion.| +Deeproot Warrior|Ixalan|186|C|{1}{G}|Creature - Merfolk Warrior|2|2|Whenever Deeproot Warrior becomes blocked, it gets +1/+1 until end of turn.| Drover of the Mighty|Ixalan|187|U|{1}{G}|Creature - Human Druid|1|1|Drover of the Mighty gets +2/+2 as long as you control a Dinosaur.${T}: Add one mana of any color to your mana pool.| +Emergent Growth|Ixalan|188|U|{3}{G}|Sorcery|||Target creature gets +5/+5 until end of turn and must be blocked this turn if able.| Emperor's Vanguard|Ixalan|189|R|{3}{G}|Creature - Human Scout|4|3|Whenever Emperor's Vanguard deals combat damage to a player, it explores.| Grazing Whiptail|Ixalan|190|C|{2}{G}{G}|Creature - Dinosaur|3|4|Reach (This creature can block creatures with flying.)/| Growing Rites of Itlimoc|Ixalan|191a|R|{2}{G}|Legendary Enchantment|||When Growing Rites of Itlimoc enters the battlefield, look at the top four cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in any order.$At the beginning of your end step, if you control four or more creatures, transform Growing Rites of Itlimoc.| Itlimoc, Cradle of the Sun|Ixalan|191b|R||Legendary Land|||(Transforms from Growing Rites of Itlimoc.)/${T}: Add {G} to your mana pool.${T}: Add {G} to your mana pool for each creature you control.| +Ixalli's Diviner|Ixalan|192|C|{1}{G}|Creature - Human Druid|0|3|When Ixalli's Diviner enters the battlefield, it explores. Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on this creature, then put the card back or put it into your graveyard.)| +Ixalli's Keeper|Ixalan|193|C|{1}{G}|Creature - Human Shaman|2|2|{7}{g}, {t}, Sacrifice Ixalli's Keeper: Target creature gets +5/+5 and gains trample until end of turn.| +Jade Guardian|Ixalan|194|C|{3}{G}|Creature - Merfolk Shaman|2|2|Hexproof$When Jade Guardian enters the battlefield, put a +1/+1 counter on target Merfolk you control.| +Jungle Delver|Ixalan|195|C|{G}|Creature - Merfolk Warrior|1|1|{3}{g}: Put a +1/+1 counter on Jungle Delver.| Kumena's Speaker|Ixalan|196|U|{G}|Creature - Merfolk|1|1|Kumena's Speaker gets +1/+1 as long as you control another Merfolk or an Island.| Merfolk Branchwalker|Ixalan|197|U|{1}{G}|Creature - Merfolk Scout|2|1|When Merfolk Branchwalker enters the battlefield, it explores. (Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on this creature, then put that card back or put it into your graveyard.)/| +New Horizons|Ixalan|198|C|{2}{G}|Enchantment - Aura|||Enchant land$When New Horizons enters the battlefield, put a +1/+1 counter on target creature you control.$Enchanted land has "{t]: Add two mana of any one color to your mana pool."| Old-Growth Dryads|Ixalan|199|R|{G}|Creature - Dryad|3|3|When Old-Growth Dryads enters the battlefield, each opponent may search his or her library for a basic land card, put it onto the battlefield tapped, then shuffle his or her library.| +Pounce|Ixalan|200|C|{1}{G}|Instant|||Target creature you control fights target creature you don't control.| Ranging Raptors|Ixalan|201|U|{2}{G}|Creature - Dinosaur|2|3|Enrage - Whenever Ranging Raptors is dealt damage, you may search your library for a basic land card, put it onto the battlefield, then shuffle your library.| Ravenous Daggertooth|Ixalan|202|C|{2}{G}|Creature - Dinosaur|3|2|Enrage - Whenever Ravenous Daggertooth is dealt damage, you gain 2 life.| Ripjaw Raptor|Ixalan|203|R|{2}{G}{G}|Creature - Dinosaur|4|5|Enrage — Whenever Ripjaw Raptor is dealt damage, draw a card.| +River Heralds' Boon|Ixalan|204|C|{1}{G}|Instant|||Put a +1/+1 counter on target creature and a +1/+1 counter on up to one target Merfolk.| Savage Stomp|Ixalan|205|U|{2}{G}|Sorcery|||Savage Stomp cost {2} less to cast if it targets a Dinosaur you control.$Put a +1/+1 counter on target creature you control. Then that creature fights target creature you don't control.| Shapers' Sanctuary|Ixalan|206|R|{G}|Enchantment|||Whenever a creature you control becomes the target of a spell or ability an opponent controls, you may draw a card.| Slice in Twain|Ixalan|207|U|{2}{G}{G}|Instant|||Destroy target artifact or enchantment.$Draw a card.| Snapping Sailback|Ixalan|208|U|{4}{G}|Creature - Dinosaur|4|4|Flash$Enrage — Whenever Snapping Sailback is dealt damage, put a +1/+1 counter on it.| +Spike-Tailed Ceratops|Ixalan|209|C|{4}{G}|Creature - Dinosaur|4|4|Spike-Tailed Ceratops can block an additional creature each combat.| Thundering Spineback|Ixalan|210|U|{5}{G}{G}|Creature - Dinosaur|5|5|Other Dinosaurs you control get +1/+1.${5}{G}: Create a 3/3 green Dinosaur creature token with trample.| Tishana's Wayfinder|Ixalan|211|C|{2}{G}|Creature - Merfolk Scout|2|2|When Tishana's Wayfinder enters the battlefield, it explores.| +Verdant Rebirth|Ixalan|212|U|{1}{G}|Instant|||Until end of turn, target creature gains "When this creature dies, return it to its owner's hand."$Draw a card.| Verdant Sun's Avatar|Ixalan|213|R|{5}{G}{G}|Creature - Dinosaur Avatar|5|5|When Verdant Sun's Avatar or another creature enters the battlefield under your control, you gain life equal to that creature's toughness.| Vineshaper Mystic|Ixalan|214|U|{2}{G}|Creature - Merfolk Shaman|1|3|When Vineshaper Mystic enters the battlefield, put a +1/+1 counter on each of up to two target Merfolk you control.| Waker of the Wilds|Ixalan|215|R|{2}{G}{G}|Creature - Merfolk Shaman|3|3|{X}{G}{G}: Put X +1/+1 counters on target land you control. That land becomes a 0/0 Elemental creature with haste. It's still a land.| @@ -32471,24 +32564,29 @@ Sky Terror|Ixalan|229|U|{R}{W}|Creature - Dinosaur|2|2|Flying, Menace| Tishana, Voice of Thunder|Ixalan|230|M|{5}{G}{U}|Legendary Creature - Merfolk Shaman|*|*|Tishana, Voice of Thunder's power and toughness are each equal to the number of cards in your hand.$You have no maximum hand size.$When Tishana enters the battlefield, draw a card for each creature you control.| Vona, Butcher of Magan|Ixalan|231|M|{3}{W}{B}|Legendary Creature - Vampire Knight|4|4|Vigilance, lifelink${t}, Pay 7 life: Destroy target nonland permanent. Activate this ability only during your turn.| Vraska, Relic Seeker|Ixalan|232|M|{4}{B}{G}|Legendary Planeswalker - Vraska|||+2: Create a 2/2 Black Pirate with Menace$-3: Destroy target artifact, creature or enchantment, create a treasure$-10: Target players life total becomes 1| -Conqueror's Foothold|Ixalan|234b|R||Land|||{T}: Add {C} to your mana pool.${2}, {T}: Draw a card, then discard a card.${4}, {T}: Draw a card.${6}, {T}: Return target card from your graveyard to your hand.| +Cobbled Wings|Ixalan|233|C|{2}|Artifact - Equipment|||Equipped creature has flying.$Equip {1}| Conqueror's Galleon|Ixalan|234a|R|{4}|Artifact - Vehicle|2|10|When Conqueror's Galleon attacks, exile it at the end of combat, then return it to the battlefield transformed under your control.$Crew 4| +Conqueror's Foothold|Ixalan|234b|R||Land|||{T}: Add {C} to your mana pool.${2}, {T}: Draw a card, then discard a card.${4}, {T}: Draw a card.${6}, {T}: Return target card from your graveyard to your hand.| Dowsing Dagger|Ixalan|235a|R|{2}|Artifact - Equipment|||When Dowsing Dagger enters the battlefield, target opponent creates two 0/2 green Plant creature tokens with defender.$Equipped creature gets +2/+1.$Whenever equipped creature deals combat damage to a player, you may transform Dowsing Dagger.$Equip 2| Lost Vale|Ixalan|235b|R||Land|||T: Add three mana of any one color to your mana pool.| Dusk Legion Dreadnought|Ixalan|236|U|{5}|Artifact - Vehicle|4|6|Vigilance$Crew 2| +Elaborate Firecannon|Ixalan|237|U|{2}|Artifact|||Elaborate Firecannon doesn't untap during your untap step.${4}, {t}: Elaborate Firecannon deals 2 damage to target creature or player.$At the beginning of your upkeep, you may discard a card. If you do, untap Elaborate Firecannon.| Fell Flagship|Ixalan|238|R|{3}|Artifact - Vehicle|||Pirates you control get +1/+0.$Whenever Fell Flagship deals combat damage to a player, that player discards a card.$Crew 3| +Gilded Sentinel|Ixalan|239|C|{4}|Artifact Creature - Golem|||| +Hierophant's Chalice|Ixalan|240|C|{3}|Artifact|||When Hierophant's Chalice enters the battlefield, target opponent loses 1 life and you gain 1 life.${t}: Add {c} to your mana pool.| Pillar of Origins|Ixalan|241|U|{2}|Artifact|||As Pillar of Origins enters the battlefield, choose a creature type.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell if the chosen type.| Pirate's Cutlass|Ixalan|242|C|{3}|Artifact - Equipment|||When Pirate's Cutlass enters the battlefield, attach it to target Pirate you control.$Equipped creature gets +2/+1.$Equip 2| Primal Amulet|Ixalan|243a|R|{4}|Artifact|||Instant and sorcery spells you cast cost {1} less to cast.$Whenever you cast an instant or sorcery spell, put a charge counter on Primal Amulet. Then if there are four or more charge counters on it, you may remove those counters and transform it.| Primal Wellspring|Ixalan|243b|R||Land|||Add one mana of any color to your mana pool. When that mana is spent to cast an instant or sorcery spell, copy that spell and you may choose new targets for the copy.| +Prying Blade|Ixalan|244|C|{1}|Artifact - Equipment|||Equipped creature gets +1/+0.$Whenever equipped creature deals combat damage to a player, create a colorless Treasure artifact token with "{t}, Sacrifice this artifact: Add one mana of any color to your mana pool."$Equip {2}| Sentinel Totem|Ixalan|245|U|{1}|Artifact|||When Sentinel Totem enters the battlefield, scry 1.${T}, Exile Sentinel Totem: Exile all cards from all graveyards.| Shadowed Caravel|Ixalan|246|R|{2}|Artifact - Vehicle|2|2|Whenever a creature you control explores, put a +1/+1 counter on Shadowed Caravel.$Crew 2| Sleek Schooner|Ixalan|247|U|{3}|Artifact - Vehicle|4|3|Crew 1| Sorcerous Spyglass|Ixalan|248|R|{2}|Artifact|||As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name.$Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.| -Spires of Orazca|Ixalan|249b|R||Land|||{T}: Add {C} to your mana pool.${T}: Untap target attacking creature an opponent controls and remove it from combat.| Thaumatic Compass|Ixalan|249a|R|{2}|Artifact|||{3}, {T}: Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library.$At the beginning of your end step, if you control seven or more lands, transform Thaumatic Compass.| -Treasure Cove|Ixalan|250b|R||Land|||{T}: Add {C} to your mana pool.${T}, Sacrifice a Treasure: Draw a card.| +Spires of Orazca|Ixalan|249b|R||Land|||{T}: Add {C} to your mana pool.${T}: Untap target attacking creature an opponent controls and remove it from combat.| Treasure Map|Ixalan|250a|R|{2}|Artifact|||{1}, {T}: Scry 1. Put a landmark counter on Treasure Map. Then if there are three or more landmark counters on it, remove those counters, transform Treasure Map, and create three colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| +Treasure Cove|Ixalan|250b|R||Land|||{T}: Add {C} to your mana pool.${T}, Sacrifice a Treasure: Draw a card.| Vanquisher's Banner|Ixalan|251|R|{5}|Artifact|||As Vanquisher's Banner enters the battlefield, choose a creature type.$Creatures you control of the chosen type get +1/+1.$Whenever you cast a creature spell of the chosen type, draw a card.| Dragonskull Summit|Ixalan|252|R||Land|||Dragonskull Summit enters the battlefield tapped unless you control a Swamp or a Mountain.${T}: Add {B} or {R} to your mana pool.| Drowned Catacomb|Ixalan|253|R||Land|||Drowned Catacomb enters the battlefield tapped unless you control an Island or a Swamp.${T}: Add {U} or {B} to your mana pool.| @@ -32497,6 +32595,7 @@ Glacial Fortress|Ixalan|255|R||Land|||Glacial Fortress enters the battlefield ta Rootbound Crag|Ixalan|256|R||Land|||Rootbound Crag enters the battlefield tapped unless you control a Mountain or a Forest.${T}: Add {R} or {G} to your mana pool.| Sunpetal Grove|Ixalan|257|R||Land|||Sunpetal Grove enters the battlefield tapped unless you control a Forest or a Plains.${T}: Add {G} or {W} to your mana pool.| Unclaimed Territory|Ixalan|258|U||Land|||As Unclaimed Territory enters the battlefield, choose a creature type.${T}: Add {C} to your mana pool.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell of the chosen type.| +Unknown Shores|Ixalan|259|C||Land|||{t}: Add {c} to your mana pool.${1}, {t}: Add one mana of any color to your mana pool.| Plains|Ixalan|260|L||Basic Land - Plains|||{T}: Add {W} to your mana pool.| Plains|Ixalan|261|L||Basic Land - Plains|||{T}: Add {W} to your mana pool.| Plains|Ixalan|262|L||Basic Land - Plains|||{T}: Add {W} to your mana pool.| From 58bba450e0450f5cf46bc624c1cd1d16f7f7e94d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 13:24:25 -0400 Subject: [PATCH 042/182] Added all XLN reprints --- Mage.Sets/src/mage/sets/Ixalan.java | 54 +++++++------------ .../src/main/java/mage/constants/SubType.java | 1 + 2 files changed, 20 insertions(+), 35 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index a579435115..c637b86e35 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -31,9 +31,10 @@ public class Ixalan extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; - cards.add(new SetCardInfo("Adanto Vanguard", 1, Rarity.UNCOMMON, mage.cards.a.AdantoVanguard.class)); cards.add(new SetCardInfo("Adanto, the First Fort", 22, Rarity.RARE, mage.cards.a.AdantoTheFirstFort.class)); + cards.add(new SetCardInfo("Adanto Vanguard", 1, Rarity.UNCOMMON, mage.cards.a.AdantoVanguard.class)); cards.add(new SetCardInfo("Admiral Beckett Brass", 217, Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); + cards.add(new SetCardInfo("Air Elemental", 45, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); cards.add(new SetCardInfo("Arcane Adaptation", 46, Rarity.RARE, mage.cards.a.ArcaneAdaptation.class)); cards.add(new SetCardInfo("Arguel's Blood Fast", 90, Rarity.RARE, mage.cards.a.ArguelsBloodFast.class)); @@ -49,12 +50,14 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Brazen Buccaneers", 134, Rarity.COMMON, mage.cards.b.BrazenBuccaneers.class)); cards.add(new SetCardInfo("Burning Sun's Avatar", 135, Rarity.RARE, mage.cards.b.BurningSunsAvatar.class)); cards.add(new SetCardInfo("Call to the Feast", 219, Rarity.UNCOMMON, mage.cards.c.CallToTheFeast.class)); + cards.add(new SetCardInfo("Cancel", 47, Rarity.COMMON, mage.cards.c.Cancel.class)); cards.add(new SetCardInfo("Captain Lannery Storm", 136, Rarity.RARE, mage.cards.c.CaptainLanneryStorm.class)); cards.add(new SetCardInfo("Captivating Crew", 137, Rarity.RARE, mage.cards.c.CaptivatingCrew.class)); cards.add(new SetCardInfo("Carnage Tyrant", 179, Rarity.MYTHIC, mage.cards.c.CarnageTyrant.class)); cards.add(new SetCardInfo("Castaway's Despair", 281, Rarity.COMMON, mage.cards.c.CastawaysDespair.class)); cards.add(new SetCardInfo("Charging Monstrosaur", 138, Rarity.UNCOMMON, mage.cards.c.ChargingMonstrosaur.class)); cards.add(new SetCardInfo("Chart a Course", 48, Rarity.UNCOMMON, mage.cards.c.ChartACourse.class)); + cards.add(new SetCardInfo("Cobbled Wings", 233, Rarity.COMMON, mage.cards.c.CobbledWings.class)); cards.add(new SetCardInfo("Commune with Dinosaurs", 181, Rarity.COMMON, mage.cards.c.CommuneWithDinosaurs.class)); cards.add(new SetCardInfo("Conqueror's Foothold", 234, Rarity.RARE, mage.cards.c.ConquerorsFoothold.class)); cards.add(new SetCardInfo("Conqueror's Galleon", 234, Rarity.RARE, mage.cards.c.ConquerorsGalleon.class)); @@ -67,6 +70,8 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Deathless Ancient", 100, Rarity.UNCOMMON, mage.cards.d.DeathlessAncient.class)); cards.add(new SetCardInfo("Deeproot Champion", 185, Rarity.RARE, mage.cards.d.DeeprootChampion.class)); cards.add(new SetCardInfo("Deeproot Waters", 51, Rarity.UNCOMMON, mage.cards.d.DeeprootWaters.class)); + cards.add(new SetCardInfo("Demolish", 139, Rarity.COMMON, mage.cards.d.Demolish.class)); + cards.add(new SetCardInfo("Demystify", 8, Rarity.COMMON, mage.cards.d.Demystify.class)); cards.add(new SetCardInfo("Desperate Castaways", 101, Rarity.COMMON, mage.cards.d.DesperateCastaways.class)); cards.add(new SetCardInfo("Dinosaur Stampede", 140, Rarity.UNCOMMON, mage.cards.d.DinosaurStampede.class)); cards.add(new SetCardInfo("Dire Fleet Captain", 221, Rarity.UNCOMMON, mage.cards.d.DireFleetCaptain.class)); @@ -77,9 +82,10 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Dreamcaller Siren", 54, Rarity.RARE, mage.cards.d.DreamcallerSiren.class)); cards.add(new SetCardInfo("Drover of the Mighty", 187, Rarity.UNCOMMON, mage.cards.d.DroverOfTheMighty.class)); cards.add(new SetCardInfo("Drowned Catacomb", 253, Rarity.RARE, mage.cards.d.DrownedCatacomb.class)); + cards.add(new SetCardInfo("Dual Shot", 141, Rarity.COMMON, mage.cards.d.DualShot.class)); cards.add(new SetCardInfo("Duress", 105, Rarity.COMMON, mage.cards.d.Duress.class)); - cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.d.DuskLegionDreadnought.class)); cards.add(new SetCardInfo("Duskborne Skymarcher", 9, Rarity.UNCOMMON, mage.cards.d.DuskborneSkymarcher.class)); + cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.d.DuskLegionDreadnought.class)); cards.add(new SetCardInfo("Emissary of Sunrise", 10, Rarity.UNCOMMON, mage.cards.e.EmissaryOfSunrise.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); @@ -87,10 +93,6 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Favorable Winds", 56, Rarity.UNCOMMON, mage.cards.f.FavorableWinds.class)); cards.add(new SetCardInfo("Fell Flagship", 238, Rarity.RARE, mage.cards.f.FellFlagship.class)); cards.add(new SetCardInfo("Field of Ruin", 254, Rarity.UNCOMMON, mage.cards.f.FieldOfRuin.class)); - cards.add(new SetCardInfo("Forest", 276, Rarity.LAND, mage.cards.basiclands.Forest.class)); - cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class)); - cards.add(new SetCardInfo("Forest", 278, Rarity.LAND, mage.cards.basiclands.Forest.class)); - cards.add(new SetCardInfo("Forest", 279, Rarity.LAND, mage.cards.basiclands.Forest.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); @@ -99,21 +101,17 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Growing Rites of Itlimoc", 191, Rarity.RARE, mage.cards.g.GrowingRitesOfItlimoc.class)); cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); + cards.add(new SetCardInfo("Hijack", 148, Rarity.COMMON, mage.cards.h.Hijack.class)); cards.add(new SetCardInfo("Hostage Taker", 223, Rarity.RARE, mage.cards.h.HostageTaker.class)); + cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); cards.add(new SetCardInfo("Huatli's Snubhorn", 286, Rarity.COMMON, mage.cards.h.HuatlisSnubhorn.class)); cards.add(new SetCardInfo("Huatli's Spurring", 287, Rarity.UNCOMMON, mage.cards.h.HuatlisSpurring.class)); - cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); cards.add(new SetCardInfo("Imperial Lancer", 15, Rarity.UNCOMMON, mage.cards.i.ImperialLancer.class)); - cards.add(new SetCardInfo("Island", 264, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 265, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 266, Rarity.LAND, mage.cards.basiclands.Island.class)); - cards.add(new SetCardInfo("Island", 267, Rarity.LAND, mage.cards.basiclands.Island.class)); cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", 191, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class)); cards.add(new SetCardInfo("Ixalan's Binding", 17, Rarity.UNCOMMON, mage.cards.i.IxalansBinding.class)); - cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); - cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); + cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); cards.add(new SetCardInfo("Kinjalli's Caller", 18, Rarity.COMMON, mage.cards.k.KinjallisCaller.class)); cards.add(new SetCardInfo("Kinjalli's Sunwing", 19, Rarity.RARE, mage.cards.k.KinjallisSunwing.class)); cards.add(new SetCardInfo("Kitesail Freebooter", 110, Rarity.UNCOMMON, mage.cards.k.KitesailFreebooter.class)); @@ -122,29 +120,20 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Legion Conquistador", 20, Rarity.COMMON, mage.cards.l.LegionConquistador.class)); cards.add(new SetCardInfo("Legion's Landing", 22, Rarity.RARE, mage.cards.l.LegionsLanding.class)); cards.add(new SetCardInfo("Lightning Strike", 149, Rarity.UNCOMMON, mage.cards.l.LightningStrike.class)); - cards.add(new SetCardInfo("Lightning-Rig Crew", 150, Rarity.UNCOMMON, mage.cards.l.LightningRigCrew.class)); cards.add(new SetCardInfo("Lookout's Dispersal", 62, Rarity.UNCOMMON, mage.cards.l.LookoutsDispersal.class)); cards.add(new SetCardInfo("Lost Vale", 235, Rarity.RARE, mage.cards.l.LostVale.class)); cards.add(new SetCardInfo("Lurking Chupacabra", 111, Rarity.UNCOMMON, mage.cards.l.LurkingChupacabra.class)); cards.add(new SetCardInfo("Makeshift Munitions", 151, Rarity.UNCOMMON, mage.cards.m.MakeshiftMunitions.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); + cards.add(new SetCardInfo("Mark of the Vampire", 113, Rarity.COMMON, mage.cards.m.MarkOfTheVampire.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Merfolk Branchwalker", 197, Rarity.UNCOMMON, mage.cards.m.MerfolkBranchwalker.class)); - cards.add(new SetCardInfo("Mountain", 272, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 273, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class)); - cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); cards.add(new SetCardInfo("Otepec Huntmaster", 153, Rarity.UNCOMMON, mage.cards.o.OtepecHuntmaster.class)); - cards.add(new SetCardInfo("Overflowing Insight", 64, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); + cards.add(new SetCardInfo("Overflowing Insight", 66, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); cards.add(new SetCardInfo("Perilous Voyage", 67, Rarity.UNCOMMON, mage.cards.p.PerilousVoyage.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); cards.add(new SetCardInfo("Pirate's Cutlass", 242, Rarity.COMMON, mage.cards.p.PiratesCutlass.class)); - cards.add(new SetCardInfo("Plains", 260, Rarity.LAND, mage.cards.basiclands.Plains.class)); - cards.add(new SetCardInfo("Plains", 261, Rarity.LAND, mage.cards.basiclands.Plains.class)); - cards.add(new SetCardInfo("Plains", 262, Rarity.LAND, mage.cards.basiclands.Plains.class)); - cards.add(new SetCardInfo("Plains", 263, Rarity.LAND, mage.cards.basiclands.Plains.class)); cards.add(new SetCardInfo("Priest of the Wakening Sun", 27, Rarity.RARE, mage.cards.p.PriestOfTheWakeningSun.class)); cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); @@ -167,6 +156,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Rootbound Crag", 256, Rarity.RARE, mage.cards.r.RootboundCrag.class)); cards.add(new SetCardInfo("Rowdy Crew", 159, Rarity.MYTHIC, mage.cards.r.RowdyCrew.class)); cards.add(new SetCardInfo("Ruin Raider", 118, Rarity.RARE, mage.cards.r.RuinRaider.class)); + cards.add(new SetCardInfo("Rummaging Goblin", 160, Rarity.COMMON, mage.cards.r.RummagingGoblin.class)); cards.add(new SetCardInfo("Ruthless Knave", 119, Rarity.UNCOMMON, mage.cards.r.RuthlessKnave.class)); cards.add(new SetCardInfo("Sanctum Seeker", 120, Rarity.RARE, mage.cards.s.SanctumSeeker.class)); cards.add(new SetCardInfo("Sanguine Sacrament", 33, Rarity.RARE, mage.cards.s.SanguineSacrament.class)); @@ -182,10 +172,9 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Skulduggery", 123, Rarity.COMMON, mage.cards.s.Skulduggery.class)); cards.add(new SetCardInfo("Sky Terror", 229, Rarity.UNCOMMON, mage.cards.s.SkyTerror.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); - cards.add(new SetCardInfo("Slice in Twain", 207, Rarity.UNCOMMON, mage.cards.s.SliceinTwain.class)); cards.add(new SetCardInfo("Snapping Sailback", 208, Rarity.UNCOMMON, mage.cards.s.SnappingSailback.class)); cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); - cards.add(new SetCardInfo("Spell Pierce", 81, Rarity.RARE, mage.cards.s.SpellPierce.class)); + cards.add(new SetCardInfo("Spell Pierce", 81, Rarity.COMMON, mage.cards.s.SpellPierce.class)); cards.add(new SetCardInfo("Spell Swindle", 82, Rarity.RARE, mage.cards.s.SpellSwindle.class)); cards.add(new SetCardInfo("Spires of Orazca", 249, Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); cards.add(new SetCardInfo("Spitfire Bastion", 173, Rarity.RARE, mage.cards.s.SpitfireBastion.class)); @@ -194,15 +183,9 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Storm Fleet Aerialist", 83, Rarity.UNCOMMON, mage.cards.s.StormFleetAerialist.class)); cards.add(new SetCardInfo("Storm Fleet Arsonist", 162, Rarity.UNCOMMON, mage.cards.s.StormFleetArsonist.class)); cards.add(new SetCardInfo("Storm Fleet Spy", 84, Rarity.UNCOMMON, mage.cards.s.StormFleetSpy.class)); - cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); - cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); cards.add(new SetCardInfo("Sunbird's Invocation", 165, Rarity.RARE, mage.cards.s.SunbirdsInvocation.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); - cards.add(new SetCardInfo("Swamp", 268, Rarity.LAND, mage.cards.basiclands.Swamp.class)); - cards.add(new SetCardInfo("Swamp", 269, Rarity.LAND, mage.cards.basiclands.Swamp.class)); - cards.add(new SetCardInfo("Swamp", 270, Rarity.LAND, mage.cards.basiclands.Swamp.class)); - cards.add(new SetCardInfo("Swamp", 271, Rarity.LAND, mage.cards.basiclands.Swamp.class)); - cards.add(new SetCardInfo("Sword-Point Diplomacy", 126, Rarity.RARE, mage.cards.s.SwordPointDiplomacy.class)); + cards.add(new SetCardInfo("Sure Strike", 166, Rarity.COMMON, mage.cards.s.SureStrike.class)); cards.add(new SetCardInfo("Temple of Aclazotz", 90, Rarity.RARE, mage.cards.t.TempleOfAclazotz.class)); cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); cards.add(new SetCardInfo("Thundering Spineback", 210, Rarity.UNCOMMON, mage.cards.t.ThunderingSpineback.class)); @@ -211,18 +194,19 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Tishana's Wayfinder", 211, Rarity.COMMON, mage.cards.t.TishanasWayfinder.class)); cards.add(new SetCardInfo("Tishana, Voice of Thunder", 230, Rarity.MYTHIC, mage.cards.t.TishanaVoiceOfThunder.class)); cards.add(new SetCardInfo("Tocatli Honor Guard", 42, Rarity.RARE, mage.cards.t.TocatliHonorGuard.class)); - cards.add(new SetCardInfo("Treasure Cove", 1250, Rarity.RARE, mage.cards.t.TreasureCove.class)); + cards.add(new SetCardInfo("Treasure Cove", 250, Rarity.RARE, mage.cards.t.TreasureCove.class)); cards.add(new SetCardInfo("Treasure Map", 250, Rarity.RARE, mage.cards.t.TreasureMap.class)); cards.add(new SetCardInfo("Unclaimed Territory", 258, Rarity.UNCOMMON, mage.cards.u.UnclaimedTerritory.class)); cards.add(new SetCardInfo("Unfriendly Fire", 172, Rarity.COMMON, mage.cards.u.UnfriendlyFire.class)); + cards.add(new SetCardInfo("Unknown Shores", 259, Rarity.COMMON, mage.cards.u.UnknownShores.class)); cards.add(new SetCardInfo("Vance's Blasting Cannons", 173, Rarity.RARE, mage.cards.v.VancesBlastingCannons.class)); cards.add(new SetCardInfo("Vanquisher's Banner", 251, Rarity.RARE, mage.cards.v.VanquishersBanner.class)); cards.add(new SetCardInfo("Verdant Sun's Avatar", 213, Rarity.RARE, mage.cards.v.VerdantSunsAvatar.class)); cards.add(new SetCardInfo("Vicious Conquistador", 128, Rarity.UNCOMMON, mage.cards.v.ViciousConquistador.class)); cards.add(new SetCardInfo("Vineshaper Mystic", 214, Rarity.UNCOMMON, mage.cards.v.VineshaperMystic.class)); cards.add(new SetCardInfo("Vona, Butcher of Magan", 231, Rarity.MYTHIC, mage.cards.v.VonaButcherOfMagan.class)); - cards.add(new SetCardInfo("Vraska's Contempt", 129, Rarity.RARE, mage.cards.v.VraskasContempt.class)); cards.add(new SetCardInfo("Vraska, Relic Seeker", 232, Rarity.MYTHIC, mage.cards.v.VraskaRelicSeeker.class)); + cards.add(new SetCardInfo("Vraska's Contempt", 129, Rarity.RARE, mage.cards.v.VraskasContempt.class)); cards.add(new SetCardInfo("Wakening Sun's Avatar", 44, Rarity.MYTHIC, mage.cards.w.WakeningSunsAvatar.class)); cards.add(new SetCardInfo("Waker of the Wilds", 215, Rarity.RARE, mage.cards.w.WakerOfTheWilds.class)); cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index dea1ad5604..aac316f43c 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -320,6 +320,7 @@ public enum SubType { TURTLE("Turtle", SubTypeSet.CreatureType), TUSKEN("Tusken", SubTypeSet.CreatureType, true), // Star Wars TROOPER("Trooper", SubTypeSet.CreatureType, true), // Star Wars + TRILOBYTE("Trilobyte",SubTypeSet.CreatureType), TWILEK("Twi'lek", SubTypeSet.CreatureType, true), // Star Wars // U From 134d01e7420123ae93ba63c71b2d8ad8fcc26121 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 13:29:33 -0400 Subject: [PATCH 043/182] readded basic lands --- Mage.Sets/src/mage/sets/Ixalan.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index c637b86e35..f31cdd6ecb 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -93,6 +93,10 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Favorable Winds", 56, Rarity.UNCOMMON, mage.cards.f.FavorableWinds.class)); cards.add(new SetCardInfo("Fell Flagship", 238, Rarity.RARE, mage.cards.f.FellFlagship.class)); cards.add(new SetCardInfo("Field of Ruin", 254, Rarity.UNCOMMON, mage.cards.f.FieldOfRuin.class)); + cards.add(new SetCardInfo("Forest", 276, Rarity.LAND, mage.cards.basiclands.Forest.class)); + cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class)); + cards.add(new SetCardInfo("Forest", 278, Rarity.LAND, mage.cards.basiclands.Forest.class)); + cards.add(new SetCardInfo("Forest", 279, Rarity.LAND, mage.cards.basiclands.Forest.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); @@ -108,6 +112,10 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Huatli's Spurring", 287, Rarity.UNCOMMON, mage.cards.h.HuatlisSpurring.class)); cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); cards.add(new SetCardInfo("Imperial Lancer", 15, Rarity.UNCOMMON, mage.cards.i.ImperialLancer.class)); + cards.add(new SetCardInfo("Island", 264, Rarity.LAND, mage.cards.basiclands.Island.class)); + cards.add(new SetCardInfo("Island", 265, Rarity.LAND, mage.cards.basiclands.Island.class)); + cards.add(new SetCardInfo("Island", 266, Rarity.LAND, mage.cards.basiclands.Island.class)); + cards.add(new SetCardInfo("Island", 267, Rarity.LAND, mage.cards.basiclands.Island.class)); cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", 191, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class)); cards.add(new SetCardInfo("Ixalan's Binding", 17, Rarity.UNCOMMON, mage.cards.i.IxalansBinding.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); @@ -128,12 +136,20 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Mark of the Vampire", 113, Rarity.COMMON, mage.cards.m.MarkOfTheVampire.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Merfolk Branchwalker", 197, Rarity.UNCOMMON, mage.cards.m.MerfolkBranchwalker.class)); + cards.add(new SetCardInfo("Mountain", 272, Rarity.LAND, mage.cards.basiclands.Mountain.class)); + cards.add(new SetCardInfo("Mountain", 273, Rarity.LAND, mage.cards.basiclands.Mountain.class)); + cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class)); + cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class)); cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); cards.add(new SetCardInfo("Otepec Huntmaster", 153, Rarity.UNCOMMON, mage.cards.o.OtepecHuntmaster.class)); cards.add(new SetCardInfo("Overflowing Insight", 66, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); cards.add(new SetCardInfo("Perilous Voyage", 67, Rarity.UNCOMMON, mage.cards.p.PerilousVoyage.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); cards.add(new SetCardInfo("Pirate's Cutlass", 242, Rarity.COMMON, mage.cards.p.PiratesCutlass.class)); + cards.add(new SetCardInfo("Plains", 260, Rarity.LAND, mage.cards.basiclands.Plains.class)); + cards.add(new SetCardInfo("Plains", 261, Rarity.LAND, mage.cards.basiclands.Plains.class)); + cards.add(new SetCardInfo("Plains", 262, Rarity.LAND, mage.cards.basiclands.Plains.class)); + cards.add(new SetCardInfo("Plains", 263, Rarity.LAND, mage.cards.basiclands.Plains.class)); cards.add(new SetCardInfo("Priest of the Wakening Sun", 27, Rarity.RARE, mage.cards.p.PriestOfTheWakeningSun.class)); cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); @@ -186,6 +202,10 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Sunbird's Invocation", 165, Rarity.RARE, mage.cards.s.SunbirdsInvocation.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); cards.add(new SetCardInfo("Sure Strike", 166, Rarity.COMMON, mage.cards.s.SureStrike.class)); + cards.add(new SetCardInfo("Swamp", 268, Rarity.LAND, mage.cards.basiclands.Swamp.class)); + cards.add(new SetCardInfo("Swamp", 269, Rarity.LAND, mage.cards.basiclands.Swamp.class)); + cards.add(new SetCardInfo("Swamp", 270, Rarity.LAND, mage.cards.basiclands.Swamp.class)); + cards.add(new SetCardInfo("Swamp", 271, Rarity.LAND, mage.cards.basiclands.Swamp.class)); cards.add(new SetCardInfo("Temple of Aclazotz", 90, Rarity.RARE, mage.cards.t.TempleOfAclazotz.class)); cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); cards.add(new SetCardInfo("Thundering Spineback", 210, Rarity.UNCOMMON, mage.cards.t.ThunderingSpineback.class)); From 551aa8a49723f93e307e7b3f0e305806952cd2cd Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 14:10:25 -0400 Subject: [PATCH 044/182] fixed an error --- Mage.Sets/src/mage/sets/Ixalan.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index f31cdd6ecb..097bd93c46 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -119,6 +119,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", 191, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class)); cards.add(new SetCardInfo("Ixalan's Binding", 17, Rarity.UNCOMMON, mage.cards.i.IxalansBinding.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); + cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); cards.add(new SetCardInfo("Kinjalli's Caller", 18, Rarity.COMMON, mage.cards.k.KinjallisCaller.class)); cards.add(new SetCardInfo("Kinjalli's Sunwing", 19, Rarity.RARE, mage.cards.k.KinjallisSunwing.class)); @@ -127,6 +128,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); cards.add(new SetCardInfo("Legion Conquistador", 20, Rarity.COMMON, mage.cards.l.LegionConquistador.class)); cards.add(new SetCardInfo("Legion's Landing", 22, Rarity.RARE, mage.cards.l.LegionsLanding.class)); + cards.add(new SetCardInfo("Lightning-Rig Crew", 150, Rarity.UNCOMMON, mage.cards.l.LightningRigCrew.class)); cards.add(new SetCardInfo("Lightning Strike", 149, Rarity.UNCOMMON, mage.cards.l.LightningStrike.class)); cards.add(new SetCardInfo("Lookout's Dispersal", 62, Rarity.UNCOMMON, mage.cards.l.LookoutsDispersal.class)); cards.add(new SetCardInfo("Lost Vale", 235, Rarity.RARE, mage.cards.l.LostVale.class)); @@ -140,6 +142,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 273, Rarity.LAND, mage.cards.basiclands.Mountain.class)); cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class)); cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class)); + cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); cards.add(new SetCardInfo("Otepec Huntmaster", 153, Rarity.UNCOMMON, mage.cards.o.OtepecHuntmaster.class)); cards.add(new SetCardInfo("Overflowing Insight", 66, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); @@ -200,12 +203,15 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Storm Fleet Arsonist", 162, Rarity.UNCOMMON, mage.cards.s.StormFleetArsonist.class)); cards.add(new SetCardInfo("Storm Fleet Spy", 84, Rarity.UNCOMMON, mage.cards.s.StormFleetSpy.class)); cards.add(new SetCardInfo("Sunbird's Invocation", 165, Rarity.RARE, mage.cards.s.SunbirdsInvocation.class)); + cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); + cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); cards.add(new SetCardInfo("Sure Strike", 166, Rarity.COMMON, mage.cards.s.SureStrike.class)); cards.add(new SetCardInfo("Swamp", 268, Rarity.LAND, mage.cards.basiclands.Swamp.class)); cards.add(new SetCardInfo("Swamp", 269, Rarity.LAND, mage.cards.basiclands.Swamp.class)); cards.add(new SetCardInfo("Swamp", 270, Rarity.LAND, mage.cards.basiclands.Swamp.class)); cards.add(new SetCardInfo("Swamp", 271, Rarity.LAND, mage.cards.basiclands.Swamp.class)); + cards.add(new SetCardInfo("Sword-Point Diplomacy", 126, Rarity.RARE, mage.cards.s.SwordPointDiplomacy.class)); cards.add(new SetCardInfo("Temple of Aclazotz", 90, Rarity.RARE, mage.cards.t.TempleOfAclazotz.class)); cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); cards.add(new SetCardInfo("Thundering Spineback", 210, Rarity.UNCOMMON, mage.cards.t.ThunderingSpineback.class)); From 8ceb457f3686f38b8827d4438d034bf48e4cc997 Mon Sep 17 00:00:00 2001 From: Christian Date: Fri, 15 Sep 2017 15:10:47 -0400 Subject: [PATCH 045/182] Implemented Ancient Brontodon --- .../src/mage/cards/a/AncientBrontodon.java | 59 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 60 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AncientBrontodon.java diff --git a/Mage.Sets/src/mage/cards/a/AncientBrontodon.java b/Mage.Sets/src/mage/cards/a/AncientBrontodon.java new file mode 100644 index 0000000000..074622f816 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AncientBrontodon.java @@ -0,0 +1,59 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author caldover + */ +public class AncientBrontodon extends CardImpl { + + public AncientBrontodon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{G}{G}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(9); + this.toughness = new MageInt(9); + } + + public AncientBrontodon(final AncientBrontodon card) { + super(card); + } + + @Override + public AncientBrontodon copy() { + return new AncientBrontodon(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 097bd93c46..9c0b1d5e97 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -35,6 +35,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Adanto Vanguard", 1, Rarity.UNCOMMON, mage.cards.a.AdantoVanguard.class)); cards.add(new SetCardInfo("Admiral Beckett Brass", 217, Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); cards.add(new SetCardInfo("Air Elemental", 45, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); + cards.add(new SetCardInfo("Ancient Brontodon", 175, Rarity.COMMON, mage.cards.a.AncientBrontodon.class)); cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); cards.add(new SetCardInfo("Arcane Adaptation", 46, Rarity.RARE, mage.cards.a.ArcaneAdaptation.class)); cards.add(new SetCardInfo("Arguel's Blood Fast", 90, Rarity.RARE, mage.cards.a.ArguelsBloodFast.class)); From c55e8d44917d444f1fbc575abc46432cd45c592f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 15:32:08 -0400 Subject: [PATCH 046/182] Implemented Bishop's Soldier --- .../src/mage/cards/b/BishopsSoldier.java | 65 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 66 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BishopsSoldier.java diff --git a/Mage.Sets/src/mage/cards/b/BishopsSoldier.java b/Mage.Sets/src/mage/cards/b/BishopsSoldier.java new file mode 100644 index 0000000000..d017251200 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BishopsSoldier.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class BishopsSoldier extends CardImpl { + + public BishopsSoldier(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + } + + public BishopsSoldier(final BishopsSoldier card) { + super(card); + } + + @Override + public BishopsSoldier copy() { + return new BishopsSoldier(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 097bd93c46..6ed49f2959 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -45,6 +45,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class)); cards.add(new SetCardInfo("Bishop of the Bloodstained", 91, Rarity.UNCOMMON, mage.cards.b.BishopOfTheBloodstained.class)); + cards.add(new SetCardInfo("Bishop's Soldier", 6, Rarity.COMMON, mage.cards.b.BishopsSoldier.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); cards.add(new SetCardInfo("Boneyard Parley", 94, Rarity.MYTHIC, mage.cards.b.BoneyardParley.class)); cards.add(new SetCardInfo("Brazen Buccaneers", 134, Rarity.COMMON, mage.cards.b.BrazenBuccaneers.class)); From 0d961364079a3c5439649eaccfdbfb195d555b07 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 15:34:30 -0400 Subject: [PATCH 047/182] Implemented Bright Reprisal --- .../src/mage/cards/b/BrightReprisal.java | 63 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 64 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BrightReprisal.java diff --git a/Mage.Sets/src/mage/cards/b/BrightReprisal.java b/Mage.Sets/src/mage/cards/b/BrightReprisal.java new file mode 100644 index 0000000000..3a8884ea8f --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BrightReprisal.java @@ -0,0 +1,63 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetAttackingCreature; + +/** + * + * @author TheElk801 + */ +public class BrightReprisal extends CardImpl { + + public BrightReprisal(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{W}"); + + // Destroy target attacking creature. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetAttackingCreature()); + + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + } + + public BrightReprisal(final BrightReprisal card) { + super(card); + } + + @Override + public BrightReprisal copy() { + return new BrightReprisal(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 6ed49f2959..59306038a1 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -49,6 +49,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); cards.add(new SetCardInfo("Boneyard Parley", 94, Rarity.MYTHIC, mage.cards.b.BoneyardParley.class)); cards.add(new SetCardInfo("Brazen Buccaneers", 134, Rarity.COMMON, mage.cards.b.BrazenBuccaneers.class)); + cards.add(new SetCardInfo("Bright Reprisal", 7, Rarity.UNCOMMON, mage.cards.b.BrightReprisal.class)); cards.add(new SetCardInfo("Burning Sun's Avatar", 135, Rarity.RARE, mage.cards.b.BurningSunsAvatar.class)); cards.add(new SetCardInfo("Call to the Feast", 219, Rarity.UNCOMMON, mage.cards.c.CallToTheFeast.class)); cards.add(new SetCardInfo("Cancel", 47, Rarity.COMMON, mage.cards.c.Cancel.class)); From dc856094a32a219d971523939debf7a18cf403a7 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 15:35:50 -0400 Subject: [PATCH 048/182] Implemented Looming Altisaur --- .../src/mage/cards/l/LoomingAltisaur.java | 59 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 60 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LoomingAltisaur.java diff --git a/Mage.Sets/src/mage/cards/l/LoomingAltisaur.java b/Mage.Sets/src/mage/cards/l/LoomingAltisaur.java new file mode 100644 index 0000000000..78a6135a42 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LoomingAltisaur.java @@ -0,0 +1,59 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.l; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class LoomingAltisaur extends CardImpl { + + public LoomingAltisaur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(1); + this.toughness = new MageInt(7); + } + + public LoomingAltisaur(final LoomingAltisaur card) { + super(card); + } + + @Override + public LoomingAltisaur copy() { + return new LoomingAltisaur(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 59306038a1..1292686b05 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -133,6 +133,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Lightning-Rig Crew", 150, Rarity.UNCOMMON, mage.cards.l.LightningRigCrew.class)); cards.add(new SetCardInfo("Lightning Strike", 149, Rarity.UNCOMMON, mage.cards.l.LightningStrike.class)); cards.add(new SetCardInfo("Lookout's Dispersal", 62, Rarity.UNCOMMON, mage.cards.l.LookoutsDispersal.class)); + cards.add(new SetCardInfo("Looming Altisaur", 23, Rarity.COMMON, mage.cards.l.LoomingAltisaur.class)); cards.add(new SetCardInfo("Lost Vale", 235, Rarity.RARE, mage.cards.l.LostVale.class)); cards.add(new SetCardInfo("Lurking Chupacabra", 111, Rarity.UNCOMMON, mage.cards.l.LurkingChupacabra.class)); cards.add(new SetCardInfo("Makeshift Munitions", 151, Rarity.UNCOMMON, mage.cards.m.MakeshiftMunitions.class)); From 8d04ce3fc9c5f094d5c2505b568504901727b822 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 15:36:16 -0400 Subject: [PATCH 049/182] Implemented Raptor Companion --- .../src/mage/cards/r/RaptorCompanion.java | 59 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 60 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RaptorCompanion.java diff --git a/Mage.Sets/src/mage/cards/r/RaptorCompanion.java b/Mage.Sets/src/mage/cards/r/RaptorCompanion.java new file mode 100644 index 0000000000..26c55fc4e3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RaptorCompanion.java @@ -0,0 +1,59 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class RaptorCompanion extends CardImpl { + + public RaptorCompanion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + } + + public RaptorCompanion(final RaptorCompanion card) { + super(card); + } + + @Override + public RaptorCompanion copy() { + return new RaptorCompanion(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 1292686b05..c62e1aa56b 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -165,6 +165,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Raiders' Wake", 116, Rarity.UNCOMMON, mage.cards.r.RaidersWake.class)); cards.add(new SetCardInfo("Rampaging Ferocidon", 154, Rarity.RARE, mage.cards.r.RampagingFerocidon.class)); cards.add(new SetCardInfo("Ranging Raptors", 201, Rarity.UNCOMMON, mage.cards.r.RangingRaptors.class)); + cards.add(new SetCardInfo("Raptor Companion", 31, Rarity.COMMON, mage.cards.r.RaptorCompanion.class)); cards.add(new SetCardInfo("Raptor Hatchling", 155, Rarity.UNCOMMON, mage.cards.r.RaptorHatchling.class)); cards.add(new SetCardInfo("Ravenous Daggertooth", 202, Rarity.COMMON, mage.cards.r.RavenousDaggertooth.class)); cards.add(new SetCardInfo("Regisaur Alpha", 227, Rarity.RARE, mage.cards.r.RegisaurAlpha.class)); From af33b1fad7ecc899ae4a82f6d365833ad3905a0d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 15:42:40 -0400 Subject: [PATCH 050/182] Implemented several vanilla/french vanilla cards --- .../src/mage/cards/c/ColossalDreadmaw.java | 64 +++++++++++++++++ .../src/mage/cards/f/FrenziedRaptor.java | 59 ++++++++++++++++ Mage.Sets/src/mage/cards/n/NestRobber.java | 64 +++++++++++++++++ .../src/mage/cards/s/ShiningAerosaur.java | 64 +++++++++++++++++ .../src/mage/cards/s/SkybladeOfTheLegion.java | 65 +++++++++++++++++ Mage.Sets/src/mage/cards/s/SunriseSeeker.java | 66 ++++++++++++++++++ Mage.Sets/src/mage/cards/w/WindStrider.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 7 ++ 8 files changed, 458 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ColossalDreadmaw.java create mode 100644 Mage.Sets/src/mage/cards/f/FrenziedRaptor.java create mode 100644 Mage.Sets/src/mage/cards/n/NestRobber.java create mode 100644 Mage.Sets/src/mage/cards/s/ShiningAerosaur.java create mode 100644 Mage.Sets/src/mage/cards/s/SkybladeOfTheLegion.java create mode 100644 Mage.Sets/src/mage/cards/s/SunriseSeeker.java create mode 100644 Mage.Sets/src/mage/cards/w/WindStrider.java diff --git a/Mage.Sets/src/mage/cards/c/ColossalDreadmaw.java b/Mage.Sets/src/mage/cards/c/ColossalDreadmaw.java new file mode 100644 index 0000000000..e1fcac90a4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ColossalDreadmaw.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class ColossalDreadmaw extends CardImpl { + + public ColossalDreadmaw(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + } + + public ColossalDreadmaw(final ColossalDreadmaw card) { + super(card); + } + + @Override + public ColossalDreadmaw copy() { + return new ColossalDreadmaw(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FrenziedRaptor.java b/Mage.Sets/src/mage/cards/f/FrenziedRaptor.java new file mode 100644 index 0000000000..6d9cc0760c --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FrenziedRaptor.java @@ -0,0 +1,59 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class FrenziedRaptor extends CardImpl { + + public FrenziedRaptor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + } + + public FrenziedRaptor(final FrenziedRaptor card) { + super(card); + } + + @Override + public FrenziedRaptor copy() { + return new FrenziedRaptor(this); + } +} diff --git a/Mage.Sets/src/mage/cards/n/NestRobber.java b/Mage.Sets/src/mage/cards/n/NestRobber.java new file mode 100644 index 0000000000..e768562b98 --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NestRobber.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.n; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class NestRobber extends CardImpl { + + public NestRobber(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + } + + public NestRobber(final NestRobber card) { + super(card); + } + + @Override + public NestRobber copy() { + return new NestRobber(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/ShiningAerosaur.java b/Mage.Sets/src/mage/cards/s/ShiningAerosaur.java new file mode 100644 index 0000000000..62b5d94763 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShiningAerosaur.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class ShiningAerosaur extends CardImpl { + + public ShiningAerosaur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + } + + public ShiningAerosaur(final ShiningAerosaur card) { + super(card); + } + + @Override + public ShiningAerosaur copy() { + return new ShiningAerosaur(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SkybladeOfTheLegion.java b/Mage.Sets/src/mage/cards/s/SkybladeOfTheLegion.java new file mode 100644 index 0000000000..2b5bb63844 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SkybladeOfTheLegion.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class SkybladeOfTheLegion extends CardImpl { + + public SkybladeOfTheLegion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + } + + public SkybladeOfTheLegion(final SkybladeOfTheLegion card) { + super(card); + } + + @Override + public SkybladeOfTheLegion copy() { + return new SkybladeOfTheLegion(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SunriseSeeker.java b/Mage.Sets/src/mage/cards/s/SunriseSeeker.java new file mode 100644 index 0000000000..0ce4951eb7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SunriseSeeker.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class SunriseSeeker extends CardImpl { + + public SunriseSeeker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // When Sunrise Seeker enters the battlefield, it explores. + } + + public SunriseSeeker(final SunriseSeeker card) { + super(card); + } + + @Override + public SunriseSeeker copy() { + return new SunriseSeeker(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WindStrider.java b/Mage.Sets/src/mage/cards/w/WindStrider.java new file mode 100644 index 0000000000..32d97120db --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WindStrider.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.w; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.abilities.keyword.FlashAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class WindStrider extends CardImpl { + + public WindStrider(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + } + + public WindStrider(final WindStrider card) { + super(card); + } + + @Override + public WindStrider copy() { + return new WindStrider(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index c62e1aa56b..5ff7e75f81 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -60,6 +60,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Charging Monstrosaur", 138, Rarity.UNCOMMON, mage.cards.c.ChargingMonstrosaur.class)); cards.add(new SetCardInfo("Chart a Course", 48, Rarity.UNCOMMON, mage.cards.c.ChartACourse.class)); cards.add(new SetCardInfo("Cobbled Wings", 233, Rarity.COMMON, mage.cards.c.CobbledWings.class)); + cards.add(new SetCardInfo("Colossal Dreadmaw", 180, Rarity.COMMON, mage.cards.c.ColossalDreadmaw.class)); cards.add(new SetCardInfo("Commune with Dinosaurs", 181, Rarity.COMMON, mage.cards.c.CommuneWithDinosaurs.class)); cards.add(new SetCardInfo("Conqueror's Foothold", 234, Rarity.RARE, mage.cards.c.ConquerorsFoothold.class)); cards.add(new SetCardInfo("Conqueror's Galleon", 234, Rarity.RARE, mage.cards.c.ConquerorsGalleon.class)); @@ -99,6 +100,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class)); cards.add(new SetCardInfo("Forest", 278, Rarity.LAND, mage.cards.basiclands.Forest.class)); cards.add(new SetCardInfo("Forest", 279, Rarity.LAND, mage.cards.basiclands.Forest.class)); + cards.add(new SetCardInfo("Frenzied Raptor", 146, Rarity.COMMON, mage.cards.f.FrenziedRaptor.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); @@ -145,6 +147,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 273, Rarity.LAND, mage.cards.basiclands.Mountain.class)); cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class)); cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class)); + cards.add(new SetCardInfo("Nest Robber", 152, Rarity.COMMON, mage.cards.n.NestRobber.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); cards.add(new SetCardInfo("Otepec Huntmaster", 153, Rarity.UNCOMMON, mage.cards.o.OtepecHuntmaster.class)); @@ -190,10 +193,12 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Shadowed Caravel", 246, Rarity.RARE, mage.cards.s.ShadowedCaravel.class)); cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); + cards.add(new SetCardInfo("Shining Aerosaur", 36, Rarity.COMMON, mage.cards.s.ShiningAerosaur.class)); cards.add(new SetCardInfo("Siren Stormtamer", 79, Rarity.UNCOMMON, mage.cards.s.SirenStormtamer.class)); cards.add(new SetCardInfo("Skittering Heartstopper", 122, Rarity.COMMON, mage.cards.s.SkitteringHeartstopper.class)); cards.add(new SetCardInfo("Skulduggery", 123, Rarity.COMMON, mage.cards.s.Skulduggery.class)); cards.add(new SetCardInfo("Sky Terror", 229, Rarity.UNCOMMON, mage.cards.s.SkyTerror.class)); + cards.add(new SetCardInfo("Skyblade of the Legion", 37, Rarity.COMMON, mage.cards.s.SkybladeOfTheLegion.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); cards.add(new SetCardInfo("Snapping Sailback", 208, Rarity.UNCOMMON, mage.cards.s.SnappingSailback.class)); cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); @@ -210,6 +215,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); + cards.add(new SetCardInfo("Sunrise Seeker", 40, Rarity.COMMON, mage.cards.s.SunriseSeeker.class)); cards.add(new SetCardInfo("Sure Strike", 166, Rarity.COMMON, mage.cards.s.SureStrike.class)); cards.add(new SetCardInfo("Swamp", 268, Rarity.LAND, mage.cards.basiclands.Swamp.class)); cards.add(new SetCardInfo("Swamp", 269, Rarity.LAND, mage.cards.basiclands.Swamp.class)); @@ -243,6 +249,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Wanted Scoundrels", 131, Rarity.UNCOMMON, mage.cards.w.WantedScoundrels.class)); cards.add(new SetCardInfo("Wildgrowth Walker", 216, Rarity.UNCOMMON, mage.cards.w.WildgrowthWalker.class)); cards.add(new SetCardInfo("Wily Goblin", 174, Rarity.UNCOMMON, mage.cards.w.WilyGoblin.class)); + cards.add(new SetCardInfo("Wind Strider", 88, Rarity.COMMON, mage.cards.w.WindStrider.class)); cards.add(new SetCardInfo("Woodland Stream", 284, Rarity.COMMON, mage.cards.w.WoodlandStream.class)); } } From 30033a68a0f08a9ca1c0ee15cc8ddb6f23e0ff48 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 15:48:23 -0400 Subject: [PATCH 051/182] Implemented several ETB explore creatures --- .../src/mage/cards/d/DireFleetInterloper.java | 69 +++++++++++++++++++ .../src/mage/cards/i/IxallisDiviner.java | 65 +++++++++++++++++ Mage.Sets/src/mage/cards/q/QueensAgent.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/cards/s/SeekersSquire.java | 65 +++++++++++++++++ Mage.Sets/src/mage/cards/s/SirenLookout.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 5 ++ 6 files changed, 342 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DireFleetInterloper.java create mode 100644 Mage.Sets/src/mage/cards/i/IxallisDiviner.java create mode 100644 Mage.Sets/src/mage/cards/q/QueensAgent.java create mode 100644 Mage.Sets/src/mage/cards/s/SeekersSquire.java create mode 100644 Mage.Sets/src/mage/cards/s/SirenLookout.java diff --git a/Mage.Sets/src/mage/cards/d/DireFleetInterloper.java b/Mage.Sets/src/mage/cards/d/DireFleetInterloper.java new file mode 100644 index 0000000000..65703fdf0d --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DireFleetInterloper.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.keyword.ExploreSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class DireFleetInterloper extends CardImpl { + + public DireFleetInterloper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Menace + this.addAbility(MenaceAbility.getInstance()); + + // When Dire Fleet Interloper enters the battlefield, it explores. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExploreSourceEffect())); + } + + public DireFleetInterloper(final DireFleetInterloper card) { + super(card); + } + + @Override + public DireFleetInterloper copy() { + return new DireFleetInterloper(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/IxallisDiviner.java b/Mage.Sets/src/mage/cards/i/IxallisDiviner.java new file mode 100644 index 0000000000..f8b9eafbe7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IxallisDiviner.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.keyword.ExploreSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class IxallisDiviner extends CardImpl { + + public IxallisDiviner(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.DRUID); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // When Ixalli's Diviner enters the battlefield, it explores. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExploreSourceEffect())); + } + + public IxallisDiviner(final IxallisDiviner card) { + super(card); + } + + @Override + public IxallisDiviner copy() { + return new IxallisDiviner(this); + } +} diff --git a/Mage.Sets/src/mage/cards/q/QueensAgent.java b/Mage.Sets/src/mage/cards/q/QueensAgent.java new file mode 100644 index 0000000000..a599004b13 --- /dev/null +++ b/Mage.Sets/src/mage/cards/q/QueensAgent.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.q; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.keyword.ExploreSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class QueensAgent extends CardImpl { + + public QueensAgent(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // When Queen's Agent enters the battlefield, it explores. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExploreSourceEffect())); + } + + public QueensAgent(final QueensAgent card) { + super(card); + } + + @Override + public QueensAgent copy() { + return new QueensAgent(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SeekersSquire.java b/Mage.Sets/src/mage/cards/s/SeekersSquire.java new file mode 100644 index 0000000000..fcae665dc1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SeekersSquire.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.keyword.ExploreSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class SeekersSquire extends CardImpl { + + public SeekersSquire(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // When Seekers' Squire enters the battlefield, it explores. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExploreSourceEffect())); + } + + public SeekersSquire(final SeekersSquire card) { + super(card); + } + + @Override + public SeekersSquire copy() { + return new SeekersSquire(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SirenLookout.java b/Mage.Sets/src/mage/cards/s/SirenLookout.java new file mode 100644 index 0000000000..534845b64e --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SirenLookout.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.keyword.ExploreSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class SirenLookout extends CardImpl { + + public SirenLookout(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.SIREN); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Siren Lookout enters the battlefield, it explores. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExploreSourceEffect())); + } + + public SirenLookout(final SirenLookout card) { + super(card); + } + + @Override + public SirenLookout copy() { + return new SirenLookout(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 5ff7e75f81..045d7eb2bc 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -79,6 +79,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Dinosaur Stampede", 140, Rarity.UNCOMMON, mage.cards.d.DinosaurStampede.class)); cards.add(new SetCardInfo("Dire Fleet Captain", 221, Rarity.UNCOMMON, mage.cards.d.DireFleetCaptain.class)); cards.add(new SetCardInfo("Dire Fleet Hoarder", 102, Rarity.COMMON, mage.cards.d.DireFleetHoarder.class)); + cards.add(new SetCardInfo("Dire Fleet Interloper", 103, Rarity.COMMON, mage.cards.d.DireFleetInterloper.class)); cards.add(new SetCardInfo("Dire Fleet Ravager", 104, Rarity.MYTHIC, mage.cards.d.DireFleetRavager.class)); cards.add(new SetCardInfo("Dowsing Dagger", 235, Rarity.RARE, mage.cards.d.DowsingDagger.class)); cards.add(new SetCardInfo("Dragonskull Summit", 252, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); @@ -122,6 +123,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Island", 267, Rarity.LAND, mage.cards.basiclands.Island.class)); cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", 191, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class)); cards.add(new SetCardInfo("Ixalan's Binding", 17, Rarity.UNCOMMON, mage.cards.i.IxalansBinding.class)); + cards.add(new SetCardInfo("Ixalli's Diviner", 192, Rarity.COMMON, mage.cards.i.IxallisDiviner.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); @@ -163,6 +165,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); + cards.add(new SetCardInfo("Queen's Agent", 114, Rarity.COMMON, mage.cards.q.QueensAgent.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); cards.add(new SetCardInfo("Raging Swordtooth", 226, Rarity.UNCOMMON, mage.cards.r.RagingSwordtooth.class)); cards.add(new SetCardInfo("Raiders' Wake", 116, Rarity.UNCOMMON, mage.cards.r.RaidersWake.class)); @@ -188,12 +191,14 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Sanguine Sacrament", 33, Rarity.RARE, mage.cards.s.SanguineSacrament.class)); cards.add(new SetCardInfo("Savage Stomp", 205, Rarity.UNCOMMON, mage.cards.s.SavageStomp.class)); cards.add(new SetCardInfo("Search for Azcanta", 74, Rarity.RARE, mage.cards.s.SearchForAzcanta.class)); + cards.add(new SetCardInfo("Seekers' Squire", 121, Rarity.UNCOMMON, mage.cards.s.SeekersSquire.class)); cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); cards.add(new SetCardInfo("Settle the Wreckage", 34, Rarity.RARE, mage.cards.s.SettleTheWreckage.class)); cards.add(new SetCardInfo("Shadowed Caravel", 246, Rarity.RARE, mage.cards.s.ShadowedCaravel.class)); cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Shining Aerosaur", 36, Rarity.COMMON, mage.cards.s.ShiningAerosaur.class)); + cards.add(new SetCardInfo("Siren Lookout", 78, Rarity.COMMON, mage.cards.s.SirenLookout.class)); cards.add(new SetCardInfo("Siren Stormtamer", 79, Rarity.UNCOMMON, mage.cards.s.SirenStormtamer.class)); cards.add(new SetCardInfo("Skittering Heartstopper", 122, Rarity.COMMON, mage.cards.s.SkitteringHeartstopper.class)); cards.add(new SetCardInfo("Skulduggery", 123, Rarity.COMMON, mage.cards.s.Skulduggery.class)); From 3785d63849ec345cb29c77f7e733d9e5918eb151 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 15:52:37 -0400 Subject: [PATCH 052/182] Implemented Encampment Keeper --- .../src/mage/cards/e/EncampmentKeeper.java | 75 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 76 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/e/EncampmentKeeper.java diff --git a/Mage.Sets/src/mage/cards/e/EncampmentKeeper.java b/Mage.Sets/src/mage/cards/e/EncampmentKeeper.java new file mode 100644 index 0000000000..92f2a2216f --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EncampmentKeeper.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.e; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class EncampmentKeeper extends CardImpl { + + public EncampmentKeeper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + + this.subtype.add(SubType.HOUND); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // {7}{W}, Sacrifice Encampment Keeper: Creatures you control get +2/+2 until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostControlledEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl("{7}{W}")); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); + } + + public EncampmentKeeper(final EncampmentKeeper card) { + super(card); + } + + @Override + public EncampmentKeeper copy() { + return new EncampmentKeeper(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 045d7eb2bc..ebbc7e1410 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -92,6 +92,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.d.DuskLegionDreadnought.class)); cards.add(new SetCardInfo("Emissary of Sunrise", 10, Rarity.UNCOMMON, mage.cards.e.EmissaryOfSunrise.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); + cards.add(new SetCardInfo("Encampment Keeper", 11, Rarity.COMMON, mage.cards.e.EncampmentKeeper.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); cards.add(new SetCardInfo("Fathom Fleet Captain", 106, Rarity.RARE, mage.cards.f.FathomFleetCaptain.class)); cards.add(new SetCardInfo("Favorable Winds", 56, Rarity.UNCOMMON, mage.cards.f.FavorableWinds.class)); From 915bcd099528bd3a28a237d658f312af1f15ca29 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 15:54:48 -0400 Subject: [PATCH 053/182] Implemented Glorifier of Dusk --- .../src/mage/cards/g/GlorifierOfDusk.java | 73 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 74 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GlorifierOfDusk.java diff --git a/Mage.Sets/src/mage/cards/g/GlorifierOfDusk.java b/Mage.Sets/src/mage/cards/g/GlorifierOfDusk.java new file mode 100644 index 0000000000..1b7d2659a1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GlorifierOfDusk.java @@ -0,0 +1,73 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class GlorifierOfDusk extends CardImpl { + + public GlorifierOfDusk(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Pay 2 life: Glorifier of Dusk gains flying until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new PayLifeCost(4))); + + // Pay 2 life: Glorifier of Dusk gains vigilance until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn), new PayLifeCost(4))); + } + + public GlorifierOfDusk(final GlorifierOfDusk card) { + super(card); + } + + @Override + public GlorifierOfDusk copy() { + return new GlorifierOfDusk(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index ebbc7e1410..8b644c337b 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -105,6 +105,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Frenzied Raptor", 146, Rarity.COMMON, mage.cards.f.FrenziedRaptor.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); + cards.add(new SetCardInfo("Glorifier of Dusk", 12, Rarity.UNCOMMON, mage.cards.g.GlorifierOfDusk.class)); cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); cards.add(new SetCardInfo("Grasping Current", 282, Rarity.RARE, mage.cards.g.GraspingCurrent.class)); cards.add(new SetCardInfo("Grazing Whiptail", 190, Rarity.COMMON, mage.cards.g.GrazingWhiptail.class)); From adeb2b61972aea2290313b31fc5c7a597a24042c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:01:15 -0400 Subject: [PATCH 054/182] Implemented Imperial Aerosaur --- .../src/mage/cards/i/ImperialAerosaur.java | 92 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 93 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/ImperialAerosaur.java diff --git a/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java b/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java new file mode 100644 index 0000000000..c7831a9b20 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java @@ -0,0 +1,92 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class ImperialAerosaur extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature you control"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(new AnotherPredicate()); + } + + public ImperialAerosaur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Imperial Aerosaur enters the battlefield, another target creature you control gets +1/+1 and gains flying until end of turn. + Effect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn); + effect.setText("another target creature you control gets +1/+1"); + Ability ability = new EntersBattlefieldTriggeredAbility(effect); + ability.addEffect(effect); + effect = new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and gains flying until end of turn"); + ability.addEffect(effect); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public ImperialAerosaur(final ImperialAerosaur card) { + super(card); + } + + @Override + public ImperialAerosaur copy() { + return new ImperialAerosaur(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 8b644c337b..de6600df98 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -118,6 +118,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Huatli's Snubhorn", 286, Rarity.COMMON, mage.cards.h.HuatlisSnubhorn.class)); cards.add(new SetCardInfo("Huatli's Spurring", 287, Rarity.UNCOMMON, mage.cards.h.HuatlisSpurring.class)); cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); + cards.add(new SetCardInfo("Imperial Aerosaur", 14, Rarity.UNCOMMON, mage.cards.i.ImperialAerosaur.class)); cards.add(new SetCardInfo("Imperial Lancer", 15, Rarity.UNCOMMON, mage.cards.i.ImperialLancer.class)); cards.add(new SetCardInfo("Island", 264, Rarity.LAND, mage.cards.basiclands.Island.class)); cards.add(new SetCardInfo("Island", 265, Rarity.LAND, mage.cards.basiclands.Island.class)); From 347fb427cc3a9cbf857a067602dcb812a225638f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:02:54 -0400 Subject: [PATCH 055/182] Implemented Inspiring Cleric --- .../src/mage/cards/i/InspiringCleric.java | 65 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 66 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/InspiringCleric.java diff --git a/Mage.Sets/src/mage/cards/i/InspiringCleric.java b/Mage.Sets/src/mage/cards/i/InspiringCleric.java new file mode 100644 index 0000000000..765707130d --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InspiringCleric.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class InspiringCleric extends CardImpl { + + public InspiringCleric(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // When Inspiring Cleric enters the battlefield, you gain 4 life. + this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(4))); + } + + public InspiringCleric(final InspiringCleric card) { + super(card); + } + + @Override + public InspiringCleric copy() { + return new InspiringCleric(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index de6600df98..d9ae924672 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -120,6 +120,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); cards.add(new SetCardInfo("Imperial Aerosaur", 14, Rarity.UNCOMMON, mage.cards.i.ImperialAerosaur.class)); cards.add(new SetCardInfo("Imperial Lancer", 15, Rarity.UNCOMMON, mage.cards.i.ImperialLancer.class)); + cards.add(new SetCardInfo("Inspiring Cleric", 16, Rarity.UNCOMMON, mage.cards.i.InspiringCleric.class)); cards.add(new SetCardInfo("Island", 264, Rarity.LAND, mage.cards.basiclands.Island.class)); cards.add(new SetCardInfo("Island", 265, Rarity.LAND, mage.cards.basiclands.Island.class)); cards.add(new SetCardInfo("Island", 266, Rarity.LAND, mage.cards.basiclands.Island.class)); From 4ace79286295ab667e84a1e0d136fce41b262d3d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:04:18 -0400 Subject: [PATCH 056/182] Implemented Legion's Judgment --- .../src/mage/cards/l/LegionsJudgment.java | 68 +++++++++++++++++++ .../src/mage/cards/s/SmiteTheMonstrous.java | 3 +- Mage.Sets/src/mage/sets/Ixalan.java | 1 + 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/l/LegionsJudgment.java diff --git a/Mage.Sets/src/mage/cards/l/LegionsJudgment.java b/Mage.Sets/src/mage/cards/l/LegionsJudgment.java new file mode 100644 index 0000000000..2f39c6af53 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LegionsJudgment.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.l; + +import java.util.UUID; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.target.TargetPermanent; + +/** + * + * @author TheElk801 + */ +public class LegionsJudgment extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power 4 or greater"); + + static { + filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 3)); + } + + public LegionsJudgment(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}"); + + // Destroy target creature with power 4 or greater. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + } + + public LegionsJudgment(final LegionsJudgment card) { + super(card); + } + + @Override + public LegionsJudgment copy() { + return new LegionsJudgment(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SmiteTheMonstrous.java b/Mage.Sets/src/mage/cards/s/SmiteTheMonstrous.java index 29dca30782..990ff187e7 100644 --- a/Mage.Sets/src/mage/cards/s/SmiteTheMonstrous.java +++ b/Mage.Sets/src/mage/cards/s/SmiteTheMonstrous.java @@ -49,8 +49,7 @@ public class SmiteTheMonstrous extends CardImpl { } public SmiteTheMonstrous(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{W}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W}"); // Destroy target creature with power 4 or greater. this.getSpellAbility().addEffect(new DestroyTargetEffect()); diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index d9ae924672..1fcd207b96 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -137,6 +137,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Kopala, Warden of Waves", 61, Rarity.RARE, mage.cards.k.KopalaWardenOfWaves.class)); cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); cards.add(new SetCardInfo("Legion Conquistador", 20, Rarity.COMMON, mage.cards.l.LegionConquistador.class)); + cards.add(new SetCardInfo("Legion's Judgment", 21, Rarity.COMMON, mage.cards.l.LegionsJudgment.class)); cards.add(new SetCardInfo("Legion's Landing", 22, Rarity.RARE, mage.cards.l.LegionsLanding.class)); cards.add(new SetCardInfo("Lightning-Rig Crew", 150, Rarity.UNCOMMON, mage.cards.l.LightningRigCrew.class)); cards.add(new SetCardInfo("Lightning Strike", 149, Rarity.UNCOMMON, mage.cards.l.LightningStrike.class)); From 8776e30c2905e1a568b0872fdc8dfc53714bc703 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:05:51 -0400 Subject: [PATCH 057/182] Implemented Paladin of the Bloodstained --- .../cards/p/PaladinOfTheBloodstained.java | 66 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 67 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PaladinOfTheBloodstained.java diff --git a/Mage.Sets/src/mage/cards/p/PaladinOfTheBloodstained.java b/Mage.Sets/src/mage/cards/p/PaladinOfTheBloodstained.java new file mode 100644 index 0000000000..00bf68a71d --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PaladinOfTheBloodstained.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.IxalanVampireToken; + +/** + * + * @author TheElk801 + */ +public class PaladinOfTheBloodstained extends CardImpl { + + public PaladinOfTheBloodstained(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // When Paladin of the Bloodstained enters the battlefield, create a 1/1 white Vampire creature token with lifelink. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new IxalanVampireToken()))); + } + + public PaladinOfTheBloodstained(final PaladinOfTheBloodstained card) { + super(card); + } + + @Override + public PaladinOfTheBloodstained copy() { + return new PaladinOfTheBloodstained(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 1fcd207b96..1e77240644 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -159,6 +159,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); cards.add(new SetCardInfo("Otepec Huntmaster", 153, Rarity.UNCOMMON, mage.cards.o.OtepecHuntmaster.class)); cards.add(new SetCardInfo("Overflowing Insight", 66, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); + cards.add(new SetCardInfo("Paladin of the Bloodstained", 25, Rarity.COMMON, mage.cards.p.PaladinOfTheBloodstained.class)); cards.add(new SetCardInfo("Perilous Voyage", 67, Rarity.UNCOMMON, mage.cards.p.PerilousVoyage.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); cards.add(new SetCardInfo("Pirate's Cutlass", 242, Rarity.COMMON, mage.cards.p.PiratesCutlass.class)); From 39026c3d27624012371fdf761dc8e220f8bee778 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:07:23 -0400 Subject: [PATCH 058/182] Implemented Pious Interdiction --- .../src/mage/cards/p/PiousInterdiction.java | 81 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PiousInterdiction.java diff --git a/Mage.Sets/src/mage/cards/p/PiousInterdiction.java b/Mage.Sets/src/mage/cards/p/PiousInterdiction.java new file mode 100644 index 0000000000..4f54325717 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PiousInterdiction.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.combat.CantAttackBlockAttachedEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class PiousInterdiction extends CardImpl { + + public PiousInterdiction(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // When Pious Interdiction enters the battlefield, you gain 2 life. + this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(2))); + + // Enchanted creature can't attack or block. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackBlockAttachedEffect(AttachmentType.AURA))); + } + + public PiousInterdiction(final PiousInterdiction card) { + super(card); + } + + @Override + public PiousInterdiction copy() { + return new PiousInterdiction(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 1e77240644..5c6c39b10c 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -162,6 +162,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Paladin of the Bloodstained", 25, Rarity.COMMON, mage.cards.p.PaladinOfTheBloodstained.class)); cards.add(new SetCardInfo("Perilous Voyage", 67, Rarity.UNCOMMON, mage.cards.p.PerilousVoyage.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); + cards.add(new SetCardInfo("Pious Interdiction", 26, Rarity.COMMON, mage.cards.p.PiousInterdiction.class)); cards.add(new SetCardInfo("Pirate's Cutlass", 242, Rarity.COMMON, mage.cards.p.PiratesCutlass.class)); cards.add(new SetCardInfo("Plains", 260, Rarity.LAND, mage.cards.basiclands.Plains.class)); cards.add(new SetCardInfo("Plains", 261, Rarity.LAND, mage.cards.basiclands.Plains.class)); From 3be116b49f9ed248ba3b5124f60c3796247c61fc Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:13:42 -0400 Subject: [PATCH 059/182] Implemented conditional boost cards --- .../src/mage/cards/h/HeadstrongBrute.java | 86 +++++++++++++++++++ .../src/mage/cards/p/PterodonKnight.java | 80 +++++++++++++++++ .../src/mage/cards/s/ShaperApprentice.java | 82 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 3 + 4 files changed, 251 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HeadstrongBrute.java create mode 100644 Mage.Sets/src/mage/cards/p/PterodonKnight.java create mode 100644 Mage.Sets/src/mage/cards/s/ShaperApprentice.java diff --git a/Mage.Sets/src/mage/cards/h/HeadstrongBrute.java b/Mage.Sets/src/mage/cards/h/HeadstrongBrute.java new file mode 100644 index 0000000000..c2b9c57a9d --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HeadstrongBrute.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.h; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.CantBlockAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author TheElk801 + */ +public class HeadstrongBrute extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("another Pirate"); + + static { + filter.add(new SubtypePredicate(SubType.PIRATE)); + filter.add(new AnotherPredicate()); + } + + public HeadstrongBrute(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.ORC); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Headstrong Brute can't block. + this.addAbility(new CantBlockAbility()); + + // Headstrong Brute has menace as long as you control another Pirate. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new ConditionalContinuousEffect(new GainAbilitySourceEffect(MenaceAbility.getInstance(), Duration.WhileOnBattlefield), + new PermanentsOnTheBattlefieldCondition(filter), "{this} has menace as long as you control another Pirate"))); + } + + public HeadstrongBrute(final HeadstrongBrute card) { + super(card); + } + + @Override + public HeadstrongBrute copy() { + return new HeadstrongBrute(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PterodonKnight.java b/Mage.Sets/src/mage/cards/p/PterodonKnight.java new file mode 100644 index 0000000000..12ce036230 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PterodonKnight.java @@ -0,0 +1,80 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author TheElk801 + */ +public class PterodonKnight extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Dinosaur"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + } + + public PterodonKnight(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Pterodon Knight has flying as long as you control a Dinosaur. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new ConditionalContinuousEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield), + new PermanentsOnTheBattlefieldCondition(filter), "{this} has flying as long as you control a Dinosaur"))); + } + + public PterodonKnight(final PterodonKnight card) { + super(card); + } + + @Override + public PterodonKnight copy() { + return new PterodonKnight(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/ShaperApprentice.java b/Mage.Sets/src/mage/cards/s/ShaperApprentice.java new file mode 100644 index 0000000000..874f84b0a0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShaperApprentice.java @@ -0,0 +1,82 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author TheElk801 + */ +public class ShaperApprentice extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("another Merfolk"); + + static { + filter.add(new SubtypePredicate(SubType.MERFOLK)); + filter.add(new AnotherPredicate()); + } + + public ShaperApprentice(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Shaper Apprentice has flying as long as you control another Merfolk. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new ConditionalContinuousEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield), + new PermanentsOnTheBattlefieldCondition(filter), "{this} has flying as long as you control another Merfolk"))); + } + + public ShaperApprentice(final ShaperApprentice card) { + super(card); + } + + @Override + public ShaperApprentice copy() { + return new ShaperApprentice(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 5c6c39b10c..b6c68807d3 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -110,6 +110,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Grasping Current", 282, Rarity.RARE, mage.cards.g.GraspingCurrent.class)); cards.add(new SetCardInfo("Grazing Whiptail", 190, Rarity.COMMON, mage.cards.g.GrazingWhiptail.class)); cards.add(new SetCardInfo("Growing Rites of Itlimoc", 191, Rarity.RARE, mage.cards.g.GrowingRitesOfItlimoc.class)); + cards.add(new SetCardInfo("Headstrong Brute", 147, Rarity.COMMON, mage.cards.h.HeadstrongBrute.class)); cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); cards.add(new SetCardInfo("Hijack", 148, Rarity.COMMON, mage.cards.h.Hijack.class)); @@ -172,6 +173,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); + cards.add(new SetCardInfo("Pterodon Knight", 28, Rarity.COMMON, mage.cards.p.PterodonKnight.class)); cards.add(new SetCardInfo("Queen's Agent", 114, Rarity.COMMON, mage.cards.q.QueensAgent.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); cards.add(new SetCardInfo("Raging Swordtooth", 226, Rarity.UNCOMMON, mage.cards.r.RagingSwordtooth.class)); @@ -202,6 +204,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); cards.add(new SetCardInfo("Settle the Wreckage", 34, Rarity.RARE, mage.cards.s.SettleTheWreckage.class)); cards.add(new SetCardInfo("Shadowed Caravel", 246, Rarity.RARE, mage.cards.s.ShadowedCaravel.class)); + cards.add(new SetCardInfo("Shaper Apprentice", 75, Rarity.COMMON, mage.cards.s.ShaperApprentice.class)); cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Shining Aerosaur", 36, Rarity.COMMON, mage.cards.s.ShiningAerosaur.class)); From 98808debcf00a5d9f75785d1fb27c793654c82a2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:16:03 -0400 Subject: [PATCH 060/182] Implemented Queen's Commission --- .../src/mage/cards/q/QueensCommission.java | 58 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 59 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/q/QueensCommission.java diff --git a/Mage.Sets/src/mage/cards/q/QueensCommission.java b/Mage.Sets/src/mage/cards/q/QueensCommission.java new file mode 100644 index 0000000000..97cf10c0f6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/q/QueensCommission.java @@ -0,0 +1,58 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.q; + +import java.util.UUID; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.IxalanVampireToken; + +/** + * + * @author TheElk801 + */ +public class QueensCommission extends CardImpl { + + public QueensCommission(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}"); + + // Create two 1/1 white Vampire creature tokens with lifelink. + this.getSpellAbility().addEffect(new CreateTokenEffect(new IxalanVampireToken(), 2)); + } + + public QueensCommission(final QueensCommission card) { + super(card); + } + + @Override + public QueensCommission copy() { + return new QueensCommission(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index b6c68807d3..4fb8954b96 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -176,6 +176,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Pterodon Knight", 28, Rarity.COMMON, mage.cards.p.PterodonKnight.class)); cards.add(new SetCardInfo("Queen's Agent", 114, Rarity.COMMON, mage.cards.q.QueensAgent.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); + cards.add(new SetCardInfo("Queen's Commission", 29, Rarity.COMMON, mage.cards.q.QueensCommission.class)); cards.add(new SetCardInfo("Raging Swordtooth", 226, Rarity.UNCOMMON, mage.cards.r.RagingSwordtooth.class)); cards.add(new SetCardInfo("Raiders' Wake", 116, Rarity.UNCOMMON, mage.cards.r.RaidersWake.class)); cards.add(new SetCardInfo("Rampaging Ferocidon", 154, Rarity.RARE, mage.cards.r.RampagingFerocidon.class)); From 8e646e3e18bf179bb2c514076a3609a4d101fa3b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:19:58 -0400 Subject: [PATCH 061/182] Implemented Rallying Roar --- Mage.Sets/src/mage/cards/r/RallyingRoar.java | 61 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 62 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RallyingRoar.java diff --git a/Mage.Sets/src/mage/cards/r/RallyingRoar.java b/Mage.Sets/src/mage/cards/r/RallyingRoar.java new file mode 100644 index 0000000000..2f73e27f35 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RallyingRoar.java @@ -0,0 +1,61 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.abilities.effects.common.UntapAllControllerEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.common.FilterControlledCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class RallyingRoar extends CardImpl { + + public RallyingRoar(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}"); + + // Creatures you control get +1/+1 until end of turn. Untap them. + this.getSpellAbility().addEffect(new BoostControlledEffect(1, 1, Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapAllControllerEffect(new FilterControlledCreaturePermanent(), "Untap them.")); + } + + public RallyingRoar(final RallyingRoar card) { + super(card); + } + + @Override + public RallyingRoar copy() { + return new RallyingRoar(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 4fb8954b96..20fddd12a7 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -179,6 +179,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Queen's Commission", 29, Rarity.COMMON, mage.cards.q.QueensCommission.class)); cards.add(new SetCardInfo("Raging Swordtooth", 226, Rarity.UNCOMMON, mage.cards.r.RagingSwordtooth.class)); cards.add(new SetCardInfo("Raiders' Wake", 116, Rarity.UNCOMMON, mage.cards.r.RaidersWake.class)); + cards.add(new SetCardInfo("Rallying Roar", 30, Rarity.UNCOMMON, mage.cards.r.RallyingRoar.class)); cards.add(new SetCardInfo("Rampaging Ferocidon", 154, Rarity.RARE, mage.cards.r.RampagingFerocidon.class)); cards.add(new SetCardInfo("Ranging Raptors", 201, Rarity.UNCOMMON, mage.cards.r.RangingRaptors.class)); cards.add(new SetCardInfo("Raptor Companion", 31, Rarity.COMMON, mage.cards.r.RaptorCompanion.class)); From 1b07db94e7e733c95145cb0f79ae51b5fbf8cee6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:24:15 -0400 Subject: [PATCH 062/182] Implemented Ritual of Rejuvenation --- .../mage/cards/r/RitualOfRejuvenation.java | 60 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 61 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RitualOfRejuvenation.java diff --git a/Mage.Sets/src/mage/cards/r/RitualOfRejuvenation.java b/Mage.Sets/src/mage/cards/r/RitualOfRejuvenation.java new file mode 100644 index 0000000000..7a5613d6b3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RitualOfRejuvenation.java @@ -0,0 +1,60 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class RitualOfRejuvenation extends CardImpl { + + public RitualOfRejuvenation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}"); + + // You gain 4 life. + this.getSpellAbility().addEffect(new GainLifeEffect(4)); + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + } + + public RitualOfRejuvenation(final RitualOfRejuvenation card) { + super(card); + } + + @Override + public RitualOfRejuvenation copy() { + return new RitualOfRejuvenation(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 20fddd12a7..2c263a037e 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -191,6 +191,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Rigging Runner", 157, Rarity.UNCOMMON, mage.cards.r.RiggingRunner.class)); cards.add(new SetCardInfo("Rile", 158, Rarity.COMMON, mage.cards.r.Rile.class)); cards.add(new SetCardInfo("Ripjaw Raptor", 203, Rarity.RARE, mage.cards.r.RipjawRaptor.class)); + cards.add(new SetCardInfo("Ritual of Rejuvenation", 32, Rarity.COMMON, mage.cards.r.RitualOfRejuvenation.class)); cards.add(new SetCardInfo("River Sneak", 70, Rarity.UNCOMMON, mage.cards.r.RiverSneak.class)); cards.add(new SetCardInfo("River's Rebuke", 71, Rarity.RARE, mage.cards.r.RiversRebuke.class)); cards.add(new SetCardInfo("Rootbound Crag", 256, Rarity.RARE, mage.cards.r.RootboundCrag.class)); From 783cd81d4aba326d2c21f325bb4e5d70d84c60e4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:30:10 -0400 Subject: [PATCH 063/182] Implemented Sheltering Light --- .../src/mage/cards/s/ShelteringLight.java | 63 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 64 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ShelteringLight.java diff --git a/Mage.Sets/src/mage/cards/s/ShelteringLight.java b/Mage.Sets/src/mage/cards/s/ShelteringLight.java new file mode 100644 index 0000000000..c8fdc1237e --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShelteringLight.java @@ -0,0 +1,63 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class ShelteringLight extends CardImpl { + + public ShelteringLight(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); + + // Target creature gains indestructible until end of turn. Scry 1. + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new ScryEffect(1)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public ShelteringLight(final ShelteringLight card) { + super(card); + } + + @Override + public ShelteringLight copy() { + return new ShelteringLight(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 2c263a037e..3e79b7eab5 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -210,6 +210,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Shaper Apprentice", 75, Rarity.COMMON, mage.cards.s.ShaperApprentice.class)); cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); + cards.add(new SetCardInfo("Sheltering Light", 35, Rarity.UNCOMMON, mage.cards.s.ShelteringLight.class)); cards.add(new SetCardInfo("Shining Aerosaur", 36, Rarity.COMMON, mage.cards.s.ShiningAerosaur.class)); cards.add(new SetCardInfo("Siren Lookout", 78, Rarity.COMMON, mage.cards.s.SirenLookout.class)); cards.add(new SetCardInfo("Siren Stormtamer", 79, Rarity.UNCOMMON, mage.cards.s.SirenStormtamer.class)); From 7bdc73c9eae246e2b6e80057ac13052174ab58a5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:32:15 -0400 Subject: [PATCH 064/182] Implemented Slash of Talons --- Mage.Sets/src/mage/cards/s/SlashOfTalons.java | 59 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 60 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SlashOfTalons.java diff --git a/Mage.Sets/src/mage/cards/s/SlashOfTalons.java b/Mage.Sets/src/mage/cards/s/SlashOfTalons.java new file mode 100644 index 0000000000..59b8aeb183 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SlashOfTalons.java @@ -0,0 +1,59 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetAttackingOrBlockingCreature; + +/** + * + * @author TheElk801 + */ +public class SlashOfTalons extends CardImpl { + + public SlashOfTalons(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); + + // Slash of Talons deals 2 damage to target attacking or blocking creature. + getSpellAbility().addEffect(new DamageTargetEffect(2)); + getSpellAbility().addTarget(new TargetAttackingOrBlockingCreature()); + } + + public SlashOfTalons(final SlashOfTalons card) { + super(card); + } + + @Override + public SlashOfTalons copy() { + return new SlashOfTalons(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 3e79b7eab5..ba6784e8a6 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -218,6 +218,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Skulduggery", 123, Rarity.COMMON, mage.cards.s.Skulduggery.class)); cards.add(new SetCardInfo("Sky Terror", 229, Rarity.UNCOMMON, mage.cards.s.SkyTerror.class)); cards.add(new SetCardInfo("Skyblade of the Legion", 37, Rarity.COMMON, mage.cards.s.SkybladeOfTheLegion.class)); + cards.add(new SetCardInfo("Slash of Talons", 38, Rarity.COMMON, mage.cards.s.SlashOfTalons.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); cards.add(new SetCardInfo("Snapping Sailback", 208, Rarity.UNCOMMON, mage.cards.s.SnappingSailback.class)); cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); From bc905b48b25aa058f57e9e440c9cf03a0805107f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:36:16 -0400 Subject: [PATCH 065/182] Implemented Territorial Hammerskull --- .../mage/cards/t/TerritorialHammerskull.java | 77 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 78 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TerritorialHammerskull.java diff --git a/Mage.Sets/src/mage/cards/t/TerritorialHammerskull.java b/Mage.Sets/src/mage/cards/t/TerritorialHammerskull.java new file mode 100644 index 0000000000..41c29ee8fa --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TerritorialHammerskull.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.common.TapTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class TerritorialHammerskull extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public TerritorialHammerskull(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Whenever Territorial Hammerskull attacks, tap target creature an opponent controls. + Ability ability = new AttacksTriggeredAbility(new TapTargetEffect(), false); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public TerritorialHammerskull(final TerritorialHammerskull card) { + super(card); + } + + @Override + public TerritorialHammerskull copy() { + return new TerritorialHammerskull(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index ba6784e8a6..f6b64afd42 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -243,6 +243,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 271, Rarity.LAND, mage.cards.basiclands.Swamp.class)); cards.add(new SetCardInfo("Sword-Point Diplomacy", 126, Rarity.RARE, mage.cards.s.SwordPointDiplomacy.class)); cards.add(new SetCardInfo("Temple of Aclazotz", 90, Rarity.RARE, mage.cards.t.TempleOfAclazotz.class)); + cards.add(new SetCardInfo("Territorial Hammerskull", 41, Rarity.COMMON, mage.cards.t.TerritorialHammerskull.class)); cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); cards.add(new SetCardInfo("Thundering Spineback", 210, Rarity.UNCOMMON, mage.cards.t.ThunderingSpineback.class)); cards.add(new SetCardInfo("Tilonalli's Knight", 169, Rarity.COMMON, mage.cards.t.TilonallisKnight.class)); From ee10d8494568394071ac31bc39587b3c3ef8b70e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:38:17 -0400 Subject: [PATCH 066/182] Implemented Depths of Desire --- .../src/mage/cards/d/DepthsOfDesire.java | 62 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 63 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DepthsOfDesire.java diff --git a/Mage.Sets/src/mage/cards/d/DepthsOfDesire.java b/Mage.Sets/src/mage/cards/d/DepthsOfDesire.java new file mode 100644 index 0000000000..04130305f1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DepthsOfDesire.java @@ -0,0 +1,62 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.TreasureToken; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class DepthsOfDesire extends CardImpl { + + public DepthsOfDesire(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); + + // Return target creature to its owner's hand. Create a colorless Treasure token with "{t}, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addEffect(new CreateTokenEffect(new TreasureToken())); + } + + public DepthsOfDesire(final DepthsOfDesire card) { + super(card); + } + + @Override + public DepthsOfDesire copy() { + return new DepthsOfDesire(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index f6b64afd42..10ec9f0fb2 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -75,6 +75,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Deeproot Waters", 51, Rarity.UNCOMMON, mage.cards.d.DeeprootWaters.class)); cards.add(new SetCardInfo("Demolish", 139, Rarity.COMMON, mage.cards.d.Demolish.class)); cards.add(new SetCardInfo("Demystify", 8, Rarity.COMMON, mage.cards.d.Demystify.class)); + cards.add(new SetCardInfo("Depths of Desire", 52, Rarity.COMMON, mage.cards.d.DepthsOfDesire.class)); cards.add(new SetCardInfo("Desperate Castaways", 101, Rarity.COMMON, mage.cards.d.DesperateCastaways.class)); cards.add(new SetCardInfo("Dinosaur Stampede", 140, Rarity.UNCOMMON, mage.cards.d.DinosaurStampede.class)); cards.add(new SetCardInfo("Dire Fleet Captain", 221, Rarity.UNCOMMON, mage.cards.d.DireFleetCaptain.class)); From 0c4497c243b59b77f5e6fb38d12a5fe3589de83a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:40:56 -0400 Subject: [PATCH 067/182] Implemented One with the Wind --- .../src/mage/cards/o/OneWithTheWind.java | 80 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 81 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/OneWithTheWind.java diff --git a/Mage.Sets/src/mage/cards/o/OneWithTheWind.java b/Mage.Sets/src/mage/cards/o/OneWithTheWind.java new file mode 100644 index 0000000000..a3a3915c01 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OneWithTheWind.java @@ -0,0 +1,80 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.o; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class OneWithTheWind extends CardImpl { + + public OneWithTheWind(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant Creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets +2/+2 and has flying. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA))); + } + + public OneWithTheWind(final OneWithTheWind card) { + super(card); + } + + @Override + public OneWithTheWind copy() { + return new OneWithTheWind(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 10ec9f0fb2..0415d6ec74 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -158,6 +158,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class)); cards.add(new SetCardInfo("Nest Robber", 152, Rarity.COMMON, mage.cards.n.NestRobber.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); + cards.add(new SetCardInfo("One with the Wind", 64, Rarity.COMMON, mage.cards.o.OneWithTheWind.class)); cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); cards.add(new SetCardInfo("Otepec Huntmaster", 153, Rarity.UNCOMMON, mage.cards.o.OtepecHuntmaster.class)); cards.add(new SetCardInfo("Overflowing Insight", 66, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); From 59e35edc9147b77b086a7f33fb7131f02c2fc162 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:42:51 -0400 Subject: [PATCH 068/182] Implemented Pirate's Prize --- Mage.Sets/src/mage/cards/p/PiratesPrize.java | 60 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 61 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PiratesPrize.java diff --git a/Mage.Sets/src/mage/cards/p/PiratesPrize.java b/Mage.Sets/src/mage/cards/p/PiratesPrize.java new file mode 100644 index 0000000000..8676bdc385 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PiratesPrize.java @@ -0,0 +1,60 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.TreasureToken; + +/** + * + * @author TheElk801 + */ +public class PiratesPrize extends CardImpl { + + public PiratesPrize(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}"); + + // Draw two cards. Create a colorless Treasure artifact token with "{t}, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); + this.getSpellAbility().addEffect(new CreateTokenEffect(new TreasureToken())); + } + + public PiratesPrize(final PiratesPrize card) { + super(card); + } + + @Override + public PiratesPrize copy() { + return new PiratesPrize(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 0415d6ec74..bba965c83b 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -167,6 +167,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); cards.add(new SetCardInfo("Pious Interdiction", 26, Rarity.COMMON, mage.cards.p.PiousInterdiction.class)); cards.add(new SetCardInfo("Pirate's Cutlass", 242, Rarity.COMMON, mage.cards.p.PiratesCutlass.class)); + cards.add(new SetCardInfo("Pirate's Prize", 68, Rarity.COMMON, mage.cards.p.PiratesPrize.class)); cards.add(new SetCardInfo("Plains", 260, Rarity.LAND, mage.cards.basiclands.Plains.class)); cards.add(new SetCardInfo("Plains", 261, Rarity.LAND, mage.cards.basiclands.Plains.class)); cards.add(new SetCardInfo("Plains", 262, Rarity.LAND, mage.cards.basiclands.Plains.class)); From b84e223ffeb9121867995cc60d71ce766433fbdd Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:45:26 -0400 Subject: [PATCH 069/182] Implemented Run Aground --- Mage.Sets/src/mage/cards/r/RunAground.java | 60 ++++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 61 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RunAground.java diff --git a/Mage.Sets/src/mage/cards/r/RunAground.java b/Mage.Sets/src/mage/cards/r/RunAground.java new file mode 100644 index 0000000000..c6005cd266 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RunAground.java @@ -0,0 +1,60 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.abilities.effects.common.PutOnLibraryTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; + +/** + * + * @author TheElk801 + */ +public class RunAground extends CardImpl { + + public RunAground(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}"); + + // Put target artifact or creature on top of it's owner's library. + this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE)); + this.getSpellAbility().addEffect(new PutOnLibraryTargetEffect(true)); + } + + public RunAground(final RunAground card) { + super(card); + } + + @Override + public RunAground copy() { + return new RunAground(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index bba965c83b..cf70faa2d6 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -201,6 +201,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Rowdy Crew", 159, Rarity.MYTHIC, mage.cards.r.RowdyCrew.class)); cards.add(new SetCardInfo("Ruin Raider", 118, Rarity.RARE, mage.cards.r.RuinRaider.class)); cards.add(new SetCardInfo("Rummaging Goblin", 160, Rarity.COMMON, mage.cards.r.RummagingGoblin.class)); + cards.add(new SetCardInfo("Run Aground", 72, Rarity.COMMON, mage.cards.r.RunAground.class)); cards.add(new SetCardInfo("Ruthless Knave", 119, Rarity.UNCOMMON, mage.cards.r.RuthlessKnave.class)); cards.add(new SetCardInfo("Sanctum Seeker", 120, Rarity.RARE, mage.cards.s.SanctumSeeker.class)); cards.add(new SetCardInfo("Sanguine Sacrament", 33, Rarity.RARE, mage.cards.s.SanguineSacrament.class)); From a4a5db632c0e6762685cd7a4bb4f11fd34f2c6cc Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:47:41 -0400 Subject: [PATCH 070/182] Implemented Sailor of Means --- Mage.Sets/src/mage/cards/s/SailorOfMeans.java | 66 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 67 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SailorOfMeans.java diff --git a/Mage.Sets/src/mage/cards/s/SailorOfMeans.java b/Mage.Sets/src/mage/cards/s/SailorOfMeans.java new file mode 100644 index 0000000000..b8d43b12cd --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SailorOfMeans.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.TreasureToken; + +/** + * + * @author TheElk801 + */ +public class SailorOfMeans extends CardImpl { + + public SailorOfMeans(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // When Sailor of Means enters the battlefield, create a colorless Treasure artifact token with "{t}, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new TreasureToken()))); + } + + public SailorOfMeans(final SailorOfMeans card) { + super(card); + } + + @Override + public SailorOfMeans copy() { + return new SailorOfMeans(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index cf70faa2d6..c314f98f45 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -203,6 +203,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Rummaging Goblin", 160, Rarity.COMMON, mage.cards.r.RummagingGoblin.class)); cards.add(new SetCardInfo("Run Aground", 72, Rarity.COMMON, mage.cards.r.RunAground.class)); cards.add(new SetCardInfo("Ruthless Knave", 119, Rarity.UNCOMMON, mage.cards.r.RuthlessKnave.class)); + cards.add(new SetCardInfo("Sailor of Means", 73, Rarity.COMMON, mage.cards.s.SailorOfMeans.class)); cards.add(new SetCardInfo("Sanctum Seeker", 120, Rarity.RARE, mage.cards.s.SanctumSeeker.class)); cards.add(new SetCardInfo("Sanguine Sacrament", 33, Rarity.RARE, mage.cards.s.SanguineSacrament.class)); cards.add(new SetCardInfo("Savage Stomp", 205, Rarity.UNCOMMON, mage.cards.s.SavageStomp.class)); From 6fe2eaf6a338017664bd0009f8c48483bc2fb4c6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 16:51:11 -0400 Subject: [PATCH 071/182] Implemented Shore Keeper --- Mage.Sets/src/mage/cards/s/ShoreKeeper.java | 70 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + .../src/main/java/mage/constants/SubType.java | 2 +- 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/s/ShoreKeeper.java diff --git a/Mage.Sets/src/mage/cards/s/ShoreKeeper.java b/Mage.Sets/src/mage/cards/s/ShoreKeeper.java new file mode 100644 index 0000000000..c243f26051 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShoreKeeper.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class ShoreKeeper extends CardImpl { + + public ShoreKeeper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); + + this.subtype.add(SubType.TRILOBITE); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // {7}{u}, {t}, Sacrifice Shore Keeper: Draw three cards. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(3), new ManaCostsImpl("{7}{W}")); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); + } + + public ShoreKeeper(final ShoreKeeper card) { + super(card); + } + + @Override + public ShoreKeeper copy() { + return new ShoreKeeper(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index c314f98f45..9ebe3b3203 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -217,6 +217,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Sheltering Light", 35, Rarity.UNCOMMON, mage.cards.s.ShelteringLight.class)); cards.add(new SetCardInfo("Shining Aerosaur", 36, Rarity.COMMON, mage.cards.s.ShiningAerosaur.class)); + cards.add(new SetCardInfo("Shore Keeper", 77, Rarity.COMMON, mage.cards.s.ShoreKeeper.class)); cards.add(new SetCardInfo("Siren Lookout", 78, Rarity.COMMON, mage.cards.s.SirenLookout.class)); cards.add(new SetCardInfo("Siren Stormtamer", 79, Rarity.UNCOMMON, mage.cards.s.SirenStormtamer.class)); cards.add(new SetCardInfo("Skittering Heartstopper", 122, Rarity.COMMON, mage.cards.s.SkitteringHeartstopper.class)); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index aac316f43c..2cfe62d1e5 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -320,7 +320,7 @@ public enum SubType { TURTLE("Turtle", SubTypeSet.CreatureType), TUSKEN("Tusken", SubTypeSet.CreatureType, true), // Star Wars TROOPER("Trooper", SubTypeSet.CreatureType, true), // Star Wars - TRILOBYTE("Trilobyte",SubTypeSet.CreatureType), + TRILOBITE("Trilobite",SubTypeSet.CreatureType), TWILEK("Twi'lek", SubTypeSet.CreatureType, true), // Star Wars // U From 1cd07b741eee18afb07eac22750a2d771c659118 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:01:38 -0400 Subject: [PATCH 072/182] Implemented Storm Sculptor --- Mage.Sets/src/mage/cards/s/StormSculptor.java | 70 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 71 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/StormSculptor.java diff --git a/Mage.Sets/src/mage/cards/s/StormSculptor.java b/Mage.Sets/src/mage/cards/s/StormSculptor.java new file mode 100644 index 0000000000..7ba9bdf056 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StormSculptor.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandChosenControlledPermanentEffect; +import mage.abilities.keyword.CantBeBlockedSourceAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterControlledCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class StormSculptor extends CardImpl { + + public StormSculptor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Storm Sculptor can't be blocked. + this.addAbility(new CantBeBlockedSourceAbility()); + + // When Storm Sculptor enters the battlefield, return a creature you control to its owner's hand. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ReturnToHandChosenControlledPermanentEffect(new FilterControlledCreaturePermanent()))); + } + + public StormSculptor(final StormSculptor card) { + super(card); + } + + @Override + public StormSculptor copy() { + return new StormSculptor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 9ebe3b3203..674220d568 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -237,6 +237,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Storm Fleet Aerialist", 83, Rarity.UNCOMMON, mage.cards.s.StormFleetAerialist.class)); cards.add(new SetCardInfo("Storm Fleet Arsonist", 162, Rarity.UNCOMMON, mage.cards.s.StormFleetArsonist.class)); cards.add(new SetCardInfo("Storm Fleet Spy", 84, Rarity.UNCOMMON, mage.cards.s.StormFleetSpy.class)); + cards.add(new SetCardInfo("Storm Sculptor", 85, Rarity.COMMON, mage.cards.s.StormSculptor.class)); cards.add(new SetCardInfo("Sunbird's Invocation", 165, Rarity.RARE, mage.cards.s.SunbirdsInvocation.class)); cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); From c5995b17c3b44e0a0bc207dacf8dd3ea343f9419 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:04:49 -0400 Subject: [PATCH 073/182] Implemented Tempest Caller --- Mage.Sets/src/mage/cards/t/TempestCaller.java | 70 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 71 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TempestCaller.java diff --git a/Mage.Sets/src/mage/cards/t/TempestCaller.java b/Mage.Sets/src/mage/cards/t/TempestCaller.java new file mode 100644 index 0000000000..1f010148f9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TempestCaller.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.TapAllTargetPlayerControlsEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class TempestCaller extends CardImpl { + + public TempestCaller(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // When Tempest Caller enters the battlefield, tap all creatures target opponent controls. + Ability ability = new EntersBattlefieldTriggeredAbility(new TapAllTargetPlayerControlsEffect(FILTER_PERMANENT_CREATURES)); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public TempestCaller(final TempestCaller card) { + super(card); + } + + @Override + public TempestCaller copy() { + return new TempestCaller(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 674220d568..c9593255c6 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -249,6 +249,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 270, Rarity.LAND, mage.cards.basiclands.Swamp.class)); cards.add(new SetCardInfo("Swamp", 271, Rarity.LAND, mage.cards.basiclands.Swamp.class)); cards.add(new SetCardInfo("Sword-Point Diplomacy", 126, Rarity.RARE, mage.cards.s.SwordPointDiplomacy.class)); + cards.add(new SetCardInfo("Tempest Caller", 86, Rarity.UNCOMMON, mage.cards.t.TempestCaller.class)); cards.add(new SetCardInfo("Temple of Aclazotz", 90, Rarity.RARE, mage.cards.t.TempleOfAclazotz.class)); cards.add(new SetCardInfo("Territorial Hammerskull", 41, Rarity.COMMON, mage.cards.t.TerritorialHammerskull.class)); cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); From 89a3537aeb4a3b18ef5ff0bdfc7488d6c276a60b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:07:20 -0400 Subject: [PATCH 074/182] Implemented Watertrap Weaver --- .../src/mage/cards/w/WatertrapWeaver.java | 79 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 80 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WatertrapWeaver.java diff --git a/Mage.Sets/src/mage/cards/w/WatertrapWeaver.java b/Mage.Sets/src/mage/cards/w/WatertrapWeaver.java new file mode 100644 index 0000000000..e299a8914d --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WatertrapWeaver.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class WatertrapWeaver extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public WatertrapWeaver(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Watertrap Weaver enters the battlefield, tap target creature an opponent controls. That creature doesn't untap during its controller's next untap step. + EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect()); + ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect()); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public WatertrapWeaver(final WatertrapWeaver card) { + super(card); + } + + @Override + public WatertrapWeaver copy() { + return new WatertrapWeaver(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index c9593255c6..8e2b841b7b 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -276,6 +276,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Waker of the Wilds", 215, Rarity.RARE, mage.cards.w.WakerOfTheWilds.class)); cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); cards.add(new SetCardInfo("Wanted Scoundrels", 131, Rarity.UNCOMMON, mage.cards.w.WantedScoundrels.class)); + cards.add(new SetCardInfo("Watertrap Weaver", 87, Rarity.COMMON, mage.cards.w.WatertrapWeaver.class)); cards.add(new SetCardInfo("Wildgrowth Walker", 216, Rarity.UNCOMMON, mage.cards.w.WildgrowthWalker.class)); cards.add(new SetCardInfo("Wily Goblin", 174, Rarity.UNCOMMON, mage.cards.w.WilyGoblin.class)); cards.add(new SetCardInfo("Wind Strider", 88, Rarity.COMMON, mage.cards.w.WindStrider.class)); From 78ca7e3be2ed2e65df503ec62be833e39e8fee9b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:12:51 -0400 Subject: [PATCH 075/182] Implemented Blight Keeper --- Mage.Sets/src/mage/cards/b/BlightKeeper.java | 81 +++++++++++++++++++ .../src/mage/cards/e/EncampmentKeeper.java | 2 + Mage.Sets/src/mage/cards/s/ShoreKeeper.java | 4 +- Mage.Sets/src/mage/sets/Ixalan.java | 1 + 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/b/BlightKeeper.java diff --git a/Mage.Sets/src/mage/cards/b/BlightKeeper.java b/Mage.Sets/src/mage/cards/b/BlightKeeper.java new file mode 100644 index 0000000000..89303c6d92 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BlightKeeper.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class BlightKeeper extends CardImpl { + + public BlightKeeper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); + + this.subtype.add(SubType.BAT); + this.subtype.add(SubType.IMP); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {7}{B}, {T}, Sacrifice Blight Keeper: Target opponent loses 4 life and you gain 4 life. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeTargetEffect(4), new ManaCostsImpl("{7}{B}")); + ability.addEffect(new GainLifeEffect(4)); + ability.addTarget(new TargetOpponent()); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); + } + + public BlightKeeper(final BlightKeeper card) { + super(card); + } + + @Override + public BlightKeeper copy() { + return new BlightKeeper(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/EncampmentKeeper.java b/Mage.Sets/src/mage/cards/e/EncampmentKeeper.java index 92f2a2216f..2ebda41ee6 100644 --- a/Mage.Sets/src/mage/cards/e/EncampmentKeeper.java +++ b/Mage.Sets/src/mage/cards/e/EncampmentKeeper.java @@ -32,6 +32,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.constants.SubType; @@ -60,6 +61,7 @@ public class EncampmentKeeper extends CardImpl { // {7}{W}, Sacrifice Encampment Keeper: Creatures you control get +2/+2 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostControlledEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl("{7}{W}")); + ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/ShoreKeeper.java b/Mage.Sets/src/mage/cards/s/ShoreKeeper.java index c243f26051..36c0826ec2 100644 --- a/Mage.Sets/src/mage/cards/s/ShoreKeeper.java +++ b/Mage.Sets/src/mage/cards/s/ShoreKeeper.java @@ -32,6 +32,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.constants.SubType; @@ -54,7 +55,8 @@ public class ShoreKeeper extends CardImpl { this.toughness = new MageInt(3); // {7}{u}, {t}, Sacrifice Shore Keeper: Draw three cards. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(3), new ManaCostsImpl("{7}{W}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(3), new ManaCostsImpl("{7}{U}")); + ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 8e2b841b7b..75367fe9fc 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -46,6 +46,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class)); cards.add(new SetCardInfo("Bishop of the Bloodstained", 91, Rarity.UNCOMMON, mage.cards.b.BishopOfTheBloodstained.class)); cards.add(new SetCardInfo("Bishop's Soldier", 6, Rarity.COMMON, mage.cards.b.BishopsSoldier.class)); + cards.add(new SetCardInfo("Blight Keeper", 92, Rarity.COMMON, mage.cards.b.BlightKeeper.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); cards.add(new SetCardInfo("Boneyard Parley", 94, Rarity.MYTHIC, mage.cards.b.BoneyardParley.class)); cards.add(new SetCardInfo("Brazen Buccaneers", 134, Rarity.COMMON, mage.cards.b.BrazenBuccaneers.class)); From 3fc3d96fe0ddeeafb279a2d37724a9c4b91ddf07 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 15 Sep 2017 23:18:40 +0200 Subject: [PATCH 076/182] Some updates to image download. --- .../card/dl/sources/MtgOnlTokensImageSource.java | 6 ++++++ .../card/dl/sources/TokensMtgImageSource.java | 14 ++++++++++++++ .../mage/plugins/card/images/DownloadPictures.java | 13 ++++++++----- .../target/maven-archiver/pom.properties | 2 +- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgOnlTokensImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgOnlTokensImageSource.java index 41207d6b9c..618b4cf464 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgOnlTokensImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgOnlTokensImageSource.java @@ -376,4 +376,10 @@ public enum MtgOnlTokensImageSource implements CardImageSource { @Override public void doPause(String httpImageUrl) { } + + @Override + public boolean isImageProvided(String setCode, String cardName) { + return true; + } + } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java index 95f4294a05..c009da8916 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java @@ -34,8 +34,10 @@ import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.logging.Level; import org.apache.log4j.Logger; import org.mage.plugins.card.images.CardDownloadData; @@ -53,6 +55,11 @@ public enum TokensMtgImageSource implements CardImageSource { private HashMap> tokensData; private final Object tokensDataSync = new Object(); + private final Set supportedSets; + + private TokensMtgImageSource() { + this.supportedSets = new LinkedHashSet<>(); + } @Override public String getSourceName() { @@ -201,6 +208,7 @@ public enum TokensMtgImageSource implements CardImageSource { List siteTokensData = parseTokensData(inputStream); for (TokenData siteData : siteTokensData) { String key = siteData.getExpansionSetCode() + "/" + siteData.getName(); + supportedSets.add(siteData.getExpansionSetCode()); ArrayList list = tokensData.get(key); if (list == null) { list = new ArrayList<>(); @@ -335,4 +343,10 @@ public enum TokensMtgImageSource implements CardImageSource { return false; } + @Override + public ArrayList getSupportedSets() { + ArrayList supportedSetsCopy = new ArrayList<>(); + supportedSetsCopy.addAll(supportedSets); + return supportedSetsCopy; + } } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index 2e81ebd36c..1396082fc7 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -81,12 +81,12 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab WIZARDS("wizards.com", WizardCardsImageSource.instance), MYTHICSPOILER("mythicspoiler.com", MythicspoilerComSource.instance), TOKENS("tokens.mtg.onl", TokensMtgImageSource.instance), - MTG_ONL("mtg.onl", MtgOnlTokensImageSource.instance), + // MTG_ONL("mtg.onl", MtgOnlTokensImageSource.instance), ALTERNATIVE("alternative.mtg.onl", AltMtgOnlTokensImageSource.instance), GRAB_BAG("GrabBag", GrabbagImageSource.instance), MAGIDEX("magidex.com", MagidexImageSource.instance), - SCRYFALL("scryfall.com", ScryfallImageSource.instance), - MAGICCARDS("magiccards.info", MagicCardsImageSource.instance); + SCRYFALL("scryfall.com", ScryfallImageSource.instance); + // MAGICCARDS("magiccards.info", MagicCardsImageSource.instance) private final String text; private final CardImageSource source; @@ -276,6 +276,8 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } } break; + case ALL_TOKENS: + break; default: int nonSetEntries = 0; if (cardImageSource.getSupportedSets() != null) { @@ -290,8 +292,9 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab int numberTokenImagesAvailable = 0; int numberCardImagesAvailable = 0; for (CardDownloadData data : allCardsMissingImage) { - if (data.isToken() && cardImageSource.isTokenSource()) { - if (cardImageSource.isImageProvided(data.getSet(), data.getName())) { + if (data.isToken()) { + if (cardImageSource.isTokenSource() + && cardImageSource.isImageProvided(data.getSet(), data.getName())) { numberTokenImagesAvailable++; cardsToDownload.add(data); } diff --git a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target/maven-archiver/pom.properties b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target/maven-archiver/pom.properties index 03ac9e7681..9ea86aa6e9 100644 --- a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target/maven-archiver/pom.properties +++ b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target/maven-archiver/pom.properties @@ -1,5 +1,5 @@ #Generated by Maven -#Sun Sep 03 07:46:59 CEST 2017 +#Fri Sep 15 22:14:29 CEST 2017 version=1.4.26 groupId=org.mage artifactId=mage-game-pennydreadfulcommanderfreeforall From 28b18b4efefe2190ec480951460e41f26ef2ccaa Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:18:49 -0400 Subject: [PATCH 077/182] Implemented Contract Killing --- .../src/mage/cards/c/ContractKilling.java | 62 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 63 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ContractKilling.java diff --git a/Mage.Sets/src/mage/cards/c/ContractKilling.java b/Mage.Sets/src/mage/cards/c/ContractKilling.java new file mode 100644 index 0000000000..507b002ff2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ContractKilling.java @@ -0,0 +1,62 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.TreasureToken; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class ContractKilling extends CardImpl { + + public ContractKilling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}{B}"); + + // Destroy target creature. Create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addEffect(new CreateTokenEffect(new TreasureToken(), 2)); + } + + public ContractKilling(final ContractKilling card) { + super(card); + } + + @Override + public ContractKilling copy() { + return new ContractKilling(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 75367fe9fc..852db1bbed 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -65,6 +65,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Commune with Dinosaurs", 181, Rarity.COMMON, mage.cards.c.CommuneWithDinosaurs.class)); cards.add(new SetCardInfo("Conqueror's Foothold", 234, Rarity.RARE, mage.cards.c.ConquerorsFoothold.class)); cards.add(new SetCardInfo("Conqueror's Galleon", 234, Rarity.RARE, mage.cards.c.ConquerorsGalleon.class)); + cards.add(new SetCardInfo("Contract Killing", 95, Rarity.COMMON, mage.cards.c.ContractKilling.class)); cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); cards.add(new SetCardInfo("Deadeye Plunderers", 220, Rarity.UNCOMMON, mage.cards.d.DeadeyePlunderers.class)); cards.add(new SetCardInfo("Deadeye Quartermaster", 50, Rarity.UNCOMMON, mage.cards.d.DeadeyeQuartermaster.class)); From eebc412ad9e1f86836cc922c457e6f75646e97ab Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 15 Sep 2017 23:19:11 +0200 Subject: [PATCH 078/182] Some updates to image download. --- .../java/org/mage/plugins/card/images/DownloadPictures.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index 1396082fc7..f96075139c 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -81,7 +81,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab WIZARDS("wizards.com", WizardCardsImageSource.instance), MYTHICSPOILER("mythicspoiler.com", MythicspoilerComSource.instance), TOKENS("tokens.mtg.onl", TokensMtgImageSource.instance), - // MTG_ONL("mtg.onl", MtgOnlTokensImageSource.instance), + // MTG_ONL("mtg.onl", MtgOnlTokensImageSource.instance), Not working correctly yet ALTERNATIVE("alternative.mtg.onl", AltMtgOnlTokensImageSource.instance), GRAB_BAG("GrabBag", GrabbagImageSource.instance), MAGIDEX("magidex.com", MagidexImageSource.instance), From 5d2b8e399d63ff19095d151ad1e9612f1c296691 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:23:23 -0400 Subject: [PATCH 079/182] Implemented Costly Plunder --- Mage.Sets/src/mage/cards/c/CostlyPlunder.java | 74 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 75 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CostlyPlunder.java diff --git a/Mage.Sets/src/mage/cards/c/CostlyPlunder.java b/Mage.Sets/src/mage/cards/c/CostlyPlunder.java new file mode 100644 index 0000000000..4a8cbd6625 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CostlyPlunder.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author TheElk801 + */ +public class CostlyPlunder extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("an artifact or creature"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.CREATURE) + )); + } + + public CostlyPlunder(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}"); + + // As an additional cost to cast Costly Plunder, sacrifice an artifact or creature. + this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true))); + + // Draw two cards. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); + } + + public CostlyPlunder(final CostlyPlunder card) { + super(card); + } + + @Override + public CostlyPlunder copy() { + return new CostlyPlunder(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 852db1bbed..c4f5d9f7a9 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -66,6 +66,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Conqueror's Foothold", 234, Rarity.RARE, mage.cards.c.ConquerorsFoothold.class)); cards.add(new SetCardInfo("Conqueror's Galleon", 234, Rarity.RARE, mage.cards.c.ConquerorsGalleon.class)); cards.add(new SetCardInfo("Contract Killing", 95, Rarity.COMMON, mage.cards.c.ContractKilling.class)); + cards.add(new SetCardInfo("Costly Plunder", 96, Rarity.COMMON, mage.cards.c.CostlyPlunder.class)); cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); cards.add(new SetCardInfo("Deadeye Plunderers", 220, Rarity.UNCOMMON, mage.cards.d.DeadeyePlunderers.class)); cards.add(new SetCardInfo("Deadeye Quartermaster", 50, Rarity.UNCOMMON, mage.cards.d.DeadeyeQuartermaster.class)); From 223864f87e57f3231ec41abb94694c7b334cf2f6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:26:11 -0400 Subject: [PATCH 080/182] Implemented Dark Nourishment --- .../src/mage/cards/d/DarkNourishment.java | 61 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 62 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DarkNourishment.java diff --git a/Mage.Sets/src/mage/cards/d/DarkNourishment.java b/Mage.Sets/src/mage/cards/d/DarkNourishment.java new file mode 100644 index 0000000000..a7709f9df8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DarkNourishment.java @@ -0,0 +1,61 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author TheElk801 + */ +public class DarkNourishment extends CardImpl { + + public DarkNourishment(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{9}{7}"); + + // Dark Nourishment deals 3 damage to target creature or player. You gain 3 life. + this.getSpellAbility().addEffect(new DamageTargetEffect(3)); + this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); + this.getSpellAbility().addEffect(new GainLifeEffect(3)); + } + + public DarkNourishment(final DarkNourishment card) { + super(card); + } + + @Override + public DarkNourishment copy() { + return new DarkNourishment(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index c4f5d9f7a9..00d8458e21 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -68,6 +68,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Contract Killing", 95, Rarity.COMMON, mage.cards.c.ContractKilling.class)); cards.add(new SetCardInfo("Costly Plunder", 96, Rarity.COMMON, mage.cards.c.CostlyPlunder.class)); cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); + cards.add(new SetCardInfo("Dark Nourishment", 97, Rarity.UNCOMMON, mage.cards.d.DarkNourishment.class)); cards.add(new SetCardInfo("Deadeye Plunderers", 220, Rarity.UNCOMMON, mage.cards.d.DeadeyePlunderers.class)); cards.add(new SetCardInfo("Deadeye Quartermaster", 50, Rarity.UNCOMMON, mage.cards.d.DeadeyeQuartermaster.class)); cards.add(new SetCardInfo("Deadeye Tormentor", 98, Rarity.COMMON, mage.cards.d.DeadeyeTormentor.class)); From f73d51d64b59917fc96551bf77f0ff4e32a3a54e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:29:19 -0400 Subject: [PATCH 081/182] Implemented March of the Drowned --- .../src/mage/cards/g/GhoulcallersChant.java | 3 +- .../src/mage/cards/m/MarchOfTheDrowned.java | 76 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java diff --git a/Mage.Sets/src/mage/cards/g/GhoulcallersChant.java b/Mage.Sets/src/mage/cards/g/GhoulcallersChant.java index c15fe75d3a..8246863f23 100644 --- a/Mage.Sets/src/mage/cards/g/GhoulcallersChant.java +++ b/Mage.Sets/src/mage/cards/g/GhoulcallersChant.java @@ -52,8 +52,7 @@ public class GhoulcallersChant extends CardImpl { } public GhoulcallersChant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}"); // Choose one - Return target creature card from your graveyard to your hand this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java b/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java new file mode 100644 index 0000000000..031e595e29 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import java.util.UUID; +import mage.abilities.Mode; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author TheElk801 + */ +public class MarchOfTheDrowned extends CardImpl { + + private static final FilterCard filter = new FilterCard("Prate cards from your graveyard"); + + static { + filter.add(new SubtypePredicate(SubType.PIRATE)); + } + + public MarchOfTheDrowned(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}"); + + // Choose one — + // &bull; Return target creature card from your graveyard to your hand. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard"))); + // &bull; Return two target Pirate cards from your graveyard to your hand. + Mode mode = new Mode(); + mode.getEffects().add(new ReturnToHandTargetEffect()); + mode.getTargets().add(new TargetCardInYourGraveyard(2, filter)); + this.getSpellAbility().addMode(mode); + } + + public MarchOfTheDrowned(final MarchOfTheDrowned card) { + super(card); + } + + @Override + public MarchOfTheDrowned copy() { + return new MarchOfTheDrowned(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 00d8458e21..2fb28a4f09 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -153,6 +153,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Lurking Chupacabra", 111, Rarity.UNCOMMON, mage.cards.l.LurkingChupacabra.class)); cards.add(new SetCardInfo("Makeshift Munitions", 151, Rarity.UNCOMMON, mage.cards.m.MakeshiftMunitions.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); + cards.add(new SetCardInfo("March of the Drowned", 112, Rarity.COMMON, mage.cards.m.MarchOfTheDrowned.class)); cards.add(new SetCardInfo("Mark of the Vampire", 113, Rarity.COMMON, mage.cards.m.MarkOfTheVampire.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Merfolk Branchwalker", 197, Rarity.UNCOMMON, mage.cards.m.MerfolkBranchwalker.class)); From 76b4d133384e56df32c15969e7395ecde5b26708 Mon Sep 17 00:00:00 2001 From: Christian Date: Fri, 15 Sep 2017 17:37:50 -0400 Subject: [PATCH 082/182] Implemented Anointed Deacon --- .../src/mage/cards/a/AnointedDeacon.java | 77 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 78 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AnointedDeacon.java diff --git a/Mage.Sets/src/mage/cards/a/AnointedDeacon.java b/Mage.Sets/src/mage/cards/a/AnointedDeacon.java new file mode 100644 index 0000000000..e11cae3779 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AnointedDeacon.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.constants.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.filter.common.FilterCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + + +/** + * + * @author caldover + */ +public class AnointedDeacon extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("target Vampire you control"); + + static { + filter.add(new SubtypePredicate(SubType.VAMPIRE)); + } + + public AnointedDeacon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // At the beginning of combat on your turn, you may have target Vampire get +2/+0 until end of turn. + Ability ability = new BeginningOfCombatTriggeredAbility(Zone.BATTLEFIELD, new BoostTargetEffect(2, 0, Duration.EndOfTurn), TargetController.YOU, true, false); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public AnointedDeacon(final AnointedDeacon card) { + super(card); + } + + @Override + public AnointedDeacon copy() { + return new AnointedDeacon(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 097bd93c46..e5a226fcd9 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -36,6 +36,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Admiral Beckett Brass", 217, Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); cards.add(new SetCardInfo("Air Elemental", 45, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); + cards.add(new SetCardInfo("Anointed Deacon", 89, Rarity.COMMON, mage.cards.a.AnointedDeacon.class)); cards.add(new SetCardInfo("Arcane Adaptation", 46, Rarity.RARE, mage.cards.a.ArcaneAdaptation.class)); cards.add(new SetCardInfo("Arguel's Blood Fast", 90, Rarity.RARE, mage.cards.a.ArguelsBloodFast.class)); cards.add(new SetCardInfo("Ashes of the Abhorrent", 2, Rarity.RARE, mage.cards.a.AshesOfTheAbhorrent.class)); From 80d98166916f3e5ae5550e79e16f1b53a961e5c2 Mon Sep 17 00:00:00 2001 From: Christian Aldover Date: Fri, 15 Sep 2017 17:55:42 -0400 Subject: [PATCH 083/182] Update AnointedDeacon.java Corrected the filter text to read "Vampire" rather than "target Vampire you control" --- Mage.Sets/src/mage/cards/a/AnointedDeacon.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/a/AnointedDeacon.java b/Mage.Sets/src/mage/cards/a/AnointedDeacon.java index e11cae3779..fd6c5757a0 100644 --- a/Mage.Sets/src/mage/cards/a/AnointedDeacon.java +++ b/Mage.Sets/src/mage/cards/a/AnointedDeacon.java @@ -46,7 +46,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate; */ public class AnointedDeacon extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("target Vampire you control"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Vampire"); static { filter.add(new SubtypePredicate(SubType.VAMPIRE)); From 75874df33fded58c13c0987595eaecf0984c5575 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 00:11:19 +0200 Subject: [PATCH 084/182] Fixed a problem of image download. --- .../plugins/card/dl/sources/TokensMtgImageSource.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java index bf55f409e7..0a2de30729 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java @@ -57,11 +57,6 @@ public enum TokensMtgImageSource implements CardImageSource { private static final Set supportedSets = new LinkedHashSet(); private final Object tokensDataSync = new Object(); - private final Set supportedSets; - - private TokensMtgImageSource() { - this.supportedSets = new LinkedHashSet<>(); - } @Override public String getSourceName() { @@ -356,10 +351,4 @@ public enum TokensMtgImageSource implements CardImageSource { return false; } - @Override - public ArrayList getSupportedSets() { - ArrayList supportedSetsCopy = new ArrayList<>(); - supportedSetsCopy.addAll(supportedSets); - return supportedSetsCopy; - } } From 7d748721da7f41cb5b1ce8aaf0bc7aa0db5103bb Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 00:11:38 +0200 Subject: [PATCH 085/182] [XLN] Added 10 cards. --- .../src/mage/cards/d/DeeprootWarrior.java | 69 ++++++++++++++ .../src/mage/cards/e/EmergentGrowth.java | 65 +++++++++++++ .../src/mage/cards/i/IxallisDiviner.java | 65 +++++++++++++ Mage.Sets/src/mage/cards/i/IxallisKeeper.java | 81 ++++++++++++++++ Mage.Sets/src/mage/cards/j/JadeGuardian.java | 75 +++++++++++++++ Mage.Sets/src/mage/cards/j/JungleDelver.java | 69 ++++++++++++++ Mage.Sets/src/mage/cards/n/NewHorizons.java | 92 +++++++++++++++++++ Mage.Sets/src/mage/cards/p/Pounce.java | 72 +++++++++++++++ .../src/mage/cards/r/RiverHeraldsBoon.java | 70 ++++++++++++++ .../src/mage/cards/s/SpikeTailedCeratops.java | 66 +++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 10 ++ .../effects/keyword/ExploreSourceEffect.java | 2 +- 12 files changed, 735 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/d/DeeprootWarrior.java create mode 100644 Mage.Sets/src/mage/cards/e/EmergentGrowth.java create mode 100644 Mage.Sets/src/mage/cards/i/IxallisDiviner.java create mode 100644 Mage.Sets/src/mage/cards/i/IxallisKeeper.java create mode 100644 Mage.Sets/src/mage/cards/j/JadeGuardian.java create mode 100644 Mage.Sets/src/mage/cards/j/JungleDelver.java create mode 100644 Mage.Sets/src/mage/cards/n/NewHorizons.java create mode 100644 Mage.Sets/src/mage/cards/p/Pounce.java create mode 100644 Mage.Sets/src/mage/cards/r/RiverHeraldsBoon.java create mode 100644 Mage.Sets/src/mage/cards/s/SpikeTailedCeratops.java diff --git a/Mage.Sets/src/mage/cards/d/DeeprootWarrior.java b/Mage.Sets/src/mage/cards/d/DeeprootWarrior.java new file mode 100644 index 0000000000..d8c8b5b83a --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeeprootWarrior.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BecomesBlockedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +/** + * + * @author LevelX2 + */ +public class DeeprootWarrior extends CardImpl { + + public DeeprootWarrior(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Deeproot Warrior becomes blocked, it gets +1/+1 until end of turn. + Effect effect = new BoostSourceEffect(1, 1, Duration.EndOfTurn); + effect.setText("it gets +1/+1 until end of turn"); + this.addAbility(new BecomesBlockedTriggeredAbility(effect, false)); + } + + public DeeprootWarrior(final DeeprootWarrior card) { + super(card); + } + + @Override + public DeeprootWarrior copy() { + return new DeeprootWarrior(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/EmergentGrowth.java b/Mage.Sets/src/mage/cards/e/EmergentGrowth.java new file mode 100644 index 0000000000..6ac84c334e --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EmergentGrowth.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.e; + +import java.util.UUID; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneTargetEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class EmergentGrowth extends CardImpl { + + public EmergentGrowth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}"); + + // Target creature gets +5/+5 until end of turn and must be blocked this turn if able. + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new BoostTargetEffect(5, 5, Duration.EndOfTurn)); + Effect effect = new MustBeBlockedByAtLeastOneTargetEffect(); + effect.setText("and must be blocked this turn if able"); + this.getSpellAbility().addEffect(effect); + } + + public EmergentGrowth(final EmergentGrowth card) { + super(card); + } + + @Override + public EmergentGrowth copy() { + return new EmergentGrowth(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/IxallisDiviner.java b/Mage.Sets/src/mage/cards/i/IxallisDiviner.java new file mode 100644 index 0000000000..63ad8d8b96 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IxallisDiviner.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.keyword.ExploreSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * + * @author LevelX2 + */ +public class IxallisDiviner extends CardImpl { + + public IxallisDiviner(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.DRUID); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // When Ixalli's Diviner enters the battlefield, it explores. (Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on this creature, then put the card back or put it into your graveyard.) + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExploreSourceEffect())); + } + + public IxallisDiviner(final IxallisDiviner card) { + super(card); + } + + @Override + public IxallisDiviner copy() { + return new IxallisDiviner(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/IxallisKeeper.java b/Mage.Sets/src/mage/cards/i/IxallisKeeper.java new file mode 100644 index 0000000000..289076e484 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IxallisKeeper.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class IxallisKeeper extends CardImpl { + + public IxallisKeeper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SHAMAN); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {7}{G}, {T}, Sacrifice Ixalli's Keeper: Target creature gets +5/+5 and gains trample until end of turn. + SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new BoostTargetEffect(5, 5, Duration.EndOfTurn) + .setText("Target creature gets +5/+5"), new ManaCostsImpl("{7}{G}")); + ability.addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn) + .setText("and gains trample until end of turn")); + ability.addTarget(new TargetCreaturePermanent()); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); + } + + public IxallisKeeper(final IxallisKeeper card) { + super(card); + } + + @Override + public IxallisKeeper copy() { + return new IxallisKeeper(this); + } +} diff --git a/Mage.Sets/src/mage/cards/j/JadeGuardian.java b/Mage.Sets/src/mage/cards/j/JadeGuardian.java new file mode 100644 index 0000000000..00ec9d541e --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JadeGuardian.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.j; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.HexproofAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class JadeGuardian extends CardImpl { + + public JadeGuardian(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.SHAMAN); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Hexproof + this.addAbility(HexproofAbility.getInstance()); + + // When Jade Guardian enters the battlefield, put a +1/+1 counter on target Merfolk you control. + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); + ability.addTarget(new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent(SubType.MERFOLK, "Merfolk you control"))); + this.addAbility(ability); + } + + public JadeGuardian(final JadeGuardian card) { + super(card); + } + + @Override + public JadeGuardian copy() { + return new JadeGuardian(this); + } +} diff --git a/Mage.Sets/src/mage/cards/j/JungleDelver.java b/Mage.Sets/src/mage/cards/j/JungleDelver.java new file mode 100644 index 0000000000..ddeee1ba8b --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JungleDelver.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.j; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.counters.CounterType; + +/** + * + * @author LevelX2 + */ +public class JungleDelver extends CardImpl { + + public JungleDelver(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {3}{G}: Put a +1/+1 counter on Jungle Delver. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl("{3}{G}"))); + } + + public JungleDelver(final JungleDelver card) { + super(card); + } + + @Override + public JungleDelver copy() { + return new JungleDelver(this); + } +} diff --git a/Mage.Sets/src/mage/cards/n/NewHorizons.java b/Mage.Sets/src/mage/cards/n/NewHorizons.java new file mode 100644 index 0000000000..f98f447144 --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NewHorizons.java @@ -0,0 +1,92 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.n; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AddManaOfAnyColorEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.mana.SimpleManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author LevelX2 + */ +public class NewHorizons extends CardImpl { + + public NewHorizons(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); + + this.subtype.add(SubType.AURA); + + // Enchant land + TargetPermanent auraTarget = new TargetLandPermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // When New Horizons enters the battlefield, put a +1/+1 counter on target creature you control. + ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + + // Enchanted land has "{T]: Add two mana of any one color to your mana pool." + Ability gainedAbility = new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(2), new TapSourceCost()); + Effect effect = new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA); + effect.setText("Enchanted land has \"{T}: Add two mana of any one color to your mana pool.\""); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + } + + public NewHorizons(final NewHorizons card) { + super(card); + } + + @Override + public NewHorizons copy() { + return new NewHorizons(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/Pounce.java b/Mage.Sets/src/mage/cards/p/Pounce.java new file mode 100644 index 0000000000..bad2a9a461 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/Pounce.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.abilities.effects.common.FightTargetsEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.Target; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class Pounce extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you don't control"); + + static { + filter.add(new ControllerPredicate(TargetController.NOT_YOU)); + } + + public Pounce(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); + + // Target creature you control fights target creature you don't control. + this.getSpellAbility().addEffect(new FightTargetsEffect()); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + Target target = new TargetCreaturePermanent(filter); + this.getSpellAbility().addTarget(target); + } + + public Pounce(final Pounce card) { + super(card); + } + + @Override + public Pounce copy() { + return new Pounce(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RiverHeraldsBoon.java b/Mage.Sets/src/mage/cards/r/RiverHeraldsBoon.java new file mode 100644 index 0000000000..1b063f5762 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RiverHeraldsBoon.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.SecondTargetPointer; + +/** + * + * @author LevelX2 + */ +public class RiverHeraldsBoon extends CardImpl { + + public RiverHeraldsBoon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); + + // Put a +1/+1 counter on target creature and a +1/+1 counter on up to one target Merfolk. + this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); + effect.setTargetPointer(new SecondTargetPointer()); + effect.setText("and a +1/+1 counter on up to one target Merfolk"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1, new FilterCreaturePermanent(SubType.MERFOLK, "Merfolk"), false)); + + } + + public RiverHeraldsBoon(final RiverHeraldsBoon card) { + super(card); + } + + @Override + public RiverHeraldsBoon copy() { + return new RiverHeraldsBoon(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SpikeTailedCeratops.java b/Mage.Sets/src/mage/cards/s/SpikeTailedCeratops.java new file mode 100644 index 0000000000..40018bcccd --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpikeTailedCeratops.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.combat.CanBlockAdditionalCreatureEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class SpikeTailedCeratops extends CardImpl { + + public SpikeTailedCeratops(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Spike-Tailed Ceratops can block an additional creature each combat. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockAdditionalCreatureEffect(Duration.WhileOnBattlefield, 1))); + } + + public SpikeTailedCeratops(final SpikeTailedCeratops card) { + super(card); + } + + @Override + public SpikeTailedCeratops copy() { + return new SpikeTailedCeratops(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 7b4f2028ab..da56dbfd7f 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -70,6 +70,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Deathgorge Scavenger", 184, Rarity.RARE, mage.cards.d.DeathgorgeScavenger.class)); cards.add(new SetCardInfo("Deathless Ancient", 100, Rarity.UNCOMMON, mage.cards.d.DeathlessAncient.class)); cards.add(new SetCardInfo("Deeproot Champion", 185, Rarity.RARE, mage.cards.d.DeeprootChampion.class)); + cards.add(new SetCardInfo("Deeproot Warrior", 186, Rarity.COMMON, mage.cards.d.DeeprootWarrior.class)); cards.add(new SetCardInfo("Deeproot Waters", 51, Rarity.UNCOMMON, mage.cards.d.DeeprootWaters.class)); cards.add(new SetCardInfo("Demolish", 139, Rarity.COMMON, mage.cards.d.Demolish.class)); cards.add(new SetCardInfo("Demystify", 8, Rarity.COMMON, mage.cards.d.Demystify.class)); @@ -87,6 +88,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Duress", 105, Rarity.COMMON, mage.cards.d.Duress.class)); cards.add(new SetCardInfo("Duskborne Skymarcher", 9, Rarity.UNCOMMON, mage.cards.d.DuskborneSkymarcher.class)); cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.d.DuskLegionDreadnought.class)); + cards.add(new SetCardInfo("Emergent Growth", 188, Rarity.UNCOMMON, mage.cards.e.EmergentGrowth.class)); cards.add(new SetCardInfo("Emissary of Sunrise", 10, Rarity.UNCOMMON, mage.cards.e.EmissaryOfSunrise.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); @@ -119,9 +121,13 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Island", 267, Rarity.LAND, mage.cards.basiclands.Island.class)); cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", 191, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class)); cards.add(new SetCardInfo("Ixalan's Binding", 17, Rarity.UNCOMMON, mage.cards.i.IxalansBinding.class)); + cards.add(new SetCardInfo("Ixalli's Diviner", 192, Rarity.COMMON, mage.cards.i.IxallisDiviner.class)); + cards.add(new SetCardInfo("Ixalli's Keeper", 193, Rarity.COMMON, mage.cards.i.IxallisKeeper.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); + cards.add(new SetCardInfo("Jade Guardian", 194, Rarity.COMMON, mage.cards.j.JadeGuardian.class)); + cards.add(new SetCardInfo("Jungle Delver", 195, Rarity.COMMON, mage.cards.j.JungleDelver.class)); cards.add(new SetCardInfo("Kinjalli's Caller", 18, Rarity.COMMON, mage.cards.k.KinjallisCaller.class)); cards.add(new SetCardInfo("Kinjalli's Sunwing", 19, Rarity.RARE, mage.cards.k.KinjallisSunwing.class)); cards.add(new SetCardInfo("Kitesail Freebooter", 110, Rarity.UNCOMMON, mage.cards.k.KitesailFreebooter.class)); @@ -143,6 +149,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 273, Rarity.LAND, mage.cards.basiclands.Mountain.class)); cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class)); cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class)); + cards.add(new SetCardInfo("New Horizons", 198, Rarity.COMMON, mage.cards.n.NewHorizons.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); cards.add(new SetCardInfo("Otepec Huntmaster", 153, Rarity.UNCOMMON, mage.cards.o.OtepecHuntmaster.class)); @@ -154,6 +161,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Plains", 261, Rarity.LAND, mage.cards.basiclands.Plains.class)); cards.add(new SetCardInfo("Plains", 262, Rarity.LAND, mage.cards.basiclands.Plains.class)); cards.add(new SetCardInfo("Plains", 263, Rarity.LAND, mage.cards.basiclands.Plains.class)); + cards.add(new SetCardInfo("Pounce", 200, Rarity.COMMON, mage.cards.p.Pounce.class)); cards.add(new SetCardInfo("Priest of the Wakening Sun", 27, Rarity.RARE, mage.cards.p.PriestOfTheWakeningSun.class)); cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); @@ -171,6 +179,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Rigging Runner", 157, Rarity.UNCOMMON, mage.cards.r.RiggingRunner.class)); cards.add(new SetCardInfo("Rile", 158, Rarity.COMMON, mage.cards.r.Rile.class)); cards.add(new SetCardInfo("Ripjaw Raptor", 203, Rarity.RARE, mage.cards.r.RipjawRaptor.class)); + cards.add(new SetCardInfo("River Heralds' Boon", 204, Rarity.COMMON, mage.cards.r.RiverHeraldsBoon.class)); cards.add(new SetCardInfo("River Sneak", 70, Rarity.UNCOMMON, mage.cards.r.RiverSneak.class)); cards.add(new SetCardInfo("River's Rebuke", 71, Rarity.RARE, mage.cards.r.RiversRebuke.class)); cards.add(new SetCardInfo("Rootbound Crag", 256, Rarity.RARE, mage.cards.r.RootboundCrag.class)); @@ -196,6 +205,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); cards.add(new SetCardInfo("Spell Pierce", 81, Rarity.COMMON, mage.cards.s.SpellPierce.class)); cards.add(new SetCardInfo("Spell Swindle", 82, Rarity.RARE, mage.cards.s.SpellSwindle.class)); + cards.add(new SetCardInfo("Spike-Tailed Ceratops", 209, Rarity.COMMON, mage.cards.s.SpikeTailedCeratops.class)); cards.add(new SetCardInfo("Spires of Orazca", 249, Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); cards.add(new SetCardInfo("Spitfire Bastion", 173, Rarity.RARE, mage.cards.s.SpitfireBastion.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java index e6ea352256..a64c9aad8c 100644 --- a/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java @@ -57,7 +57,7 @@ public class ExploreSourceEffect extends OneShotEffect { public ExploreSourceEffect() { super(Outcome.Benefit); - this.staticText = "it explores"; + this.staticText = "it explores. (Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on this creature, then put the card back or put it into your graveyard.)"; } public ExploreSourceEffect(final ExploreSourceEffect effect) { From ab8b0fe362617972facdc56ec88087f978e1ff00 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:38:23 -0400 Subject: [PATCH 086/182] Implemented Skymarch Bloodletter --- .../src/mage/cards/m/MarchOfTheDrowned.java | 2 +- .../src/mage/cards/s/SkymarchBloodletter.java | 77 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/s/SkymarchBloodletter.java diff --git a/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java b/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java index 031e595e29..f90824d1cd 100644 --- a/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java +++ b/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java @@ -45,7 +45,7 @@ import mage.target.common.TargetCardInYourGraveyard; */ public class MarchOfTheDrowned extends CardImpl { - private static final FilterCard filter = new FilterCard("Prate cards from your graveyard"); + private static final FilterCard filter = new FilterCard("Pirate cards from your graveyard"); static { filter.add(new SubtypePredicate(SubType.PIRATE)); diff --git a/Mage.Sets/src/mage/cards/s/SkymarchBloodletter.java b/Mage.Sets/src/mage/cards/s/SkymarchBloodletter.java new file mode 100644 index 0000000000..6e873593d1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SkymarchBloodletter.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.Target; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class SkymarchBloodletter extends CardImpl { + + public SkymarchBloodletter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Skymarch Bloodletters enters the battlefield, target opponent loses 1 life and you gain 1 life. + Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(1), false); + ability.addEffect(new GainLifeEffect(1)); + Target target = new TargetOpponent(); + ability.addTarget(target); + this.addAbility(ability); + } + + public SkymarchBloodletter(final SkymarchBloodletter card) { + super(card); + } + + @Override + public SkymarchBloodletter copy() { + return new SkymarchBloodletter(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index f892df8c2d..0701dd39a8 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -239,6 +239,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Skulduggery", 123, Rarity.COMMON, mage.cards.s.Skulduggery.class)); cards.add(new SetCardInfo("Sky Terror", 229, Rarity.UNCOMMON, mage.cards.s.SkyTerror.class)); cards.add(new SetCardInfo("Skyblade of the Legion", 37, Rarity.COMMON, mage.cards.s.SkybladeOfTheLegion.class)); + cards.add(new SetCardInfo("Skymarch Bloodletter", 124, Rarity.COMMON, mage.cards.s.SkymarchBloodletter.class)); cards.add(new SetCardInfo("Slash of Talons", 38, Rarity.COMMON, mage.cards.s.SlashOfTalons.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); cards.add(new SetCardInfo("Snapping Sailback", 208, Rarity.UNCOMMON, mage.cards.s.SnappingSailback.class)); From 0565ab439cf730ca6d4e75061884429595f390d6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:40:11 -0400 Subject: [PATCH 087/182] Implemented Spreading Rot --- Mage.Sets/src/mage/cards/s/SpreadingRot.java | 61 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 62 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SpreadingRot.java diff --git a/Mage.Sets/src/mage/cards/s/SpreadingRot.java b/Mage.Sets/src/mage/cards/s/SpreadingRot.java new file mode 100644 index 0000000000..d1781ff113 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpreadingRot.java @@ -0,0 +1,61 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.LoseLifeTargetControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author TheElk801 + */ +public class SpreadingRot extends CardImpl { + + public SpreadingRot(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}"); + + // Destroy target land. Its controller loses 2 life. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addEffect(new LoseLifeTargetControllerEffect(2)); + this.getSpellAbility().addTarget(new TargetLandPermanent()); + } + + public SpreadingRot(final SpreadingRot card) { + super(card); + } + + @Override + public SpreadingRot copy() { + return new SpreadingRot(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 0701dd39a8..c8d1dd28ef 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -249,6 +249,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Spike-Tailed Ceratops", 209, Rarity.COMMON, mage.cards.s.SpikeTailedCeratops.class)); cards.add(new SetCardInfo("Spires of Orazca", 249, Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); cards.add(new SetCardInfo("Spitfire Bastion", 173, Rarity.RARE, mage.cards.s.SpitfireBastion.class)); + cards.add(new SetCardInfo("Spreading Rot", 125, Rarity.COMMON, mage.cards.s.SpreadingRot.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); cards.add(new SetCardInfo("Storm Fleet Aerialist", 83, Rarity.UNCOMMON, mage.cards.s.StormFleetAerialist.class)); From 7608f5fcabccb2c053032cd8e6b4f3f064b91673 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:43:23 -0400 Subject: [PATCH 088/182] Implemented Vanquish the Weak --- .../src/mage/cards/v/VanquishTheWeak.java | 68 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 69 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VanquishTheWeak.java diff --git a/Mage.Sets/src/mage/cards/v/VanquishTheWeak.java b/Mage.Sets/src/mage/cards/v/VanquishTheWeak.java new file mode 100644 index 0000000000..0c6fe5ec4f --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VanquishTheWeak.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.v; + +import java.util.UUID; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.target.TargetPermanent; + +/** + * + * @author TheElk801 + */ +public class VanquishTheWeak extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power 3 or less"); + + static { + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 4)); + } + + public VanquishTheWeak(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}"); + + // Destroy target creature with power 3 or less. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + } + + public VanquishTheWeak(final VanquishTheWeak card) { + super(card); + } + + @Override + public VanquishTheWeak copy() { + return new VanquishTheWeak(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index c8d1dd28ef..aed43764d4 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -284,6 +284,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Unfriendly Fire", 172, Rarity.COMMON, mage.cards.u.UnfriendlyFire.class)); cards.add(new SetCardInfo("Unknown Shores", 259, Rarity.COMMON, mage.cards.u.UnknownShores.class)); cards.add(new SetCardInfo("Vance's Blasting Cannons", 173, Rarity.RARE, mage.cards.v.VancesBlastingCannons.class)); + cards.add(new SetCardInfo("Vanquish the Weak", 127, Rarity.COMMON, mage.cards.v.VanquishTheWeak.class)); cards.add(new SetCardInfo("Vanquisher's Banner", 251, Rarity.RARE, mage.cards.v.VanquishersBanner.class)); cards.add(new SetCardInfo("Verdant Sun's Avatar", 213, Rarity.RARE, mage.cards.v.VerdantSunsAvatar.class)); cards.add(new SetCardInfo("Vicious Conquistador", 128, Rarity.UNCOMMON, mage.cards.v.ViciousConquistador.class)); From 6b991008b165ca7dc9fff8bd4c3a4dda3c2c7172 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:44:57 -0400 Subject: [PATCH 089/182] Implemented Bonded Horncrest --- .../src/mage/cards/b/BondedHorncrest.java | 65 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 66 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BondedHorncrest.java diff --git a/Mage.Sets/src/mage/cards/b/BondedHorncrest.java b/Mage.Sets/src/mage/cards/b/BondedHorncrest.java new file mode 100644 index 0000000000..a62a078324 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BondedHorncrest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.CantAttackAloneAbility; +import mage.abilities.keyword.CantBlockAloneAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class BondedHorncrest extends CardImpl { + + public BondedHorncrest(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Bonded Horncrest can't attack or block alone. + this.addAbility(new CantAttackAloneAbility()); + this.addAbility(CantBlockAloneAbility.getInstance()); + } + + public BondedHorncrest(final BondedHorncrest card) { + super(card); + } + + @Override + public BondedHorncrest copy() { + return new BondedHorncrest(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index aed43764d4..7cd0245771 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -50,6 +50,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Bishop's Soldier", 6, Rarity.COMMON, mage.cards.b.BishopsSoldier.class)); cards.add(new SetCardInfo("Blight Keeper", 92, Rarity.COMMON, mage.cards.b.BlightKeeper.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); + cards.add(new SetCardInfo("Bonded Horncrest", 133, Rarity.UNCOMMON, mage.cards.b.BondedHorncrest.class)); cards.add(new SetCardInfo("Boneyard Parley", 94, Rarity.MYTHIC, mage.cards.b.BoneyardParley.class)); cards.add(new SetCardInfo("Brazen Buccaneers", 134, Rarity.COMMON, mage.cards.b.BrazenBuccaneers.class)); cards.add(new SetCardInfo("Bright Reprisal", 7, Rarity.UNCOMMON, mage.cards.b.BrightReprisal.class)); From 0e220ba379915ca601b91ff18c26d473e5bed9c6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:46:43 -0400 Subject: [PATCH 090/182] Implemented Fathom Fleet Firebrand --- .../mage/cards/f/FathomFleetFirebrand.java | 68 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 69 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FathomFleetFirebrand.java diff --git a/Mage.Sets/src/mage/cards/f/FathomFleetFirebrand.java b/Mage.Sets/src/mage/cards/f/FathomFleetFirebrand.java new file mode 100644 index 0000000000..9e03ba0b03 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FathomFleetFirebrand.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class FathomFleetFirebrand extends CardImpl { + + public FathomFleetFirebrand(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {1}{r}: Fathom Fleet Firebrand gets +1/+0 until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{1}{R}"))); + } + + public FathomFleetFirebrand(final FathomFleetFirebrand card) { + super(card); + } + + @Override + public FathomFleetFirebrand copy() { + return new FathomFleetFirebrand(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 7cd0245771..16ae980850 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -105,6 +105,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Encampment Keeper", 11, Rarity.COMMON, mage.cards.e.EncampmentKeeper.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); cards.add(new SetCardInfo("Fathom Fleet Captain", 106, Rarity.RARE, mage.cards.f.FathomFleetCaptain.class)); + cards.add(new SetCardInfo("Fathom Fleet Firebrand", 142, Rarity.COMMON, mage.cards.f.FathomFleetFirebrand.class)); cards.add(new SetCardInfo("Favorable Winds", 56, Rarity.UNCOMMON, mage.cards.f.FavorableWinds.class)); cards.add(new SetCardInfo("Fell Flagship", 238, Rarity.RARE, mage.cards.f.FellFlagship.class)); cards.add(new SetCardInfo("Field of Ruin", 254, Rarity.UNCOMMON, mage.cards.f.FieldOfRuin.class)); From 56911cc58ead9fce8eb6eac0126c9ca0d3ac064b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:51:19 -0400 Subject: [PATCH 091/182] Implemented Swashbuckling --- Mage.Sets/src/mage/cards/s/Swashbuckling.java | 80 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 81 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/Swashbuckling.java diff --git a/Mage.Sets/src/mage/cards/s/Swashbuckling.java b/Mage.Sets/src/mage/cards/s/Swashbuckling.java new file mode 100644 index 0000000000..e0315b48b9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Swashbuckling.java @@ -0,0 +1,80 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class Swashbuckling extends CardImpl { + + public Swashbuckling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets +2/+2 and has haste. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(HasteAbility.getInstance(), AttachmentType.AURA))); + } + + public Swashbuckling(final Swashbuckling card) { + super(card); + } + + @Override + public Swashbuckling copy() { + return new Swashbuckling(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 16ae980850..f935864d8a 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -268,6 +268,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 269, Rarity.LAND, mage.cards.basiclands.Swamp.class)); cards.add(new SetCardInfo("Swamp", 270, Rarity.LAND, mage.cards.basiclands.Swamp.class)); cards.add(new SetCardInfo("Swamp", 271, Rarity.LAND, mage.cards.basiclands.Swamp.class)); + cards.add(new SetCardInfo("Swashbuckling", 167, Rarity.COMMON, mage.cards.s.Swashbuckling.class)); cards.add(new SetCardInfo("Sword-Point Diplomacy", 126, Rarity.RARE, mage.cards.s.SwordPointDiplomacy.class)); cards.add(new SetCardInfo("Tempest Caller", 86, Rarity.UNCOMMON, mage.cards.t.TempestCaller.class)); cards.add(new SetCardInfo("Temple of Aclazotz", 90, Rarity.RARE, mage.cards.t.TempleOfAclazotz.class)); From 62bb67776ecd14e196efd290b511e0ffa4d9f8f8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:56:11 -0400 Subject: [PATCH 092/182] Implemented Atzocan Archer --- Mage.Sets/src/mage/cards/a/AtzocanArcher.java | 84 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 85 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AtzocanArcher.java diff --git a/Mage.Sets/src/mage/cards/a/AtzocanArcher.java b/Mage.Sets/src/mage/cards/a/AtzocanArcher.java new file mode 100644 index 0000000000..7cb2fb513a --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AtzocanArcher.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.FightTargetSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class AtzocanArcher extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature"); + + static { + filter.add(new AnotherPredicate()); + } + + public AtzocanArcher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ARCHER); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // When Atzocan Archer enters the battlefield, you may have it fight another target creature. + Effect effect = new FightTargetSourceEffect(); + effect.setText("you may have it fight another target creature"); + Ability ability = new EntersBattlefieldTriggeredAbility(effect, true); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public AtzocanArcher(final AtzocanArcher card) { + super(card); + } + + @Override + public AtzocanArcher copy() { + return new AtzocanArcher(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index f935864d8a..60beddf2fa 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -41,6 +41,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Arcane Adaptation", 46, Rarity.RARE, mage.cards.a.ArcaneAdaptation.class)); cards.add(new SetCardInfo("Arguel's Blood Fast", 90, Rarity.RARE, mage.cards.a.ArguelsBloodFast.class)); cards.add(new SetCardInfo("Ashes of the Abhorrent", 2, Rarity.RARE, mage.cards.a.AshesOfTheAbhorrent.class)); + cards.add(new SetCardInfo("Atzocan Archer", 176, Rarity.UNCOMMON, mage.cards.a.AtzocanArcher.class)); cards.add(new SetCardInfo("Axis of Mortality", 3, Rarity.MYTHIC, mage.cards.a.AxisOfMortality.class)); cards.add(new SetCardInfo("Azcanta, The Sunken Ruin", 74, Rarity.RARE, mage.cards.a.AzcantaTheSunkenRuin.class)); cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.b.BelligerentBrontodon.class)); From 4aa6304c1758898d02cf69e7cebb2b2e91208e31 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 17:58:57 -0400 Subject: [PATCH 093/182] Implemented Blossom Dryad --- Mage.Sets/src/mage/cards/b/BlossomDryad.java | 70 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 71 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BlossomDryad.java diff --git a/Mage.Sets/src/mage/cards/b/BlossomDryad.java b/Mage.Sets/src/mage/cards/b/BlossomDryad.java new file mode 100644 index 0000000000..617b44e590 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BlossomDryad.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author TheElk801 + */ +public class BlossomDryad extends CardImpl { + + public BlossomDryad(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.DRYAD); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {t}: Untap target land. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapTargetEffect(), new TapSourceCost()); + ability.addTarget(new TargetLandPermanent()); + this.addAbility(ability); + } + + public BlossomDryad(final BlossomDryad card) { + super(card); + } + + @Override + public BlossomDryad copy() { + return new BlossomDryad(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 60beddf2fa..b0447e4f8f 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -51,6 +51,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Bishop's Soldier", 6, Rarity.COMMON, mage.cards.b.BishopsSoldier.class)); cards.add(new SetCardInfo("Blight Keeper", 92, Rarity.COMMON, mage.cards.b.BlightKeeper.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); + cards.add(new SetCardInfo("Blossom Dryad", 178, Rarity.COMMON, mage.cards.b.BlossomDryad.class)); cards.add(new SetCardInfo("Bonded Horncrest", 133, Rarity.UNCOMMON, mage.cards.b.BondedHorncrest.class)); cards.add(new SetCardInfo("Boneyard Parley", 94, Rarity.MYTHIC, mage.cards.b.BoneyardParley.class)); cards.add(new SetCardInfo("Brazen Buccaneers", 134, Rarity.COMMON, mage.cards.b.BrazenBuccaneers.class)); From cc1acdc62c0f8d0aa5503a4b0018f42e7ec62fd0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 18:03:07 -0400 Subject: [PATCH 094/182] Implemented Crash the Ramparts --- .../src/mage/cards/c/CrashTheRamparts.java | 68 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 69 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CrashTheRamparts.java diff --git a/Mage.Sets/src/mage/cards/c/CrashTheRamparts.java b/Mage.Sets/src/mage/cards/c/CrashTheRamparts.java new file mode 100644 index 0000000000..c199a4a077 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CrashTheRamparts.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class CrashTheRamparts extends CardImpl { + + public CrashTheRamparts(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); + + // Target creature gets +3/+3 and gains trample until end of turn. + Effect effect = new BoostTargetEffect(3, 3, Duration.EndOfTurn); + effect.setText("Target creature gets +3/+3"); + this.getSpellAbility().addEffect(effect); + effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and gains trample until end of turn"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public CrashTheRamparts(final CrashTheRamparts card) { + super(card); + } + + @Override + public CrashTheRamparts copy() { + return new CrashTheRamparts(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index b0447e4f8f..e583301e63 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -72,6 +72,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Conqueror's Galleon", 234, Rarity.RARE, mage.cards.c.ConquerorsGalleon.class)); cards.add(new SetCardInfo("Contract Killing", 95, Rarity.COMMON, mage.cards.c.ContractKilling.class)); cards.add(new SetCardInfo("Costly Plunder", 96, Rarity.COMMON, mage.cards.c.CostlyPlunder.class)); + cards.add(new SetCardInfo("Crash the Ramparts", 182, Rarity.COMMON, mage.cards.c.CrashTheRamparts.class)); cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); cards.add(new SetCardInfo("Dark Nourishment", 97, Rarity.UNCOMMON, mage.cards.d.DarkNourishment.class)); cards.add(new SetCardInfo("Deadeye Plunderers", 220, Rarity.UNCOMMON, mage.cards.d.DeadeyePlunderers.class)); From 6966cbe3dd45cbf92428a9a7e89fdda2b9325663 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 18:06:19 -0400 Subject: [PATCH 095/182] Implemented Crushing Canopy --- .../src/mage/cards/c/CrushingCanopy.java | 76 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 77 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CrushingCanopy.java diff --git a/Mage.Sets/src/mage/cards/c/CrushingCanopy.java b/Mage.Sets/src/mage/cards/c/CrushingCanopy.java new file mode 100644 index 0000000000..26fa449740 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CrushingCanopy.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.abilities.Mode; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetEnchantmentPermanent; + +/** + * + * @author TheElk801 + */ +public class CrushingCanopy extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with flying"); + + static { + filter.add(new AbilityPredicate(FlyingAbility.class)); + } + + public CrushingCanopy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); + + // Choose one -- + // * Destroy target creature with flying. + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + // * Destroy target enchantment. + Mode mode = new Mode(); + mode.getTargets().add(new TargetEnchantmentPermanent()); + mode.getEffects().add(new DestroyTargetEffect()); + this.getSpellAbility().addMode(mode); + } + + public CrushingCanopy(final CrushingCanopy card) { + super(card); + } + + @Override + public CrushingCanopy copy() { + return new CrushingCanopy(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index e583301e63..64999207bd 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -73,6 +73,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Contract Killing", 95, Rarity.COMMON, mage.cards.c.ContractKilling.class)); cards.add(new SetCardInfo("Costly Plunder", 96, Rarity.COMMON, mage.cards.c.CostlyPlunder.class)); cards.add(new SetCardInfo("Crash the Ramparts", 182, Rarity.COMMON, mage.cards.c.CrashTheRamparts.class)); + cards.add(new SetCardInfo("Crushing Canopy", 183, Rarity.COMMON, mage.cards.c.CrushingCanopy.class)); cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); cards.add(new SetCardInfo("Dark Nourishment", 97, Rarity.UNCOMMON, mage.cards.d.DarkNourishment.class)); cards.add(new SetCardInfo("Deadeye Plunderers", 220, Rarity.UNCOMMON, mage.cards.d.DeadeyePlunderers.class)); From 18ac3365f8104af9acc5ffad18f02cd41024f892 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 18:07:44 -0400 Subject: [PATCH 096/182] Implemented Gilded Sentinel --- .../src/mage/cards/g/GildedSentinel.java | 56 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 57 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GildedSentinel.java diff --git a/Mage.Sets/src/mage/cards/g/GildedSentinel.java b/Mage.Sets/src/mage/cards/g/GildedSentinel.java new file mode 100644 index 0000000000..060dd11be0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GildedSentinel.java @@ -0,0 +1,56 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class GildedSentinel extends CardImpl { + + public GildedSentinel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + + this.subtype.add(SubType.GOLEM); + } + + public GildedSentinel(final GildedSentinel card) { + super(card); + } + + @Override + public GildedSentinel copy() { + return new GildedSentinel(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 64999207bd..460418b106 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -118,6 +118,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Forest", 278, Rarity.LAND, mage.cards.basiclands.Forest.class)); cards.add(new SetCardInfo("Forest", 279, Rarity.LAND, mage.cards.basiclands.Forest.class)); cards.add(new SetCardInfo("Frenzied Raptor", 146, Rarity.COMMON, mage.cards.f.FrenziedRaptor.class)); + cards.add(new SetCardInfo("Gilded Sentinel", 239, Rarity.COMMON, mage.cards.g.GildedSentinel.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); cards.add(new SetCardInfo("Glorifier of Dusk", 12, Rarity.UNCOMMON, mage.cards.g.GlorifierOfDusk.class)); From 5b04acf1ec2e1d7c2735e6a081375687c0205a97 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 18:10:16 -0400 Subject: [PATCH 097/182] Implemented Hierophant's Chalice --- .../src/mage/cards/h/HierophantsChalice.java | 70 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 71 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HierophantsChalice.java diff --git a/Mage.Sets/src/mage/cards/h/HierophantsChalice.java b/Mage.Sets/src/mage/cards/h/HierophantsChalice.java new file mode 100644 index 0000000000..7773026a68 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HierophantsChalice.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.h; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.Target; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class HierophantsChalice extends CardImpl { + + public HierophantsChalice(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + // When Hierophant's Chalice enters the battlefield, target opponent loses 1 life and you gain 1 life. + Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(1), false); + ability.addEffect(new GainLifeEffect(1)); + Target target = new TargetOpponent(); + ability.addTarget(target); + this.addAbility(ability); + + // {t}: Add {c} to your mana pool. + this.addAbility(new ColorlessManaAbility()); + } + + public HierophantsChalice(final HierophantsChalice card) { + super(card); + } + + @Override + public HierophantsChalice copy() { + return new HierophantsChalice(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 460418b106..b1dc86731d 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -129,6 +129,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Headstrong Brute", 147, Rarity.COMMON, mage.cards.h.HeadstrongBrute.class)); cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); + cards.add(new SetCardInfo("Hierophant's Chalice", 240, Rarity.COMMON, mage.cards.h.HierophantsChalice.class)); cards.add(new SetCardInfo("Hijack", 148, Rarity.COMMON, mage.cards.h.Hijack.class)); cards.add(new SetCardInfo("Hostage Taker", 223, Rarity.RARE, mage.cards.h.HostageTaker.class)); cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); From 8633a303b13cecc0ff563d7e875eec60be118941 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 18:14:20 -0400 Subject: [PATCH 098/182] Implemented Prying Blade --- Mage.Sets/src/mage/cards/p/PryingBlade.java | 74 +++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 75 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PryingBlade.java diff --git a/Mage.Sets/src/mage/cards/p/PryingBlade.java b/Mage.Sets/src/mage/cards/p/PryingBlade.java new file mode 100644 index 0000000000..fca092898e --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PryingBlade.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.permanent.token.TreasureToken; + +/** + * + * @author TheElk801 + */ +public class PryingBlade extends CardImpl { + + public PryingBlade(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); + + this.subtype.add(SubType.EQUIPMENT); + + // Equipped creature gets +1/+0. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 0))); + + // Whenever equipped creature deals combat damage to a player, create a colorless Treasure artifact token with "{t}, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.addAbility(new DealsDamageToAPlayerAttachedTriggeredAbility(new CreateTokenEffect(new TreasureToken()), "equipped creature", false)); + + // Equip {2} + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); + } + + public PryingBlade(final PryingBlade card) { + super(card); + } + + @Override + public PryingBlade copy() { + return new PryingBlade(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index b1dc86731d..8a3efddb32 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -198,6 +198,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); + cards.add(new SetCardInfo("Prying Blade", 244, Rarity.COMMON, mage.cards.p.PryingBlade.class)); cards.add(new SetCardInfo("Pterodon Knight", 28, Rarity.COMMON, mage.cards.p.PterodonKnight.class)); cards.add(new SetCardInfo("Queen's Agent", 114, Rarity.COMMON, mage.cards.q.QueensAgent.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); From 85d70660b81f050666013b0b4ba8d4e825349f6f Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 01:32:00 +0200 Subject: [PATCH 099/182] [XLN] Added 10 cards. --- Mage.Sets/src/mage/cards/b/BlindingFog.java | 64 ++++++++++ .../src/mage/cards/e/ElaborateFirecannon.java | 81 +++++++++++++ .../src/mage/cards/f/FieryCannonade.java | 67 +++++++++++ .../src/mage/cards/f/FireShrineKeeper.java | 79 +++++++++++++ .../src/mage/cards/f/FirecannonBlast.java | 72 ++++++++++++ .../src/mage/cards/g/GrimCaptainsCall.java | 111 ++++++++++++++++++ .../src/mage/cards/h/HeartlessPillage.java | 71 +++++++++++ .../mage/cards/s/StormFleetPyromancer.java | 76 ++++++++++++ .../src/mage/cards/t/ThrashOfRaptors.java | 89 ++++++++++++++ .../src/mage/cards/v/VerdantRebirth.java | 70 +++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 10 ++ 11 files changed, 790 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BlindingFog.java create mode 100644 Mage.Sets/src/mage/cards/e/ElaborateFirecannon.java create mode 100644 Mage.Sets/src/mage/cards/f/FieryCannonade.java create mode 100644 Mage.Sets/src/mage/cards/f/FireShrineKeeper.java create mode 100644 Mage.Sets/src/mage/cards/f/FirecannonBlast.java create mode 100644 Mage.Sets/src/mage/cards/g/GrimCaptainsCall.java create mode 100644 Mage.Sets/src/mage/cards/h/HeartlessPillage.java create mode 100644 Mage.Sets/src/mage/cards/s/StormFleetPyromancer.java create mode 100644 Mage.Sets/src/mage/cards/t/ThrashOfRaptors.java create mode 100644 Mage.Sets/src/mage/cards/v/VerdantRebirth.java diff --git a/Mage.Sets/src/mage/cards/b/BlindingFog.java b/Mage.Sets/src/mage/cards/b/BlindingFog.java new file mode 100644 index 0000000000..fbac6b9092 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BlindingFog.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.abilities.effects.common.PreventAllDamageToAllEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.HexproofAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURE; +import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES; + +/** + * + * @author LevelX2 + */ +public class BlindingFog extends CardImpl { + + public BlindingFog(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); + + // Prevent all damage that would be dealt to creatures this turn. + this.getSpellAbility().addEffect(new PreventAllDamageToAllEffect(Duration.EndOfTurn, FILTER_PERMANENT_CREATURES)); + // Creatures you control gain hexproof until end of turn. + this.getSpellAbility().addEffect(new GainAbilityControlledEffect(HexproofAbility.getInstance(), Duration.EndOfTurn, FILTER_PERMANENT_CREATURE, false)); + } + + public BlindingFog(final BlindingFog card) { + super(card); + } + + @Override + public BlindingFog copy() { + return new BlindingFog(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/ElaborateFirecannon.java b/Mage.Sets/src/mage/cards/e/ElaborateFirecannon.java new file mode 100644 index 0000000000..ae2b2fc43d --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ElaborateFirecannon.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.e; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect; +import mage.abilities.effects.common.UntapSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LevelX2 + */ +public class ElaborateFirecannon extends CardImpl { + + public ElaborateFirecannon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + // Elaborate Firecannon doesn't untap during your untap step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect())); + + // {4}, {T}: Elaborate Firecannon deals 2 damage to target creature or player. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new ManaCostsImpl<>("{4}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + + // At the beginning of your upkeep, you may discard a card. If you do, untap Elaborate Firecannon. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DoIfCostPaid( + new UntapSourceEffect(), new DiscardCardCost()), TargetController.YOU, false)); + + } + + public ElaborateFirecannon(final ElaborateFirecannon card) { + super(card); + } + + @Override + public ElaborateFirecannon copy() { + return new ElaborateFirecannon(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FieryCannonade.java b/Mage.Sets/src/mage/cards/f/FieryCannonade.java new file mode 100644 index 0000000000..670ed09aee --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FieryCannonade.java @@ -0,0 +1,67 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.abilities.effects.common.DamageAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author LevelX2 + */ +public class FieryCannonade extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Pirate creature"); + + static { + filter.add(Predicates.not(new SubtypePredicate(SubType.PIRATE))); + } + + public FieryCannonade(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); + + // Fiery Cannonade deals 2 damage to each non-Pirate creature. + this.getSpellAbility().addEffect(new DamageAllEffect(2, filter)); + } + + public FieryCannonade(final FieryCannonade card) { + super(card); + } + + @Override + public FieryCannonade copy() { + return new FieryCannonade(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FireShrineKeeper.java b/Mage.Sets/src/mage/cards/f/FireShrineKeeper.java new file mode 100644 index 0000000000..e7ff050e4a --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FireShrineKeeper.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class FireShrineKeeper extends CardImpl { + + public FireShrineKeeper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Menace + this.addAbility(MenaceAbility.getInstance()); + + // {7}{R}, {T}, Sacrifice Fire Shrine Keeper: It deals 3 damage to each of up to two target creatures. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new DamageTargetEffect(3).setText("It deals 3 damage to each of up to two target creatures"), new ManaCostsImpl<>("{7}{R}")); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetCreaturePermanent(0, 2)); + this.addAbility(ability); + } + + public FireShrineKeeper(final FireShrineKeeper card) { + super(card); + } + + @Override + public FireShrineKeeper copy() { + return new FireShrineKeeper(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FirecannonBlast.java b/Mage.Sets/src/mage/cards/f/FirecannonBlast.java new file mode 100644 index 0000000000..9078ed3743 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FirecannonBlast.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.abilities.condition.InvertCondition; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreaturePermanent; +import mage.watchers.common.PlayerAttackedWatcher; + +/** + * + * @author LevelX2 + */ +public class FirecannonBlast extends CardImpl { + + public FirecannonBlast(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}{R}"); + + // Firecannon Blast deals 3 damage to target creature. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new DamageTargetEffect(3), + new InvertCondition(RaidCondition.instance), + "{this} deals 3 damage to target creature")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + // Raid - Firecannon Blast deals 6 damage to that creature instead if you attacked with a creature this turn. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new DamageTargetEffect(6, false), + RaidCondition.instance, + "

Raid — {this} deals 6 damage to that creature instead if you attacked with a creature this turn")); + this.getSpellAbility().addWatcher(new PlayerAttackedWatcher()); + } + + public FirecannonBlast(final FirecannonBlast card) { + super(card); + } + + @Override + public FirecannonBlast copy() { + return new FirecannonBlast(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GrimCaptainsCall.java b/Mage.Sets/src/mage/cards/g/GrimCaptainsCall.java new file mode 100644 index 0000000000..e5c2ffc7ce --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GrimCaptainsCall.java @@ -0,0 +1,111 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author LevelX2 + */ +public class GrimCaptainsCall extends CardImpl { + + public GrimCaptainsCall(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); + + // Return a Pirate card from your graveyard to your hand, then do the same for Vampire, Dinosaur, and Merfolk. + this.getSpellAbility().addEffect(new GrimCaptainsCallEffect()); + } + + public GrimCaptainsCall(final GrimCaptainsCall card) { + super(card); + } + + @Override + public GrimCaptainsCall copy() { + return new GrimCaptainsCall(this); + } +} + +class GrimCaptainsCallEffect extends OneShotEffect { + + public GrimCaptainsCallEffect() { + super(Outcome.Benefit); + this.staticText = "Return a Pirate card from your graveyard to your hand, then do the same for Vampire, Dinosaur, and Merfolk"; + } + + public GrimCaptainsCallEffect(final GrimCaptainsCallEffect effect) { + super(effect); + } + + @Override + public GrimCaptainsCallEffect copy() { + return new GrimCaptainsCallEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + returnToHand(game, SubType.PIRATE, controller, source); + returnToHand(game, SubType.VAMPIRE, controller, source); + returnToHand(game, SubType.DINOSAUR, controller, source); + returnToHand(game, SubType.MERFOLK, controller, source); + return true; + } + return false; + } + + private void returnToHand(Game game, SubType subType, Player controller, Ability source) { + FilterCreatureCard filter = new FilterCreatureCard(); + filter.add(new SubtypePredicate(subType)); + TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(new FilterCreatureCard()); + if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) { + if (controller.chooseTarget(outcome, target, source, game)) { + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + controller.moveCards(card, Zone.HAND, source, game); + } + } + } + } +} diff --git a/Mage.Sets/src/mage/cards/h/HeartlessPillage.java b/Mage.Sets/src/mage/cards/h/HeartlessPillage.java new file mode 100644 index 0000000000..82d888547a --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HeartlessPillage.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.h; + +import java.util.UUID; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.TreasureToken; +import mage.target.common.TargetOpponent; +import mage.watchers.common.PlayerAttackedWatcher; + +/** + * + * @author LevelX2 + */ +public class HeartlessPillage extends CardImpl { + + public HeartlessPillage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); + + // Target opponent discards two cards. + this.getSpellAbility().addTarget(new TargetOpponent()); + this.getSpellAbility().addEffect(new DiscardTargetEffect(2)); + + // Raid — If you attacked with a creature this turn, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new CreateTokenEffect(new TreasureToken()), + RaidCondition.instance, + "

Raid — If you attacked with a creature this turn, create a colorless Treasure artifact token with \"{T}, Sacrifice this artifact: Add one mana of any color to your mana pool.\"")); + this.getSpellAbility().addWatcher(new PlayerAttackedWatcher()); + } + + public HeartlessPillage(final HeartlessPillage card) { + super(card); + } + + @Override + public HeartlessPillage copy() { + return new HeartlessPillage(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/StormFleetPyromancer.java b/Mage.Sets/src/mage/cards/s/StormFleetPyromancer.java new file mode 100644 index 0000000000..471c04af6c --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StormFleetPyromancer.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetCreatureOrPlayer; +import mage.watchers.common.PlayerAttackedWatcher; + +/** + * + * @author LevelX2 + */ +public class StormFleetPyromancer extends CardImpl { + + public StormFleetPyromancer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PIRATE); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Raid - When Storm Fleet Pyromancer enters the battlefield, if you attacked with a creature this turn, Storm Fleet Pyromancer deals 2 damage to target creature or player. + Ability ability = new ConditionalTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(2)), + RaidCondition.instance, + "Raid — When {this} enters the battlefield, if you attacked with a creature this turn, {this} deals 2 damage to target creature or player."); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability, new PlayerAttackedWatcher()); + } + + public StormFleetPyromancer(final StormFleetPyromancer card) { + super(card); + } + + @Override + public StormFleetPyromancer copy() { + return new StormFleetPyromancer(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/ThrashOfRaptors.java b/Mage.Sets/src/mage/cards/t/ThrashOfRaptors.java new file mode 100644 index 0000000000..f5562f54c4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThrashOfRaptors.java @@ -0,0 +1,89 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author LevelX2 + */ +public class ThrashOfRaptors extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another Dinosaur"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + filter.add(new AnotherPredicate()); + } + + public ThrashOfRaptors(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // As long as you control another Dinosaur, Thrash of Raptors gets +2/+0 and has trample. + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(2, 0, Duration.WhileOnBattlefield), + new PermanentsOnTheBattlefieldCondition(filter), + "As long as you control another Dinosaur, {this} gets +2/+0")); + ability.addEffect(new ConditionalContinuousEffect( + new GainAbilitySourceEffect(TrampleAbility.getInstance()), + new PermanentsOnTheBattlefieldCondition(filter), + "and has trample")); + this.addAbility(ability); + } + + public ThrashOfRaptors(final ThrashOfRaptors card) { + super(card); + } + + @Override + public ThrashOfRaptors copy() { + return new ThrashOfRaptors(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VerdantRebirth.java b/Mage.Sets/src/mage/cards/v/VerdantRebirth.java new file mode 100644 index 0000000000..5c8d03c421 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VerdantRebirth.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.v; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class VerdantRebirth extends CardImpl { + + public VerdantRebirth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); + + // Until end of turn, target creature gains "When this creature dies, return it to its owner's hand." + Ability gainedAbility = new DiesTriggeredAbility(new ReturnToHandSourceEffect(), false); + Effect effect = new GainAbilityTargetEffect(gainedAbility, Duration.EndOfTurn); + effect.setText("Until end of turn, target creature gains \"When this creature dies, return it to its owner's hand.\""); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + // Draw a card. + getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("

Draw a card")); + } + + public VerdantRebirth(final VerdantRebirth card) { + super(card); + } + + @Override + public VerdantRebirth copy() { + return new VerdantRebirth(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 74ebe8fe00..71e8589aac 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -47,6 +47,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class)); cards.add(new SetCardInfo("Bishop of the Bloodstained", 91, Rarity.UNCOMMON, mage.cards.b.BishopOfTheBloodstained.class)); + cards.add(new SetCardInfo("Blinding Fog", 177, Rarity.COMMON, mage.cards.b.BlindingFog.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); cards.add(new SetCardInfo("Boneyard Parley", 94, Rarity.MYTHIC, mage.cards.b.BoneyardParley.class)); cards.add(new SetCardInfo("Brazen Buccaneers", 134, Rarity.COMMON, mage.cards.b.BrazenBuccaneers.class)); @@ -89,6 +90,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Duress", 105, Rarity.COMMON, mage.cards.d.Duress.class)); cards.add(new SetCardInfo("Duskborne Skymarcher", 9, Rarity.UNCOMMON, mage.cards.d.DuskborneSkymarcher.class)); cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.d.DuskLegionDreadnought.class)); + cards.add(new SetCardInfo("Elaborate Firecannon", 237, Rarity.UNCOMMON, mage.cards.e.ElaborateFirecannon.class)); cards.add(new SetCardInfo("Emergent Growth", 188, Rarity.UNCOMMON, mage.cards.e.EmergentGrowth.class)); cards.add(new SetCardInfo("Emissary of Sunrise", 10, Rarity.UNCOMMON, mage.cards.e.EmissaryOfSunrise.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); @@ -97,6 +99,9 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Favorable Winds", 56, Rarity.UNCOMMON, mage.cards.f.FavorableWinds.class)); cards.add(new SetCardInfo("Fell Flagship", 238, Rarity.RARE, mage.cards.f.FellFlagship.class)); cards.add(new SetCardInfo("Field of Ruin", 254, Rarity.UNCOMMON, mage.cards.f.FieldOfRuin.class)); + cards.add(new SetCardInfo("Fiery Cannonade", 143, Rarity.UNCOMMON, mage.cards.f.FieryCannonade.class)); + cards.add(new SetCardInfo("Fire Shrine Keeper", 144, Rarity.COMMON, mage.cards.f.FireShrineKeeper.class)); + cards.add(new SetCardInfo("Firecannon Blast", 145, Rarity.COMMON, mage.cards.f.FirecannonBlast.class)); cards.add(new SetCardInfo("Forest", 276, Rarity.LAND, mage.cards.basiclands.Forest.class)); cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class)); cards.add(new SetCardInfo("Forest", 278, Rarity.LAND, mage.cards.basiclands.Forest.class)); @@ -106,8 +111,10 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); cards.add(new SetCardInfo("Grasping Current", 282, Rarity.RARE, mage.cards.g.GraspingCurrent.class)); cards.add(new SetCardInfo("Grazing Whiptail", 190, Rarity.COMMON, mage.cards.g.GrazingWhiptail.class)); + cards.add(new SetCardInfo("Grim Captain's Call", 108, Rarity.UNCOMMON, mage.cards.g.GrimCaptainsCall.class)); cards.add(new SetCardInfo("Growing Rites of Itlimoc", 191, Rarity.RARE, mage.cards.g.GrowingRitesOfItlimoc.class)); cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); + cards.add(new SetCardInfo("Heartless Pillage", 109, Rarity.UNCOMMON, mage.cards.h.HeartlessPillage.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); cards.add(new SetCardInfo("Hijack", 148, Rarity.COMMON, mage.cards.h.Hijack.class)); cards.add(new SetCardInfo("Hostage Taker", 223, Rarity.RARE, mage.cards.h.HostageTaker.class)); @@ -213,6 +220,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); cards.add(new SetCardInfo("Storm Fleet Aerialist", 83, Rarity.UNCOMMON, mage.cards.s.StormFleetAerialist.class)); cards.add(new SetCardInfo("Storm Fleet Arsonist", 162, Rarity.UNCOMMON, mage.cards.s.StormFleetArsonist.class)); + cards.add(new SetCardInfo("Storm Fleet Pyromancer", 163, Rarity.COMMON, mage.cards.s.StormFleetPyromancer.class)); cards.add(new SetCardInfo("Storm Fleet Spy", 84, Rarity.UNCOMMON, mage.cards.s.StormFleetSpy.class)); cards.add(new SetCardInfo("Sunbird's Invocation", 165, Rarity.RARE, mage.cards.s.SunbirdsInvocation.class)); cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); @@ -226,6 +234,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Sword-Point Diplomacy", 126, Rarity.RARE, mage.cards.s.SwordPointDiplomacy.class)); cards.add(new SetCardInfo("Temple of Aclazotz", 90, Rarity.RARE, mage.cards.t.TempleOfAclazotz.class)); cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); + cards.add(new SetCardInfo("Thrash of Raptors", 168, Rarity.COMMON, mage.cards.t.ThrashOfRaptors.class)); cards.add(new SetCardInfo("Thundering Spineback", 210, Rarity.UNCOMMON, mage.cards.t.ThunderingSpineback.class)); cards.add(new SetCardInfo("Tilonalli's Knight", 169, Rarity.COMMON, mage.cards.t.TilonallisKnight.class)); cards.add(new SetCardInfo("Tilonalli's Skinshifter", 170, Rarity.RARE, mage.cards.t.TilonallisSkinshifter.class)); @@ -240,6 +249,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Unknown Shores", 259, Rarity.COMMON, mage.cards.u.UnknownShores.class)); cards.add(new SetCardInfo("Vance's Blasting Cannons", 173, Rarity.RARE, mage.cards.v.VancesBlastingCannons.class)); cards.add(new SetCardInfo("Vanquisher's Banner", 251, Rarity.RARE, mage.cards.v.VanquishersBanner.class)); + cards.add(new SetCardInfo("Verdant Rebirth", 212, Rarity.UNCOMMON, mage.cards.v.VerdantRebirth.class)); cards.add(new SetCardInfo("Verdant Sun's Avatar", 213, Rarity.RARE, mage.cards.v.VerdantSunsAvatar.class)); cards.add(new SetCardInfo("Vicious Conquistador", 128, Rarity.UNCOMMON, mage.cards.v.ViciousConquistador.class)); cards.add(new SetCardInfo("Vineshaper Mystic", 214, Rarity.UNCOMMON, mage.cards.v.VineshaperMystic.class)); From b6212a943a3ef0fca1cb31fff6d4ed763d1b482c Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 02:01:25 +0200 Subject: [PATCH 100/182] Some minor changes. --- .../mage/plugins/card/dl/sources/MythicspoilerComSource.java | 4 ++++ Mage.Sets/src/mage/cards/r/RagingSwordtooth.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java index 93bd2a6d11..baa1830363 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java @@ -272,6 +272,10 @@ public enum MythicspoilerComSource implements CardImageSource { cardNameAliases.put("AKH-reducerumble", "reducerubble"); cardNameAliases.put("AKH-forsakethewordly", "forsaketheworldly"); cardNameAliases.put("AKH-kefnatsmonument", "kefnetsmonument"); + cardNameAliases.put("XLN-kinjaliscaller", "kinjalliscaller"); + cardNameAliases.put("XLN-lookoutsdecision", "lookoutsdispersal"); + cardNameAliases.put("XLN-infuriatedgladiodon", "ragingswordtooth"); + cardNameAliases.put("XLN-redoubledvolley", "repeatingbarrage"); cardNameAliasesStart = new HashMap<>(); HashSet names = new HashSet<>(); diff --git a/Mage.Sets/src/mage/cards/r/RagingSwordtooth.java b/Mage.Sets/src/mage/cards/r/RagingSwordtooth.java index ecb8b4a279..cf4f97889d 100644 --- a/Mage.Sets/src/mage/cards/r/RagingSwordtooth.java +++ b/Mage.Sets/src/mage/cards/r/RagingSwordtooth.java @@ -45,7 +45,7 @@ import mage.filter.predicate.permanent.AnotherPredicate; */ public class RagingSwordtooth extends CardImpl { - private static FilterCreaturePermanent filter = new FilterCreaturePermanent("other creature"); + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("other creature"); static { filter.add(new AnotherPredicate()); From 6373a0bd8749226eb0476ee86632bdf16e3d82c1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 20:05:15 -0400 Subject: [PATCH 101/182] readded Slice in Twain --- Mage.Sets/src/mage/sets/Ixalan.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 668b6bc19a..1250bd2d86 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -258,6 +258,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Skymarch Bloodletter", 124, Rarity.COMMON, mage.cards.s.SkymarchBloodletter.class)); cards.add(new SetCardInfo("Slash of Talons", 38, Rarity.COMMON, mage.cards.s.SlashOfTalons.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); + cards.add(new SetCardInfo("Slice in Twain", 207, Rarity.UNCOMMON, mage.cards.s.SliceinTwain.class)); cards.add(new SetCardInfo("Snapping Sailback", 208, Rarity.UNCOMMON, mage.cards.s.SnappingSailback.class)); cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); cards.add(new SetCardInfo("Spell Pierce", 81, Rarity.COMMON, mage.cards.s.SpellPierce.class)); From 3789dbf14acb1b1ea3846d559be1f7e891658241 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 20:28:12 -0400 Subject: [PATCH 102/182] Implemented Steadfast Armasaur --- .../src/mage/cards/s/SteadfastArmasaur.java | 83 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 84 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SteadfastArmasaur.java diff --git a/Mage.Sets/src/mage/cards/s/SteadfastArmasaur.java b/Mage.Sets/src/mage/cards/s/SteadfastArmasaur.java new file mode 100644 index 0000000000..e7faecfc71 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SteadfastArmasaur.java @@ -0,0 +1,83 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.SourcePermanentToughnessValue; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.BlockedByIdPredicate; +import mage.filter.predicate.permanent.BlockingAttackerIdPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class SteadfastArmasaur extends CardImpl { + + public SteadfastArmasaur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // {1}{W}, {T}: Steadfast Armasaur deals damage equal to its toughness to target creature blocking or blocked by it. + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature blocking or blocked by it"); + filter.add(Predicates.or(new BlockedByIdPredicate(this.getId()), + new BlockingAttackerIdPredicate(this.getId()))); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(SourcePermanentToughnessValue.getInstance()), new ManaCostsImpl("{1}{W}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent(filter)); + } + + public SteadfastArmasaur(final SteadfastArmasaur card) { + super(card); + } + + @Override + public SteadfastArmasaur copy() { + return new SteadfastArmasaur(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 1250bd2d86..dcf76f3786 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -268,6 +268,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Spitfire Bastion", 173, Rarity.RARE, mage.cards.s.SpitfireBastion.class)); cards.add(new SetCardInfo("Spreading Rot", 125, Rarity.COMMON, mage.cards.s.SpreadingRot.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); + cards.add(new SetCardInfo("Steadfast Armasaur", 39, Rarity.UNCOMMON, mage.cards.s.SteadfastArmasaur.class)); cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); cards.add(new SetCardInfo("Storm Fleet Aerialist", 83, Rarity.UNCOMMON, mage.cards.s.StormFleetAerialist.class)); cards.add(new SetCardInfo("Storm Fleet Arsonist", 162, Rarity.UNCOMMON, mage.cards.s.StormFleetArsonist.class)); From 648613d06d70e4d573d06787fe571c78cd751fa8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 20:30:34 -0400 Subject: [PATCH 103/182] Implemented Vampire's Zeal --- Mage.Sets/src/mage/cards/v/VampiresZeal.java | 69 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VampiresZeal.java diff --git a/Mage.Sets/src/mage/cards/v/VampiresZeal.java b/Mage.Sets/src/mage/cards/v/VampiresZeal.java new file mode 100644 index 0000000000..ce2e87c7ea --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VampiresZeal.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.v; + +import java.util.UUID; +import mage.abilities.condition.LockedInCondition; +import mage.abilities.condition.common.TargetHasSubtypeCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class VampiresZeal extends CardImpl { + + public VampiresZeal(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); + + // Target creature gets +2/+2 until end of turn. If it's a Vampire, it gains first strike until end of turn. + this.getSpellAbility().addEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new ConditionalContinuousEffect( + new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn), new LockedInCondition(new TargetHasSubtypeCondition(SubType.VAMPIRE)), + "If it's a Vampire, it gains first strike until end of turn")); + } + + public VampiresZeal(final VampiresZeal card) { + super(card); + } + + @Override + public VampiresZeal copy() { + return new VampiresZeal(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index dcf76f3786..b1d67d2cd0 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -304,6 +304,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Unclaimed Territory", 258, Rarity.UNCOMMON, mage.cards.u.UnclaimedTerritory.class)); cards.add(new SetCardInfo("Unfriendly Fire", 172, Rarity.COMMON, mage.cards.u.UnfriendlyFire.class)); cards.add(new SetCardInfo("Unknown Shores", 259, Rarity.COMMON, mage.cards.u.UnknownShores.class)); + cards.add(new SetCardInfo("Vampire's Zeal", 43, Rarity.COMMON, mage.cards.v.VampiresZeal.class)); cards.add(new SetCardInfo("Vance's Blasting Cannons", 173, Rarity.RARE, mage.cards.v.VancesBlastingCannons.class)); cards.add(new SetCardInfo("Vanquish the Weak", 127, Rarity.COMMON, mage.cards.v.VanquishTheWeak.class)); cards.add(new SetCardInfo("Vanquisher's Banner", 251, Rarity.RARE, mage.cards.v.VanquishersBanner.class)); From 72c6f7baafdbe1709223246c95db4099edfbff2c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 20:33:21 -0400 Subject: [PATCH 104/182] Implemented Dive Down --- Mage.Sets/src/mage/cards/d/DiveDown.java | 68 ++++++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 69 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DiveDown.java diff --git a/Mage.Sets/src/mage/cards/d/DiveDown.java b/Mage.Sets/src/mage/cards/d/DiveDown.java new file mode 100644 index 0000000000..d094dade72 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DiveDown.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.HexproofAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class DiveDown extends CardImpl { + + public DiveDown(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}"); + + // Target creature you control gets +0/+3 and gains hexproof until end of turn. + Effect effect = new BoostTargetEffect(3, 3, Duration.EndOfTurn); + effect.setText("Target creature you control gets +0/+3"); + this.getSpellAbility().addEffect(effect); + effect = new GainAbilityTargetEffect(HexproofAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and gains hexproof until end of turn"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + } + + public DiveDown(final DiveDown card) { + super(card); + } + + @Override + public DiveDown copy() { + return new DiveDown(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index b1d67d2cd0..824ad75c8f 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -95,6 +95,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Dire Fleet Hoarder", 102, Rarity.COMMON, mage.cards.d.DireFleetHoarder.class)); cards.add(new SetCardInfo("Dire Fleet Interloper", 103, Rarity.COMMON, mage.cards.d.DireFleetInterloper.class)); cards.add(new SetCardInfo("Dire Fleet Ravager", 104, Rarity.MYTHIC, mage.cards.d.DireFleetRavager.class)); + cards.add(new SetCardInfo("Dive Down", 53, Rarity.COMMON, mage.cards.d.DiveDown.class)); cards.add(new SetCardInfo("Dowsing Dagger", 235, Rarity.RARE, mage.cards.d.DowsingDagger.class)); cards.add(new SetCardInfo("Dragonskull Summit", 252, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); cards.add(new SetCardInfo("Dreamcaller Siren", 54, Rarity.RARE, mage.cards.d.DreamcallerSiren.class)); From 143a91d140e160b156a7fb5f729e821900475bc3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 20:40:01 -0400 Subject: [PATCH 105/182] Implemented Fleet Swallower --- .../src/mage/cards/f/FleetSwallower.java | 100 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 101 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FleetSwallower.java diff --git a/Mage.Sets/src/mage/cards/f/FleetSwallower.java b/Mage.Sets/src/mage/cards/f/FleetSwallower.java new file mode 100644 index 0000000000..7dca9daf93 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FleetSwallower.java @@ -0,0 +1,100 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; + +/** + * + * @author TheElk801 + */ +public class FleetSwallower extends CardImpl { + + public FleetSwallower(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}"); + + this.subtype.add(SubType.FISH); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Whenever Fleet Swallower attacks, target player puts the top half of his or her library, rounded up, into his or her graveyard. + Ability ability = new AttacksTriggeredAbility(new FleetSwallowerEffect(), false); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + } + + public FleetSwallower(final FleetSwallower card) { + super(card); + } + + @Override + public FleetSwallower copy() { + return new FleetSwallower(this); + } +} + +class FleetSwallowerEffect extends OneShotEffect { + + public FleetSwallowerEffect() { + super(Outcome.Detriment); + staticText = "target player puts the top half of his or her library, rounded up, into his or her graveyard"; + } + + public FleetSwallowerEffect(final FleetSwallowerEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getFirstTarget()); + if (player != null) { + int amount = (int) Math.ceil(player.getLibrary().size() * .5); + return player.moveCards(player.getLibrary().getTopCards(game, amount), Zone.GRAVEYARD, source, game); + } + return false; + } + + @Override + public FleetSwallowerEffect copy() { + return new FleetSwallowerEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 824ad75c8f..738a06c875 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -119,6 +119,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Fiery Cannonade", 143, Rarity.UNCOMMON, mage.cards.f.FieryCannonade.class)); cards.add(new SetCardInfo("Fire Shrine Keeper", 144, Rarity.COMMON, mage.cards.f.FireShrineKeeper.class)); cards.add(new SetCardInfo("Firecannon Blast", 145, Rarity.COMMON, mage.cards.f.FirecannonBlast.class)); + cards.add(new SetCardInfo("Fleet Swallower", 57, Rarity.RARE, mage.cards.f.FleetSwallower.class)); cards.add(new SetCardInfo("Forest", 276, Rarity.LAND, mage.cards.basiclands.Forest.class)); cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class)); cards.add(new SetCardInfo("Forest", 278, Rarity.LAND, mage.cards.basiclands.Forest.class)); From 129501b8cba5eabe795f52d9c2369939bdf30b5d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 20:45:42 -0400 Subject: [PATCH 106/182] Implemented Navigator's Ruin --- .../src/mage/cards/n/NavigatorsRuin.java | 68 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 69 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/n/NavigatorsRuin.java diff --git a/Mage.Sets/src/mage/cards/n/NavigatorsRuin.java b/Mage.Sets/src/mage/cards/n/NavigatorsRuin.java new file mode 100644 index 0000000000..a480cc771c --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NavigatorsRuin.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.n; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class NavigatorsRuin extends CardImpl { + + public NavigatorsRuin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + + // Raid - At the beginning of your end step, if you attacked with a creature this turm, target opponent puts the top four cards of his or her library into his or her graveyard. + Ability ability = new ConditionalTriggeredAbility( + new BeginningOfEndStepTriggeredAbility(new PutLibraryIntoGraveTargetEffect(4), TargetController.YOU, false), + RaidCondition.instance, + "Raid - At the beginning of your end step, if you attacked with a creature this turn, target opponent puts the top four cards of his or her library into his or her graveyard."); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public NavigatorsRuin(final NavigatorsRuin card) { + super(card); + } + + @Override + public NavigatorsRuin copy() { + return new NavigatorsRuin(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 738a06c875..7f0692d6a4 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -185,6 +185,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 273, Rarity.LAND, mage.cards.basiclands.Mountain.class)); cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class)); cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class)); + cards.add(new SetCardInfo("Navigator's Ruin", 63, Rarity.UNCOMMON, mage.cards.n.NavigatorsRuin.class)); cards.add(new SetCardInfo("New Horizons", 198, Rarity.COMMON, mage.cards.n.NewHorizons.class)); cards.add(new SetCardInfo("Nest Robber", 152, Rarity.COMMON, mage.cards.n.NestRobber.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); From 0f8a799115d494dab9e3447a21c68f671ec14978 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 20:52:13 -0400 Subject: [PATCH 107/182] Implemented Shipwreck Looter --- .../src/mage/cards/n/NavigatorsRuin.java | 5 +- .../src/mage/cards/s/ShipwreckLooter.java | 75 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/s/ShipwreckLooter.java diff --git a/Mage.Sets/src/mage/cards/n/NavigatorsRuin.java b/Mage.Sets/src/mage/cards/n/NavigatorsRuin.java index a480cc771c..f7f9d41799 100644 --- a/Mage.Sets/src/mage/cards/n/NavigatorsRuin.java +++ b/Mage.Sets/src/mage/cards/n/NavigatorsRuin.java @@ -38,6 +38,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.TargetController; import mage.target.common.TargetOpponent; +import mage.watchers.common.PlayerAttackedWatcher; /** * @@ -52,9 +53,9 @@ public class NavigatorsRuin extends CardImpl { Ability ability = new ConditionalTriggeredAbility( new BeginningOfEndStepTriggeredAbility(new PutLibraryIntoGraveTargetEffect(4), TargetController.YOU, false), RaidCondition.instance, - "Raid - At the beginning of your end step, if you attacked with a creature this turn, target opponent puts the top four cards of his or her library into his or her graveyard."); + "Raid - At the beginning of your end step, if you attacked with a creature this turn, target opponent puts the top four cards of his or her library into his or her graveyard."); ability.addTarget(new TargetOpponent()); - this.addAbility(ability); + this.addAbility(ability, new PlayerAttackedWatcher()); } public NavigatorsRuin(final NavigatorsRuin card) { diff --git a/Mage.Sets/src/mage/cards/s/ShipwreckLooter.java b/Mage.Sets/src/mage/cards/s/ShipwreckLooter.java new file mode 100644 index 0000000000..8265cb424b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShipwreckLooter.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetOpponent; +import mage.watchers.common.PlayerAttackedWatcher; + +/** + * + * @author TheElk801 + */ +public class ShipwreckLooter extends CardImpl { + + public ShipwreckLooter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Raid - When Shipwreck Looter enters the battlefield,if you attacked with a creature this turn, you may draw a card. If you do, discard a card. + Ability ability = new ConditionalTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(1, 1, true)), + RaidCondition.instance, + "Raid - When {this} enters the battlefield,if you attacked with a creature this turn, you may draw a card. If you do, discard a card."); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability, new PlayerAttackedWatcher()); + } + + public ShipwreckLooter(final ShipwreckLooter card) { + super(card); + } + + @Override + public ShipwreckLooter copy() { + return new ShipwreckLooter(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 7f0692d6a4..4f56892280 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -251,6 +251,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Sheltering Light", 35, Rarity.UNCOMMON, mage.cards.s.ShelteringLight.class)); cards.add(new SetCardInfo("Shining Aerosaur", 36, Rarity.COMMON, mage.cards.s.ShiningAerosaur.class)); + cards.add(new SetCardInfo("Shipwreck Looter", 76, Rarity.COMMON, mage.cards.s.ShipwreckLooter.class)); cards.add(new SetCardInfo("Shore Keeper", 77, Rarity.COMMON, mage.cards.s.ShoreKeeper.class)); cards.add(new SetCardInfo("Siren Lookout", 78, Rarity.COMMON, mage.cards.s.SirenLookout.class)); cards.add(new SetCardInfo("Siren Stormtamer", 79, Rarity.UNCOMMON, mage.cards.s.SirenStormtamer.class)); From d0dd98dfd6536b82908bd03a902547f1cc8ec2c0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 21:35:15 -0400 Subject: [PATCH 108/182] Implemented Siren's Ruse --- Mage.Sets/src/mage/cards/s/SirensRuse.java | 100 +++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 101 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SirensRuse.java diff --git a/Mage.Sets/src/mage/cards/s/SirensRuse.java b/Mage.Sets/src/mage/cards/s/SirensRuse.java new file mode 100644 index 0000000000..c6acf46fed --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SirensRuse.java @@ -0,0 +1,100 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.common.ExileTargetForSourceEffect; +import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class SirensRuse extends CardImpl { + + public SirensRuse(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + // Exile target creature you control, then return that card to the battlefield under its owner's control. If a Pirate was exiled this way, draw a card. + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + this.getSpellAbility().addEffect(new SirensRuseEffect()); + } + + public SirensRuse(final SirensRuse card) { + super(card); + } + + @Override + public SirensRuse copy() { + return new SirensRuse(this); + } +} + +class SirensRuseEffect extends ExileTargetForSourceEffect { + + SirensRuseEffect() { + super(); + this.staticText = "Exile target creature you control, then return that card to the battlefield under its owner's control. If a Pirate was exiled this way, draw a card."; + } + + SirensRuseEffect(final SirensRuseEffect effect) { + super(effect); + } + + @Override + public SirensRuseEffect copy() { + return new SirensRuseEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + boolean isPirate = false; + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent != null && permanent.getSubtype(game).contains(SubType.PIRATE)) { + isPirate = true; + } + if (super.apply(game, source)) { + new ReturnToBattlefieldUnderYourControlTargetEffect(true).apply(game, source); + if (isPirate && player != null) { + player.drawCards(1, game); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 4f56892280..3f12fda38a 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -255,6 +255,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Shore Keeper", 77, Rarity.COMMON, mage.cards.s.ShoreKeeper.class)); cards.add(new SetCardInfo("Siren Lookout", 78, Rarity.COMMON, mage.cards.s.SirenLookout.class)); cards.add(new SetCardInfo("Siren Stormtamer", 79, Rarity.UNCOMMON, mage.cards.s.SirenStormtamer.class)); + cards.add(new SetCardInfo("Siren's Ruse", 80, Rarity.COMMON, mage.cards.s.SirensRuse.class)); cards.add(new SetCardInfo("Skittering Heartstopper", 122, Rarity.COMMON, mage.cards.s.SkitteringHeartstopper.class)); cards.add(new SetCardInfo("Skulduggery", 123, Rarity.COMMON, mage.cards.s.Skulduggery.class)); cards.add(new SetCardInfo("Sky Terror", 229, Rarity.UNCOMMON, mage.cards.s.SkyTerror.class)); From f9828755c817bf4edf831fa6c76811a5be7525b1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 21:38:44 -0400 Subject: [PATCH 109/182] Implemented Fathom Fleet Cutthroat --- .../mage/cards/f/FathomFleetCutthroat.java | 79 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 80 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FathomFleetCutthroat.java diff --git a/Mage.Sets/src/mage/cards/f/FathomFleetCutthroat.java b/Mage.Sets/src/mage/cards/f/FathomFleetCutthroat.java new file mode 100644 index 0000000000..a20944d0d7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FathomFleetCutthroat.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.WasDealtDamageThisTurnPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class FathomFleetCutthroat extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls that was dealt damage this turn"); + + static { + filter.add(new WasDealtDamageThisTurnPredicate()); + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public FathomFleetCutthroat(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.PIRATE); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When Fathom Fleet Cutthroat enters the battlefield, destroy target creature an opponent controls that was dealt damage this turn. + Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect(), false); + ability.addTarget(new TargetCreaturePermanent(filter)); + } + + public FathomFleetCutthroat(final FathomFleetCutthroat card) { + super(card); + } + + @Override + public FathomFleetCutthroat copy() { + return new FathomFleetCutthroat(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 3f12fda38a..264c0542d0 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -112,6 +112,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Encampment Keeper", 11, Rarity.COMMON, mage.cards.e.EncampmentKeeper.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); cards.add(new SetCardInfo("Fathom Fleet Captain", 106, Rarity.RARE, mage.cards.f.FathomFleetCaptain.class)); + cards.add(new SetCardInfo("Fathom Fleet Cutthroat", 107, Rarity.COMMON, mage.cards.f.FathomFleetCutthroat.class)); cards.add(new SetCardInfo("Fathom Fleet Firebrand", 142, Rarity.COMMON, mage.cards.f.FathomFleetFirebrand.class)); cards.add(new SetCardInfo("Favorable Winds", 56, Rarity.UNCOMMON, mage.cards.f.FavorableWinds.class)); cards.add(new SetCardInfo("Fell Flagship", 238, Rarity.RARE, mage.cards.f.FellFlagship.class)); From a99cce3ef1701ecfc323430e102ff17877321887 Mon Sep 17 00:00:00 2001 From: spjspj Date: Sat, 16 Sep 2017 12:02:12 +1000 Subject: [PATCH 110/182] Fix gen-existing-cards-by-set.pl --- Mage.Sets/src/mage/sets/Ixalan.java | 1 + Utils/gen-existing-cards-by-set.pl | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 668b6bc19a..0507cbfc84 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -258,6 +258,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Skymarch Bloodletter", 124, Rarity.COMMON, mage.cards.s.SkymarchBloodletter.class)); cards.add(new SetCardInfo("Slash of Talons", 38, Rarity.COMMON, mage.cards.s.SlashOfTalons.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); + cards.add(new SetCardInfo("Slice in Twain", 207, Rarity.UNCOMMON, mage.cards.s.SliceInTwain.class)); cards.add(new SetCardInfo("Snapping Sailback", 208, Rarity.UNCOMMON, mage.cards.s.SnappingSailback.class)); cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); cards.add(new SetCardInfo("Spell Pierce", 81, Rarity.COMMON, mage.cards.s.SpellPierce.class)); diff --git a/Utils/gen-existing-cards-by-set.pl b/Utils/gen-existing-cards-by-set.pl index 800a39bd76..9c6e0a4f7f 100755 --- a/Utils/gen-existing-cards-by-set.pl +++ b/Utils/gen-existing-cards-by-set.pl @@ -71,6 +71,7 @@ foreach $potentialSideA (sort @setCards) { #print (">>$potentialSideA\n"); if ($potentialSideA =~ m/.*,,,(\d+)(a)$/) { my $cardNumSideB = $1 . "b"; + my $orig_cardNumSideB = $1 . "b"; my $val; foreach $val (sort @setCards) { if ($val =~ m/$cardNumSideB$/) { @@ -93,6 +94,7 @@ foreach $potentialSideA (sort @setCards) { print ("Adding in: $potentialSideA \/\/ $val,,,$cardNumSideB\n"); $cardsFound = $cardsFound - 1; + $cardNumSideB = $orig_cardNumSideB; } } } From 54ada45dfad1fe0580cee80491cda4bcd5ea3c97 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 23:33:16 -0400 Subject: [PATCH 111/182] Fixed Vance's Blasting Cannons --- Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java index 4247174359..ab69c1400b 100644 --- a/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java +++ b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java @@ -159,7 +159,7 @@ class CastFromNonHandZoneTargetEffect extends AsThoughEffectImpl { class VancesBlastingCannonsFlipTrigger extends TriggeredAbilityImpl { public VancesBlastingCannonsFlipTrigger() { - super(Zone.BATTLEFIELD, new TransformSourceEffect(true)); + super(Zone.BATTLEFIELD, new TransformSourceEffect(true), true); } public VancesBlastingCannonsFlipTrigger(final VancesBlastingCannonsFlipTrigger ability) { @@ -189,6 +189,6 @@ class VancesBlastingCannonsFlipTrigger extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever you cast your third spell in a turn, transform {this}"; + return "Whenever you cast your third spell in a turn, you may transform {this}"; } } From 217a17b864cd62b261601c969a584be3aac2e687 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Fri, 15 Sep 2017 23:34:49 -0400 Subject: [PATCH 112/182] Removed planeswalker uniqueness rule --- Mage/src/main/java/mage/game/GameImpl.java | 29 ---------------------- 1 file changed, 29 deletions(-) diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index 23ede72e50..b1856a43dc 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -60,9 +60,7 @@ import mage.filter.FilterCard; import mage.filter.FilterPermanent; import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.common.FilterPlaneswalkerPermanent; import mage.filter.predicate.mageobject.NamePredicate; -import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.mageobject.SupertypePredicate; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.combat.Combat; @@ -1934,33 +1932,6 @@ public abstract class GameImpl implements Game, Serializable { } } } - //201300713 - 704.5j - // If a player controls two or more planeswalkers that share a planeswalker type, that player - // chooses one of them, and the rest are put into their owners' graveyards. - // This is called the "planeswalker uniqueness rule." - if (planeswalkers.size() > 1) { //don't bother checking if less than 2 planeswalkers in play - for (Permanent planeswalker : planeswalkers) { - for (SubType planeswalkertype : planeswalker.getSubtype(this)) { - FilterPlaneswalkerPermanent filterPlaneswalker = new FilterPlaneswalkerPermanent(); - filterPlaneswalker.add(new SubtypePredicate(planeswalkertype)); - filterPlaneswalker.add(new ControllerIdPredicate(planeswalker.getControllerId())); - if (getBattlefield().contains(filterPlaneswalker, planeswalker.getControllerId(), this, 2)) { - Player controller = this.getPlayer(planeswalker.getControllerId()); - if (controller != null) { - Target targetPlaneswalkerToKeep = new TargetPermanent(filterPlaneswalker); - targetPlaneswalkerToKeep.setTargetName(planeswalkertype.toString() + " to keep?"); - controller.chooseTarget(Outcome.Benefit, targetPlaneswalkerToKeep, null, this); - for (Permanent dupPlaneswalker : this.getBattlefield().getActivePermanents(filterPlaneswalker, planeswalker.getControllerId(), this)) { - if (!targetPlaneswalkerToKeep.getTargets().contains(dupPlaneswalker.getId())) { - movePermanentToGraveyardWithInfo(dupPlaneswalker); - } - } - } - return true; - } - } - } - } //201300713 - 704.5k // If a player controls two or more legendary permanents with the same name, that player // chooses one of them, and the rest are put into their owners' graveyards. From 9ae4e7d4ef3035da5b4a5252056c44480b8710db Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 10:33:08 +0200 Subject: [PATCH 113/182] Added logic to add manual links to MythicSpoilers image source. --- .../dl/sources/MythicspoilerComSource.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java index baa1830363..9fc3658775 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java @@ -64,6 +64,7 @@ public enum MythicspoilerComSource implements CardImageSource { private final Map> cardNameAliasesStart; private final Map> sets; private final Set supportedSets; + private final Map> manualLinks; @Override public String getSourceName() { @@ -277,6 +278,21 @@ public enum MythicspoilerComSource implements CardImageSource { cardNameAliases.put("XLN-infuriatedgladiodon", "ragingswordtooth"); cardNameAliases.put("XLN-redoubledvolley", "repeatingbarrage"); + // + manualLinks = new HashMap<>(); + HashMap links = new HashMap<>(); + links.put("templeofaclazotz", "templeofaclazotz"); + links.put("conquerorsfoothold", "conquerorsfoothold"); + links.put("primalwellspring", "primalwellspring"); + links.put("azcantathesunkenruin", "azcantathesunkenruin"); + links.put("spiresoforazca", "spiresoforazca"); + links.put("treasurecove", "treasurecove"); + links.put("itlimoccradleofthesun", "itlimoccradleofthesun"); + links.put("lostvale", "lostvale"); + links.put("adantothefirstfort", "adantothefirstport"); + links.put("spitfirebastion", "spitfirebastion"); + manualLinks.put("XLN", links); + cardNameAliasesStart = new HashMap<>(); HashSet names = new HashSet<>(); names.add("eldrazidevastator.jpg"); @@ -372,7 +388,12 @@ public enum MythicspoilerComSource implements CardImageSource { pageLinks.put(cardName, baseUrl + cardLink); } } - + Map linksToAdd = manualLinks.get(cardSet); + if (linksToAdd != null) { + for (Map.Entry link : linksToAdd.entrySet()) { + pageLinks.put(link.getKey(), baseUrl + "cards/" + link.getValue() + ".jpg"); + } + } return pageLinks; } From 5d32e21ea04dead91c72a866c40a3300a64524ea Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 10:35:18 +0200 Subject: [PATCH 114/182] Renamed SliceInTwain class name. --- .../src/mage/cards/s/SliceInXXTwain.java | 61 +++++++++++++++++++ Mage.Sets/src/mage/sets/Commander2013.java | 2 +- Mage.Sets/src/mage/sets/ScarsOfMirrodin.java | 2 +- 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/s/SliceInXXTwain.java diff --git a/Mage.Sets/src/mage/cards/s/SliceInXXTwain.java b/Mage.Sets/src/mage/cards/s/SliceInXXTwain.java new file mode 100644 index 0000000000..22575fdc3f --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SliceInXXTwain.java @@ -0,0 +1,61 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; + +/** + * + * @author Loki + */ +public class SliceInXXTwain extends CardImpl { + + public SliceInXXTwain(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}{G}"); + + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.ARTIFACT_OR_ENCHANTMENT_PERMANENT)); + } + + public SliceInXXTwain(final SliceInXXTwain card) { + super(card); + } + + @Override + public SliceInXXTwain copy() { + return new SliceInXXTwain(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Commander2013.java b/Mage.Sets/src/mage/sets/Commander2013.java index d16160f195..3d7a4241e2 100644 --- a/Mage.Sets/src/mage/sets/Commander2013.java +++ b/Mage.Sets/src/mage/sets/Commander2013.java @@ -317,7 +317,7 @@ public class Commander2013 extends ExpansionSet { cards.add(new SetCardInfo("Skyscribing", 57, Rarity.UNCOMMON, mage.cards.s.Skyscribing.class)); cards.add(new SetCardInfo("Skyward Eye Prophets", 214, Rarity.UNCOMMON, mage.cards.s.SkywardEyeProphets.class)); cards.add(new SetCardInfo("Slice and Dice", 119, Rarity.UNCOMMON, mage.cards.s.SliceAndDice.class)); - cards.add(new SetCardInfo("Slice in Twain", 170, Rarity.UNCOMMON, mage.cards.s.SliceinTwain.class)); + cards.add(new SetCardInfo("Slice in Twain", 170, Rarity.UNCOMMON, mage.cards.s.SliceInXXTwain.class)); cards.add(new SetCardInfo("Slippery Karst", 324, Rarity.COMMON, mage.cards.s.SlipperyKarst.class)); cards.add(new SetCardInfo("Smoldering Crater", 325, Rarity.COMMON, mage.cards.s.SmolderingCrater.class)); cards.add(new SetCardInfo("Sol Ring", 259, Rarity.UNCOMMON, mage.cards.s.SolRing.class)); diff --git a/Mage.Sets/src/mage/sets/ScarsOfMirrodin.java b/Mage.Sets/src/mage/sets/ScarsOfMirrodin.java index 7271d76581..a2196bb9e8 100644 --- a/Mage.Sets/src/mage/sets/ScarsOfMirrodin.java +++ b/Mage.Sets/src/mage/sets/ScarsOfMirrodin.java @@ -247,7 +247,7 @@ public class ScarsOfMirrodin extends ExpansionSet { cards.add(new SetCardInfo("Skinrender", 78, Rarity.UNCOMMON, mage.cards.s.Skinrender.class)); cards.add(new SetCardInfo("Skithiryx, the Blight Dragon", 79, Rarity.MYTHIC, mage.cards.s.SkithiryxTheBlightDragon.class)); cards.add(new SetCardInfo("Sky-Eel School", 44, Rarity.COMMON, mage.cards.s.SkyEelSchool.class)); - cards.add(new SetCardInfo("Slice in Twain", 127, Rarity.UNCOMMON, mage.cards.s.SliceinTwain.class)); + cards.add(new SetCardInfo("Slice in Twain", 127, Rarity.UNCOMMON, mage.cards.s.SliceInXXTwain.class)); cards.add(new SetCardInfo("Snapsail Glider", 203, Rarity.COMMON, mage.cards.s.SnapsailGlider.class)); cards.add(new SetCardInfo("Soliton", 204, Rarity.COMMON, mage.cards.s.Soliton.class)); cards.add(new SetCardInfo("Soul Parry", 21, Rarity.COMMON, mage.cards.s.SoulParry.class)); From 53324c0f4d986fc01e2760da77987f3f51807c1d Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 10:38:10 +0200 Subject: [PATCH 115/182] Reverted making Menace a MageSingleton. --- .../src/mage/cards/a/AdroitHateflayer.java | 2 +- .../src/mage/cards/a/AlleyStrangler.java | 2 +- .../src/mage/cards/a/AradaraExpress.java | 2 +- .../src/mage/cards/a/AtarkaPummeler.java | 2 +- .../src/mage/cards/b/BelligerentSliver.java | 2 +- .../src/mage/cards/b/BloodChinRager.java | 2 +- Mage.Sets/src/mage/cards/b/BobaFett.java | 2 +- Mage.Sets/src/mage/cards/b/BoggartBrute.java | 2 +- .../src/mage/cards/b/BontuTheGlorified.java | 2 +- Mage.Sets/src/mage/cards/b/BullRancor.java | 2 +- .../src/mage/cards/c/CaterwaulingBoggart.java | 4 ++-- .../src/mage/cards/c/ChitinousCloak.java | 2 +- .../src/mage/cards/c/ChitteringHost.java | 4 ++-- .../src/mage/cards/c/CursedMinotaur.java | 2 +- Mage.Sets/src/mage/cards/d/DarthVader.java | 2 +- Mage.Sets/src/mage/cards/d/Demoralize.java | 2 +- .../src/mage/cards/d/DeputizedProtester.java | 2 +- Mage.Sets/src/mage/cards/d/DerangedWhelp.java | 2 +- .../src/mage/cards/d/DireFleetInterloper.java | 2 +- .../src/mage/cards/d/DireFleetRavager.java | 2 +- Mage.Sets/src/mage/cards/d/Dreamstealer.java | 2 +- Mage.Sets/src/mage/cards/d/DrivenDespair.java | 2 +- .../src/mage/cards/e/EmberhornMinotaur.java | 2 +- .../src/mage/cards/e/EmbraalBruiser.java | 2 +- .../src/mage/cards/f/FathomFleetCaptain.java | 2 +- .../src/mage/cards/f/FireShrineKeeper.java | 2 +- .../src/mage/cards/f/FiremantleMage.java | 2 +- .../src/mage/cards/f/FlamebladeAdept.java | 2 +- .../src/mage/cards/g/GatstafRavagers.java | 2 +- .../src/mage/cards/g/GeyserfieldStalker.java | 2 +- .../src/mage/cards/g/GiantSpectacle.java | 2 +- .../src/mage/cards/g/GiltLeafWinnower.java | 2 +- .../src/mage/cards/g/GlintSleeveSiphoner.java | 2 +- .../src/mage/cards/g/GoblinDarkDwellers.java | 2 +- .../src/mage/cards/g/GoblinFreerunner.java | 2 +- .../src/mage/cards/g/GoblinGloryChaser.java | 2 +- .../src/mage/cards/g/GoblinWarDrums.java | 2 +- Mage.Sets/src/mage/cards/g/GorillaWarCry.java | 2 +- Mage.Sets/src/mage/cards/g/GrafHarvest.java | 2 +- Mage.Sets/src/mage/cards/g/GraniticTitan.java | 2 +- Mage.Sets/src/mage/cards/g/GruulNodorog.java | 2 +- Mage.Sets/src/mage/cards/g/GruulWarChant.java | 2 +- .../src/mage/cards/h/HeadstrongBrute.java | 2 +- .../src/mage/cards/h/HordeOfBoggarts.java | 2 +- .../src/mage/cards/h/HoundOfTheFarbogs.java | 2 +- .../mage/cards/i/IkraShidiqiTheUsurper.java | 2 +- .../src/mage/cards/i/ImposingVisage.java | 2 +- .../src/mage/cards/i/InsolentNeonate.java | 2 +- Mage.Sets/src/mage/cards/i/IreShaman.java | 2 +- .../src/mage/cards/i/IroasGodOfVictory.java | 2 +- Mage.Sets/src/mage/cards/j/JangoFett.java | 2 +- .../mage/cards/k/KariZevSkyshipRaider.java | 2 +- .../src/mage/cards/k/KederektCreeper.java | 2 +- .../src/mage/cards/k/KhenraScrapper.java | 2 +- .../src/mage/cards/k/KheruMindEater.java | 2 +- .../cards/k/KozilekTheGreatDistortion.java | 2 +- .../src/mage/cards/k/KozileksShrieker.java | 2 +- .../src/mage/cards/l/LordOfTheAccursed.java | 2 +- Mage.Sets/src/mage/cards/l/LoseCalm.java | 2 +- Mage.Sets/src/mage/cards/m/MadcapSkills.java | 2 +- .../src/mage/cards/m/MajesticMyriarch.java | 2 +- .../src/mage/cards/m/MathasFiendSeeker.java | 2 +- Mage.Sets/src/mage/cards/m/MaulfistSquad.java | 2 +- .../src/mage/cards/m/MoonriseIntruder.java | 2 +- .../src/mage/cards/m/MorkrutNecropod.java | 2 +- .../src/mage/cards/n/NoxiousGearhulk.java | 2 +- .../src/mage/cards/o/OdricLunarchMarshal.java | 2 +- Mage.Sets/src/mage/cards/p/PlagueBelcher.java | 2 +- .../src/mage/cards/p/PurphorossEmissary.java | 4 ++-- Mage.Sets/src/mage/cards/p/PyreheartWolf.java | 2 +- .../src/mage/cards/r/RampagingFerocidon.java | 2 +- .../src/mage/cards/r/RelentlessDead.java | 2 +- .../src/mage/cards/r/RipscalePredator.java | 2 +- .../src/mage/cards/s/ScroungedScythe.java | 2 +- .../src/mage/cards/s/SearingSpearAskari.java | 2 +- .../src/mage/cards/s/ShatterskullRecruit.java | 2 +- Mage.Sets/src/mage/cards/s/SinProdder.java | 2 +- Mage.Sets/src/mage/cards/s/SinuousVermin.java | 2 +- Mage.Sets/src/mage/cards/s/SithLord.java | 2 +- Mage.Sets/src/mage/cards/s/SkyTerror.java | 2 +- .../src/mage/cards/s/StormbloodBerserker.java | 2 +- Mage.Sets/src/mage/cards/s/SummitApes.java | 2 +- .../src/mage/cards/s/SweatworksBrawler.java | 2 +- .../src/mage/cards/t/TerrorOfKruinPass.java | 2 +- .../src/mage/cards/t/ThrabenFoulbloods.java | 2 +- .../src/mage/cards/t/TwoHeadedDragon.java | 2 +- .../src/mage/cards/t/TwoHeadedSliver.java | 2 +- Mage.Sets/src/mage/cards/u/UntamedHunger.java | 2 +- .../src/mage/cards/v/ViashinoRunner.java | 2 +- Mage.Sets/src/mage/cards/v/VineKami.java | 2 +- Mage.Sets/src/mage/cards/w/WaywardGiant.java | 2 +- .../src/mage/cards/w/WeldfastMonitor.java | 2 +- Mage.Sets/src/mage/cards/w/WindSpirit.java | 2 +- .../cards/abilities/keywords/ExertTest.java | 2 +- .../cards/abilities/keywords/RenownTest.java | 2 +- .../mage/abilities/keyword/MenaceAbility.java | 23 +++++++------------ .../game/permanent/token/PirateToken.java | 2 +- 97 files changed, 107 insertions(+), 114 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AdroitHateflayer.java b/Mage.Sets/src/mage/cards/a/AdroitHateflayer.java index e233c66512..a8019903e3 100644 --- a/Mage.Sets/src/mage/cards/a/AdroitHateflayer.java +++ b/Mage.Sets/src/mage/cards/a/AdroitHateflayer.java @@ -51,7 +51,7 @@ public class AdroitHateflayer extends CardImpl { this.toughness = new MageInt(3); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Whenever Adroit Hateflayer attacks, each opponent loses 2 life. this.addAbility(new AttacksTriggeredAbility(new LoseLifeOpponentsEffect(2), false)); diff --git a/Mage.Sets/src/mage/cards/a/AlleyStrangler.java b/Mage.Sets/src/mage/cards/a/AlleyStrangler.java index 39c189faa4..2dec0ba20c 100644 --- a/Mage.Sets/src/mage/cards/a/AlleyStrangler.java +++ b/Mage.Sets/src/mage/cards/a/AlleyStrangler.java @@ -50,7 +50,7 @@ public class AlleyStrangler extends CardImpl { this.toughness = new MageInt(3); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public AlleyStrangler(final AlleyStrangler card) { diff --git a/Mage.Sets/src/mage/cards/a/AradaraExpress.java b/Mage.Sets/src/mage/cards/a/AradaraExpress.java index 15ef9ba686..9decfe7403 100644 --- a/Mage.Sets/src/mage/cards/a/AradaraExpress.java +++ b/Mage.Sets/src/mage/cards/a/AradaraExpress.java @@ -49,7 +49,7 @@ public class AradaraExpress extends CardImpl { this.toughness = new MageInt(6); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Crew 4 this.addAbility(new CrewAbility(4)); } diff --git a/Mage.Sets/src/mage/cards/a/AtarkaPummeler.java b/Mage.Sets/src/mage/cards/a/AtarkaPummeler.java index b71d99d5af..631bbb377e 100644 --- a/Mage.Sets/src/mage/cards/a/AtarkaPummeler.java +++ b/Mage.Sets/src/mage/cards/a/AtarkaPummeler.java @@ -63,7 +63,7 @@ public class AtarkaPummeler extends CardImpl { // Formidable - {3}{R}{R}: Creatures you control gain menace until end of turn. Activate this ability only if creature you control have total power 8 or greater. (They can't be blocked except by two or more creatures.) Ability ability = new ActivateIfConditionActivatedAbility( Zone.BATTLEFIELD, - new GainAbilityAllEffect(MenaceAbility.getInstance(), Duration.EndOfTurn, filter), + new GainAbilityAllEffect(new MenaceAbility(), Duration.EndOfTurn, filter), new ManaCostsImpl("{3}{R}{R}"), FormidableCondition.instance); ability.setAbilityWord(AbilityWord.FORMIDABLE); diff --git a/Mage.Sets/src/mage/cards/b/BelligerentSliver.java b/Mage.Sets/src/mage/cards/b/BelligerentSliver.java index 4237231bc9..02af27ab0c 100644 --- a/Mage.Sets/src/mage/cards/b/BelligerentSliver.java +++ b/Mage.Sets/src/mage/cards/b/BelligerentSliver.java @@ -62,7 +62,7 @@ public class BelligerentSliver extends CardImpl { this.toughness = new MageInt(2); // Sliver creatures you control have menace. (They can't be blocked except by two or more creatures.)" - Effect effect = new GainAbilityAllEffect(MenaceAbility.getInstance(), Duration.WhileOnBattlefield, filter); + Effect effect = new GainAbilityAllEffect(new MenaceAbility(), Duration.WhileOnBattlefield, filter); effect.setText("Sliver creatures you control have menace. (They can't be blocked except by two or more creatures.)"); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); } diff --git a/Mage.Sets/src/mage/cards/b/BloodChinRager.java b/Mage.Sets/src/mage/cards/b/BloodChinRager.java index 286f2aafa1..2657e0931b 100644 --- a/Mage.Sets/src/mage/cards/b/BloodChinRager.java +++ b/Mage.Sets/src/mage/cards/b/BloodChinRager.java @@ -60,7 +60,7 @@ public class BloodChinRager extends CardImpl { this.toughness = new MageInt(2); // Whenever Blood-Chin Rager attacks, Warrior creatures you control gain menace until end of turn. (They can't be blocked except by two or more creatures.) - this.addAbility(new AttacksTriggeredAbility(new GainAbilityAllEffect(MenaceAbility.getInstance(), Duration.EndOfTurn, filter), false)); + this.addAbility(new AttacksTriggeredAbility(new GainAbilityAllEffect(new MenaceAbility(), Duration.EndOfTurn, filter), false)); } public BloodChinRager(final BloodChinRager card) { diff --git a/Mage.Sets/src/mage/cards/b/BobaFett.java b/Mage.Sets/src/mage/cards/b/BobaFett.java index 6efbf2d0d6..7680e3cfdb 100644 --- a/Mage.Sets/src/mage/cards/b/BobaFett.java +++ b/Mage.Sets/src/mage/cards/b/BobaFett.java @@ -60,7 +60,7 @@ public class BobaFett extends CardImpl { this.toughness = new MageInt(4); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Deathtouch this.addAbility(DeathtouchAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/b/BoggartBrute.java b/Mage.Sets/src/mage/cards/b/BoggartBrute.java index 33931e649f..dbf317e2f2 100644 --- a/Mage.Sets/src/mage/cards/b/BoggartBrute.java +++ b/Mage.Sets/src/mage/cards/b/BoggartBrute.java @@ -48,7 +48,7 @@ public class BoggartBrute extends CardImpl { this.toughness = new MageInt(2); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public BoggartBrute(final BoggartBrute card) { diff --git a/Mage.Sets/src/mage/cards/b/BontuTheGlorified.java b/Mage.Sets/src/mage/cards/b/BontuTheGlorified.java index 8165cbbf05..41bb478723 100644 --- a/Mage.Sets/src/mage/cards/b/BontuTheGlorified.java +++ b/Mage.Sets/src/mage/cards/b/BontuTheGlorified.java @@ -65,7 +65,7 @@ public class BontuTheGlorified extends CardImpl { this.toughness = new MageInt(6); //Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); //Indestructible this.addAbility(IndestructibleAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/b/BullRancor.java b/Mage.Sets/src/mage/cards/b/BullRancor.java index a65a4333b0..b61ec2923c 100644 --- a/Mage.Sets/src/mage/cards/b/BullRancor.java +++ b/Mage.Sets/src/mage/cards/b/BullRancor.java @@ -59,7 +59,7 @@ public class BullRancor extends CardImpl { // As long as Bull Rancor is monstrous, creatures you control have menace. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( - new GainAbilityControlledEffect(MenaceAbility.getInstance(), Duration.WhileOnBattlefield), + new GainAbilityControlledEffect(new MenaceAbility(), Duration.WhileOnBattlefield), MonstrousCondition.instance, "As long as Bull Rancor is monstrous, creatures you control have menace") )); diff --git a/Mage.Sets/src/mage/cards/c/CaterwaulingBoggart.java b/Mage.Sets/src/mage/cards/c/CaterwaulingBoggart.java index b2b68486c2..23593081c2 100644 --- a/Mage.Sets/src/mage/cards/c/CaterwaulingBoggart.java +++ b/Mage.Sets/src/mage/cards/c/CaterwaulingBoggart.java @@ -66,13 +66,13 @@ public class CaterwaulingBoggart extends CardImpl { // Each Goblin you control has menace. (They can't be blocked except by two or more creatures.) this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect( - MenaceAbility.getInstance(), + new MenaceAbility(), Duration.WhileOnBattlefield, filterGoblin, "Each Goblin you control has menace. (They can't be blocked except by two or more creatures.)"))); // Each Elemental you control has menace. (They can't be blocked except by two or more creatures.) this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect( - MenaceAbility.getInstance(), + new MenaceAbility(), Duration.WhileOnBattlefield, filterElemental, "Each Elemental you control has menace. (They can't be blocked except by two or more creatures.)"))); } diff --git a/Mage.Sets/src/mage/cards/c/ChitinousCloak.java b/Mage.Sets/src/mage/cards/c/ChitinousCloak.java index 505ab9a600..165c8f52c2 100644 --- a/Mage.Sets/src/mage/cards/c/ChitinousCloak.java +++ b/Mage.Sets/src/mage/cards/c/ChitinousCloak.java @@ -56,7 +56,7 @@ public class ChitinousCloak extends CardImpl { // Equipped creature gets +2/+2 and has menace. Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2)); - Effect effect = new GainAbilityAttachedEffect(MenaceAbility.getInstance(), AttachmentType.EQUIPMENT); + Effect effect = new GainAbilityAttachedEffect(new MenaceAbility(), AttachmentType.EQUIPMENT); effect.setText("and has menace"); ability.addEffect(effect); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/c/ChitteringHost.java b/Mage.Sets/src/mage/cards/c/ChitteringHost.java index 2f638f1f4f..9e65b786e8 100644 --- a/Mage.Sets/src/mage/cards/c/ChitteringHost.java +++ b/Mage.Sets/src/mage/cards/c/ChitteringHost.java @@ -61,13 +61,13 @@ public class ChitteringHost extends MeldCard { this.addAbility(HasteAbility.getInstance()); // Menace (This creature can't be blocked except by two or more creatures. - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // When Chittering Host enters the battlefield, other creatures you control get +1/+0 and gain menace until end of turn. Effect effect = new BoostControlledEffect(1, 0, Duration.EndOfTurn, true); effect.setText("other creatures you control get +1/+0"); Ability ability = new EntersBattlefieldTriggeredAbility(effect, false); - effect = new GainAbilityAllEffect(MenaceAbility.getInstance(), Duration.EndOfTurn, new FilterControlledCreaturePermanent("other creatures"), true); + effect = new GainAbilityAllEffect(new MenaceAbility(), Duration.EndOfTurn, new FilterControlledCreaturePermanent("other creatures"), true); effect.setText("and gain menace until end of turn"); ability.addEffect(effect); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/c/CursedMinotaur.java b/Mage.Sets/src/mage/cards/c/CursedMinotaur.java index 2e37c6d8f9..a363957ba0 100644 --- a/Mage.Sets/src/mage/cards/c/CursedMinotaur.java +++ b/Mage.Sets/src/mage/cards/c/CursedMinotaur.java @@ -50,7 +50,7 @@ public class CursedMinotaur extends CardImpl { this.toughness = new MageInt(2); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } diff --git a/Mage.Sets/src/mage/cards/d/DarthVader.java b/Mage.Sets/src/mage/cards/d/DarthVader.java index 2907d5f1f8..85a40aca5d 100644 --- a/Mage.Sets/src/mage/cards/d/DarthVader.java +++ b/Mage.Sets/src/mage/cards/d/DarthVader.java @@ -63,7 +63,7 @@ public class DarthVader extends CardImpl { this.nightCard = true; // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Lifelink this.addAbility(LifelinkAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/d/Demoralize.java b/Mage.Sets/src/mage/cards/d/Demoralize.java index bbf15fec7b..fc29a2b247 100644 --- a/Mage.Sets/src/mage/cards/d/Demoralize.java +++ b/Mage.Sets/src/mage/cards/d/Demoralize.java @@ -52,7 +52,7 @@ public class Demoralize extends CardImpl { // All creatures gain menace until end of turn. (They can't be blocked except by two or more creatures.) - this.getSpellAbility().addEffect(new GainAbilityAllEffect(MenaceAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES)); + this.getSpellAbility().addEffect(new GainAbilityAllEffect(new MenaceAbility(), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES)); // Threshold — If seven or more cards are in your graveyard, creatures can't block this turn. this.getSpellAbility().addEffect( diff --git a/Mage.Sets/src/mage/cards/d/DeputizedProtester.java b/Mage.Sets/src/mage/cards/d/DeputizedProtester.java index 0851efc39e..b5550b8828 100644 --- a/Mage.Sets/src/mage/cards/d/DeputizedProtester.java +++ b/Mage.Sets/src/mage/cards/d/DeputizedProtester.java @@ -50,7 +50,7 @@ public class DeputizedProtester extends CardImpl { this.toughness = new MageInt(1); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Melee this.addAbility(new MeleeAbility()); } diff --git a/Mage.Sets/src/mage/cards/d/DerangedWhelp.java b/Mage.Sets/src/mage/cards/d/DerangedWhelp.java index 1cdf0c5631..7b00a45fb7 100644 --- a/Mage.Sets/src/mage/cards/d/DerangedWhelp.java +++ b/Mage.Sets/src/mage/cards/d/DerangedWhelp.java @@ -48,7 +48,7 @@ public class DerangedWhelp extends CardImpl { this.toughness = new MageInt(1); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public DerangedWhelp(final DerangedWhelp card) { diff --git a/Mage.Sets/src/mage/cards/d/DireFleetInterloper.java b/Mage.Sets/src/mage/cards/d/DireFleetInterloper.java index 65703fdf0d..f0ccc16a90 100644 --- a/Mage.Sets/src/mage/cards/d/DireFleetInterloper.java +++ b/Mage.Sets/src/mage/cards/d/DireFleetInterloper.java @@ -52,7 +52,7 @@ public class DireFleetInterloper extends CardImpl { this.toughness = new MageInt(2); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // When Dire Fleet Interloper enters the battlefield, it explores. this.addAbility(new EntersBattlefieldTriggeredAbility(new ExploreSourceEffect())); diff --git a/Mage.Sets/src/mage/cards/d/DireFleetRavager.java b/Mage.Sets/src/mage/cards/d/DireFleetRavager.java index 821e8beb0c..2cb8e9204a 100644 --- a/Mage.Sets/src/mage/cards/d/DireFleetRavager.java +++ b/Mage.Sets/src/mage/cards/d/DireFleetRavager.java @@ -58,7 +58,7 @@ public class DireFleetRavager extends CardImpl { this.toughness = new MageInt(4); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Deathtouch this.addAbility(DeathtouchAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/d/Dreamstealer.java b/Mage.Sets/src/mage/cards/d/Dreamstealer.java index 9bda51702d..d48f9a3a77 100644 --- a/Mage.Sets/src/mage/cards/d/Dreamstealer.java +++ b/Mage.Sets/src/mage/cards/d/Dreamstealer.java @@ -58,7 +58,7 @@ public class Dreamstealer extends CardImpl { this.toughness = new MageInt(2); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // When Dreamstealer deals combat damage to a player, that player discards that many cards. this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new DreamstealerDiscardEffect(), false, true)); diff --git a/Mage.Sets/src/mage/cards/d/DrivenDespair.java b/Mage.Sets/src/mage/cards/d/DrivenDespair.java index 82afbe7ce2..7d15b56b48 100644 --- a/Mage.Sets/src/mage/cards/d/DrivenDespair.java +++ b/Mage.Sets/src/mage/cards/d/DrivenDespair.java @@ -63,7 +63,7 @@ public class DrivenDespair extends SplitCard { // Aftermath ((CardImpl) (getRightHalfCard())).addAbility(new AftermathAbility().setRuleAtTheTop(true)); // Until end of turn, creatures you control gain menace and "Whenever this creature deals combat damage to a player, that player discards a card." - getRightHalfCard().getSpellAbility().addEffect(new GainAbilityControlledEffect(MenaceAbility.getInstance(), Duration.EndOfTurn)); + getRightHalfCard().getSpellAbility().addEffect(new GainAbilityControlledEffect(new MenaceAbility(), Duration.EndOfTurn)); ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DiscardTargetEffect(1), false, true); getRightHalfCard().getSpellAbility().addEffect(new GainAbilityControlledEffect(ability, Duration.EndOfTurn) .setText("and \"Whenever this creature deals combat damage to a player, that player discards a card.\"")); diff --git a/Mage.Sets/src/mage/cards/e/EmberhornMinotaur.java b/Mage.Sets/src/mage/cards/e/EmberhornMinotaur.java index eb5aab3ed4..855609590c 100644 --- a/Mage.Sets/src/mage/cards/e/EmberhornMinotaur.java +++ b/Mage.Sets/src/mage/cards/e/EmberhornMinotaur.java @@ -59,7 +59,7 @@ public class EmberhornMinotaur extends CardImpl { Effect effect = new BoostSourceEffect(1, 1, Duration.EndOfTurn); effect.setText("it gets +1/+1"); BecomesExertSourceTriggeredAbility ability = new BecomesExertSourceTriggeredAbility(effect); - effect = new GainAbilitySourceEffect(MenaceAbility.getInstance(), Duration.EndOfTurn); + effect = new GainAbilitySourceEffect(new MenaceAbility(), Duration.EndOfTurn); effect.setText("and gains menace until end of turn"); ability.addEffect(effect); this.addAbility(new ExertAbility(ability)); diff --git a/Mage.Sets/src/mage/cards/e/EmbraalBruiser.java b/Mage.Sets/src/mage/cards/e/EmbraalBruiser.java index 74c8ed3d52..9904469165 100644 --- a/Mage.Sets/src/mage/cards/e/EmbraalBruiser.java +++ b/Mage.Sets/src/mage/cards/e/EmbraalBruiser.java @@ -60,7 +60,7 @@ public class EmbraalBruiser extends CardImpl { // Embraal Bruiser has menace as long as you control an artifact. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( - new GainAbilitySourceEffect(MenaceAbility.getInstance()), + new GainAbilitySourceEffect(new MenaceAbility()), new PermanentsOnTheBattlefieldCondition(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT), "{this} has menace as long as you control an artifact"))); } diff --git a/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java b/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java index 45715268b9..72f6e09eae 100644 --- a/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java +++ b/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java @@ -70,7 +70,7 @@ public class FathomFleetCaptain extends CardImpl { this.toughness = new MageInt(1); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Whenever Fathom Fleet Captain attacks, if you control another nontoken Pirate, you may pay {2}. If you do, creature a 2/2 black Pirate creature token with menace. this.addAbility(new ConditionalTriggeredAbility( diff --git a/Mage.Sets/src/mage/cards/f/FireShrineKeeper.java b/Mage.Sets/src/mage/cards/f/FireShrineKeeper.java index e7ff050e4a..442e83b0b8 100644 --- a/Mage.Sets/src/mage/cards/f/FireShrineKeeper.java +++ b/Mage.Sets/src/mage/cards/f/FireShrineKeeper.java @@ -57,7 +57,7 @@ public class FireShrineKeeper extends CardImpl { this.toughness = new MageInt(1); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // {7}{R}, {T}, Sacrifice Fire Shrine Keeper: It deals 3 damage to each of up to two target creatures. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, diff --git a/Mage.Sets/src/mage/cards/f/FiremantleMage.java b/Mage.Sets/src/mage/cards/f/FiremantleMage.java index 6123439b52..0de938a125 100644 --- a/Mage.Sets/src/mage/cards/f/FiremantleMage.java +++ b/Mage.Sets/src/mage/cards/f/FiremantleMage.java @@ -55,7 +55,7 @@ public class FiremantleMage extends CardImpl { // Rally — Whenver Firemantle Mage or another Ally enters the battlefield under your control, creatures you control gain menace until end of turn. this.addAbility(new AllyEntersBattlefieldTriggeredAbility( - new GainAbilityControlledEffect(MenaceAbility.getInstance(), Duration.EndOfTurn, FILTER_PERMANENT_CREATURES), false)); + new GainAbilityControlledEffect(new MenaceAbility(), Duration.EndOfTurn, FILTER_PERMANENT_CREATURES), false)); } public FiremantleMage(final FiremantleMage card) { diff --git a/Mage.Sets/src/mage/cards/f/FlamebladeAdept.java b/Mage.Sets/src/mage/cards/f/FlamebladeAdept.java index ab1b40c5c4..f464c8c133 100644 --- a/Mage.Sets/src/mage/cards/f/FlamebladeAdept.java +++ b/Mage.Sets/src/mage/cards/f/FlamebladeAdept.java @@ -53,7 +53,7 @@ public class FlamebladeAdept extends CardImpl { this.toughness = new MageInt(2); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Whenever you cycle or discard a card, Flameblade Adept gets +1/+0 until end of turn. this.addAbility(new CycleOrDiscardControllerTriggeredAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn))); diff --git a/Mage.Sets/src/mage/cards/g/GatstafRavagers.java b/Mage.Sets/src/mage/cards/g/GatstafRavagers.java index 00b7d4fa11..f84e3cf6b4 100644 --- a/Mage.Sets/src/mage/cards/g/GatstafRavagers.java +++ b/Mage.Sets/src/mage/cards/g/GatstafRavagers.java @@ -60,7 +60,7 @@ public class GatstafRavagers extends CardImpl { this.nightCard = true; // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Gatstaf Ravagers. TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), TargetController.ANY, false); this.addAbility(new ConditionalTriggeredAbility(ability, TwoOrMoreSpellsWereCastLastTurnCondition.instance, TransformAbility.TWO_OR_MORE_SPELLS_TRANSFORM_RULE)); diff --git a/Mage.Sets/src/mage/cards/g/GeyserfieldStalker.java b/Mage.Sets/src/mage/cards/g/GeyserfieldStalker.java index 3fd4a648b2..265d515e2c 100644 --- a/Mage.Sets/src/mage/cards/g/GeyserfieldStalker.java +++ b/Mage.Sets/src/mage/cards/g/GeyserfieldStalker.java @@ -51,7 +51,7 @@ public class GeyserfieldStalker extends CardImpl { this.toughness = new MageInt(2); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Landfall - Whenever a land enters the battlefield under your control, Geyserfield Stalker gets +2/+2 until end of turn. this.addAbility(new LandfallAbility(new BoostSourceEffect(2, 2, Duration.EndOfTurn), false)); } diff --git a/Mage.Sets/src/mage/cards/g/GiantSpectacle.java b/Mage.Sets/src/mage/cards/g/GiantSpectacle.java index 64d45642ba..230a5d5b69 100644 --- a/Mage.Sets/src/mage/cards/g/GiantSpectacle.java +++ b/Mage.Sets/src/mage/cards/g/GiantSpectacle.java @@ -65,7 +65,7 @@ public class GiantSpectacle extends CardImpl { // Enchanted creature gets +2/+1 and has menace. ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 1)); - Effect effect = new GainAbilityAttachedEffect(MenaceAbility.getInstance(), AttachmentType.AURA); + Effect effect = new GainAbilityAttachedEffect(new MenaceAbility(), AttachmentType.AURA); effect.setText("and has menace"); ability.addEffect(effect); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/g/GiltLeafWinnower.java b/Mage.Sets/src/mage/cards/g/GiltLeafWinnower.java index f34f1a538d..ccd3ff2cba 100644 --- a/Mage.Sets/src/mage/cards/g/GiltLeafWinnower.java +++ b/Mage.Sets/src/mage/cards/g/GiltLeafWinnower.java @@ -66,7 +66,7 @@ public class GiltLeafWinnower extends CardImpl { this.toughness = new MageInt(3); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // When Gilt-Leaf Winnower enters the battlefield, you may destroy target non-Elf creature whose power and toughness aren't equal. Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect(), true); diff --git a/Mage.Sets/src/mage/cards/g/GlintSleeveSiphoner.java b/Mage.Sets/src/mage/cards/g/GlintSleeveSiphoner.java index c0d760847e..826eda1504 100644 --- a/Mage.Sets/src/mage/cards/g/GlintSleeveSiphoner.java +++ b/Mage.Sets/src/mage/cards/g/GlintSleeveSiphoner.java @@ -60,7 +60,7 @@ public class GlintSleeveSiphoner extends CardImpl { this.toughness = new MageInt(1); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Whenever Glint-Sleeve Siphoner enters the battlefield or attacks, you get {E}. this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new GetEnergyCountersControllerEffect(1))); diff --git a/Mage.Sets/src/mage/cards/g/GoblinDarkDwellers.java b/Mage.Sets/src/mage/cards/g/GoblinDarkDwellers.java index e4c2ee68cc..31b558779c 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinDarkDwellers.java +++ b/Mage.Sets/src/mage/cards/g/GoblinDarkDwellers.java @@ -72,7 +72,7 @@ public class GoblinDarkDwellers extends CardImpl { this.toughness = new MageInt(4); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // When Goblin Dark-Dwellers enters the battlefield, you may cast target instant or sorcery card with converted mana cost 3 or less // from your graveyard without paying its mana cost. If that card would be put into your graveyard this turn, exile it instead. diff --git a/Mage.Sets/src/mage/cards/g/GoblinFreerunner.java b/Mage.Sets/src/mage/cards/g/GoblinFreerunner.java index 84483903b7..a35e8f22c7 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinFreerunner.java +++ b/Mage.Sets/src/mage/cards/g/GoblinFreerunner.java @@ -54,7 +54,7 @@ public class GoblinFreerunner extends CardImpl { addAbility(new SurgeAbility(this, "{1}{R}")); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public GoblinFreerunner(final GoblinFreerunner card) { diff --git a/Mage.Sets/src/mage/cards/g/GoblinGloryChaser.java b/Mage.Sets/src/mage/cards/g/GoblinGloryChaser.java index ccb9e7e70e..d63dd615c1 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinGloryChaser.java +++ b/Mage.Sets/src/mage/cards/g/GoblinGloryChaser.java @@ -62,7 +62,7 @@ public class GoblinGloryChaser extends CardImpl { // As long as Goblin Glory Chaser is renowned, it has menace. Effect effect = new ConditionalContinuousEffect( - new GainAbilitySourceEffect(MenaceAbility.getInstance(), Duration.WhileOnBattlefield), + new GainAbilitySourceEffect(new MenaceAbility(), Duration.WhileOnBattlefield), RenownedSourceCondition.instance, "As long as {this} is renowned, it has menace"); Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); diff --git a/Mage.Sets/src/mage/cards/g/GoblinWarDrums.java b/Mage.Sets/src/mage/cards/g/GoblinWarDrums.java index de6f4e1b4a..f53fba6830 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinWarDrums.java +++ b/Mage.Sets/src/mage/cards/g/GoblinWarDrums.java @@ -56,7 +56,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; // Creatures you control have menace. (They can't be blocked except by two or more creatures.) - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(MenaceAbility.getInstance(), Duration.WhileOnBattlefield, filter))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new MenaceAbility(), Duration.WhileOnBattlefield, filter))); } public GoblinWarDrums(final GoblinWarDrums card) { diff --git a/Mage.Sets/src/mage/cards/g/GorillaWarCry.java b/Mage.Sets/src/mage/cards/g/GorillaWarCry.java index 3e80fa03e2..3b0f9366fb 100644 --- a/Mage.Sets/src/mage/cards/g/GorillaWarCry.java +++ b/Mage.Sets/src/mage/cards/g/GorillaWarCry.java @@ -56,7 +56,7 @@ public class GorillaWarCry extends CardImpl { this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(TurnPhase.COMBAT, BeforeBlockersAreDeclaredCondition.instance)); // All creatures gain menace until end of turn. (They can't be blocked except by two or more creatures.) - Effect effect = new GainAbilityAllEffect(MenaceAbility.getInstance(), Duration.EndOfTurn, new FilterCreaturePermanent()); + Effect effect = new GainAbilityAllEffect(new MenaceAbility(), Duration.EndOfTurn, new FilterCreaturePermanent()); effect.setText("All creatures gain menace until end of turn. (They can't be blocked except by two or more creatures.)"); this.getSpellAbility().addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/g/GrafHarvest.java b/Mage.Sets/src/mage/cards/g/GrafHarvest.java index 5aff10b608..e6ae038832 100644 --- a/Mage.Sets/src/mage/cards/g/GrafHarvest.java +++ b/Mage.Sets/src/mage/cards/g/GrafHarvest.java @@ -65,7 +65,7 @@ public class GrafHarvest extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{B}"); // Zombies you control have menace. - Effect effect = new GainAbilityAllEffect(MenaceAbility.getInstance(), Duration.WhileOnBattlefield, filter); + Effect effect = new GainAbilityAllEffect(new MenaceAbility(), Duration.WhileOnBattlefield, filter); effect.setText("Zombies you control have menace. (They can't be blocked except by two or more creatures.)"); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); diff --git a/Mage.Sets/src/mage/cards/g/GraniticTitan.java b/Mage.Sets/src/mage/cards/g/GraniticTitan.java index 8485fc9e8d..22fd617fe8 100644 --- a/Mage.Sets/src/mage/cards/g/GraniticTitan.java +++ b/Mage.Sets/src/mage/cards/g/GraniticTitan.java @@ -19,7 +19,7 @@ public class GraniticTitan extends CardImpl { toughness = new MageInt(4); // Menace - addAbility(MenaceAbility.getInstance()); + addAbility(new MenaceAbility()); // Cycling {2} addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}"))); diff --git a/Mage.Sets/src/mage/cards/g/GruulNodorog.java b/Mage.Sets/src/mage/cards/g/GruulNodorog.java index ad4d87a336..961d2d966b 100644 --- a/Mage.Sets/src/mage/cards/g/GruulNodorog.java +++ b/Mage.Sets/src/mage/cards/g/GruulNodorog.java @@ -54,7 +54,7 @@ public class GruulNodorog extends CardImpl { this.toughness = new MageInt(4); //{R}: Gruul Nodorog gains menace until end of turn. (It can't be blocked except by two or more creatures.) - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(MenaceAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{R}"))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(new MenaceAbility(), Duration.EndOfTurn), new ManaCostsImpl("{R}"))); } public GruulNodorog(final GruulNodorog card) { diff --git a/Mage.Sets/src/mage/cards/g/GruulWarChant.java b/Mage.Sets/src/mage/cards/g/GruulWarChant.java index 3f4ffe4726..9f0b2125d3 100644 --- a/Mage.Sets/src/mage/cards/g/GruulWarChant.java +++ b/Mage.Sets/src/mage/cards/g/GruulWarChant.java @@ -60,7 +60,7 @@ public class GruulWarChant extends CardImpl { // Attacking creatures you control get +1/+0 and have menace. (They can't be blocked except by two or more creatures.) - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(MenaceAbility.getInstance(), Duration.WhileOnBattlefield, filter)); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new MenaceAbility(), Duration.WhileOnBattlefield, filter)); ability.addEffect(new BoostAllEffect(1,0, Duration.WhileOnBattlefield, filter, false)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HeadstrongBrute.java b/Mage.Sets/src/mage/cards/h/HeadstrongBrute.java index c2b9c57a9d..c70577694a 100644 --- a/Mage.Sets/src/mage/cards/h/HeadstrongBrute.java +++ b/Mage.Sets/src/mage/cards/h/HeadstrongBrute.java @@ -71,7 +71,7 @@ public class HeadstrongBrute extends CardImpl { // Headstrong Brute has menace as long as you control another Pirate. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new ConditionalContinuousEffect(new GainAbilitySourceEffect(MenaceAbility.getInstance(), Duration.WhileOnBattlefield), + new ConditionalContinuousEffect(new GainAbilitySourceEffect(new MenaceAbility(), Duration.WhileOnBattlefield), new PermanentsOnTheBattlefieldCondition(filter), "{this} has menace as long as you control another Pirate"))); } diff --git a/Mage.Sets/src/mage/cards/h/HordeOfBoggarts.java b/Mage.Sets/src/mage/cards/h/HordeOfBoggarts.java index ad750f0937..06d1816e65 100644 --- a/Mage.Sets/src/mage/cards/h/HordeOfBoggarts.java +++ b/Mage.Sets/src/mage/cards/h/HordeOfBoggarts.java @@ -66,7 +66,7 @@ public class HordeOfBoggarts extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new PermanentsOnBattlefieldCount(filter), Duration.EndOfGame))); // Menace (This creature can't be blocked except by two or more creatures.) - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public HordeOfBoggarts(final HordeOfBoggarts card) { diff --git a/Mage.Sets/src/mage/cards/h/HoundOfTheFarbogs.java b/Mage.Sets/src/mage/cards/h/HoundOfTheFarbogs.java index 3b8e8060a7..71772a177c 100644 --- a/Mage.Sets/src/mage/cards/h/HoundOfTheFarbogs.java +++ b/Mage.Sets/src/mage/cards/h/HoundOfTheFarbogs.java @@ -60,7 +60,7 @@ public class HoundOfTheFarbogs extends CardImpl { // Delirium — Hound of the Farborgs has menace as long as there are four or more card types among cards in your graveyard. Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, - new ConditionalContinuousEffect(new GainAbilitySourceEffect(MenaceAbility.getInstance(), Duration.WhileOnBattlefield), DeliriumCondition.instance, RULE)); + new ConditionalContinuousEffect(new GainAbilitySourceEffect(new MenaceAbility(), Duration.WhileOnBattlefield), DeliriumCondition.instance, RULE)); ability.setAbilityWord(AbilityWord.DELIRIUM); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/IkraShidiqiTheUsurper.java b/Mage.Sets/src/mage/cards/i/IkraShidiqiTheUsurper.java index b8d88ed1a2..cb990d4622 100644 --- a/Mage.Sets/src/mage/cards/i/IkraShidiqiTheUsurper.java +++ b/Mage.Sets/src/mage/cards/i/IkraShidiqiTheUsurper.java @@ -61,7 +61,7 @@ public class IkraShidiqiTheUsurper extends CardImpl { this.toughness = new MageInt(7); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Whenever a creature you control deals combat damage to a player, you gain life equal to that creature's toughness. this.addAbility(new IkraShidiqiTheUsurperTriggeredAbility()); diff --git a/Mage.Sets/src/mage/cards/i/ImposingVisage.java b/Mage.Sets/src/mage/cards/i/ImposingVisage.java index 6d3bd7685c..8e3d76dd72 100644 --- a/Mage.Sets/src/mage/cards/i/ImposingVisage.java +++ b/Mage.Sets/src/mage/cards/i/ImposingVisage.java @@ -63,7 +63,7 @@ public class ImposingVisage extends CardImpl { this.addAbility(ability); // Enchanted creature has menace. (It can't be blocked except by two or more creatures.) - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(MenaceAbility.getInstance(), AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(new MenaceAbility(), AttachmentType.AURA))); } public ImposingVisage(final ImposingVisage card) { diff --git a/Mage.Sets/src/mage/cards/i/InsolentNeonate.java b/Mage.Sets/src/mage/cards/i/InsolentNeonate.java index 8cbcc6144f..b7c186a823 100644 --- a/Mage.Sets/src/mage/cards/i/InsolentNeonate.java +++ b/Mage.Sets/src/mage/cards/i/InsolentNeonate.java @@ -54,7 +54,7 @@ public class InsolentNeonate extends CardImpl { this.toughness = new MageInt(1); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Discard a card, Sacrifice Insolent Neonate: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new DiscardCardCost()); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/i/IreShaman.java b/Mage.Sets/src/mage/cards/i/IreShaman.java index 2d8544a4d1..e58fe28962 100644 --- a/Mage.Sets/src/mage/cards/i/IreShaman.java +++ b/Mage.Sets/src/mage/cards/i/IreShaman.java @@ -64,7 +64,7 @@ public class IreShaman extends CardImpl { this.toughness = new MageInt(1); // Menace (This creature can't be blocked except by two or more creatures.) - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Megamorph {R} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{R}"), true)); diff --git a/Mage.Sets/src/mage/cards/i/IroasGodOfVictory.java b/Mage.Sets/src/mage/cards/i/IroasGodOfVictory.java index aa2381b680..00b036f9d9 100644 --- a/Mage.Sets/src/mage/cards/i/IroasGodOfVictory.java +++ b/Mage.Sets/src/mage/cards/i/IroasGodOfVictory.java @@ -75,7 +75,7 @@ public class IroasGodOfVictory extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); // Creatures you control have menace. (They can't be blocked except by two or more creatures.) - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(MenaceAbility.getInstance(), Duration.WhileOnBattlefield, filter))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new MenaceAbility(), Duration.WhileOnBattlefield, filter))); // Prevent all damage that would be dealt to attacking creatures you control. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, filterAttacking))); diff --git a/Mage.Sets/src/mage/cards/j/JangoFett.java b/Mage.Sets/src/mage/cards/j/JangoFett.java index 6079f99bc6..1f62423053 100644 --- a/Mage.Sets/src/mage/cards/j/JangoFett.java +++ b/Mage.Sets/src/mage/cards/j/JangoFett.java @@ -71,7 +71,7 @@ public class JangoFett extends CardImpl { this.toughness = new MageInt(2); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Haste this.addAbility(HasteAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/k/KariZevSkyshipRaider.java b/Mage.Sets/src/mage/cards/k/KariZevSkyshipRaider.java index b7f67f6043..43c4993629 100644 --- a/Mage.Sets/src/mage/cards/k/KariZevSkyshipRaider.java +++ b/Mage.Sets/src/mage/cards/k/KariZevSkyshipRaider.java @@ -64,7 +64,7 @@ public class KariZevSkyshipRaider extends CardImpl { this.addAbility(FirstStrikeAbility.getInstance()); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Whenever Kari Zev, Skyship Raider attacks, create a legendary 2/1 red Monkey creature token named Ragavan that's tapped and attacking. Exile that token at end of combat. this.addAbility(new AttacksTriggeredAbility(new KariZevSkyshipRaiderEffect(), false)); diff --git a/Mage.Sets/src/mage/cards/k/KederektCreeper.java b/Mage.Sets/src/mage/cards/k/KederektCreeper.java index 2fa7de084b..e806e4fafb 100644 --- a/Mage.Sets/src/mage/cards/k/KederektCreeper.java +++ b/Mage.Sets/src/mage/cards/k/KederektCreeper.java @@ -53,7 +53,7 @@ public class KederektCreeper extends CardImpl { this.addAbility(DeathtouchAbility.getInstance()); // Menace (This creature can't be blocked except by two or more creatures.) - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public KederektCreeper(final KederektCreeper card) { diff --git a/Mage.Sets/src/mage/cards/k/KhenraScrapper.java b/Mage.Sets/src/mage/cards/k/KhenraScrapper.java index 7416329584..df5a4af154 100644 --- a/Mage.Sets/src/mage/cards/k/KhenraScrapper.java +++ b/Mage.Sets/src/mage/cards/k/KhenraScrapper.java @@ -54,7 +54,7 @@ public class KhenraScrapper extends CardImpl { this.toughness = new MageInt(3); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // You may exert Khenra Scrapper as it attacks. When you do, it gets +2/+0 until end of turn. this.addAbility(new ExertAbility(new BecomesExertSourceTriggeredAbility(new BoostSourceEffect(2, 0, Duration.EndOfTurn)))); diff --git a/Mage.Sets/src/mage/cards/k/KheruMindEater.java b/Mage.Sets/src/mage/cards/k/KheruMindEater.java index fb07722cd2..5be14b360b 100644 --- a/Mage.Sets/src/mage/cards/k/KheruMindEater.java +++ b/Mage.Sets/src/mage/cards/k/KheruMindEater.java @@ -67,7 +67,7 @@ public class KheruMindEater extends CardImpl { this.toughness = new MageInt(3); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Whenever Kheru Mind-Eater deals combat damage to a player, that player exiles a card from his or her hand face down. this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new KheruMindEaterExileEffect(), false, true)); diff --git a/Mage.Sets/src/mage/cards/k/KozilekTheGreatDistortion.java b/Mage.Sets/src/mage/cards/k/KozilekTheGreatDistortion.java index b285af7621..31db10e3dc 100644 --- a/Mage.Sets/src/mage/cards/k/KozilekTheGreatDistortion.java +++ b/Mage.Sets/src/mage/cards/k/KozilekTheGreatDistortion.java @@ -79,7 +79,7 @@ public class KozilekTheGreatDistortion extends CardImpl { new CardsInHandCondition(ComparisonType.FEWER_THAN, 7), "When you cast {this}, if you have fewer than seven cards in hand, draw cards equal to the difference.")); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Discard a card with converted mana cost X: Counter target spell with converted mana cost X. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(), new KozilekDiscardCost()); diff --git a/Mage.Sets/src/mage/cards/k/KozileksShrieker.java b/Mage.Sets/src/mage/cards/k/KozileksShrieker.java index 6e5daf684b..ef2a66100c 100644 --- a/Mage.Sets/src/mage/cards/k/KozileksShrieker.java +++ b/Mage.Sets/src/mage/cards/k/KozileksShrieker.java @@ -63,7 +63,7 @@ public class KozileksShrieker extends CardImpl { Effect effect = new BoostSourceEffect(1, 0, Duration.EndOfTurn); effect.setText("{this} gets +1/+0"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{C}")); - effect = new GainAbilitySourceEffect(MenaceAbility.getInstance(), Duration.EndOfTurn); + effect = new GainAbilitySourceEffect(new MenaceAbility(), Duration.EndOfTurn); effect.setText("and gains menace until end of turn"); ability.addEffect(effect); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/l/LordOfTheAccursed.java b/Mage.Sets/src/mage/cards/l/LordOfTheAccursed.java index fad3fc6aa8..7ba04117a0 100644 --- a/Mage.Sets/src/mage/cards/l/LordOfTheAccursed.java +++ b/Mage.Sets/src/mage/cards/l/LordOfTheAccursed.java @@ -65,7 +65,7 @@ public class LordOfTheAccursed extends CardImpl { //{2}{B}, Tap: All Zombies gain menace until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect( - MenaceAbility.getInstance(), + new MenaceAbility(), Duration.EndOfTurn, filter, "All Zombies gains menace until end of turn."), new ManaCostsImpl("{1}{B}")); diff --git a/Mage.Sets/src/mage/cards/l/LoseCalm.java b/Mage.Sets/src/mage/cards/l/LoseCalm.java index 6f28ff7ac1..7891c5c802 100644 --- a/Mage.Sets/src/mage/cards/l/LoseCalm.java +++ b/Mage.Sets/src/mage/cards/l/LoseCalm.java @@ -56,7 +56,7 @@ public class LoseCalm extends CardImpl { this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn, "It gains haste until end of turn")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - effect = new GainAbilityTargetEffect(MenaceAbility.getInstance(), Duration.EndOfTurn); + effect = new GainAbilityTargetEffect(new MenaceAbility(), Duration.EndOfTurn); effect.setText("and menace until end of turn. (A creature with menace can't be blocked except by two or more creatures.) "); this.getSpellAbility().addEffect(effect); } diff --git a/Mage.Sets/src/mage/cards/m/MadcapSkills.java b/Mage.Sets/src/mage/cards/m/MadcapSkills.java index 20e4d5d57b..b3c89573c6 100644 --- a/Mage.Sets/src/mage/cards/m/MadcapSkills.java +++ b/Mage.Sets/src/mage/cards/m/MadcapSkills.java @@ -65,7 +65,7 @@ public class MadcapSkills extends CardImpl { // Enchanted creature gets +3/+0 and and has menace. (It can't be blocked except by two or more creatures.) this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 0))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(MenaceAbility.getInstance(), AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(new MenaceAbility(), AttachmentType.AURA))); } public MadcapSkills(final MadcapSkills card) { diff --git a/Mage.Sets/src/mage/cards/m/MajesticMyriarch.java b/Mage.Sets/src/mage/cards/m/MajesticMyriarch.java index f1c3ccdd0a..eb20db682b 100644 --- a/Mage.Sets/src/mage/cards/m/MajesticMyriarch.java +++ b/Mage.Sets/src/mage/cards/m/MajesticMyriarch.java @@ -187,7 +187,7 @@ class MajesticMyriarchEffect extends OneShotEffect { // Menace if (game.getBattlefield().contains(filterMenace, source.getControllerId(), 1, game)) { - game.addEffect(new GainAbilitySourceEffect(MenaceAbility.getInstance(), Duration.EndOfTurn), source); + game.addEffect(new GainAbilitySourceEffect(new MenaceAbility(), Duration.EndOfTurn), source); } // Reach diff --git a/Mage.Sets/src/mage/cards/m/MathasFiendSeeker.java b/Mage.Sets/src/mage/cards/m/MathasFiendSeeker.java index 61710ca3b1..5e9422278a 100644 --- a/Mage.Sets/src/mage/cards/m/MathasFiendSeeker.java +++ b/Mage.Sets/src/mage/cards/m/MathasFiendSeeker.java @@ -76,7 +76,7 @@ public class MathasFiendSeeker extends CardImpl { this.toughness = new MageInt(3); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // At the beginning of your end step, put a bounty counter on target creature an opponent controls. For as long as that creature has a bounty counter on it, it has "When this creature dies, each opponent draws a card and gains 2 life." Ability ability = new BeginningOfYourEndStepTriggeredAbility(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()), false); diff --git a/Mage.Sets/src/mage/cards/m/MaulfistSquad.java b/Mage.Sets/src/mage/cards/m/MaulfistSquad.java index 36064255ed..21ba08c1b1 100644 --- a/Mage.Sets/src/mage/cards/m/MaulfistSquad.java +++ b/Mage.Sets/src/mage/cards/m/MaulfistSquad.java @@ -50,7 +50,7 @@ public class MaulfistSquad extends CardImpl { this.toughness = new MageInt(1); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Fabricate 1 this.addAbility(new FabricateAbility(1)); diff --git a/Mage.Sets/src/mage/cards/m/MoonriseIntruder.java b/Mage.Sets/src/mage/cards/m/MoonriseIntruder.java index 17508ecef2..52451801a1 100644 --- a/Mage.Sets/src/mage/cards/m/MoonriseIntruder.java +++ b/Mage.Sets/src/mage/cards/m/MoonriseIntruder.java @@ -60,7 +60,7 @@ public class MoonriseIntruder extends CardImpl { this.transformable = true; // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Moonrise Intruder. TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), TargetController.ANY, false); diff --git a/Mage.Sets/src/mage/cards/m/MorkrutNecropod.java b/Mage.Sets/src/mage/cards/m/MorkrutNecropod.java index e94e979e3a..af45b60e8e 100644 --- a/Mage.Sets/src/mage/cards/m/MorkrutNecropod.java +++ b/Mage.Sets/src/mage/cards/m/MorkrutNecropod.java @@ -64,7 +64,7 @@ public class MorkrutNecropod extends CardImpl { this.toughness = new MageInt(7); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Whenever Morkrut Necropod attacks or blocks, sacrifice another creature or land. this.addAbility(new AttacksOrBlocksTriggeredAbility(new SacrificeControllerEffect(filter, 1, ""), false)); diff --git a/Mage.Sets/src/mage/cards/n/NoxiousGearhulk.java b/Mage.Sets/src/mage/cards/n/NoxiousGearhulk.java index ea283f6b40..ac97025754 100644 --- a/Mage.Sets/src/mage/cards/n/NoxiousGearhulk.java +++ b/Mage.Sets/src/mage/cards/n/NoxiousGearhulk.java @@ -64,7 +64,7 @@ public class NoxiousGearhulk extends CardImpl { this.toughness = new MageInt(4); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // When Noxious Gearhulk enters the battlefield, you may destroy another target creature. If a creature is destroyed this way, you gain life equal to its toughness. Ability ability = new EntersBattlefieldTriggeredAbility(new NoxiousGearhulkEffect()); diff --git a/Mage.Sets/src/mage/cards/o/OdricLunarchMarshal.java b/Mage.Sets/src/mage/cards/o/OdricLunarchMarshal.java index b7d535e0d1..353a072d4b 100644 --- a/Mage.Sets/src/mage/cards/o/OdricLunarchMarshal.java +++ b/Mage.Sets/src/mage/cards/o/OdricLunarchMarshal.java @@ -161,7 +161,7 @@ class OdricLunarchMarshalEffect extends OneShotEffect { // Menace if (game.getBattlefield().contains(filterMenace, source.getControllerId(), 1, game)) { - game.addEffect(new GainAbilityControlledEffect(MenaceAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source); + game.addEffect(new GainAbilityControlledEffect(new MenaceAbility(), Duration.EndOfTurn, filterCreatures), source); } // Reach diff --git a/Mage.Sets/src/mage/cards/p/PlagueBelcher.java b/Mage.Sets/src/mage/cards/p/PlagueBelcher.java index 048ee5f58b..8fb0c4c615 100644 --- a/Mage.Sets/src/mage/cards/p/PlagueBelcher.java +++ b/Mage.Sets/src/mage/cards/p/PlagueBelcher.java @@ -70,7 +70,7 @@ public class PlagueBelcher extends CardImpl { this.toughness = new MageInt(4); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // When Plague Belcher enters the battlefield, put two -1/-1 counters on target creature you control. Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.M1M1.createInstance(2))); diff --git a/Mage.Sets/src/mage/cards/p/PurphorossEmissary.java b/Mage.Sets/src/mage/cards/p/PurphorossEmissary.java index 1a129f3138..a427dc47c5 100644 --- a/Mage.Sets/src/mage/cards/p/PurphorossEmissary.java +++ b/Mage.Sets/src/mage/cards/p/PurphorossEmissary.java @@ -60,11 +60,11 @@ public class PurphorossEmissary extends CardImpl { this.addAbility(new BestowAbility(this, "{6}{R}")); // Menace (This creature can't be blocked except by two or more creatures.) - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Enchanted creature gets +3/+3 and and has menace. Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3,3)); - Effect effect = new GainAbilityAttachedEffect(MenaceAbility.getInstance(), AttachmentType.AURA); + Effect effect = new GainAbilityAttachedEffect(new MenaceAbility(), AttachmentType.AURA); effect.setText("and has menace"); ability.addEffect(effect); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/p/PyreheartWolf.java b/Mage.Sets/src/mage/cards/p/PyreheartWolf.java index 7f2a4d7477..8ab32e9b2b 100644 --- a/Mage.Sets/src/mage/cards/p/PyreheartWolf.java +++ b/Mage.Sets/src/mage/cards/p/PyreheartWolf.java @@ -62,7 +62,7 @@ public class PyreheartWolf extends CardImpl { this.toughness = new MageInt(1); // Whenever Pyreheart Wolf attacks, creatures you control gain menace until end of turn. (They can't be blocked except by two or more creatures.) - this.addAbility(new AttacksTriggeredAbility(new GainAbilityAllEffect(MenaceAbility.getInstance(), Duration.EndOfTurn, filter), false)); + this.addAbility(new AttacksTriggeredAbility(new GainAbilityAllEffect(new MenaceAbility(), Duration.EndOfTurn, filter), false)); // Undying (When this creature dies, if it had no +1/+1 counters on it, return it to the battlefield under its owner's control with a +1/+1 counter on it.) this.addAbility(new UndyingAbility()); diff --git a/Mage.Sets/src/mage/cards/r/RampagingFerocidon.java b/Mage.Sets/src/mage/cards/r/RampagingFerocidon.java index 2efeba3540..17663bc7fa 100644 --- a/Mage.Sets/src/mage/cards/r/RampagingFerocidon.java +++ b/Mage.Sets/src/mage/cards/r/RampagingFerocidon.java @@ -71,7 +71,7 @@ public class RampagingFerocidon extends CardImpl { this.toughness = new MageInt(3); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Players can't gain life. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new RampagingFerocidonEffect())); diff --git a/Mage.Sets/src/mage/cards/r/RelentlessDead.java b/Mage.Sets/src/mage/cards/r/RelentlessDead.java index 58f0084032..48e4026b52 100644 --- a/Mage.Sets/src/mage/cards/r/RelentlessDead.java +++ b/Mage.Sets/src/mage/cards/r/RelentlessDead.java @@ -63,7 +63,7 @@ public class RelentlessDead extends CardImpl { this.toughness = new MageInt(2); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // When Relentless Dead dies, you may pay {B}. If you do, return it to its owner's hand. this.addAbility(new DiesTriggeredAbility(new DoIfCostPaid(new ReturnToHandSourceEffect(), new ManaCostsImpl("{B}")))); diff --git a/Mage.Sets/src/mage/cards/r/RipscalePredator.java b/Mage.Sets/src/mage/cards/r/RipscalePredator.java index 7f7e7d00a0..916b3383d9 100644 --- a/Mage.Sets/src/mage/cards/r/RipscalePredator.java +++ b/Mage.Sets/src/mage/cards/r/RipscalePredator.java @@ -49,7 +49,7 @@ public class RipscalePredator extends CardImpl { this.toughness = new MageInt(5); // Ripscale Predator can't be blocked except by two or more creatures. - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public RipscalePredator(final RipscalePredator card) { diff --git a/Mage.Sets/src/mage/cards/s/ScroungedScythe.java b/Mage.Sets/src/mage/cards/s/ScroungedScythe.java index ceb1af837f..eded8abdd1 100644 --- a/Mage.Sets/src/mage/cards/s/ScroungedScythe.java +++ b/Mage.Sets/src/mage/cards/s/ScroungedScythe.java @@ -60,7 +60,7 @@ public class ScroungedScythe extends CardImpl { // As long as equipped creature is a Human, it has menace. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new ConditionalContinuousEffect(new GainAbilityAttachedEffect(MenaceAbility.getInstance(), AttachmentType.EQUIPMENT), + new ConditionalContinuousEffect(new GainAbilityAttachedEffect(new MenaceAbility(), AttachmentType.EQUIPMENT), new EquippedHasSubtypeCondition(SubType.HUMAN), staticText))); // Equip {2} diff --git a/Mage.Sets/src/mage/cards/s/SearingSpearAskari.java b/Mage.Sets/src/mage/cards/s/SearingSpearAskari.java index 9f1d878f86..95e1ac33b1 100644 --- a/Mage.Sets/src/mage/cards/s/SearingSpearAskari.java +++ b/Mage.Sets/src/mage/cards/s/SearingSpearAskari.java @@ -59,7 +59,7 @@ public class SearingSpearAskari extends CardImpl { this.addAbility(new FlankingAbility()); // {1}{R}: Searing Spear Askari gains menace until end of turn. (It can't be blocked except by two or more creatures.) - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(MenaceAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{1}{R}"))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(new MenaceAbility(), Duration.EndOfTurn), new ManaCostsImpl("{1}{R}"))); } public SearingSpearAskari(final SearingSpearAskari card) { diff --git a/Mage.Sets/src/mage/cards/s/ShatterskullRecruit.java b/Mage.Sets/src/mage/cards/s/ShatterskullRecruit.java index 719ef83550..692c50fdc3 100644 --- a/Mage.Sets/src/mage/cards/s/ShatterskullRecruit.java +++ b/Mage.Sets/src/mage/cards/s/ShatterskullRecruit.java @@ -50,7 +50,7 @@ public class ShatterskullRecruit extends CardImpl { this.toughness = new MageInt(4); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public ShatterskullRecruit(final ShatterskullRecruit card) { diff --git a/Mage.Sets/src/mage/cards/s/SinProdder.java b/Mage.Sets/src/mage/cards/s/SinProdder.java index 9df1da79ad..bae067a022 100644 --- a/Mage.Sets/src/mage/cards/s/SinProdder.java +++ b/Mage.Sets/src/mage/cards/s/SinProdder.java @@ -61,7 +61,7 @@ public class SinProdder extends CardImpl { this.toughness = new MageInt(2); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // At the beginning of your upkeep, reveal the top card of your library. Any opponent may have you put that card into your graveyard. If a player does, // Sin Prodder deals damage to that player equal to that card's converted mana cost. Otherwise, put that card into your hand. diff --git a/Mage.Sets/src/mage/cards/s/SinuousVermin.java b/Mage.Sets/src/mage/cards/s/SinuousVermin.java index b1593aa7b8..c231331838 100644 --- a/Mage.Sets/src/mage/cards/s/SinuousVermin.java +++ b/Mage.Sets/src/mage/cards/s/SinuousVermin.java @@ -62,7 +62,7 @@ public class SinuousVermin extends CardImpl { // As long as Sinuous Vermin is monstrous, it has menace. Ability ability = new SimpleStaticAbility( Zone.BATTLEFIELD, - new ConditionalContinuousEffect(new GainAbilitySourceEffect(MenaceAbility.getInstance(), Duration.WhileOnBattlefield), + new ConditionalContinuousEffect(new GainAbilitySourceEffect(new MenaceAbility(), Duration.WhileOnBattlefield), MonstrousCondition.instance, "As long as {this} is monstrous, it has menace")); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/s/SithLord.java b/Mage.Sets/src/mage/cards/s/SithLord.java index 76c6509cdf..60255f1c54 100644 --- a/Mage.Sets/src/mage/cards/s/SithLord.java +++ b/Mage.Sets/src/mage/cards/s/SithLord.java @@ -59,7 +59,7 @@ public class SithLord extends CardImpl { this.toughness = new MageInt(2); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Sith Lord enters the battlefield with X +1/+1 counters on it, where X is the total life lost by your opponents this turn. this.addAbility(new EntersBattlefieldAbility(new SithLordEffect(), rule)); diff --git a/Mage.Sets/src/mage/cards/s/SkyTerror.java b/Mage.Sets/src/mage/cards/s/SkyTerror.java index b0163d354d..fd25a46b7f 100644 --- a/Mage.Sets/src/mage/cards/s/SkyTerror.java +++ b/Mage.Sets/src/mage/cards/s/SkyTerror.java @@ -53,7 +53,7 @@ public class SkyTerror extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } diff --git a/Mage.Sets/src/mage/cards/s/StormbloodBerserker.java b/Mage.Sets/src/mage/cards/s/StormbloodBerserker.java index a2186fd39b..4970f4f179 100644 --- a/Mage.Sets/src/mage/cards/s/StormbloodBerserker.java +++ b/Mage.Sets/src/mage/cards/s/StormbloodBerserker.java @@ -51,7 +51,7 @@ public class StormbloodBerserker extends CardImpl { this.addAbility(new BloodthirstAbility(2)); // Menace (This creature can't be blocked except by two or more creatures.) - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public StormbloodBerserker(final StormbloodBerserker card) { diff --git a/Mage.Sets/src/mage/cards/s/SummitApes.java b/Mage.Sets/src/mage/cards/s/SummitApes.java index 0126be12a0..2c5f762434 100644 --- a/Mage.Sets/src/mage/cards/s/SummitApes.java +++ b/Mage.Sets/src/mage/cards/s/SummitApes.java @@ -65,7 +65,7 @@ public class SummitApes extends CardImpl { // As long as you control a Mountain, Summit Apes has menace. (It can't be blocked except by two or more creatures.) this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new ConditionalContinuousEffect(new GainAbilitySourceEffect(MenaceAbility.getInstance()), new PermanentsOnTheBattlefieldCondition(filter), rule))); + new ConditionalContinuousEffect(new GainAbilitySourceEffect(new MenaceAbility()), new PermanentsOnTheBattlefieldCondition(filter), rule))); } public SummitApes(final SummitApes card) { diff --git a/Mage.Sets/src/mage/cards/s/SweatworksBrawler.java b/Mage.Sets/src/mage/cards/s/SweatworksBrawler.java index e283cd7257..83f9283dbe 100644 --- a/Mage.Sets/src/mage/cards/s/SweatworksBrawler.java +++ b/Mage.Sets/src/mage/cards/s/SweatworksBrawler.java @@ -54,7 +54,7 @@ public class SweatworksBrawler extends CardImpl { addAbility(new ImproviseAbility()); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public SweatworksBrawler(final SweatworksBrawler card) { diff --git a/Mage.Sets/src/mage/cards/t/TerrorOfKruinPass.java b/Mage.Sets/src/mage/cards/t/TerrorOfKruinPass.java index b29a2d35c2..3c2189926e 100644 --- a/Mage.Sets/src/mage/cards/t/TerrorOfKruinPass.java +++ b/Mage.Sets/src/mage/cards/t/TerrorOfKruinPass.java @@ -76,7 +76,7 @@ public class TerrorOfKruinPass extends CardImpl { this.addAbility(DoubleStrikeAbility.getInstance()); // Werewolves you control have menace. (They can't be blocked except by two or more creatures.) - Effect effect = new ConditionalContinuousEffect(new GainAbilityAllEffect(MenaceAbility.getInstance(), Duration.Custom, filter), new TransformedCondition(), ruleText); + Effect effect = new ConditionalContinuousEffect(new GainAbilityAllEffect(new MenaceAbility(), Duration.Custom, filter), new TransformedCondition(), ruleText); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Terror of Kruin Pass. diff --git a/Mage.Sets/src/mage/cards/t/ThrabenFoulbloods.java b/Mage.Sets/src/mage/cards/t/ThrabenFoulbloods.java index f39a557744..6a55263541 100644 --- a/Mage.Sets/src/mage/cards/t/ThrabenFoulbloods.java +++ b/Mage.Sets/src/mage/cards/t/ThrabenFoulbloods.java @@ -59,7 +59,7 @@ public class ThrabenFoulbloods extends CardImpl { // Delirium — Thraben Foulbloods gets +1/+1 and has menace as long as there are four or more card types among cards in your graveyard. (A creature with menace can't be blocked except by two or more creatures.) ConditionalContinuousEffect effect = new ConditionalContinuousEffect(new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), DeliriumCondition.instance, "Delirium — {this} gets +1/+1"); Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); - ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(MenaceAbility.getInstance()), DeliriumCondition.instance, + ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(new MenaceAbility()), DeliriumCondition.instance, "and has menace as long as there are four or more card types among cards in your graveyard. (A creature with menace can't be blocked except by two or more creatures.)")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TwoHeadedDragon.java b/Mage.Sets/src/mage/cards/t/TwoHeadedDragon.java index 69f9a4d8c5..53828c92d9 100644 --- a/Mage.Sets/src/mage/cards/t/TwoHeadedDragon.java +++ b/Mage.Sets/src/mage/cards/t/TwoHeadedDragon.java @@ -63,7 +63,7 @@ public class TwoHeadedDragon extends CardImpl { this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2,0, Duration.EndOfTurn),new ManaCostsImpl("{1}{R}"))); // Menace (This creature can't be blocked except by two or more creatures.) - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); // Two-Headed Dragon can block an additional creature each combat. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockAdditionalCreatureEffect())); diff --git a/Mage.Sets/src/mage/cards/t/TwoHeadedSliver.java b/Mage.Sets/src/mage/cards/t/TwoHeadedSliver.java index 39fcd989c5..d2bf0bbdea 100644 --- a/Mage.Sets/src/mage/cards/t/TwoHeadedSliver.java +++ b/Mage.Sets/src/mage/cards/t/TwoHeadedSliver.java @@ -56,7 +56,7 @@ public class TwoHeadedSliver extends CardImpl { // All Sliver creatures have menace. (They can't be blocked except by two or more creatures.) this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect( - MenaceAbility.getInstance(), + new MenaceAbility(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE_SLIVERS, "All Sliver creatures have menace. (They can't be blocked except by two or more creatures.)"))); } diff --git a/Mage.Sets/src/mage/cards/u/UntamedHunger.java b/Mage.Sets/src/mage/cards/u/UntamedHunger.java index e2bcd15cad..3e442a8d32 100644 --- a/Mage.Sets/src/mage/cards/u/UntamedHunger.java +++ b/Mage.Sets/src/mage/cards/u/UntamedHunger.java @@ -65,7 +65,7 @@ public class UntamedHunger extends CardImpl { // Enchanted creature gets +2/+1 and has menace. ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 1)); - Effect effect = new GainAbilityAttachedEffect(MenaceAbility.getInstance(), AttachmentType.AURA); + Effect effect = new GainAbilityAttachedEffect(new MenaceAbility(), AttachmentType.AURA); effect.setText("and has menace"); ability.addEffect(effect); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/v/ViashinoRunner.java b/Mage.Sets/src/mage/cards/v/ViashinoRunner.java index 5056c300a7..82d43889c5 100644 --- a/Mage.Sets/src/mage/cards/v/ViashinoRunner.java +++ b/Mage.Sets/src/mage/cards/v/ViashinoRunner.java @@ -49,7 +49,7 @@ public class ViashinoRunner extends CardImpl { this.toughness = new MageInt(2); // Menace (This creature can't be blocked except by two or more creatures.) - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public ViashinoRunner(final ViashinoRunner card) { diff --git a/Mage.Sets/src/mage/cards/v/VineKami.java b/Mage.Sets/src/mage/cards/v/VineKami.java index f9f5904630..d004762114 100644 --- a/Mage.Sets/src/mage/cards/v/VineKami.java +++ b/Mage.Sets/src/mage/cards/v/VineKami.java @@ -50,7 +50,7 @@ public class VineKami extends CardImpl { this.toughness = new MageInt(4); // Menace (This creature can't be blocked except by two or more creatures.) - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); this.addAbility(new SoulshiftAbility(6)); } diff --git a/Mage.Sets/src/mage/cards/w/WaywardGiant.java b/Mage.Sets/src/mage/cards/w/WaywardGiant.java index eb46bea018..853d79594a 100644 --- a/Mage.Sets/src/mage/cards/w/WaywardGiant.java +++ b/Mage.Sets/src/mage/cards/w/WaywardGiant.java @@ -48,7 +48,7 @@ public class WaywardGiant extends CardImpl { this.toughness = new MageInt(5); // Menace - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public WaywardGiant(final WaywardGiant card) { diff --git a/Mage.Sets/src/mage/cards/w/WeldfastMonitor.java b/Mage.Sets/src/mage/cards/w/WeldfastMonitor.java index e520e706ba..78d2919763 100644 --- a/Mage.Sets/src/mage/cards/w/WeldfastMonitor.java +++ b/Mage.Sets/src/mage/cards/w/WeldfastMonitor.java @@ -55,7 +55,7 @@ public class WeldfastMonitor extends CardImpl { // {R}: Weldfast Monitor gains menace until end of turn this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new GainAbilitySourceEffect(MenaceAbility.getInstance(), Duration.EndOfTurn), new ColoredManaCost(ColoredManaSymbol.R))); + new GainAbilitySourceEffect(new MenaceAbility(), Duration.EndOfTurn), new ColoredManaCost(ColoredManaSymbol.R))); } diff --git a/Mage.Sets/src/mage/cards/w/WindSpirit.java b/Mage.Sets/src/mage/cards/w/WindSpirit.java index 74b9a53e11..399e0b9523 100644 --- a/Mage.Sets/src/mage/cards/w/WindSpirit.java +++ b/Mage.Sets/src/mage/cards/w/WindSpirit.java @@ -54,7 +54,7 @@ public class WindSpirit extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Menace (This creature can't be blocked except by two or more creatures.) - this.addAbility(MenaceAbility.getInstance()); + this.addAbility(new MenaceAbility()); } public WindSpirit(final WindSpirit card) { diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ExertTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ExertTest.java index fabd383709..67053e496d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ExertTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ExertTest.java @@ -105,7 +105,7 @@ public class ExertTest extends CardTestPlayerBase { setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); execute(); - assertAbility(playerA, minotaur, MenaceAbility.getInstance(), true); + assertAbility(playerA, minotaur, new MenaceAbility(), true); assertPowerToughness(playerA, minotaur, 5, 4); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RenownTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RenownTest.java index 9cf055f0a6..4a138d3fc3 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RenownTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RenownTest.java @@ -203,7 +203,7 @@ public class RenownTest extends CardTestPlayerBase { Permanent goblin = getPermanent("Goblin Glory Chaser", playerA); Assert.assertEquals("has has renown", true, goblin.isRenowned()); - assertAbility(playerA, "Goblin Glory Chaser", MenaceAbility.getInstance(), true); + assertAbility(playerA, "Goblin Glory Chaser", new MenaceAbility(), true); assertPowerToughness(playerA, "Goblin Glory Chaser", 2, 2); assertLife(playerA, 20); diff --git a/Mage/src/main/java/mage/abilities/keyword/MenaceAbility.java b/Mage/src/main/java/mage/abilities/keyword/MenaceAbility.java index 6e55108574..22654b647b 100644 --- a/Mage/src/main/java/mage/abilities/keyword/MenaceAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/MenaceAbility.java @@ -5,35 +5,28 @@ */ package mage.abilities.keyword; -import java.io.ObjectStreamException; import mage.abilities.Ability; -import mage.abilities.EvasionAbility; -import mage.abilities.MageSingleton; +import mage.abilities.StaticAbility; import mage.abilities.effects.common.combat.CantBeBlockedByOneEffect; +import mage.constants.Zone; /** * * @author LevelX2 */ -public class MenaceAbility extends EvasionAbility implements MageSingleton { +public class MenaceAbility extends StaticAbility { // Menace may not be a Singleton because the source ability is needed in the continuous effect - private static final MenaceAbility instance = new MenaceAbility(); - - private Object readResolve() throws ObjectStreamException { - return instance; + public MenaceAbility() { + super(Zone.BATTLEFIELD, new CantBeBlockedByOneEffect(2)); } - public static MenaceAbility getInstance() { - return instance; - } - - private MenaceAbility() { - this.addEffect(new CantBeBlockedByOneEffect(2)); + public MenaceAbility(final MenaceAbility ability) { + super(ability); } @Override public Ability copy() { - return instance; + return new MenaceAbility(this); } @Override diff --git a/Mage/src/main/java/mage/game/permanent/token/PirateToken.java b/Mage/src/main/java/mage/game/permanent/token/PirateToken.java index 37a3ee7a52..fe4d04270f 100644 --- a/Mage/src/main/java/mage/game/permanent/token/PirateToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/PirateToken.java @@ -45,6 +45,6 @@ public class PirateToken extends Token { subtype.add(SubType.PIRATE); power = new MageInt(2); toughness = new MageInt(2); - addAbility(MenaceAbility.getInstance()); + addAbility(new MenaceAbility()); } } From c0cffd6b87d371cc091f474eb6b1a36be2167c05 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 10:38:20 +0200 Subject: [PATCH 116/182] Renamed SliceInTwain class name. --- .../cards/s/{SliceInXXTwain.java => SliceInTwain.java} | 10 +++++----- Mage.Sets/src/mage/sets/Commander2013.java | 6 ++---- Mage.Sets/src/mage/sets/Ixalan.java | 2 ++ Mage.Sets/src/mage/sets/ScarsOfMirrodin.java | 5 ++--- 4 files changed, 11 insertions(+), 12 deletions(-) rename Mage.Sets/src/mage/cards/s/{SliceInXXTwain.java => SliceInTwain.java} (90%) diff --git a/Mage.Sets/src/mage/cards/s/SliceInXXTwain.java b/Mage.Sets/src/mage/cards/s/SliceInTwain.java similarity index 90% rename from Mage.Sets/src/mage/cards/s/SliceInXXTwain.java rename to Mage.Sets/src/mage/cards/s/SliceInTwain.java index 22575fdc3f..91c3ef929a 100644 --- a/Mage.Sets/src/mage/cards/s/SliceInXXTwain.java +++ b/Mage.Sets/src/mage/cards/s/SliceInTwain.java @@ -40,9 +40,9 @@ import mage.target.TargetPermanent; * * @author Loki */ -public class SliceInXXTwain extends CardImpl { +public class SliceInTwain extends CardImpl { - public SliceInXXTwain(UUID ownerId, CardSetInfo setInfo) { + public SliceInTwain(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}{G}"); this.getSpellAbility().addEffect(new DestroyTargetEffect()); @@ -50,12 +50,12 @@ public class SliceInXXTwain extends CardImpl { this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.ARTIFACT_OR_ENCHANTMENT_PERMANENT)); } - public SliceInXXTwain(final SliceInXXTwain card) { + public SliceInTwain(final SliceInTwain card) { super(card); } @Override - public SliceInXXTwain copy() { - return new SliceInXXTwain(this); + public SliceInTwain copy() { + return new SliceInTwain(this); } } diff --git a/Mage.Sets/src/mage/sets/Commander2013.java b/Mage.Sets/src/mage/sets/Commander2013.java index 3d7a4241e2..16892d6876 100644 --- a/Mage.Sets/src/mage/sets/Commander2013.java +++ b/Mage.Sets/src/mage/sets/Commander2013.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.sets; import mage.cards.ExpansionSet; @@ -37,7 +36,6 @@ import mage.constants.SetType; * * @author LevelX2 */ - public class Commander2013 extends ExpansionSet { private static final Commander2013 instance = new Commander2013(); @@ -317,7 +315,7 @@ public class Commander2013 extends ExpansionSet { cards.add(new SetCardInfo("Skyscribing", 57, Rarity.UNCOMMON, mage.cards.s.Skyscribing.class)); cards.add(new SetCardInfo("Skyward Eye Prophets", 214, Rarity.UNCOMMON, mage.cards.s.SkywardEyeProphets.class)); cards.add(new SetCardInfo("Slice and Dice", 119, Rarity.UNCOMMON, mage.cards.s.SliceAndDice.class)); - cards.add(new SetCardInfo("Slice in Twain", 170, Rarity.UNCOMMON, mage.cards.s.SliceInXXTwain.class)); + cards.add(new SetCardInfo("Slice in Twain", 170, Rarity.UNCOMMON, mage.cards.s.SliceInTwain.class)); cards.add(new SetCardInfo("Slippery Karst", 324, Rarity.COMMON, mage.cards.s.SlipperyKarst.class)); cards.add(new SetCardInfo("Smoldering Crater", 325, Rarity.COMMON, mage.cards.s.SmolderingCrater.class)); cards.add(new SetCardInfo("Sol Ring", 259, Rarity.UNCOMMON, mage.cards.s.SolRing.class)); diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index ed8f3468ff..95ec338e02 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -31,6 +31,8 @@ public class Ixalan extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; + this.maxCardNumberInBooster = 279; + cards.add(new SetCardInfo("Adanto, the First Fort", 22, Rarity.RARE, mage.cards.a.AdantoTheFirstFort.class)); cards.add(new SetCardInfo("Adanto Vanguard", 1, Rarity.UNCOMMON, mage.cards.a.AdantoVanguard.class)); cards.add(new SetCardInfo("Admiral Beckett Brass", 217, Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); diff --git a/Mage.Sets/src/mage/sets/ScarsOfMirrodin.java b/Mage.Sets/src/mage/sets/ScarsOfMirrodin.java index a2196bb9e8..24db557f77 100644 --- a/Mage.Sets/src/mage/sets/ScarsOfMirrodin.java +++ b/Mage.Sets/src/mage/sets/ScarsOfMirrodin.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.sets; import mage.cards.ExpansionSet; @@ -247,7 +246,7 @@ public class ScarsOfMirrodin extends ExpansionSet { cards.add(new SetCardInfo("Skinrender", 78, Rarity.UNCOMMON, mage.cards.s.Skinrender.class)); cards.add(new SetCardInfo("Skithiryx, the Blight Dragon", 79, Rarity.MYTHIC, mage.cards.s.SkithiryxTheBlightDragon.class)); cards.add(new SetCardInfo("Sky-Eel School", 44, Rarity.COMMON, mage.cards.s.SkyEelSchool.class)); - cards.add(new SetCardInfo("Slice in Twain", 127, Rarity.UNCOMMON, mage.cards.s.SliceInXXTwain.class)); + cards.add(new SetCardInfo("Slice in Twain", 127, Rarity.UNCOMMON, mage.cards.s.SliceInTwain.class)); cards.add(new SetCardInfo("Snapsail Glider", 203, Rarity.COMMON, mage.cards.s.SnapsailGlider.class)); cards.add(new SetCardInfo("Soliton", 204, Rarity.COMMON, mage.cards.s.Soliton.class)); cards.add(new SetCardInfo("Soul Parry", 21, Rarity.COMMON, mage.cards.s.SoulParry.class)); From 88e81896b2d5ecfd71c29f384615957255a880b4 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 10:58:14 +0200 Subject: [PATCH 117/182] Some fixes to white cards. --- Mage.Sets/src/mage/cards/a/AshesOfTheAbhorrent.java | 4 ++-- Mage.Sets/src/mage/cards/b/BishopOfRebirth.java | 9 +++++---- Mage.Sets/src/mage/cards/g/GlorifierOfDusk.java | 6 +++--- Mage.Sets/src/mage/cards/g/GoringCeratops.java | 4 ++-- Mage.Sets/src/mage/cards/i/ImperialAerosaur.java | 5 ++--- Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java | 2 +- Mage.Sets/src/mage/cards/s/SteadfastArmasaur.java | 3 ++- Mage.Sets/src/mage/cards/s/SunriseSeeker.java | 9 ++++++--- 8 files changed, 23 insertions(+), 19 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AshesOfTheAbhorrent.java b/Mage.Sets/src/mage/cards/a/AshesOfTheAbhorrent.java index 6591636360..482cfc09ac 100644 --- a/Mage.Sets/src/mage/cards/a/AshesOfTheAbhorrent.java +++ b/Mage.Sets/src/mage/cards/a/AshesOfTheAbhorrent.java @@ -52,7 +52,7 @@ public class AshesOfTheAbhorrent extends CardImpl { public AshesOfTheAbhorrent(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); - // Players can't cast spells from graveyards or activate abilities from graveyards. + // Players can't cast spells from graveyards or activate abilities of cards in graveyards. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AshesOfTheAbhorrentEffect())); // Whenever a creature dies, you gain 1 life. @@ -73,7 +73,7 @@ class AshesOfTheAbhorrentEffect extends ContinuousRuleModifyingEffectImpl { public AshesOfTheAbhorrentEffect() { super(Duration.WhileOnBattlefield, Outcome.Neutral); - staticText = "Players can't cast spells from graveyards or activate abilities from graveyards"; + staticText = "Players can't cast spells from graveyards or activate abilities of cards in graveyards"; } public AshesOfTheAbhorrentEffect(final AshesOfTheAbhorrentEffect effect) { diff --git a/Mage.Sets/src/mage/cards/b/BishopOfRebirth.java b/Mage.Sets/src/mage/cards/b/BishopOfRebirth.java index f60e12001b..590ac7d9a3 100644 --- a/Mage.Sets/src/mage/cards/b/BishopOfRebirth.java +++ b/Mage.Sets/src/mage/cards/b/BishopOfRebirth.java @@ -36,8 +36,8 @@ import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.ComparisonType; +import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -49,7 +49,7 @@ import mage.target.common.TargetCardInYourGraveyard; * @author TacomenX */ public class BishopOfRebirth extends CardImpl { - + private static final FilterCard filter = new FilterCreatureCard("creature card with converted mana cost 3 or less from your graveyard"); static { @@ -59,7 +59,7 @@ public class BishopOfRebirth extends CardImpl { public BishopOfRebirth(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}"); - + this.subtype.add(SubType.VAMPIRE); this.subtype.add(SubType.CLERIC); this.power = new MageInt(3); @@ -69,7 +69,8 @@ public class BishopOfRebirth extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // Whenever Bishop of Rebirth attacks, you may return target creature card with converted mana cost 3 or less from your graveyard to the battlefield. - Ability ability = new AttacksTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), true); + Ability ability = new AttacksTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect() + .setText("you may return target creature card with converted mana cost 3 or less from your graveyard to the battlefield"), true); ability.addTarget(new TargetCardInYourGraveyard(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GlorifierOfDusk.java b/Mage.Sets/src/mage/cards/g/GlorifierOfDusk.java index 1b7d2659a1..6e27e1ee5e 100644 --- a/Mage.Sets/src/mage/cards/g/GlorifierOfDusk.java +++ b/Mage.Sets/src/mage/cards/g/GlorifierOfDusk.java @@ -34,11 +34,11 @@ import mage.abilities.costs.common.PayLifeCost; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.VigilanceAbility; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.Zone; /** @@ -56,10 +56,10 @@ public class GlorifierOfDusk extends CardImpl { this.toughness = new MageInt(4); // Pay 2 life: Glorifier of Dusk gains flying until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new PayLifeCost(4))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new PayLifeCost(2))); // Pay 2 life: Glorifier of Dusk gains vigilance until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn), new PayLifeCost(4))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn), new PayLifeCost(2))); } public GlorifierOfDusk(final GlorifierOfDusk card) { diff --git a/Mage.Sets/src/mage/cards/g/GoringCeratops.java b/Mage.Sets/src/mage/cards/g/GoringCeratops.java index 9d7b378700..b8a30f1a26 100644 --- a/Mage.Sets/src/mage/cards/g/GoringCeratops.java +++ b/Mage.Sets/src/mage/cards/g/GoringCeratops.java @@ -37,8 +37,8 @@ import mage.abilities.keyword.DoubleStrikeAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.StaticFilters; /** @@ -59,7 +59,7 @@ public class GoringCeratops extends CardImpl { // Whenever Goring Ceratops attacks, other creatures you control gain double strike until end of turn. Effect effect = new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURE, true); - effect.setText("other creatures you control gain double strike"); + effect.setText("other creatures you control gain double strike until end of turn"); Ability ability = new AttacksTriggeredAbility(effect, false); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java b/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java index c7831a9b20..5fbffa9852 100644 --- a/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java +++ b/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java @@ -29,17 +29,16 @@ package mage.cards.i; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.constants.SubType; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.TargetController; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.AnotherPredicate; @@ -72,7 +71,7 @@ public class ImperialAerosaur extends CardImpl { // When Imperial Aerosaur enters the battlefield, another target creature you control gets +1/+1 and gains flying until end of turn. Effect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn); effect.setText("another target creature you control gets +1/+1"); - Ability ability = new EntersBattlefieldTriggeredAbility(effect); + EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(effect); ability.addEffect(effect); effect = new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn); effect.setText("and gains flying until end of turn"); diff --git a/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java b/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java index 84bf9affeb..7e40ff5721 100644 --- a/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java +++ b/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java @@ -78,7 +78,7 @@ public class PriestOfTheWakeningSun extends CardImpl { this.addAbility(ability); // {3}{W}{W}, Sacrifice Priest of the Wakening Sun: Search your library for a Dinosaur card, reveal it, put it into your hand, then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); + TargetCardInLibrary target = new TargetCardInLibrary(filter); Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInHandEffect(new TargetCardInLibrary(target), true, true), new ManaCostsImpl("{3}{W}{W}")); ability2.addCost(new SacrificeSourceCost()); this.addAbility(ability2); diff --git a/Mage.Sets/src/mage/cards/s/SteadfastArmasaur.java b/Mage.Sets/src/mage/cards/s/SteadfastArmasaur.java index e7faecfc71..9c299c382e 100644 --- a/Mage.Sets/src/mage/cards/s/SteadfastArmasaur.java +++ b/Mage.Sets/src/mage/cards/s/SteadfastArmasaur.java @@ -35,11 +35,11 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.SourcePermanentToughnessValue; import mage.abilities.effects.common.DamageTargetEffect; -import mage.constants.SubType; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; @@ -70,6 +70,7 @@ public class SteadfastArmasaur extends CardImpl { Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(SourcePermanentToughnessValue.getInstance()), new ManaCostsImpl("{1}{W}")); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); } public SteadfastArmasaur(final SteadfastArmasaur card) { diff --git a/Mage.Sets/src/mage/cards/s/SunriseSeeker.java b/Mage.Sets/src/mage/cards/s/SunriseSeeker.java index 0ce4951eb7..66deabb826 100644 --- a/Mage.Sets/src/mage/cards/s/SunriseSeeker.java +++ b/Mage.Sets/src/mage/cards/s/SunriseSeeker.java @@ -29,11 +29,13 @@ package mage.cards.s; import java.util.UUID; import mage.MageInt; -import mage.constants.SubType; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.keyword.ExploreSourceEffect; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; /** * @@ -43,7 +45,7 @@ public class SunriseSeeker extends CardImpl { public SunriseSeeker(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); - + this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SCOUT); this.power = new MageInt(3); @@ -52,7 +54,8 @@ public class SunriseSeeker extends CardImpl { // Vigilance this.addAbility(VigilanceAbility.getInstance()); - // When Sunrise Seeker enters the battlefield, it explores. + // When Sunrise Seeker enters the battlefield, it explores. + this.addAbility(new EntersBattlefieldAbility(new ExploreSourceEffect())); } public SunriseSeeker(final SunriseSeeker card) { From cb79fd0514fd34574d8b6a41a3a3cb33c39da586 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 11:11:17 +0200 Subject: [PATCH 118/182] Some fixes to blue cards. --- Mage.Sets/src/mage/cards/o/OneWithTheWind.java | 14 ++++++++------ Mage.Sets/src/mage/cards/t/TempestCaller.java | 6 +++--- Mage.Sets/src/mage/cards/w/WatertrapWeaver.java | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Mage.Sets/src/mage/cards/o/OneWithTheWind.java b/Mage.Sets/src/mage/cards/o/OneWithTheWind.java index a3a3915c01..487892e8eb 100644 --- a/Mage.Sets/src/mage/cards/o/OneWithTheWind.java +++ b/Mage.Sets/src/mage/cards/o/OneWithTheWind.java @@ -28,15 +28,11 @@ package mage.cards.o; import java.util.UUID; -import mage.constants.SubType; -import mage.target.common.TargetCreaturePermanent; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.constants.Outcome; -import mage.target.TargetPermanent; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -44,7 +40,11 @@ import mage.cards.CardSetInfo; import mage.constants.AttachmentType; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; /** * @@ -65,8 +65,10 @@ public class OneWithTheWind extends CardImpl { this.addAbility(ability); // Enchanted creature gets +2/+2 and has flying. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA))); + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield)); + ability.addEffect(new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA) + .setText("and has flying")); + this.addAbility(ability); } public OneWithTheWind(final OneWithTheWind card) { diff --git a/Mage.Sets/src/mage/cards/t/TempestCaller.java b/Mage.Sets/src/mage/cards/t/TempestCaller.java index 1f010148f9..94ee292caa 100644 --- a/Mage.Sets/src/mage/cards/t/TempestCaller.java +++ b/Mage.Sets/src/mage/cards/t/TempestCaller.java @@ -32,11 +32,11 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.TapAllTargetPlayerControlsEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES; +import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; import mage.target.common.TargetOpponent; /** @@ -54,7 +54,7 @@ public class TempestCaller extends CardImpl { this.toughness = new MageInt(3); // When Tempest Caller enters the battlefield, tap all creatures target opponent controls. - Ability ability = new EntersBattlefieldTriggeredAbility(new TapAllTargetPlayerControlsEffect(FILTER_PERMANENT_CREATURES)); + Ability ability = new EntersBattlefieldTriggeredAbility(new TapAllTargetPlayerControlsEffect(new FilterCreaturePermanent("creatures target opponent controls"))); ability.addTarget(new TargetOpponent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/w/WatertrapWeaver.java b/Mage.Sets/src/mage/cards/w/WatertrapWeaver.java index e299a8914d..2820a85eee 100644 --- a/Mage.Sets/src/mage/cards/w/WatertrapWeaver.java +++ b/Mage.Sets/src/mage/cards/w/WatertrapWeaver.java @@ -32,10 +32,10 @@ import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; import mage.abilities.effects.common.TapTargetEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.TargetController; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; @@ -63,7 +63,7 @@ public class WatertrapWeaver extends CardImpl { // When Watertrap Weaver enters the battlefield, tap target creature an opponent controls. That creature doesn't untap during its controller's next untap step. EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect()); - ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect()); + ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect("that creature")); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } From 21c3e2cf02ce79a4279f51376e7797ef7f2a0186 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 11:39:33 +0200 Subject: [PATCH 119/182] Some fixes to black cards. --- Mage.Sets/src/mage/cards/a/AnointedDeacon.java | 11 ++++++----- .../src/mage/cards/b/BishopOfTheBloodstained.java | 8 ++++---- Mage.Sets/src/mage/cards/b/BlightKeeper.java | 4 ++-- Mage.Sets/src/mage/cards/d/DarkNourishment.java | 4 ++-- Mage.Sets/src/mage/cards/d/DeathlessAncient.java | 8 +++++--- Mage.Sets/src/mage/cards/f/FathomFleetCutthroat.java | 3 ++- Mage.Sets/src/mage/cards/l/LurkingChupacabra.java | 3 ++- Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java | 3 ++- Mage.Sets/src/mage/cards/m/MarkOfTheVampire.java | 11 ++++++----- Mage.Sets/src/mage/cards/r/RuthlessKnave.java | 4 ++-- Mage.Sets/src/mage/cards/s/SkymarchBloodletter.java | 4 ++-- .../AttacksCreatureYouControlTriggeredAbility.java | 2 +- 12 files changed, 36 insertions(+), 29 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AnointedDeacon.java b/Mage.Sets/src/mage/cards/a/AnointedDeacon.java index fd6c5757a0..fff9f72130 100644 --- a/Mage.Sets/src/mage/cards/a/AnointedDeacon.java +++ b/Mage.Sets/src/mage/cards/a/AnointedDeacon.java @@ -32,13 +32,12 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BeginningOfCombatTriggeredAbility; import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.constants.*; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; -import mage.target.common.TargetCreaturePermanent; import mage.filter.predicate.mageobject.SubtypePredicate; - +import mage.target.common.TargetCreaturePermanent; /** * @@ -54,14 +53,16 @@ public class AnointedDeacon extends CardImpl { public AnointedDeacon(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); - + this.subtype.add(SubType.VAMPIRE); this.subtype.add(SubType.CLERIC); this.power = new MageInt(3); this.toughness = new MageInt(3); // At the beginning of combat on your turn, you may have target Vampire get +2/+0 until end of turn. - Ability ability = new BeginningOfCombatTriggeredAbility(Zone.BATTLEFIELD, new BoostTargetEffect(2, 0, Duration.EndOfTurn), TargetController.YOU, true, false); + Ability ability = new BeginningOfCombatTriggeredAbility(Zone.BATTLEFIELD, + new BoostTargetEffect(2, 0, Duration.EndOfTurn).setText("you may have target Vampire get +2/+0 until end of turn"), + TargetController.YOU, true, false); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BishopOfTheBloodstained.java b/Mage.Sets/src/mage/cards/b/BishopOfTheBloodstained.java index e0164886e0..d301e788ac 100644 --- a/Mage.Sets/src/mage/cards/b/BishopOfTheBloodstained.java +++ b/Mage.Sets/src/mage/cards/b/BishopOfTheBloodstained.java @@ -33,15 +33,15 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.LoseLifeTargetEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.TargetController; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.permanent.ControllerPredicate; -import mage.target.TargetPlayer; +import mage.target.common.TargetOpponent; /** * @@ -64,9 +64,9 @@ public class BishopOfTheBloodstained extends CardImpl { this.power = new MageInt(3); this.toughness = new MageInt(3); - // When Bishop of the Bloodstained enters the battlefield, target player loses 1 life for each vampire you control. + // When Bishop of the Bloodstained enters the battlefield, target opponent loses 1 life for each vampire you control. Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(new PermanentsOnBattlefieldCount(filter))); - ability.addTarget(new TargetPlayer()); + ability.addTarget(new TargetOpponent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BlightKeeper.java b/Mage.Sets/src/mage/cards/b/BlightKeeper.java index 89303c6d92..b0c7d19305 100644 --- a/Mage.Sets/src/mage/cards/b/BlightKeeper.java +++ b/Mage.Sets/src/mage/cards/b/BlightKeeper.java @@ -36,11 +36,11 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.LoseLifeTargetEffect; -import mage.constants.SubType; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.target.common.TargetOpponent; @@ -63,7 +63,7 @@ public class BlightKeeper extends CardImpl { // {7}{B}, {T}, Sacrifice Blight Keeper: Target opponent loses 4 life and you gain 4 life. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeTargetEffect(4), new ManaCostsImpl("{7}{B}")); - ability.addEffect(new GainLifeEffect(4)); + ability.addEffect(new GainLifeEffect(4).setText("and you gain 4 life")); ability.addTarget(new TargetOpponent()); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/d/DarkNourishment.java b/Mage.Sets/src/mage/cards/d/DarkNourishment.java index a7709f9df8..4ade700f3c 100644 --- a/Mage.Sets/src/mage/cards/d/DarkNourishment.java +++ b/Mage.Sets/src/mage/cards/d/DarkNourishment.java @@ -42,9 +42,9 @@ import mage.target.common.TargetCreatureOrPlayer; public class DarkNourishment extends CardImpl { public DarkNourishment(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{9}{7}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{B}"); - // Dark Nourishment deals 3 damage to target creature or player. You gain 3 life. + // Dark Nourishment deals 3 damage to target creature or player. You gain 3 life. this.getSpellAbility().addEffect(new DamageTargetEffect(3)); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); this.getSpellAbility().addEffect(new GainLifeEffect(3)); diff --git a/Mage.Sets/src/mage/cards/d/DeathlessAncient.java b/Mage.Sets/src/mage/cards/d/DeathlessAncient.java index d1c0ee4ab7..1db85ec80b 100644 --- a/Mage.Sets/src/mage/cards/d/DeathlessAncient.java +++ b/Mage.Sets/src/mage/cards/d/DeathlessAncient.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapTargetCost; -import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -59,7 +59,7 @@ public class DeathlessAncient extends CardImpl { public DeathlessAncient(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); - + this.subtype.add(SubType.VAMPIRE); this.subtype.add(SubType.KNIGHT); this.power = new MageInt(4); @@ -69,7 +69,9 @@ public class DeathlessAncient extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Tap three untapped Vampires you control: Return Deathless Ancient from your graveyard to your hand. - this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnToHandSourceEffect(), new TapTargetCost(new TargetControlledPermanent(3, 3, filter, true)))); + this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, + new ReturnSourceFromGraveyardToHandEffect(), + new TapTargetCost(new TargetControlledPermanent(3, 3, filter, true)))); } diff --git a/Mage.Sets/src/mage/cards/f/FathomFleetCutthroat.java b/Mage.Sets/src/mage/cards/f/FathomFleetCutthroat.java index a20944d0d7..cb3a84b619 100644 --- a/Mage.Sets/src/mage/cards/f/FathomFleetCutthroat.java +++ b/Mage.Sets/src/mage/cards/f/FathomFleetCutthroat.java @@ -32,10 +32,10 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.TargetController; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; @@ -66,6 +66,7 @@ public class FathomFleetCutthroat extends CardImpl { // When Fathom Fleet Cutthroat enters the battlefield, destroy target creature an opponent controls that was dealt damage this turn. Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect(), false); ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); } public FathomFleetCutthroat(final FathomFleetCutthroat card) { diff --git a/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java b/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java index 7f607f32f9..8740ed771a 100644 --- a/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java +++ b/Mage.Sets/src/mage/cards/l/LurkingChupacabra.java @@ -32,11 +32,11 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.effects.common.CreatureExploresTriggeredAbility; import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.TargetController; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; @@ -65,6 +65,7 @@ public class LurkingChupacabra extends CardImpl { // Whenever a creature you control explores, target creature an opponent controls gets -2/-2 until end of turn Ability ability = new CreatureExploresTriggeredAbility(new BoostTargetEffect(-2, -2, Duration.EndOfTurn)); ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); } public LurkingChupacabra(final LurkingChupacabra card) { diff --git a/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java b/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java index f90824d1cd..393917cb02 100644 --- a/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java +++ b/Mage.Sets/src/mage/cards/m/MarchOfTheDrowned.java @@ -29,6 +29,7 @@ package mage.cards.m; import java.util.UUID; import mage.abilities.Mode; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -60,7 +61,7 @@ public class MarchOfTheDrowned extends CardImpl { this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard"))); // &bull; Return two target Pirate cards from your graveyard to your hand. Mode mode = new Mode(); - mode.getEffects().add(new ReturnToHandTargetEffect()); + mode.getEffects().add(new ReturnFromGraveyardToHandTargetEffect()); mode.getTargets().add(new TargetCardInYourGraveyard(2, filter)); this.getSpellAbility().addMode(mode); } diff --git a/Mage.Sets/src/mage/cards/m/MarkOfTheVampire.java b/Mage.Sets/src/mage/cards/m/MarkOfTheVampire.java index 0ffebe20cd..1e19206300 100644 --- a/Mage.Sets/src/mage/cards/m/MarkOfTheVampire.java +++ b/Mage.Sets/src/mage/cards/m/MarkOfTheVampire.java @@ -28,6 +28,7 @@ package mage.cards.m; import java.util.UUID; +import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; @@ -38,9 +39,9 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AttachmentType; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -52,10 +53,9 @@ import mage.target.common.TargetCreaturePermanent; public class MarkOfTheVampire extends CardImpl { public MarkOfTheVampire(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); this.subtype.add(SubType.AURA); - // Enchant creature TargetPermanent target = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(target); @@ -63,8 +63,9 @@ public class MarkOfTheVampire extends CardImpl { this.addAbility(new EnchantAbility(target.getTargetName())); // Enchanted creature gets +2/+2 and has lifelink. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(LifelinkAbility.getInstance(), AttachmentType.AURA))); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield)); + ability.addEffect(new GainAbilityAttachedEffect(LifelinkAbility.getInstance(), AttachmentType.AURA).setText("and has lifelink")); + this.addAbility(ability); } public MarkOfTheVampire(final MarkOfTheVampire card) { diff --git a/Mage.Sets/src/mage/cards/r/RuthlessKnave.java b/Mage.Sets/src/mage/cards/r/RuthlessKnave.java index 76d1c47b70..c78724c8d2 100644 --- a/Mage.Sets/src/mage/cards/r/RuthlessKnave.java +++ b/Mage.Sets/src/mage/cards/r/RuthlessKnave.java @@ -35,10 +35,10 @@ import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledPermanent; @@ -53,7 +53,7 @@ import mage.target.common.TargetControlledPermanent; */ public class RuthlessKnave extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("three other creatures"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("three three Treasures"); static { filter.add(new SubtypePredicate(SubType.TREASURE)); diff --git a/Mage.Sets/src/mage/cards/s/SkymarchBloodletter.java b/Mage.Sets/src/mage/cards/s/SkymarchBloodletter.java index 6e873593d1..ea776f269b 100644 --- a/Mage.Sets/src/mage/cards/s/SkymarchBloodletter.java +++ b/Mage.Sets/src/mage/cards/s/SkymarchBloodletter.java @@ -33,11 +33,11 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.LoseLifeTargetEffect; -import mage.constants.SubType; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.target.Target; import mage.target.common.TargetOpponent; @@ -60,7 +60,7 @@ public class SkymarchBloodletter extends CardImpl { // When Skymarch Bloodletters enters the battlefield, target opponent loses 1 life and you gain 1 life. Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(1), false); - ability.addEffect(new GainLifeEffect(1)); + ability.addEffect(new GainLifeEffect(1).setText("and you gain 1 life")); Target target = new TargetOpponent(); ability.addTarget(target); this.addAbility(ability); diff --git a/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java index 9ec48797fd..37f535e7a5 100644 --- a/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java @@ -102,6 +102,6 @@ public class AttacksCreatureYouControlTriggeredAbility extends TriggeredAbilityI @Override public String getRule() { - return "When" + (once ? "" : "ever") + " a" + (filter.getMessage().startsWith("a") ? "n " : " ") + " attacks, " + super.getRule(); + return "When" + (once ? "" : "ever") + " a" + (filter.getMessage().startsWith("a") ? "n " : " ") + filter.getMessage() + " attacks, " + super.getRule(); } } From d66a9d1693701c9fe42ff424611504a11932feac Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 15:14:21 +0200 Subject: [PATCH 120/182] Some fixes to red cards. --- Mage.Sets/src/mage/cards/l/LightningRigCrew.java | 4 ++-- Mage.Sets/src/mage/cards/s/SunCrownedHunters.java | 2 +- Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java | 2 +- Mage.Sets/src/mage/cards/s/Swashbuckling.java | 14 ++++++++------ .../common/SacrificePermanentTriggeredAbility.java | 2 +- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Mage.Sets/src/mage/cards/l/LightningRigCrew.java b/Mage.Sets/src/mage/cards/l/LightningRigCrew.java index 5efca5ac86..9afcd776e5 100644 --- a/Mage.Sets/src/mage/cards/l/LightningRigCrew.java +++ b/Mage.Sets/src/mage/cards/l/LightningRigCrew.java @@ -35,10 +35,10 @@ import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.common.DamagePlayersEffect; import mage.abilities.effects.common.UntapSourceEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.FilterSpell; @@ -50,7 +50,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate; */ public class LightningRigCrew extends CardImpl { - private static final FilterSpell filter = new FilterSpell(); + private static final FilterSpell filter = new FilterSpell("a Pirate spell"); static { filter.add(new SubtypePredicate(SubType.PIRATE)); diff --git a/Mage.Sets/src/mage/cards/s/SunCrownedHunters.java b/Mage.Sets/src/mage/cards/s/SunCrownedHunters.java index e50d7f7eae..d9fa321f93 100644 --- a/Mage.Sets/src/mage/cards/s/SunCrownedHunters.java +++ b/Mage.Sets/src/mage/cards/s/SunCrownedHunters.java @@ -53,7 +53,7 @@ public class SunCrownedHunters extends CardImpl { this.toughness = new MageInt(4); // Enrage — Whenever Sun-Crowned Hunters is dealt damage, it deals 3 damage to target opponent. - Ability ability = new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), false, true); + Ability ability = new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3, true, "it"), false, true); ability.addTarget(new TargetOpponent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index 37f66ca4e6..aca1f428e3 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -111,7 +111,7 @@ class SunbirdsInvocationEffect extends OneShotEffect { public SunbirdsInvocationEffect() { super(Outcome.PutCardInPlay); - staticText = "Reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; + staticText = "reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; } public SunbirdsInvocationEffect(final SunbirdsInvocationEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/Swashbuckling.java b/Mage.Sets/src/mage/cards/s/Swashbuckling.java index e0315b48b9..1e35c418f0 100644 --- a/Mage.Sets/src/mage/cards/s/Swashbuckling.java +++ b/Mage.Sets/src/mage/cards/s/Swashbuckling.java @@ -28,15 +28,11 @@ package mage.cards.s; import java.util.UUID; -import mage.constants.SubType; -import mage.target.common.TargetCreaturePermanent; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.constants.Outcome; -import mage.target.TargetPermanent; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; @@ -44,7 +40,11 @@ import mage.cards.CardSetInfo; import mage.constants.AttachmentType; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; /** * @@ -65,8 +65,10 @@ public class Swashbuckling extends CardImpl { this.addAbility(ability); // Enchanted creature gets +2/+2 and has haste. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(HasteAbility.getInstance(), AttachmentType.AURA))); + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield)); + ability.addEffect(new GainAbilityAttachedEffect(HasteAbility.getInstance(), AttachmentType.AURA) + .setText("and has haste")); + this.addAbility(ability); } public Swashbuckling(final Swashbuckling card) { diff --git a/Mage/src/main/java/mage/abilities/common/SacrificePermanentTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/SacrificePermanentTriggeredAbility.java index df815bf873..6222095098 100644 --- a/Mage/src/main/java/mage/abilities/common/SacrificePermanentTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/SacrificePermanentTriggeredAbility.java @@ -75,6 +75,6 @@ public class SacrificePermanentTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever you sacrifice" + filter.getMessage() + ", " + super.getRule(); + return "Whenever you sacrifice " + filter.getMessage() + ", " + super.getRule(); } } From afd6bc080df0f47c5297a820180b3312fa2b5bca Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 15:14:52 +0200 Subject: [PATCH 121/182] Removed exception for missing subType to prevent empty card list in older deck editors. --- .../src/main/java/mage/constants/SubType.java | 18 ++++++++--------- Mage/src/main/java/mage/util/SubTypeList.java | 20 ++++++++++--------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index 2cfe62d1e5..755d1ea658 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -4,7 +4,6 @@ import java.util.Arrays; import java.util.EnumSet; import java.util.Set; import java.util.stream.Collectors; - import mage.util.SubTypeList; public enum SubType { @@ -12,7 +11,6 @@ public enum SubType { //205.3k Instants and sorceries share their lists of subtypes; these subtypes are called spell types. ARCANE("Arcane", SubTypeSet.SpellType), TRAP("Trap", SubTypeSet.SpellType), - // 205.3i: Lands have their own unique set of subtypes; these subtypes are called land types. // Of that list, Forest, Island, Mountain, Plains, and Swamp are the basic land types. FOREST("Forest", SubTypeSet.BasicLandType), @@ -28,13 +26,11 @@ public enum SubType { MINE("Mine", SubTypeSet.NonBasicLandType), POWER_PLANT("Power-Plant", SubTypeSet.NonBasicLandType), TOWER("Tower", SubTypeSet.NonBasicLandType), - // 205.3h Enchantments have their own unique set of subtypes; these subtypes are called enchantment types. AURA("Aura", SubTypeSet.EnchantmentType), CARTOUCHE("Cartouche", SubTypeSet.EnchantmentType), CURSE("Curse", SubTypeSet.EnchantmentType), SHRINE("Shrine", SubTypeSet.EnchantmentType), - // 205.3g: Artifacts have their own unique set of subtypes; these subtypes are called artifact types. CLUE("Clue", SubTypeSet.ArtifactType), CONTRAPTION("Contraption", SubTypeSet.ArtifactType), @@ -42,7 +38,6 @@ public enum SubType { FORTIFICATION("Fortification", SubTypeSet.ArtifactType), TREASURE("Treasure", SubTypeSet.ArtifactType), VEHICLE("Vehicle", SubTypeSet.ArtifactType), - // 205.3m : Creatures and tribals share their lists of subtypes; these subtypes are called creature types. // A ADVISOR("Advisor", SubTypeSet.CreatureType), @@ -320,7 +315,7 @@ public enum SubType { TURTLE("Turtle", SubTypeSet.CreatureType), TUSKEN("Tusken", SubTypeSet.CreatureType, true), // Star Wars TROOPER("Trooper", SubTypeSet.CreatureType, true), // Star Wars - TRILOBITE("Trilobite",SubTypeSet.CreatureType), + TRILOBITE("Trilobite", SubTypeSet.CreatureType), TWILEK("Twi'lek", SubTypeSet.CreatureType, true), // Star Wars // U @@ -427,9 +422,12 @@ public enum SubType { return s; } } - throw new IllegalArgumentException("no subtype for " + subType + " exists"); + org.apache.log4j.Logger.getLogger(SubType.class).error("no subtype for " + subType + " exists"); + return null; } + ; + public SubTypeSet getSubTypeSet() { return subTypeSet; } @@ -446,9 +444,9 @@ public enum SubType { public static Set getBasicLands(boolean customSet) { return Arrays.stream(values()) - .filter(p -> p.getSubTypeSet() == SubTypeSet.BasicLandType) - .filter(s -> s.customSet == customSet) - .collect(Collectors.toSet()); + .filter(p -> p.getSubTypeSet() == SubTypeSet.BasicLandType) + .filter(s -> s.customSet == customSet) + .collect(Collectors.toSet()); } public static SubTypeList getLandTypes(boolean customSet) { diff --git a/Mage/src/main/java/mage/util/SubTypeList.java b/Mage/src/main/java/mage/util/SubTypeList.java index 8f90b17a8b..08fc2575ba 100644 --- a/Mage/src/main/java/mage/util/SubTypeList.java +++ b/Mage/src/main/java/mage/util/SubTypeList.java @@ -5,7 +5,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; - import mage.constants.SubType; public class SubTypeList extends ArrayList { @@ -13,30 +12,33 @@ public class SubTypeList extends ArrayList { @Deprecated public boolean addAll(List subtypes) { return addAll(subtypes.stream() - .map(SubType::byDescription) - .collect(Collectors.toList())); + .map(SubType::byDescription) + .collect(Collectors.toList())); } @Deprecated - public boolean removeAll(List subtypes){ + public boolean removeAll(List subtypes) { return removeAll(subtypes.stream() - .map(SubType::byDescription) - .collect(Collectors.toList())); + .map(SubType::byDescription) + .collect(Collectors.toList())); } - public boolean add(SubType... subTypes) { return Collections.addAll(this, subTypes); } public boolean removeAll(SubType... subTypes) { return super.removeAll(Arrays.stream(subTypes) - .collect(Collectors.toList())); + .collect(Collectors.toList())); } @Deprecated public boolean add(String s) { - return add(SubType.byDescription(s)); + SubType subType = SubType.byDescription(s); + if (subType != null) { + return add(subType); + } + return false; } @Deprecated From 092167c55786d4bb913a611821d56a2fb0fd0d67 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 15:40:26 +0200 Subject: [PATCH 122/182] Some fixes to green cards. --- Mage.Sets/src/mage/cards/s/SavageStomp.java | 4 +++- Mage.Sets/src/mage/cards/s/SliceInTwain.java | 2 +- Mage.Sets/src/mage/cards/s/SnappingSailback.java | 6 ++++-- Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java | 2 +- Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java | 6 +++--- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SavageStomp.java b/Mage.Sets/src/mage/cards/s/SavageStomp.java index 1b8b13dd8b..96c8084d4c 100644 --- a/Mage.Sets/src/mage/cards/s/SavageStomp.java +++ b/Mage.Sets/src/mage/cards/s/SavageStomp.java @@ -69,7 +69,9 @@ public class SavageStomp extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}"); // Savage Stomp costs {2} less to cast if it targets a Dinosaur you control. - this.addAbility(new SimpleStaticAbility(Zone.STACK, new SpellCostReductionSourceEffect(2, SavageStompCondition.instance))); + this.addAbility(new SimpleStaticAbility(Zone.STACK, + new SpellCostReductionSourceEffect(2, SavageStompCondition.instance)) + .setRuleAtTheTop(true)); // Put a +1/+1 counter on target creature you control. Then that creature fights target creature you don't control. Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); diff --git a/Mage.Sets/src/mage/cards/s/SliceInTwain.java b/Mage.Sets/src/mage/cards/s/SliceInTwain.java index 91c3ef929a..4e1695832a 100644 --- a/Mage.Sets/src/mage/cards/s/SliceInTwain.java +++ b/Mage.Sets/src/mage/cards/s/SliceInTwain.java @@ -46,7 +46,7 @@ public class SliceInTwain extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}{G}"); this.getSpellAbility().addEffect(new DestroyTargetEffect()); - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("
br>Draw a card")); this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.ARTIFACT_OR_ENCHANTMENT_PERMANENT)); } diff --git a/Mage.Sets/src/mage/cards/s/SnappingSailback.java b/Mage.Sets/src/mage/cards/s/SnappingSailback.java index ff83e86be4..7a7d1468d6 100644 --- a/Mage.Sets/src/mage/cards/s/SnappingSailback.java +++ b/Mage.Sets/src/mage/cards/s/SnappingSailback.java @@ -31,11 +31,11 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.DealtDamageToSourceTriggeredAbility; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.constants.SubType; import mage.abilities.keyword.FlashAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; @@ -56,7 +56,9 @@ public class SnappingSailback extends CardImpl { this.addAbility(FlashAbility.getInstance()); // Enrage — Whenever Snapping Sailback is dealt damage, put a +1/+1 counter on it. - this.addAbility(new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), false)); + this.addAbility(new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, + new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)) + .setText("put a +1/+1 counter on it"), false)); } public SnappingSailback(final SnappingSailback card) { diff --git a/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java b/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java index 962f98a54a..7a75f45fd1 100644 --- a/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java +++ b/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java @@ -52,7 +52,7 @@ import mage.players.Player; public class VerdantSunsAvatar extends CardImpl { public VerdantSunsAvatar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}"); this.subtype.add(SubType.DINOSAUR); this.subtype.add(SubType.AVATAR); diff --git a/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java b/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java index f8cc6944ab..f9cbcd3f23 100644 --- a/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java +++ b/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java @@ -39,8 +39,8 @@ import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.common.FilterControlledLandPermanent; @@ -62,10 +62,10 @@ public class WakerOfTheWilds extends CardImpl { this.toughness = new MageInt(3); // {X}{G}{G}: Put X +1/+1 counters on target land you control. That land becomes a 0/0 Elemental creature with haste that's still a land. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance(0), new ManacostVariableValue()), new ManaCostsImpl("{X}{G}{G}")); Effect effect = new BecomesCreatureTargetEffect(new WallOfResurgenceToken(), false, true, Duration.Custom); - effect.setText("That land becomes a 0/0 Elemental creature with haste that's still a land"); + effect.setText("That land becomes a 0/0 Elemental creature with haste. It's still a land"); ability.addEffect(effect); ability.addTarget(new TargetControlledPermanent(new FilterControlledLandPermanent())); this.addAbility(ability); From 563856434d697af2642c04eaf262cade24b11ab8 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 16:03:12 +0200 Subject: [PATCH 123/182] Some more minor fixes. --- Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java | 3 ++- Mage.Sets/src/mage/cards/c/ConquerorsFoothold.java | 4 ++-- Mage.Sets/src/mage/cards/d/DireFleetCaptain.java | 3 ++- Mage.Sets/src/mage/cards/f/FieldOfRuin.java | 13 ++++--------- Mage.Sets/src/mage/cards/j/JacesSentinel.java | 1 + .../SearchLibraryGraveyardPutInHandEffect.java | 4 ++-- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java index a5554dd505..77f6f60025 100644 --- a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java +++ b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java @@ -85,7 +85,8 @@ public class AdmiralBeckettBrass extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); // At the beginning of your end step, gain control of target nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn. - Ability ability = new BeginningOfEndStepTriggeredAbility(new GainControlTargetEffect(Duration.Custom), TargetController.YOU, false); + Ability ability = new BeginningOfEndStepTriggeredAbility(new GainControlTargetEffect(Duration.Custom) + .setText("gain control of target nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn"), TargetController.YOU, false); ability.addTarget(new TargetNonlandPermanent()); originalId = ability.getOriginalId(); this.addAbility(ability, new DamagedByPiratesWatcher()); diff --git a/Mage.Sets/src/mage/cards/c/ConquerorsFoothold.java b/Mage.Sets/src/mage/cards/c/ConquerorsFoothold.java index 0c50dac919..13c53d85bf 100644 --- a/Mage.Sets/src/mage/cards/c/ConquerorsFoothold.java +++ b/Mage.Sets/src/mage/cards/c/ConquerorsFoothold.java @@ -33,7 +33,7 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawDiscardControllerEffect; -import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -71,7 +71,7 @@ public class ConquerorsFoothold extends CardImpl { // {6}, {T}: Return target card from your graveyard to your hand. SimpleActivatedAbility ability3 = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new ReturnToHandTargetEffect(), + new ReturnFromGraveyardToHandTargetEffect(), new ManaCostsImpl("{6}")); ability3.addCost(new TapSourceCost()); ability3.addTarget(new TargetCardInYourGraveyard()); diff --git a/Mage.Sets/src/mage/cards/d/DireFleetCaptain.java b/Mage.Sets/src/mage/cards/d/DireFleetCaptain.java index e264cc78fa..cf82dab875 100644 --- a/Mage.Sets/src/mage/cards/d/DireFleetCaptain.java +++ b/Mage.Sets/src/mage/cards/d/DireFleetCaptain.java @@ -64,7 +64,8 @@ public class DireFleetCaptain extends CardImpl { // Whenever Dire Fleet Captain attacks, it gets +1/+1 until end of turn for each other attacking Pirate. PermanentsOnBattlefieldCount value = new PermanentsOnBattlefieldCount(filter); - this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(value, value, Duration.EndOfTurn, true), false)); + this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(value, value, Duration.EndOfTurn, true) + .setText("it gets +1/+1 until end of turn for each other attacking Pirate"), false)); } public DireFleetCaptain(final DireFleetCaptain card) { diff --git a/Mage.Sets/src/mage/cards/f/FieldOfRuin.java b/Mage.Sets/src/mage/cards/f/FieldOfRuin.java index ccd0cc0f34..93cce26254 100644 --- a/Mage.Sets/src/mage/cards/f/FieldOfRuin.java +++ b/Mage.Sets/src/mage/cards/f/FieldOfRuin.java @@ -36,9 +36,9 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.mana.ColorlessManaAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SuperType; @@ -79,6 +79,7 @@ public class FieldOfRuin extends CardImpl { ability.addCost(new SacrificeSourceCost()); ability.addEffect(new FieldOfRuinEffect()); ability.addTarget(new TargetLandPermanent(filter)); + this.addAbility(ability); } public FieldOfRuin(final FieldOfRuin card) { @@ -95,7 +96,7 @@ class FieldOfRuinEffect extends OneShotEffect { FieldOfRuinEffect() { super(Outcome.Benefit); - this.staticText = "Each player searches his or her library for a basic land card, puts it onto the battlefield, then shuffles his or her library."; + this.staticText = "Each player searches his or her library for a basic land card, puts it onto the battlefield, then shuffles his or her library"; } FieldOfRuinEffect(final FieldOfRuinEffect effect) { @@ -116,13 +117,7 @@ class FieldOfRuinEffect extends OneShotEffect { if (player != null) { TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD); if (player.searchLibrary(target, game)) { - for (UUID cardId : target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); - if (card != null) { - card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId()); - } - - } + player.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); player.shuffleLibrary(source, game); } } diff --git a/Mage.Sets/src/mage/cards/j/JacesSentinel.java b/Mage.Sets/src/mage/cards/j/JacesSentinel.java index dfdedbaa66..a9288ece7d 100644 --- a/Mage.Sets/src/mage/cards/j/JacesSentinel.java +++ b/Mage.Sets/src/mage/cards/j/JacesSentinel.java @@ -78,6 +78,7 @@ public class JacesSentinel extends CardImpl { new CantBeBlockedSourceEffect(), new PermanentsOnTheBattlefieldCondition(filter), "and has can't be blocked")); + this.addAbility(ability); } public JacesSentinel(final JacesSentinel card) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryGraveyardPutInHandEffect.java b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryGraveyardPutInHandEffect.java index cba730ab17..f540608e80 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryGraveyardPutInHandEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryGraveyardPutInHandEffect.java @@ -57,8 +57,8 @@ public class SearchLibraryGraveyardPutInHandEffect extends OneShotEffect { super(Outcome.Benefit); this.filter = filter; this.forceToSearchBoth = forceToSearchBoth; - staticText = "Search your library and" + (forceToSearchBoth ? "" : "/or ") + " graveyard for a card named " + filter.getMessage() + - ", reveal it, and put it into your hand. " + (forceToSearchBoth ? "Then shuffle your library" : "If you search your library this way, shuffle it"); + staticText = "search your library and" + (forceToSearchBoth ? "" : "/or ") + " graveyard for a card named " + filter.getMessage() + + ", reveal it, and put it into your hand. " + (forceToSearchBoth ? "Then shuffle your library" : "If you search your library this way, shuffle it"); } public SearchLibraryGraveyardPutInHandEffect(final SearchLibraryGraveyardPutInHandEffect effect) { From 0b574dd6f2da6583f87c0a74e3eb74ec4a801a65 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 10:24:35 -0400 Subject: [PATCH 124/182] Added TODO notes for cards with activated abilities that rely on adjustTargets and therefore can't be copied correctly (Mairsil, etc). Gonna work on this in a separate branch --- Mage.Sets/src/mage/cards/a/AlexiZephyrMage.java | 1 + Mage.Sets/src/mage/cards/a/AncientHellkite.java | 1 + Mage.Sets/src/mage/cards/c/CandelabraOfTawnos.java | 1 + Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java | 1 + Mage.Sets/src/mage/cards/c/CrownOfDoom.java | 1 + Mage.Sets/src/mage/cards/c/CuombajjWitches.java | 1 + Mage.Sets/src/mage/cards/d/DeclarationOfNaught.java | 1 + Mage.Sets/src/mage/cards/d/DeepfireElemental.java | 1 + Mage.Sets/src/mage/cards/f/FloodwaterDam.java | 1 + Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java | 1 + Mage.Sets/src/mage/cards/g/GorillaShaman.java | 1 + Mage.Sets/src/mage/cards/h/HakimLoreweaver.java | 1 + Mage.Sets/src/mage/cards/h/HearthKami.java | 1 + Mage.Sets/src/mage/cards/h/HopeOfGhirapur.java | 1 + Mage.Sets/src/mage/cards/l/LinessaZephyrMage.java | 1 + Mage.Sets/src/mage/cards/m/MagusOfTheCandelabra.java | 1 + Mage.Sets/src/mage/cards/m/MartyrOfBones.java | 1 + Mage.Sets/src/mage/cards/m/MinamoSightbender.java | 1 + Mage.Sets/src/mage/cards/m/MishrasHelix.java | 1 + Mage.Sets/src/mage/cards/n/NecropolisFiend.java | 1 + Mage.Sets/src/mage/cards/p/Plaguebearer.java | 1 + Mage.Sets/src/mage/cards/q/QuillmaneBaku.java | 1 + Mage.Sets/src/mage/cards/s/SynodArtificer.java | 1 + 23 files changed, 23 insertions(+) diff --git a/Mage.Sets/src/mage/cards/a/AlexiZephyrMage.java b/Mage.Sets/src/mage/cards/a/AlexiZephyrMage.java index 97b927b056..bd8ff13e1c 100644 --- a/Mage.Sets/src/mage/cards/a/AlexiZephyrMage.java +++ b/Mage.Sets/src/mage/cards/a/AlexiZephyrMage.java @@ -70,6 +70,7 @@ public class AlexiZephyrMage extends CardImpl { this.power = new MageInt(3); this.toughness = new MageInt(3); + //TODO: Make ability properly copiable // {X}{U}, {tap}, Discard two cards: Return X target creatures to their owners' hands. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{X}{U}")); ability.addCost(new TapSourceCost()); diff --git a/Mage.Sets/src/mage/cards/a/AncientHellkite.java b/Mage.Sets/src/mage/cards/a/AncientHellkite.java index bb830ed973..13b83e4168 100644 --- a/Mage.Sets/src/mage/cards/a/AncientHellkite.java +++ b/Mage.Sets/src/mage/cards/a/AncientHellkite.java @@ -60,6 +60,7 @@ public class AncientHellkite extends CardImpl { this.power = new MageInt(6); this.toughness = new MageInt(6); + //TODO: Make ability properly copiable this.addAbility(FlyingAbility.getInstance()); Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{R}"), SourceAttackingCondition.instance); ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls"))); diff --git a/Mage.Sets/src/mage/cards/c/CandelabraOfTawnos.java b/Mage.Sets/src/mage/cards/c/CandelabraOfTawnos.java index a203852f83..2d85919813 100644 --- a/Mage.Sets/src/mage/cards/c/CandelabraOfTawnos.java +++ b/Mage.Sets/src/mage/cards/c/CandelabraOfTawnos.java @@ -53,6 +53,7 @@ public class CandelabraOfTawnos extends CardImpl { public CandelabraOfTawnos(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}"); + //TODO: Make ability properly copiable // {X}, {T}: Untap X target lands. Effect effect = new UntapTargetEffect(); effect.setText("untap X target lands"); diff --git a/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java b/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java index 00a524ad1b..459920fa24 100644 --- a/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java +++ b/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java @@ -75,6 +75,7 @@ public class ChampionOfStraySouls extends CardImpl { * ability, before you pay any costs. You can't target any of the * creatures you sacrifice. */ + //TODO: Make ability properly copiable // {3}{B}{B}, {T}, Sacrifice X other creatures: Return X target creatures from your graveyard to the battlefield. Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect(); effect.setText("Return X target creatures from your graveyard to the battlefield"); diff --git a/Mage.Sets/src/mage/cards/c/CrownOfDoom.java b/Mage.Sets/src/mage/cards/c/CrownOfDoom.java index 3a447de9f2..f5417c9a11 100644 --- a/Mage.Sets/src/mage/cards/c/CrownOfDoom.java +++ b/Mage.Sets/src/mage/cards/c/CrownOfDoom.java @@ -68,6 +68,7 @@ public class CrownOfDoom extends CardImpl { effect.setText("it gets +2/+0 until end of turn"); this.addAbility(new AttacksAllTriggeredAbility(effect, false, StaticFilters.FILTER_PERMANENT_CREATURE, SetTargetPointer.PERMANENT, true)); + //TODO: Make ability properly copiable // {2}: Target player other than Crown of Doom's owner gains control of it. Activate this ability only during your turn. Ability ability = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new CrownOfDoomEffect(), new ManaCostsImpl("{2}"), MyTurnCondition.instance); ability.addTarget(new TargetPlayer(1, 1, false, new FilterPlayer("player other than Crown of Doom's owner"))); diff --git a/Mage.Sets/src/mage/cards/c/CuombajjWitches.java b/Mage.Sets/src/mage/cards/c/CuombajjWitches.java index 2cb334d4f7..f4ea8c4cf1 100644 --- a/Mage.Sets/src/mage/cards/c/CuombajjWitches.java +++ b/Mage.Sets/src/mage/cards/c/CuombajjWitches.java @@ -62,6 +62,7 @@ public class CuombajjWitches extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(3); + //TODO: Make ability properly copiable // {T}: Cuombajj Witches deals 1 damage to target creature or player and 1 damage to target creature or player of an opponent's choice. Effect effect = new DamageTargetEffect(1); effect.setText("{this} deals 1 damage to target creature or player and 1 damage to target creature or player of an opponent's choice"); diff --git a/Mage.Sets/src/mage/cards/d/DeclarationOfNaught.java b/Mage.Sets/src/mage/cards/d/DeclarationOfNaught.java index afd5f0c8ca..b0fb8f6405 100644 --- a/Mage.Sets/src/mage/cards/d/DeclarationOfNaught.java +++ b/Mage.Sets/src/mage/cards/d/DeclarationOfNaught.java @@ -58,6 +58,7 @@ public class DeclarationOfNaught extends CardImpl { // As Declaration of Naught enters the battlefield, name a card. this.addAbility(new AsEntersBattlefieldAbility(new NameACardEffect(NameACardEffect.TypeOfName.ALL))); + //TODO: Make ability properly copiable // {U}: Counter target spell with the chosen name. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(), new ManaCostsImpl("{U}")); ability.addTarget(new TargetSpell(filter)); diff --git a/Mage.Sets/src/mage/cards/d/DeepfireElemental.java b/Mage.Sets/src/mage/cards/d/DeepfireElemental.java index f4e4f95ecb..60ed530eb7 100644 --- a/Mage.Sets/src/mage/cards/d/DeepfireElemental.java +++ b/Mage.Sets/src/mage/cards/d/DeepfireElemental.java @@ -68,6 +68,7 @@ public class DeepfireElemental extends CardImpl { this.power = new MageInt(4); this.toughness = new MageInt(4); + //TODO: Make ability properly copiable // {X}{X}{1}: Destroy target artifact or creature with converted mana cost X. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{X}{X}{1}")); ability.addTarget(new TargetPermanent(filter)); diff --git a/Mage.Sets/src/mage/cards/f/FloodwaterDam.java b/Mage.Sets/src/mage/cards/f/FloodwaterDam.java index dc1340b577..10f6e12d9b 100644 --- a/Mage.Sets/src/mage/cards/f/FloodwaterDam.java +++ b/Mage.Sets/src/mage/cards/f/FloodwaterDam.java @@ -53,6 +53,7 @@ public class FloodwaterDam extends CardImpl { public FloodwaterDam(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + //TODO: Make ability properly copiable // {X}{X}{1}, {tap}: Tap X target lands. Effect effect = new TapTargetEffect(); effect.setText("tap X target lands"); diff --git a/Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java b/Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java index 46b50fe457..2972eaff42 100644 --- a/Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java +++ b/Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java @@ -69,6 +69,7 @@ public class GethLordOfTheVault extends CardImpl { // Intimidate this.addAbility(IntimidateAbility.getInstance()); + //TODO: Make ability properly copiable // {X}{B}: Put target artifact or creature card with converted mana cost X from an opponent's graveyard onto the battlefield under your control tapped. // Then that player puts the top X cards of his or her library into his or her graveyard. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GethLordOfTheVaultEffect(), new ManaCostsImpl("{X}{B}")); diff --git a/Mage.Sets/src/mage/cards/g/GorillaShaman.java b/Mage.Sets/src/mage/cards/g/GorillaShaman.java index fd7b5bc985..96ce257d6f 100644 --- a/Mage.Sets/src/mage/cards/g/GorillaShaman.java +++ b/Mage.Sets/src/mage/cards/g/GorillaShaman.java @@ -62,6 +62,7 @@ public class GorillaShaman extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(1); + //TODO: Make ability properly copiable // {X}{X}{1}: Destroy target noncreature artifact with converted mana cost X. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{X}{X}{1}")); ability.addTarget(new TargetPermanent(new FilterArtifactPermanent("noncreature artifact with converted mana cost X"))); diff --git a/Mage.Sets/src/mage/cards/h/HakimLoreweaver.java b/Mage.Sets/src/mage/cards/h/HakimLoreweaver.java index 1e0edfe2d0..1b3082b518 100644 --- a/Mage.Sets/src/mage/cards/h/HakimLoreweaver.java +++ b/Mage.Sets/src/mage/cards/h/HakimLoreweaver.java @@ -81,6 +81,7 @@ public class HakimLoreweaver extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); + //TODO: Make ability properly copiable // {U}{U}: Return target Aura card from your graveyard to the battlefield attached to Hakim, Loreweaver. Activate this ability only during your upkeep and only if Hakim isn't enchanted. Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new HakimLoreweaverEffect(), new ManaCostsImpl("{U}{U}"), new HakimLoreweaverCondition(), rule); ability.addTarget(new TargetCardInYourGraveyard()); diff --git a/Mage.Sets/src/mage/cards/h/HearthKami.java b/Mage.Sets/src/mage/cards/h/HearthKami.java index f9b6d38f2a..636785d695 100644 --- a/Mage.Sets/src/mage/cards/h/HearthKami.java +++ b/Mage.Sets/src/mage/cards/h/HearthKami.java @@ -60,6 +60,7 @@ public class HearthKami extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(1); + //TODO: Make ability properly copiable // {X}, Sacrifice Hearth Kami: Destroy target artifact with converted mana cost X. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{X}")); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/h/HopeOfGhirapur.java b/Mage.Sets/src/mage/cards/h/HopeOfGhirapur.java index 51502d1549..07c212e770 100644 --- a/Mage.Sets/src/mage/cards/h/HopeOfGhirapur.java +++ b/Mage.Sets/src/mage/cards/h/HopeOfGhirapur.java @@ -70,6 +70,7 @@ public class HopeOfGhirapur extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); + //TODO: Make ability properly copiable // Sacrifice Hope of Ghirapur: Until your next turn, target player who was dealt combat damage by Hope of Ghirapur this turn can't cast noncreature spells. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HopeOfGhirapurCantCastEffect(), new SacrificeSourceCost()); ability.addTarget(new TargetPlayer()); diff --git a/Mage.Sets/src/mage/cards/l/LinessaZephyrMage.java b/Mage.Sets/src/mage/cards/l/LinessaZephyrMage.java index f1b2d931d3..a3d8e126ca 100644 --- a/Mage.Sets/src/mage/cards/l/LinessaZephyrMage.java +++ b/Mage.Sets/src/mage/cards/l/LinessaZephyrMage.java @@ -74,6 +74,7 @@ public class LinessaZephyrMage extends CardImpl { this.power = new MageInt(3); this.toughness = new MageInt(3); + //TODO: Make ability properly copiable // {X}{U}{U}, {tap}: Return target creature with converted mana cost X to its owner's hand. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{X}{U}{U}")); ability.addCost(new TapSourceCost()); diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheCandelabra.java b/Mage.Sets/src/mage/cards/m/MagusOfTheCandelabra.java index 16507b49f1..c9a584d835 100644 --- a/Mage.Sets/src/mage/cards/m/MagusOfTheCandelabra.java +++ b/Mage.Sets/src/mage/cards/m/MagusOfTheCandelabra.java @@ -59,6 +59,7 @@ public class MagusOfTheCandelabra extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(2); + //TODO: Make ability properly copiable // {X}, {T}: Untap X target lands. Effect effect = new UntapTargetEffect(); effect.setText("untap X target lands"); diff --git a/Mage.Sets/src/mage/cards/m/MartyrOfBones.java b/Mage.Sets/src/mage/cards/m/MartyrOfBones.java index eeda1f3e4d..ef14fb0c7c 100644 --- a/Mage.Sets/src/mage/cards/m/MartyrOfBones.java +++ b/Mage.Sets/src/mage/cards/m/MartyrOfBones.java @@ -68,6 +68,7 @@ public class MartyrOfBones extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(1); + //TODO: Make ability properly copiable // {1}, Reveal X black cards from your hand, Sacrifice Martyr of Bones: Exile up to X target cards from a single graveyard. Effect effect = new ExileTargetEffect(null, null, Zone.GRAVEYARD); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(1)); diff --git a/Mage.Sets/src/mage/cards/m/MinamoSightbender.java b/Mage.Sets/src/mage/cards/m/MinamoSightbender.java index 9c7326c9a3..2b58cb8755 100644 --- a/Mage.Sets/src/mage/cards/m/MinamoSightbender.java +++ b/Mage.Sets/src/mage/cards/m/MinamoSightbender.java @@ -64,6 +64,7 @@ public class MinamoSightbender extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(2); + //TODO: Make ability properly copiable // {X}, {T}: Target creature with power X or less can't be blocked this turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBeBlockedTargetEffect(), new ManaCostsImpl("{X}")); Target target = new TargetCreaturePermanent(filter); diff --git a/Mage.Sets/src/mage/cards/m/MishrasHelix.java b/Mage.Sets/src/mage/cards/m/MishrasHelix.java index 3e5e464bc4..c8beab689b 100644 --- a/Mage.Sets/src/mage/cards/m/MishrasHelix.java +++ b/Mage.Sets/src/mage/cards/m/MishrasHelix.java @@ -53,6 +53,7 @@ public class MishrasHelix extends CardImpl { public MishrasHelix(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}"); + //TODO: Make ability properly copiable // {X}, {tap}: Tap X target lands. Effect effect = new TapTargetEffect("X target lands"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}")); diff --git a/Mage.Sets/src/mage/cards/n/NecropolisFiend.java b/Mage.Sets/src/mage/cards/n/NecropolisFiend.java index eda396ee11..6ddb06b9ed 100644 --- a/Mage.Sets/src/mage/cards/n/NecropolisFiend.java +++ b/Mage.Sets/src/mage/cards/n/NecropolisFiend.java @@ -74,6 +74,7 @@ public class NecropolisFiend extends CardImpl { this.addAbility(new DelveAbility()); // Flying this.addAbility(FlyingAbility.getInstance()); + //TODO: Make ability properly copiable // {X}, {T}, Exile X cards from your graveyard: Target creature gets -X/-X until end of turn. DynamicValue xValue = new SignInversionDynamicValue(new ManacostVariableValue()); Effect effect = new BoostTargetEffect(xValue,xValue,Duration.EndOfTurn); diff --git a/Mage.Sets/src/mage/cards/p/Plaguebearer.java b/Mage.Sets/src/mage/cards/p/Plaguebearer.java index 7749ad75d4..e308d6b8ee 100644 --- a/Mage.Sets/src/mage/cards/p/Plaguebearer.java +++ b/Mage.Sets/src/mage/cards/p/Plaguebearer.java @@ -67,6 +67,7 @@ public class Plaguebearer extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(1); + //TODO: Make ability properly copiable // {X}{X}{B}: Destroy target nonblack creature with converted mana cost X. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{X}{X}{B}")); ability.addTarget(new TargetPermanent(filter)); diff --git a/Mage.Sets/src/mage/cards/q/QuillmaneBaku.java b/Mage.Sets/src/mage/cards/q/QuillmaneBaku.java index 2d72cae907..7efe835b4e 100644 --- a/Mage.Sets/src/mage/cards/q/QuillmaneBaku.java +++ b/Mage.Sets/src/mage/cards/q/QuillmaneBaku.java @@ -71,6 +71,7 @@ public class QuillmaneBaku extends CardImpl { // Whenever you cast a Spirit or Arcane spell, you may put a ki counter on Skullmane Baku. this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.KI.createInstance()), StaticFilters.SPIRIT_OR_ARCANE_CARD, true)); + //TODO: Make ability properly copiable // {1}, Tap, Remove X ki counters from Quillmane Baku: Return target creature with converted mana cost X or less to its owner's hand. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new QuillmaneBakuReturnEffect(), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); diff --git a/Mage.Sets/src/mage/cards/s/SynodArtificer.java b/Mage.Sets/src/mage/cards/s/SynodArtificer.java index 98ab8fcfa5..bd0ac7cc02 100644 --- a/Mage.Sets/src/mage/cards/s/SynodArtificer.java +++ b/Mage.Sets/src/mage/cards/s/SynodArtificer.java @@ -69,6 +69,7 @@ public class SynodArtificer extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(2); + //TODO: Make ability properly copiable // {X}, {tap}: Tap X target noncreature artifacts. Effect tapEffect = new TapTargetEffect(); tapEffect.setText("Tap X target noncreature artifacts."); From 2d6bcd83f4c6f4acb60f1027afaf5206266861fb Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 16:55:58 +0200 Subject: [PATCH 125/182] xmage 1.4.26V4 --- Mage.Common/src/main/java/mage/utils/MageVersion.java | 2 +- .../src/mage/player/human/HumanPlayer.java | 6 ++++-- .../src/main/java/mage/cards/repository/CardRepository.java | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java index 0b45f8ca40..e0c0a9435a 100644 --- a/Mage.Common/src/main/java/mage/utils/MageVersion.java +++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java @@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable { public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MINOR = 4; public final static int MAGE_VERSION_PATCH = 26; - public final static String MAGE_VERSION_MINOR_PATCH = "V3"; + public final static String MAGE_VERSION_MINOR_PATCH = "V4"; public final static String MAGE_VERSION_INFO = ""; private final int major; diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index 751e1739d2..69e89b0c08 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -1112,8 +1112,10 @@ public class HumanPlayer extends PlayerImpl { // attack selected default defender declareAttacker(attacker.getId(), attackedDefender, game, false); } -// } else if (response.getInteger() != null) { // Ok or F-Key - + } else if (response.getInteger() != null) { // F-Key + if (checkIfAttackersValid(game)) { + return; + } } else if (response.getBoolean() != null) { // ok button if (checkIfAttackersValid(game)) { return; diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index 8224840662..36a866cf23 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -58,7 +58,7 @@ public enum CardRepository { // raise this if db structure was changed private static final long CARD_DB_VERSION = 51; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 90; + private static final long CARD_CONTENT_VERSION = 91; private Dao cardDao; private Set classNames; From 99caa2858d71e5fb99f6d8e3f7c4c0a4c178afed Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 13:06:40 -0400 Subject: [PATCH 126/182] Implemented Survivor of the Unseen --- Mage.Sets/src/mage/cards/s/SliceInTwain.java | 61 --------- .../src/mage/cards/s/SurvivorOfTheUnseen.java | 118 ++++++++++++++++++ Mage.Sets/src/mage/sets/Coldsnap.java | 1 + 3 files changed, 119 insertions(+), 61 deletions(-) delete mode 100644 Mage.Sets/src/mage/cards/s/SliceInTwain.java create mode 100644 Mage.Sets/src/mage/cards/s/SurvivorOfTheUnseen.java diff --git a/Mage.Sets/src/mage/cards/s/SliceInTwain.java b/Mage.Sets/src/mage/cards/s/SliceInTwain.java deleted file mode 100644 index 4e1695832a..0000000000 --- a/Mage.Sets/src/mage/cards/s/SliceInTwain.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of BetaSteward_at_googlemail.com. - */ -package mage.cards.s; - -import java.util.UUID; -import mage.abilities.effects.common.DestroyTargetEffect; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.filter.StaticFilters; -import mage.target.TargetPermanent; - -/** - * - * @author Loki - */ -public class SliceInTwain extends CardImpl { - - public SliceInTwain(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}{G}"); - - this.getSpellAbility().addEffect(new DestroyTargetEffect()); - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("
br>Draw a card")); - this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.ARTIFACT_OR_ENCHANTMENT_PERMANENT)); - } - - public SliceInTwain(final SliceInTwain card) { - super(card); - } - - @Override - public SliceInTwain copy() { - return new SliceInTwain(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SurvivorOfTheUnseen.java b/Mage.Sets/src/mage/cards/s/SurvivorOfTheUnseen.java new file mode 100644 index 0000000000..cf4c4bade3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SurvivorOfTheUnseen.java @@ -0,0 +1,118 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.constants.SubType; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInHand; + +/** + * + * @author TheElk801 + */ +public class SurvivorOfTheUnseen extends CardImpl { + + public SurvivorOfTheUnseen(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Cumulative upkeep {2} + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{2}"))); + + // {T}: Draw two cards, then put a card from your hand on top of your library. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new SurvivorOfTheUnseenEffect(), new TapSourceCost())); + } + + public SurvivorOfTheUnseen(final SurvivorOfTheUnseen card) { + super(card); + } + + @Override + public SurvivorOfTheUnseen copy() { + return new SurvivorOfTheUnseen(this); + } +} + +class SurvivorOfTheUnseenEffect extends OneShotEffect { + + public SurvivorOfTheUnseenEffect() { + super(Outcome.DrawCard); + staticText = "Draw two cards, then put a card from your hand on top of your library"; + } + + public SurvivorOfTheUnseenEffect(final SurvivorOfTheUnseenEffect effect) { + super(effect); + } + + @Override + public SurvivorOfTheUnseenEffect copy() { + return new SurvivorOfTheUnseenEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + player.drawCards(2, game); + putOnLibrary(player, source, game); + return true; + } + return false; + } + + private boolean putOnLibrary(Player player, Ability source, Game game) { + TargetCardInHand target = new TargetCardInHand(); + if (target.canChoose(source.getSourceId(), player.getId(), game)) { + player.chooseTarget(Outcome.ReturnToHand, target, source, game); + Card card = player.getHand().get(target.getFirstTarget(), game); + if (card != null) { + return player.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.HAND, true, false); + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Coldsnap.java b/Mage.Sets/src/mage/sets/Coldsnap.java index 2560657144..ee0b109eb1 100644 --- a/Mage.Sets/src/mage/sets/Coldsnap.java +++ b/Mage.Sets/src/mage/sets/Coldsnap.java @@ -167,6 +167,7 @@ public class Coldsnap extends ExpansionSet { cards.add(new SetCardInfo("Surging Flame", 99, Rarity.COMMON, mage.cards.s.SurgingFlame.class)); cards.add(new SetCardInfo("Surging Might", 125, Rarity.COMMON, mage.cards.s.SurgingMight.class)); cards.add(new SetCardInfo("Surging Sentinels", 20, Rarity.COMMON, mage.cards.s.SurgingSentinels.class)); + cards.add(new SetCardInfo("Survivor of the Unseen", 48, Rarity.COMMON, mage.cards.s.SurvivorOfTheUnseen.class)); cards.add(new SetCardInfo("Swift Maneuver", 21, Rarity.COMMON, mage.cards.s.SwiftManeuver.class)); cards.add(new SetCardInfo("Tamanoa", 132, Rarity.RARE, mage.cards.t.Tamanoa.class)); cards.add(new SetCardInfo("Thermopod", 100, Rarity.COMMON, mage.cards.t.Thermopod.class)); From 33aefec8d00389418acbbdc20e2f50d6ce0e2b61 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 13:11:47 -0400 Subject: [PATCH 127/182] Implemented Foresight --- Mage.Sets/src/mage/cards/f/Foresight.java | 109 +++++++++++++++++++ Mage.Sets/src/mage/cards/s/SliceinTwain.java | 63 ----------- Mage.Sets/src/mage/sets/Alliances.java | 1 + 3 files changed, 110 insertions(+), 63 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/f/Foresight.java delete mode 100644 Mage.Sets/src/mage/cards/s/SliceinTwain.java diff --git a/Mage.Sets/src/mage/cards/f/Foresight.java b/Mage.Sets/src/mage/cards/f/Foresight.java new file mode 100644 index 0000000000..19bd5aa71e --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/Foresight.java @@ -0,0 +1,109 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.delayed.AtTheBeginOfNextUpkeepDelayedTriggeredAbility; +import mage.abilities.effects.SearchEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class Foresight extends CardImpl { + + public Foresight(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}"); + + // Search your library for three cards, exile them, then shuffle your library. + this.getSpellAbility().addEffect(new ForesightEffect()); + + // Draw a card at the beginning of the next turn's upkeep. + this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(new DrawCardSourceControllerEffect(1)), false)); + } + + public Foresight(final Foresight card) { + super(card); + } + + @Override + public Foresight copy() { + return new Foresight(this); + } +} + +class ForesightEffect extends SearchEffect { + + ForesightEffect() { + super(new TargetCardInLibrary(3, new FilterCard()), Outcome.Benefit); + staticText = "Search your library for three cards, exile them, then shuffle your library."; + } + + ForesightEffect(final ForesightEffect effect) { + super(effect); + } + + @Override + public ForesightEffect copy() { + return new ForesightEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player.searchLibrary(target, game)) { + for (UUID targetId : getTargets()) { + Card card = player.getLibrary().getCard(targetId, game); + if (card != null) { + card.moveToExile(null, null, targetId, game); + } + } + return true; + } + player.shuffleLibrary(source, game); + return false; + } + + public List getTargets() { + return target.getTargets(); + } + +} diff --git a/Mage.Sets/src/mage/cards/s/SliceinTwain.java b/Mage.Sets/src/mage/cards/s/SliceinTwain.java deleted file mode 100644 index abb03b3116..0000000000 --- a/Mage.Sets/src/mage/cards/s/SliceinTwain.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of BetaSteward_at_googlemail.com. - */ - -package mage.cards.s; - -import mage.abilities.effects.common.DestroyTargetEffect; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.filter.StaticFilters; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * - * @author Loki - */ -public class SliceinTwain extends CardImpl { - - public SliceinTwain (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{G}{G}"); - - this.getSpellAbility().addEffect(new DestroyTargetEffect()); - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); - this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.ARTIFACT_OR_ENCHANTMENT_PERMANENT)); - } - - public SliceinTwain (final SliceinTwain card) { - super(card); - } - - @Override - public SliceinTwain copy() { - return new SliceinTwain(this); - } -} diff --git a/Mage.Sets/src/mage/sets/Alliances.java b/Mage.Sets/src/mage/sets/Alliances.java index 87f01b760f..4532bc7548 100644 --- a/Mage.Sets/src/mage/sets/Alliances.java +++ b/Mage.Sets/src/mage/sets/Alliances.java @@ -78,6 +78,7 @@ public class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Fevered Strength", 11, Rarity.COMMON, FeveredStrength.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Floodwater Dam", 161, Rarity.RARE, mage.cards.f.FloodwaterDam.class)); cards.add(new SetCardInfo("Force of Will", 42, Rarity.UNCOMMON, mage.cards.f.ForceOfWill.class)); + cards.add(new SetCardInfo("Foresight", 162, Rarity.COMMON, mage.cards.f.Foresight.class)); cards.add(new SetCardInfo("Gorilla Berserkers", 75, Rarity.COMMON, GorillaBerserkers.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gorilla Berserkers", 76, Rarity.COMMON, GorillaBerserkers.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gorilla Chieftain", 77, Rarity.COMMON, mage.cards.g.GorillaChieftain.class, NON_FULL_USE_VARIOUS)); From e6bfe0b6dbb14cbedfb5d0abacd6378f75a30892 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 13:19:34 -0400 Subject: [PATCH 128/182] readded Slice in Twain again --- Mage.Sets/src/mage/cards/s/SliceInTwain.java | 61 ++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SliceInTwain.java diff --git a/Mage.Sets/src/mage/cards/s/SliceInTwain.java b/Mage.Sets/src/mage/cards/s/SliceInTwain.java new file mode 100644 index 0000000000..4e1695832a --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SliceInTwain.java @@ -0,0 +1,61 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; + +/** + * + * @author Loki + */ +public class SliceInTwain extends CardImpl { + + public SliceInTwain(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}{G}"); + + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("
br>Draw a card")); + this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.ARTIFACT_OR_ENCHANTMENT_PERMANENT)); + } + + public SliceInTwain(final SliceInTwain card) { + super(card); + } + + @Override + public SliceInTwain copy() { + return new SliceInTwain(this); + } +} From e15f0206677bb5660ce6f65a37e7a4a52dc45f45 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 22:51:12 +0200 Subject: [PATCH 129/182] Deathgorge Scavenger - Fixed triggered ability. --- .../src/mage/cards/d/DeathgorgeScavenger.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java b/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java index 13b6ae13b3..868409cd85 100644 --- a/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java +++ b/Mage.Sets/src/mage/cards/d/DeathgorgeScavenger.java @@ -34,12 +34,12 @@ import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.Card; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -92,14 +92,16 @@ class DeathgorgeScavengerEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Card card = game.getCard(getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); - if (controller != null && card != null) { - controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true); - if (card.isCreature()) { - controller.gainLife(2, game); - } else { - new BoostSourceEffect(1, 1, Duration.EndOfTurn).apply(game, source); + if (controller != null) { + Card card = game.getCard(getTargetPointer().getFirst(game, source)); + if (card != null) { + controller.moveCards(card, Zone.EXILED, source, game); + if (card.isCreature()) { + controller.gainLife(2, game); + } else { + game.addEffect(new BoostSourceEffect(1, 1, Duration.EndOfTurn), source); + } } return true; } From 01e4ce2c42836458b418c16d54e53d5c13543485 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 16 Sep 2017 22:56:03 +0200 Subject: [PATCH 130/182] * Marauding Looter - Fixed that the draw discard effect was not optional. --- Mage.Sets/src/mage/cards/m/MaraudingLooter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/m/MaraudingLooter.java b/Mage.Sets/src/mage/cards/m/MaraudingLooter.java index 317c96ced2..c87a6297a6 100644 --- a/Mage.Sets/src/mage/cards/m/MaraudingLooter.java +++ b/Mage.Sets/src/mage/cards/m/MaraudingLooter.java @@ -57,7 +57,7 @@ public class MaraudingLooter extends CardImpl { // Raid - At the beginning of your end step, if you attacked with a creature this turn, you may draw a card. If you do, discard a card. Ability ability = new ConditionalTriggeredAbility( - new BeginningOfEndStepTriggeredAbility(new DrawDiscardControllerEffect(1, 1), TargetController.YOU, false), + new BeginningOfEndStepTriggeredAbility(new DrawDiscardControllerEffect(1, 1, true), TargetController.YOU, false), RaidCondition.instance, "Raid — At the beginning of your end step, " + "if you attacked with a creature this turn, " From c4a342ffcb0fbf7538e2308ab2fd97f1da07aa92 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 21:41:31 -0400 Subject: [PATCH 131/182] Fixed Fell Flagship (#4002) --- Mage.Sets/src/mage/cards/f/FellFlagship.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mage.Sets/src/mage/cards/f/FellFlagship.java b/Mage.Sets/src/mage/cards/f/FellFlagship.java index 1726fc2bdc..c518dd75a1 100644 --- a/Mage.Sets/src/mage/cards/f/FellFlagship.java +++ b/Mage.Sets/src/mage/cards/f/FellFlagship.java @@ -28,6 +28,7 @@ package mage.cards.f; import java.util.UUID; +import mage.MageInt; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.continuous.BoostControlledEffect; @@ -58,6 +59,8 @@ public class FellFlagship extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); this.subtype.add(SubType.VEHICLE); + this.power = new MageInt(3); + this.toughness = new MageInt(3); // Pirates you control get +1/+0. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield, filter))); From b819803a4f1fe6dd0c0274cf3f72023667b0c021 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 21:45:32 -0400 Subject: [PATCH 132/182] Fixed Search for Azcanta --- Mage.Sets/src/mage/cards/s/SearchForAzcanta.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java b/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java index 70389391b7..1fe5f694a8 100644 --- a/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java +++ b/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java @@ -64,7 +64,7 @@ public class SearchForAzcanta extends CardImpl { this.addSuperType(SuperType.LEGENDARY); // At the beginning of your upkeep, look at the top card of your library. You may put it into your graveyard. Then if you have seven or more cards in your graveyard, you may transform Search for Azcanta. - Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SearchForAzcantaLookLibraryEffect(), TargetController.YOU, false); + Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SearchForAzcantaLookLibraryEffect(), TargetController.YOU, true); ability.addEffect(new ConditionalOneShotEffect(new TransformSourceEffect(true), new CardsInControllerGraveCondition(7), "Then if you have seven or more cards in your graveyard, you may transform {this}")); this.addAbility(ability); From e646c75487239ea98afe8ed89f1e254d501d0830 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 21:46:12 -0400 Subject: [PATCH 133/182] Fixed Dowsing Dagger token --- .../main/java/mage/game/permanent/token/DefenderPlantToken.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/game/permanent/token/DefenderPlantToken.java b/Mage/src/main/java/mage/game/permanent/token/DefenderPlantToken.java index 046b1daab9..b1915879c1 100644 --- a/Mage/src/main/java/mage/game/permanent/token/DefenderPlantToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/DefenderPlantToken.java @@ -52,7 +52,7 @@ public class DefenderPlantToken extends Token { cardType.add(CardType.CREATURE); subtype.add(SubType.PLANT); power = new MageInt(0); - toughness = new MageInt(1); + toughness = new MageInt(2); this.addAbility(DefenderAbility.getInstance()); } From 573f247393aeb25b96bd6055e95ad9a6fc917cb0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 21:48:12 -0400 Subject: [PATCH 134/182] Fixed Gilded Sentinel --- Mage.Sets/src/mage/cards/g/GildedSentinel.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mage.Sets/src/mage/cards/g/GildedSentinel.java b/Mage.Sets/src/mage/cards/g/GildedSentinel.java index 060dd11be0..1175fab4a7 100644 --- a/Mage.Sets/src/mage/cards/g/GildedSentinel.java +++ b/Mage.Sets/src/mage/cards/g/GildedSentinel.java @@ -28,6 +28,7 @@ package mage.cards.g; import java.util.UUID; +import mage.MageInt; import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -43,6 +44,9 @@ public class GildedSentinel extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); this.subtype.add(SubType.GOLEM); + + this.power = new MageInt(3); + this.toughness = new MageInt(3); } public GildedSentinel(final GildedSentinel card) { From ff567ed20a1590007907290ef5544468ed48d8da Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 21:48:35 -0400 Subject: [PATCH 135/182] Fixed Dive Down --- Mage.Sets/src/mage/cards/d/DiveDown.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/d/DiveDown.java b/Mage.Sets/src/mage/cards/d/DiveDown.java index d094dade72..8ce6392e1c 100644 --- a/Mage.Sets/src/mage/cards/d/DiveDown.java +++ b/Mage.Sets/src/mage/cards/d/DiveDown.java @@ -48,7 +48,7 @@ public class DiveDown extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}"); // Target creature you control gets +0/+3 and gains hexproof until end of turn. - Effect effect = new BoostTargetEffect(3, 3, Duration.EndOfTurn); + Effect effect = new BoostTargetEffect(0, 3, Duration.EndOfTurn); effect.setText("Target creature you control gets +0/+3"); this.getSpellAbility().addEffect(effect); effect = new GainAbilityTargetEffect(HexproofAbility.getInstance(), Duration.EndOfTurn); From c07eedf7522accee83060da99d65bf3da82a6eda Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 21:50:44 -0400 Subject: [PATCH 136/182] Fixed Entrancing Melody --- Mage.Sets/src/mage/cards/e/EntrancingMelody.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/e/EntrancingMelody.java b/Mage.Sets/src/mage/cards/e/EntrancingMelody.java index b84395188b..8a49d375f0 100644 --- a/Mage.Sets/src/mage/cards/e/EntrancingMelody.java +++ b/Mage.Sets/src/mage/cards/e/EntrancingMelody.java @@ -37,7 +37,6 @@ import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.Duration; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.target.common.TargetCreaturePermanent; @@ -65,8 +64,8 @@ public class EntrancingMelody extends CardImpl { if (ability instanceof SpellAbility) { ability.getTargets().clear(); int xValue = ability.getManaCostsToPay().getX(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost X or less"); - filter.add(Predicates.not(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue))); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost X"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue)); ability.addTarget(new TargetCreaturePermanent(filter)); } } From 49f047f70056b2f102d70e17f7cecd12661d2214 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 22:07:48 -0400 Subject: [PATCH 137/182] Fixed Deadeye Tracker possibly giving an error --- Mage.Sets/src/mage/cards/d/DeadeyeTracker.java | 13 ++----------- Mage.Sets/src/mage/cards/n/NullmageAdvocate.java | 6 +++--- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DeadeyeTracker.java b/Mage.Sets/src/mage/cards/d/DeadeyeTracker.java index 5915342b3d..405263345e 100644 --- a/Mage.Sets/src/mage/cards/d/DeadeyeTracker.java +++ b/Mage.Sets/src/mage/cards/d/DeadeyeTracker.java @@ -40,12 +40,9 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.other.OwnerPredicate; -import mage.target.common.TargetCardInASingleGraveyard; +import mage.target.common.TargetCardInOpponentsGraveyard; /** * @@ -53,12 +50,6 @@ import mage.target.common.TargetCardInASingleGraveyard; */ public class DeadeyeTracker extends CardImpl { - private static final FilterCard filter = new FilterCard("cards from an opponent's graveyard"); - - static { - filter.add(Predicates.not(new OwnerPredicate(TargetController.YOU))); - } - public DeadeyeTracker(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); @@ -73,7 +64,7 @@ public class DeadeyeTracker extends CardImpl { Effect effect = new ExploreSourceEffect(); effect.setText("{this} explores"); ability.addEffect(effect); - ability.addTarget(new TargetCardInASingleGraveyard(2, 2, filter)); + ability.addTarget(new TargetCardInOpponentsGraveyard(2, 2, new FilterCard("cards from an opponent's graveyard"), true)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/n/NullmageAdvocate.java b/Mage.Sets/src/mage/cards/n/NullmageAdvocate.java index 74edc35411..951a8c5ad0 100644 --- a/Mage.Sets/src/mage/cards/n/NullmageAdvocate.java +++ b/Mage.Sets/src/mage/cards/n/NullmageAdvocate.java @@ -54,7 +54,7 @@ import java.util.UUID; public class NullmageAdvocate extends CardImpl { public NullmageAdvocate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.INSECT); this.subtype.add(SubType.DRUID); this.power = new MageInt(2); @@ -64,11 +64,11 @@ public class NullmageAdvocate extends CardImpl { Effect effect = new ReturnFromGraveyardToHandTargetEffect(); effect.setText("Return two target cards from an opponent's graveyard to his or her hand"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); - + effect = new DestroyTargetEffect("Destroy target artifact or enchantment"); effect.setTargetPointer(new SecondTargetPointer()); ability.addEffect(effect); - ability.addTarget(new TargetCardInOpponentsGraveyard(2,2, new FilterCard("two target cards from an opponent's graveyard"), true)); + ability.addTarget(new TargetCardInOpponentsGraveyard(2, 2, new FilterCard("cards from an opponent's graveyard"), true)); ability.addTarget(new TargetPermanent(StaticFilters.ARTIFACT_OR_ENCHANTMENT_PERMANENT)); this.addAbility(ability); } From 77110bbc5a50c9312781957c2e5b9e560f4e3dfe Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 23:07:33 -0400 Subject: [PATCH 138/182] Fixed Admiral Beckett Brass trigger (#4006) --- .../src/mage/cards/a/AdmiralBeckettBrass.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java index 77f6f60025..84b6dcd8c1 100644 --- a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java +++ b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java @@ -53,6 +53,7 @@ import mage.filter.predicate.Predicate; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; +import mage.game.events.DamagedPlayerEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetNonlandPermanent; @@ -85,9 +86,8 @@ public class AdmiralBeckettBrass extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); // At the beginning of your end step, gain control of target nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn. - Ability ability = new BeginningOfEndStepTriggeredAbility(new GainControlTargetEffect(Duration.Custom) - .setText("gain control of target nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn"), TargetController.YOU, false); - ability.addTarget(new TargetNonlandPermanent()); + Ability ability = new BeginningOfEndStepTriggeredAbility(new GainControlTargetEffect(Duration.Custom), TargetController.YOU, false); + ability.addTarget(new TargetNonlandPermanent(new FilterNonlandPermanent("nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn"))); originalId = ability.getOriginalId(); this.addAbility(ability, new DamagedByPiratesWatcher()); } @@ -138,15 +138,17 @@ class DamagedByPiratesWatcher extends Watcher { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER && event.getFlag()) { - Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (creature != null && creature.getSubtype(game).contains(SubType.PIRATE)) { - if (damageSourceIds.keySet().contains(event.getTargetId())) { - damageSourceIds.get(event.getTargetId()).add(creature.getId()); - } else { - Set creatureSet = new HashSet(); - creatureSet.add(creature.getId()); - damageSourceIds.put(event.getTargetId(), creatureSet); + if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER) { + if (((DamagedPlayerEvent) event).isCombatDamage()) { + Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (creature != null && creature.getSubtype(game).contains(SubType.PIRATE)) { + if (damageSourceIds.keySet().contains(event.getTargetId())) { + damageSourceIds.get(event.getTargetId()).add(creature.getId()); + } else { + Set creatureSet = new HashSet(); + creatureSet.add(creature.getId()); + damageSourceIds.put(event.getTargetId(), creatureSet); + } } } } From 60f7b5bcbf9f0c4952a5ab46d058b03acc54319c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 16 Sep 2017 23:18:08 -0400 Subject: [PATCH 139/182] Fixed Sunrise Seeker --- Mage.Sets/src/mage/cards/s/SunriseSeeker.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SunriseSeeker.java b/Mage.Sets/src/mage/cards/s/SunriseSeeker.java index 66deabb826..c5194fb74a 100644 --- a/Mage.Sets/src/mage/cards/s/SunriseSeeker.java +++ b/Mage.Sets/src/mage/cards/s/SunriseSeeker.java @@ -29,7 +29,7 @@ package mage.cards.s; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.keyword.ExploreSourceEffect; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; @@ -55,7 +55,7 @@ public class SunriseSeeker extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // When Sunrise Seeker enters the battlefield, it explores. - this.addAbility(new EntersBattlefieldAbility(new ExploreSourceEffect())); + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExploreSourceEffect())); } public SunriseSeeker(final SunriseSeeker card) { From 1d5d201d296a5c7ec8d681fdd522f1f9c42d3ad0 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 17 Sep 2017 11:01:04 +0200 Subject: [PATCH 140/182] * Iconic Masters - Fixed some wrong rarities. --- Mage.Sets/src/mage/sets/IconicMasters.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/sets/IconicMasters.java b/Mage.Sets/src/mage/sets/IconicMasters.java index 129666276b..835ea5dd44 100644 --- a/Mage.Sets/src/mage/sets/IconicMasters.java +++ b/Mage.Sets/src/mage/sets/IconicMasters.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.sets; import mage.cards.ExpansionSet; @@ -54,9 +53,9 @@ public class IconicMasters extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; - + cards.add(new SetCardInfo("Scion of Ugin", 1, Rarity.COMMON, mage.cards.s.ScionOfUgin.class)); - cards.add(new SetCardInfo("Abzan Battle Priest", 2, Rarity.COMMON, mage.cards.a.AbzanBattlePriest.class)); + cards.add(new SetCardInfo("Abzan Battle Priest", 2, Rarity.UNCOMMON, mage.cards.a.AbzanBattlePriest.class)); cards.add(new SetCardInfo("Abzan Falconer", 3, Rarity.UNCOMMON, mage.cards.a.AbzanFalconer.class)); cards.add(new SetCardInfo("Ainok Bond-Kin", 4, Rarity.COMMON, mage.cards.a.AinokBondKin.class)); cards.add(new SetCardInfo("Ajani's Pridemate", 5, Rarity.UNCOMMON, mage.cards.a.AjanisPridemate.class)); @@ -197,7 +196,7 @@ public class IconicMasters extends ExpansionSet { cards.add(new SetCardInfo("Monastery Swiftspear", 140, Rarity.UNCOMMON, mage.cards.m.MonasterySwiftspear.class)); cards.add(new SetCardInfo("Pillar of Flame", 141, Rarity.COMMON, mage.cards.p.PillarOfFlame.class)); cards.add(new SetCardInfo("Prodigal Pyromancer", 142, Rarity.UNCOMMON, mage.cards.p.ProdigalPyromancer.class)); - cards.add(new SetCardInfo("Rift Bolt", 143, Rarity.COMMON, mage.cards.r.RiftBolt.class)); + cards.add(new SetCardInfo("Rift Bolt", 143, Rarity.UNCOMMON, mage.cards.r.RiftBolt.class)); cards.add(new SetCardInfo("Ryusei, the Falling Star", 144, Rarity.RARE, mage.cards.r.RyuseiTheFallingStar.class)); cards.add(new SetCardInfo("Scourge of Valkas", 145, Rarity.RARE, mage.cards.s.ScourgeOfValkas.class)); cards.add(new SetCardInfo("Splatter Thug", 146, Rarity.COMMON, mage.cards.s.SplatterThug.class)); @@ -227,7 +226,7 @@ public class IconicMasters extends ExpansionSet { cards.add(new SetCardInfo("Ivy Elemental", 170, Rarity.COMMON, mage.cards.i.IvyElemental.class)); cards.add(new SetCardInfo("Jaddi Offshoot", 171, Rarity.COMMON, mage.cards.j.JaddiOffshoot.class)); cards.add(new SetCardInfo("Jugan, the Rising Star", 172, Rarity.RARE, mage.cards.j.JuganTheRisingStar.class)); - cards.add(new SetCardInfo("Lead the Stampede", 173, Rarity.UNCOMMON, mage.cards.l.LeadTheStampede.class)); + cards.add(new SetCardInfo("Lead the Stampede", 173, Rarity.COMMON, mage.cards.l.LeadTheStampede.class)); cards.add(new SetCardInfo("Lotus Cobra", 174, Rarity.RARE, mage.cards.l.LotusCobra.class)); cards.add(new SetCardInfo("Lure", 175, Rarity.UNCOMMON, mage.cards.l.Lure.class)); cards.add(new SetCardInfo("Nantuko Shaman", 176, Rarity.COMMON, mage.cards.n.NantukoShaman.class)); From ae0d87b7ecf2d245125e877450a2282dd1e01145 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 17 Sep 2017 11:33:16 +0200 Subject: [PATCH 141/182] * Image download - added Ixalan & Iconic Masters to Scryfall and mythicspoilers.com. --- .../card/dl/sources/MythicspoilerComSource.java | 1 + .../card/dl/sources/ScryfallImageSource.java | 16 +++++++++++++++- .../plugins/card/images/CardDownloadData.java | 6 +++--- .../plugins/card/images/DownloadPictures.java | 8 ++++++-- .../src/main/resources/image.url.properties | 2 +- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java index 9fc3658775..03ba31aac4 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java @@ -251,6 +251,7 @@ public enum MythicspoilerComSource implements CardImageSource { supportedSets.add("E01"); supportedSets.add("HOU"); supportedSets.add("C17"); + supportedSets.add("IMA"); supportedSets.add("XLN"); sets = new LinkedHashMap<>(); diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index a54e5c0118..759a9bdacf 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -199,11 +199,25 @@ public enum ScryfallImageSource implements CardImageSource { supportedSets.add("E01"); supportedSets.add("HOU"); supportedSets.add("C17"); + supportedSets.add("XLN"); +// supportedSets.add("DDT"); + supportedSets.add("IMA"); +// supportedSets.add("E02"); +// supportedSets.add("V17"); +// supportedSets.add("UST"); +// supportedSets.add("RIX"); +// supportedSets.add("A25"); +// supportedSets.add("DOM"); +// supportedSets.add("M19"); + } @Override public String generateURL(CardDownloadData card) throws Exception { - return "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/" + card.getCollectorId() + "?format=image"; + return "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/" + + card.getCollectorId() + + (card.isSecondSide() ? "b" : "") + + "?format=image"; } @Override diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/CardDownloadData.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/CardDownloadData.java index 6c70b19810..9956f8e10f 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/CardDownloadData.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/CardDownloadData.java @@ -40,7 +40,7 @@ public class CardDownloadData { } public CardDownloadData(String name, String set, String collectorId, boolean usesVariousArt, Integer type, String tokenSetCode, String tokenDescriptor, boolean token, boolean twoFacedCard, boolean secondSide) { - this(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor, token, false, false, ""); + this(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor, token, twoFacedCard, secondSide, ""); } public CardDownloadData(String name, String set, String collectorId, boolean usesVariousArt, Integer type, String tokenSetCode, String tokenDescriptor, boolean token, boolean twoFacedCard, boolean secondSide, String tokenClassName) { @@ -72,7 +72,7 @@ public class CardDownloadData { this.usesVariousArt = card.usesVariousArt; this.tokenSetCode = card.tokenSetCode; this.tokenDescriptor = card.tokenDescriptor; - this.tokenClassName = tokenClassName; + this.tokenClassName = card.tokenClassName; this.fileName = card.fileName; } @@ -163,7 +163,7 @@ public class CardDownloadData { public String getTokenDescriptor() { return tokenDescriptor; } - + public void setTokenClassName(String tokenClassName) { this.tokenClassName = tokenClassName; } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index d993eec652..5de6018be0 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -429,9 +429,13 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab if (card.getSecondSideName() == null || card.getSecondSideName().trim().isEmpty()) { throw new IllegalStateException("Second side card can't have empty name."); } + url = new CardDownloadData(card.getSecondSideName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), true); url.setType2(isType2); allCardsUrls.add(url); + if (card.getSetCode().equals("XLN")) { + logger.info(card.getSetCode() + "second side: " + card.getSecondSideName() + " -name: " + card.getName()); + } } if (card.isFlipCard()) { if (card.getFlipCardName() == null || card.getFlipCardName().trim().isEmpty()) { @@ -444,11 +448,11 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab allCardsUrls.add(cardDownloadData); } } else if (card.getCardNumber().isEmpty() || "0".equals(card.getCardNumber())) { - System.err.println("There was a critical error!"); logger.error("Card has no collector ID and won't be sent to client: " + card.getName()); } else if (card.getSetCode().isEmpty()) { - System.err.println("There was a critical error!"); logger.error("Card has no set name and won't be sent to client:" + card.getName()); + } else { + logger.info("Card was not selected: " + card.getName()); } }); allCardsUrls.addAll(getTokenCardUrls()); diff --git a/Mage.Client/src/main/resources/image.url.properties b/Mage.Client/src/main/resources/image.url.properties index 8b2b31bb07..0ded050d87 100644 --- a/Mage.Client/src/main/resources/image.url.properties +++ b/Mage.Client/src/main/resources/image.url.properties @@ -74,6 +74,6 @@ dd3evg=ddaevg dd3gvl=ddagvl dd3jvc=ddajvc # Remove setname as soon as the images can be downloaded -ignore.urls=TOK,DDT,V17,IMA,RIX,E02,M19,M25,DOM,UST,H17 +ignore.urls=TOK,DDT,V17,RIX,E02,M19,M25,DOM,UST,H17 # sets ordered by release time (newest goes first) token.lookup.order=M19,M25,DOM,E02,RIX,UST,XLN,IMA,H17,C17,V17,E01,DDT,CMA,HOU,MM3,DDS,AKH,DD3DVD,DD3EVG,DD3GVL,DD3JVC,H09,AER,PCA,C16,V16,MPS,KLD,DDR,CN2,EMN,EMA,SOI,DDQ,CP,CMA,ARENA,SUS,APAC,EURO,UGIN,C15,OGW,EXP,DDP,BFZ,DRB,V09,V10,V11,V12,V13,V14,V15,TPR,MPRP,DD3,DDO,ORI,MM2,PTC,DTK,FRF,KTK,M15,VMA,CNS,JOU,BNG,THS,DDL,M14,MMA,DGM,GTC,RTR,M13,AVR,DDI,DKA,ISD,M12,NPH,MBS,SOM,M11,ROE,DDE,WWK,ZEN,M10,GVL,ARB,DVD,CFX,JVC,ALA,EVE,SHM,EVG,MOR,LRW,10E,CLS,CHK,GRC \ No newline at end of file From 3622206cf1ad9dc1f378b6b3c62b3323785e176a Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 17 Sep 2017 11:34:50 +0200 Subject: [PATCH 142/182] * Image download - added Ixalan & Iconic Masters to Scryfall and mythicspoilers.com. --- .../java/org/mage/plugins/card/images/DownloadPictures.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index 5de6018be0..0895b79219 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -433,9 +433,6 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab url = new CardDownloadData(card.getSecondSideName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), true); url.setType2(isType2); allCardsUrls.add(url); - if (card.getSetCode().equals("XLN")) { - logger.info(card.getSetCode() + "second side: " + card.getSecondSideName() + " -name: " + card.getName()); - } } if (card.isFlipCard()) { if (card.getFlipCardName() == null || card.getFlipCardName().trim().isEmpty()) { From cab5919203adcba0119e262b86f81af4bfda6ab8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 09:02:00 -0400 Subject: [PATCH 143/182] Fixed Duskborne Skymarcher targeting non-attackers --- Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java b/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java index 32423191b8..4eb31fefe5 100644 --- a/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java +++ b/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java @@ -71,7 +71,7 @@ public class DuskborneSkymarcher extends CardImpl { // {W}, {T}: Target attacking vampire gets +1/+1 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{W}")); ability.addCost(new TapSourceCost()); - ability.addTarget(new TargetCreaturePermanent()); + ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } From 3a3ca3ba96117b5dd68f14a2c96432cbef39fddb Mon Sep 17 00:00:00 2001 From: spjspj Date: Sun, 17 Sep 2017 23:26:23 +1000 Subject: [PATCH 144/182] Fix Sunbird's Invocation --- Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index aca1f428e3..41cf909e38 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -111,7 +111,7 @@ class SunbirdsInvocationEffect extends OneShotEffect { public SunbirdsInvocationEffect() { super(Outcome.PutCardInPlay); - staticText = "reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; + staticText = "Reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; } public SunbirdsInvocationEffect(final SunbirdsInvocationEffect effect) { @@ -139,10 +139,9 @@ class SunbirdsInvocationEffect extends OneShotEffect { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { if (controller.chooseUse(outcome, "Do you wish to cast " + card.getName(), source, game)) { - Card copy = game.copyCard(card, source, source.getControllerId()); - controller.cast(copy.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true); + cards.remove(card); } - return true; } } } From 8b1ec81c7a8fd95bdbfa4476c629cf4ff802ae4c Mon Sep 17 00:00:00 2001 From: spjspj Date: Sun, 17 Sep 2017 23:29:24 +1000 Subject: [PATCH 145/182] Fix Sunbird's Invocation --- Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index 41cf909e38..aa541a7d06 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -111,7 +111,7 @@ class SunbirdsInvocationEffect extends OneShotEffect { public SunbirdsInvocationEffect() { super(Outcome.PutCardInPlay); - staticText = "Reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; + staticText = "reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; } public SunbirdsInvocationEffect(final SunbirdsInvocationEffect effect) { From d5166f60410b516d516f20bc84d49141fa5405ee Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 10:28:44 -0400 Subject: [PATCH 146/182] Fixed Imperial Aerosaur double pumping --- Mage.Sets/src/mage/cards/i/ImperialAerosaur.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java b/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java index 5fbffa9852..a40cf227aa 100644 --- a/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java +++ b/Mage.Sets/src/mage/cards/i/ImperialAerosaur.java @@ -72,7 +72,6 @@ public class ImperialAerosaur extends CardImpl { Effect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn); effect.setText("another target creature you control gets +1/+1"); EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(effect); - ability.addEffect(effect); effect = new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn); effect.setText("and gains flying until end of turn"); ability.addEffect(effect); From b8d24883e831dc948db8f5a51d1403ec094433eb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 10:33:12 -0400 Subject: [PATCH 147/182] Fixed Sun-Crowned Hunters text --- Mage.Sets/src/mage/cards/s/SunCrownedHunters.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/SunCrownedHunters.java b/Mage.Sets/src/mage/cards/s/SunCrownedHunters.java index d9fa321f93..a433bbd376 100644 --- a/Mage.Sets/src/mage/cards/s/SunCrownedHunters.java +++ b/Mage.Sets/src/mage/cards/s/SunCrownedHunters.java @@ -53,7 +53,9 @@ public class SunCrownedHunters extends CardImpl { this.toughness = new MageInt(4); // Enrage — Whenever Sun-Crowned Hunters is dealt damage, it deals 3 damage to target opponent. - Ability ability = new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3, true, "it"), false, true); + Ability ability = new DealtDamageToSourceTriggeredAbility( + Zone.BATTLEFIELD, new DamageTargetEffect(3).setText("it deals 3 damage to target opponent"), false, true + ); ability.addTarget(new TargetOpponent()); this.addAbility(ability); } From b8b017066283c780d86e0245da7f74acf578df00 Mon Sep 17 00:00:00 2001 From: spjspj Date: Mon, 18 Sep 2017 00:38:02 +1000 Subject: [PATCH 148/182] Add Tokens to card-pictures-tok for viewer. --- Mage.Client/src/main/resources/card-pictures-tok.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Mage.Client/src/main/resources/card-pictures-tok.txt b/Mage.Client/src/main/resources/card-pictures-tok.txt index c172c971f3..2bad012c0a 100644 --- a/Mage.Client/src/main/resources/card-pictures-tok.txt +++ b/Mage.Client/src/main/resources/card-pictures-tok.txt @@ -1096,6 +1096,16 @@ |Generate|TOK:WWK|Snake|||SnakeToken| |Generate|TOK:WWK|Soldier Ally|||JoinTheRanksSoldierToken| |Generate|TOK:WWK|Wolf|||WolfToken| +|Generate|TOK:XLN|Dinosaur|||DinosaurToken| +|Generate|TOK:XLN|Illusion|||JaceCunningCastawayIllusionToken| +|Generate|TOK:XLN|Merfolk|||MerfolkHexproofToken| +|Generate|TOK:XLN|Pirate|||PirateToken| +|Generate|TOK:XLN|Plant|||DefenderPlantToken| +|Generate|TOK:XLN|Treasure|1||TreasureToken| +|Generate|TOK:XLN|Treasure|2||TreasureToken| +|Generate|TOK:XLN|Treasure|3||TreasureToken| +|Generate|TOK:XLN|Treasure|4||TreasureToken| +|Generate|TOK:XLN|Vampire|||IxalanVampireToken| |Generate|TOK:ZEN|Angel|||AngelToken| |Generate|TOK:ZEN|Beast|||BeastToken2| |Generate|TOK:ZEN|Bird|||BirdToken| From 9a57480f4b32231cdae497a3a3d8db7db6cfd69f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 12:42:59 -0400 Subject: [PATCH 149/182] Fixed Dual Nature --- Mage.Sets/src/mage/cards/d/DualNature.java | 234 ++++++++++++++++++ Mage.Sets/src/mage/sets/Prophecy.java | 1 + .../LeavesBattlefieldAllTriggeredAbility.java | 25 +- Utils/keywords.txt | 2 +- 4 files changed, 259 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/d/DualNature.java diff --git a/Mage.Sets/src/mage/cards/d/DualNature.java b/Mage.Sets/src/mage/cards/d/DualNature.java new file mode 100644 index 0000000000..23da3a3638 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DualNature.java @@ -0,0 +1,234 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.common.LeavesBattlefieldAllTriggeredAbility; +import mage.abilities.common.ZoneChangeTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.abilities.effects.common.ExileAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SetTargetPointer; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.util.CardUtil; + +/** + * + * @author TheElk801 + */ +public class DualNature extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creature"); + + static { + filter.add(Predicates.not(new TokenPredicate())); + } + + public DualNature(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}{G}"); + + // Whenever a nontoken creature enters the battlefield, its controller creates a token that's a copy of that creature. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, new DualNatureCreateTokenEffect(), filter, false, SetTargetPointer.PERMANENT, + "Whenever a nontoken creature enters the battlefield, its controller creates a token that's a copy of that creature." + )); + + // Whenever a nontoken creature leaves the battlefield, exile all tokens with the same name as that creature. + this.addAbility(new LeavesBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, new DualNatureCreatureLeavesEffect(), filter, false, SetTargetPointer.PERMANENT + )); + + // When Dual Nature leaves the battlefield, exile all tokens created with Dual Nature. + this.addAbility(new DualNatureLeavesBattlefieldTriggeredAbility()); + } + + public DualNature(final DualNature card) { + super(card); + } + + @Override + public DualNature copy() { + return new DualNature(this); + } +} + +class DualNatureCreateTokenEffect extends OneShotEffect { + + DualNatureCreateTokenEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "its controller creates a token that's a copy of that creature"; + } + + DualNatureCreateTokenEffect(final DualNatureCreateTokenEffect effect) { + super(effect); + } + + @Override + public DualNatureCreateTokenEffect copy() { + return new DualNatureCreateTokenEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(permanent.getControllerId()); + effect.setTargetPointer(targetPointer); + effect.apply(game, source); + Object object = game.getState().getValue(CardUtil.getCardZoneString("_tokensCreated", source.getSourceId(), game)); + Set tokensCreated; + if (object != null) { + tokensCreated = (Set) object; + } else { + tokensCreated = new HashSet<>(); + } + for (Permanent perm : effect.getAddedPermanent()) { + if (perm != null) { + tokensCreated.add(perm.getId()); + } + } + game.getState().setValue(CardUtil.getCardZoneString("_tokensCreated", source.getSourceId(), game), tokensCreated); + } + return true; + } +} + +class DualNatureCreatureLeavesEffect extends OneShotEffect { + + DualNatureCreatureLeavesEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "exile all tokens with the same name as that creature"; + } + + DualNatureCreatureLeavesEffect(final DualNatureCreatureLeavesEffect effect) { + super(effect); + } + + @Override + public DualNatureCreatureLeavesEffect copy() { + return new DualNatureCreatureLeavesEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent creature = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source)); + if (creature != null) { + FilterPermanent filter = new FilterPermanent(); + filter.add(new TokenPredicate()); + filter.add(new NamePredicate(creature.getName())); + new ExileAllEffect(filter).apply(game, source); + return true; + } + return false; + } +} + +class DualNatureLeavesBattlefieldTriggeredAbility extends ZoneChangeTriggeredAbility { + + DualNatureLeavesBattlefieldTriggeredAbility() { + super(Zone.BATTLEFIELD, null, new DualNatureExileEffect(), "When {this} leaves the battlefield, ", false); + } + + DualNatureLeavesBattlefieldTriggeredAbility(DualNatureLeavesBattlefieldTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (super.checkTrigger(event, game)) { + for (Effect effect : this.getEffects()) { + if (effect instanceof DualNatureExileEffect) { + ((DualNatureExileEffect) effect).setCardZoneString(CardUtil.getCardZoneString("_tokensCreated", this.getSourceId(), game, true)); + } + } + return true; + } + return false; + } + + @Override + public DualNatureLeavesBattlefieldTriggeredAbility copy() { + return new DualNatureLeavesBattlefieldTriggeredAbility(this); + } +} + +class DualNatureExileEffect extends OneShotEffect { + + private String cardZoneString; + + DualNatureExileEffect() { + super(Outcome.Benefit); + this.staticText = "exile all tokens created with {this}."; + } + + DualNatureExileEffect(final DualNatureExileEffect effect) { + super(effect); + this.cardZoneString = effect.cardZoneString; + } + + @Override + public DualNatureExileEffect copy() { + return new DualNatureExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Object object = game.getState().getValue(cardZoneString); + if (object != null) { + Set tokensCreated = (Set) object; + for (UUID tokenId : tokensCreated) { + Permanent token = game.getPermanent(tokenId); + if (token != null) { + token.destroy(source.getSourceId(), game, true); + } + } + } + return true; + } + + public void setCardZoneString(String cardZoneString) { + this.cardZoneString = cardZoneString; + } +} diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 0a6bea024a..b238baeb12 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -81,6 +81,7 @@ public class Prophecy extends ExpansionSet { cards.add(new SetCardInfo("Despoil", 62, Rarity.COMMON, mage.cards.d.Despoil.class)); cards.add(new SetCardInfo("Devastate", 87, Rarity.COMMON, mage.cards.d.Devastate.class)); cards.add(new SetCardInfo("Diving Griffin", 6, Rarity.COMMON, mage.cards.d.DivingGriffin.class)); + cards.add(new SetCardInfo("Dual Nature", 112, Rarity.RARE, mage.cards.d.DualNature.class)); cards.add(new SetCardInfo("Entangler", 7, Rarity.UNCOMMON, mage.cards.e.Entangler.class)); cards.add(new SetCardInfo("Excavation", 33, Rarity.UNCOMMON, mage.cards.e.Excavation.class)); cards.add(new SetCardInfo("Fault Riders", 88, Rarity.COMMON, mage.cards.f.FaultRiders.class)); diff --git a/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java index 2c05677467..5ed3b300b7 100644 --- a/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java @@ -30,12 +30,14 @@ package mage.abilities.common; import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; /** * @@ -44,6 +46,7 @@ import mage.game.permanent.Permanent; public class LeavesBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl { protected FilterPermanent filter; + protected SetTargetPointer setTargetPointer; public LeavesBattlefieldAllTriggeredAbility(Effect effect, FilterPermanent filter) { this(effect, filter, false); @@ -54,13 +57,19 @@ public class LeavesBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl { } public LeavesBattlefieldAllTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional) { + this(zone, effect, filter, optional, SetTargetPointer.NONE); + } + + public LeavesBattlefieldAllTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean optional, SetTargetPointer setTargetPointer) { super(zone, effect, optional); this.filter = filter; + this.setTargetPointer = setTargetPointer; } public LeavesBattlefieldAllTriggeredAbility(final LeavesBattlefieldAllTriggeredAbility ability) { super(ability); filter = ability.filter; + setTargetPointer = ability.setTargetPointer; } @Override @@ -79,8 +88,20 @@ public class LeavesBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl { if (zEvent.getFromZone() == Zone.BATTLEFIELD) { UUID targetId = event.getTargetId(); Permanent permanent = game.getPermanentOrLKIBattlefield(targetId); - if (permanent != null) { - return filter.match(permanent, getSourceId(), getControllerId(), game); + if (permanent != null && filter.match(permanent, getSourceId(), getControllerId(), game)) { + if (setTargetPointer != SetTargetPointer.NONE) { + for (Effect effect : this.getEffects()) { + switch (setTargetPointer) { + case PERMANENT: + effect.setTargetPointer(new FixedTarget(permanent.getId())); + break; + case PLAYER: + effect.setTargetPointer(new FixedTarget(permanent.getControllerId())); + break; + } + } + } + return true; } } return false; diff --git a/Utils/keywords.txt b/Utils/keywords.txt index fa26cf2924..f2c980846b 100644 --- a/Utils/keywords.txt +++ b/Utils/keywords.txt @@ -54,7 +54,7 @@ Lifelink|instance| Living weapon|new| Madness|card, cost| Melee|new| -Menace|instance| +Menace|new| Miracle|cost| Mountaincycling|cost| Mountainwalk|new| From f58cd9ef3d9564684b9b09746301398d914ba1ef Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 12:50:31 -0400 Subject: [PATCH 150/182] Fixed Angrath's Marauders not doubling damage --- Mage.Sets/src/mage/cards/a/AngrathsMarauders.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java b/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java index a08e15a073..e6e12b2eec 100644 --- a/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java +++ b/Mage.Sets/src/mage/cards/a/AngrathsMarauders.java @@ -50,7 +50,7 @@ public class AngrathsMarauders extends CardImpl { public AngrathsMarauders(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}{R}"); - + this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.PIRATE); this.power = new MageInt(4); @@ -69,6 +69,7 @@ public class AngrathsMarauders extends CardImpl { return new AngrathsMarauders(this); } } + class AngrathsMaraudersEffect extends ReplacementEffectImpl { public AngrathsMaraudersEffect() { @@ -96,11 +97,11 @@ class AngrathsMaraudersEffect extends ReplacementEffectImpl { return true; } return false; - } - + } + @Override public boolean applies(GameEvent event, Ability source, Game game) { - return event.getSourceId().equals(source.getControllerId()); + return game.getControllerId(event.getSourceId()).equals(source.getControllerId()); } @Override From 4385aae8deafa236db22d0bd69f5af97579063e1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 12:54:32 -0400 Subject: [PATCH 151/182] Fixed Belligerent Brontodon to only affect your creatures --- .../mage/cards/b/BelligerentBrontodon.java | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java b/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java index f1a1b50e25..df036bce3b 100644 --- a/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java +++ b/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java @@ -37,7 +37,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; /** @@ -54,7 +54,7 @@ public class BelligerentBrontodon extends CardImpl { this.toughness = new MageInt(6); // Each creature you control assigns combat damage equal to its toughness rather than its power. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MilitantDinosaurCombatDamageRuleEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BelligerentBrontodonCombatDamageRuleEffect())); } public BelligerentBrontodon(final BelligerentBrontodon card) { @@ -67,31 +67,27 @@ public class BelligerentBrontodon extends CardImpl { } } -class MilitantDinosaurCombatDamageRuleEffect extends ContinuousEffectImpl { +class BelligerentBrontodonCombatDamageRuleEffect extends ContinuousEffectImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); - - static { - filter.add(new ControllerPredicate(TargetController.YOU)); - } - - public MilitantDinosaurCombatDamageRuleEffect() { + public BelligerentBrontodonCombatDamageRuleEffect() { super(Duration.WhileOnBattlefield, Outcome.Detriment); staticText = "Each creature you control assigns combat damage equal to its toughness rather than its power"; } - public MilitantDinosaurCombatDamageRuleEffect(final MilitantDinosaurCombatDamageRuleEffect effect) { + public BelligerentBrontodonCombatDamageRuleEffect(final BelligerentBrontodonCombatDamageRuleEffect effect) { super(effect); } @Override - public MilitantDinosaurCombatDamageRuleEffect copy() { - return new MilitantDinosaurCombatDamageRuleEffect(this); + public BelligerentBrontodonCombatDamageRuleEffect copy() { + return new BelligerentBrontodonCombatDamageRuleEffect(this); } @Override public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { // Change the rule + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(new ControllerIdPredicate(source.getControllerId())); game.getCombat().setUseToughnessForDamage(true); game.getCombat().addUseToughnessForDamageFilter(filter); return true; From ff4445d1812b71e44bf835b998ac7bc10bb375dc Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 12:56:01 -0400 Subject: [PATCH 152/182] Fixed Deadeye Quartermaster not searching for vehicles --- Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java b/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java index c99d19e5e6..049f6915fa 100644 --- a/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java +++ b/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java @@ -49,7 +49,10 @@ public class DeadeyeQuartermaster extends CardImpl { private static final FilterCard filter = new FilterCard("an Equipment or Vehicle card"); static { - filter.add(Predicates.or(new SubtypePredicate(SubType.EQUIPMENT), new SubtypePredicate(SubType.EQUIPMENT))); + filter.add(Predicates.or( + new SubtypePredicate(SubType.EQUIPMENT), + new SubtypePredicate(SubType.VEHICLE) + )); } public DeadeyeQuartermaster(UUID ownerId, CardSetInfo setInfo) { From 0b5bd900a6875069debc8dcc5867dc8eefa972c1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 13:22:42 -0400 Subject: [PATCH 153/182] Fixed Primal Wellspring and Pyromancer's Goggles being optional triggers --- Mage.Sets/src/mage/cards/p/PrimalWellspring.java | 2 +- Mage.Sets/src/mage/cards/p/PyromancersGoggles.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/p/PrimalWellspring.java b/Mage.Sets/src/mage/cards/p/PrimalWellspring.java index fc8793547e..cbdbae5b85 100644 --- a/Mage.Sets/src/mage/cards/p/PrimalWellspring.java +++ b/Mage.Sets/src/mage/cards/p/PrimalWellspring.java @@ -81,7 +81,7 @@ class PyrimalWellspringTriggeredAbility extends TriggeredAbilityImpl { String abilityOriginalId; public PyrimalWellspringTriggeredAbility(UUID abilityOriginalId, Effect effect) { - super(Zone.ALL, effect, true); + super(Zone.ALL, effect, false); this.abilityOriginalId = abilityOriginalId.toString(); } diff --git a/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java b/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java index 742d616a05..fd658c276e 100644 --- a/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java +++ b/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java @@ -54,7 +54,7 @@ import mage.target.targetpointer.FixedTarget; public class PyromancersGoggles extends CardImpl { public PyromancersGoggles(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); addSuperType(SuperType.LEGENDARY); // {T}: Add {R} to your mana pool. @@ -89,7 +89,7 @@ class PyromancersGogglesTriggeredAbility extends TriggeredAbilityImpl { String abilityOriginalId; public PyromancersGogglesTriggeredAbility(UUID abilityOriginalId, Effect effect) { - super(Zone.ALL, effect, true); + super(Zone.ALL, effect, false); this.abilityOriginalId = abilityOriginalId.toString(); } From ea4ff44ed78d57da84b0f854744966864a367433 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 14:04:42 -0400 Subject: [PATCH 154/182] Implemented Iridescent Drake --- .../src/mage/cards/i/IridescentDrake.java | 117 ++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasDestiny.java | 1 + 2 files changed, 118 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/IridescentDrake.java diff --git a/Mage.Sets/src/mage/cards/i/IridescentDrake.java b/Mage.Sets/src/mage/cards/i/IridescentDrake.java new file mode 100644 index 0000000000..223ddb3276 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IridescentDrake.java @@ -0,0 +1,117 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.predicate.other.AuraCardCanAttachToPermanentId; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCardInGraveyard; + +/** + * + * @author TheElk801 + */ +public class IridescentDrake extends CardImpl { + + public IridescentDrake(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.DRAKE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Iridescent Drake enters the battlefield, put target Aura card from a graveyard onto the battlefield under your control attached to Iridescent Drake. + Ability ability = new EntersBattlefieldTriggeredAbility(new IridescentDrakeEffect()); + ability.addTarget(new TargetCardInGraveyard()); + this.addAbility(ability); + } + + public IridescentDrake(final IridescentDrake card) { + super(card); + } + + @Override + public IridescentDrake copy() { + return new IridescentDrake(this); + } +} + +class IridescentDrakeEffect extends OneShotEffect { + + public IridescentDrakeEffect() { + super(Outcome.Benefit); + this.staticText = "put target Aura card from a graveyard onto the battlefield under your control attached to {this}"; + } + + public IridescentDrakeEffect(final IridescentDrakeEffect effect) { + super(effect); + } + + @Override + public IridescentDrakeEffect copy() { + return new IridescentDrakeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getSourceId()); + Card targetAuraCard = game.getCard(source.getFirstTarget()); + if (controller != null + && permanent != null + && controller.canRespond() + && targetAuraCard != null + && new AuraCardCanAttachToPermanentId(permanent.getId()).apply(targetAuraCard, game)) { + Target target = targetAuraCard.getSpellAbility().getTargets().get(0); + if (target != null) { + game.getState().setValue("attachTo:" + targetAuraCard.getId(), permanent); + controller.moveCards(targetAuraCard, Zone.BATTLEFIELD, source, game); + return permanent.addAttachment(targetAuraCard.getId(), game); + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasDestiny.java b/Mage.Sets/src/mage/sets/UrzasDestiny.java index 87ed6e299a..e05b5e775a 100644 --- a/Mage.Sets/src/mage/sets/UrzasDestiny.java +++ b/Mage.Sets/src/mage/sets/UrzasDestiny.java @@ -104,6 +104,7 @@ public class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Hunting Moa", 109, Rarity.UNCOMMON, mage.cards.h.HuntingMoa.class)); cards.add(new SetCardInfo("Illuminated Wings", 34, Rarity.COMMON, mage.cards.i.IlluminatedWings.class)); cards.add(new SetCardInfo("Impatience", 88, Rarity.RARE, mage.cards.i.Impatience.class)); + cards.add(new SetCardInfo("Iridescent Drake", 35, Rarity.UNCOMMON, mage.cards.i.IridescentDrake.class)); cards.add(new SetCardInfo("Junk Diver", 132, Rarity.RARE, mage.cards.j.JunkDiver.class)); cards.add(new SetCardInfo("Keldon Champion", 90, Rarity.UNCOMMON, mage.cards.k.KeldonChampion.class)); cards.add(new SetCardInfo("Keldon Vandals", 91, Rarity.COMMON, mage.cards.k.KeldonVandals.class)); From 1fb37a3834d96b373bd5ac5130a6cc5b27767e04 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 14:49:30 -0400 Subject: [PATCH 155/182] fixed Sunbird's Invocation not using LKI --- Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index aa541a7d06..e451faaa09 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -92,7 +92,7 @@ class SunbirdsInvocationTriggeredAbility extends SpellCastControllerTriggeredAbi if (spell != null && spell.getFromZone() == Zone.HAND) { if (spell.getCard() != null) { for (Effect effect : getEffects()) { - effect.setTargetPointer(new FixedTarget(spell.getId())); + effect.setTargetPointer(new FixedTarget(spell.getId(), spell.getZoneChangeCounter(game))); } return true; } @@ -126,7 +126,7 @@ class SunbirdsInvocationEffect extends OneShotEffect { return false; } Cards cards = new CardsImpl(); - int xValue = game.getStack().getSpell(getTargetPointer().getFirst(game, source)).getConvertedManaCost(); + int xValue = game.getLastKnownInformation(this.getTargetPointer().getFirst(game, source), Zone.STACK).getConvertedManaCost(); cards.addAll(controller.getLibrary().getTopCards(game, xValue)); if (!cards.isEmpty()) { controller.revealCards(sourceObject.getIdName(), cards, game); From c6fe18d3986dfc9921093cb6993dda95fd1b6494 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 17 Sep 2017 22:32:40 +0200 Subject: [PATCH 156/182] * Tunnel Vision - Reworked card movement. --- Mage.Sets/src/mage/cards/t/TunnelVision.java | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Mage.Sets/src/mage/cards/t/TunnelVision.java b/Mage.Sets/src/mage/cards/t/TunnelVision.java index 03ef8cd3b8..9c1b33d698 100644 --- a/Mage.Sets/src/mage/cards/t/TunnelVision.java +++ b/Mage.Sets/src/mage/cards/t/TunnelVision.java @@ -27,6 +27,8 @@ */ package mage.cards.t; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; @@ -51,10 +53,10 @@ import mage.target.TargetPlayer; public class TunnelVision extends CardImpl { public TunnelVision(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{U}"); - // Name a card. Target player reveals cards from the top of his or her library until the named card is revealed. - // If it is, that player puts the rest of the revealed cards into his or her graveyard and puts the named card on top of his or her library. + // Name a card. Target player reveals cards from the top of his or her library until the named card is revealed. + // If it is, that player puts the rest of the revealed cards into his or her graveyard and puts the named card on top of his or her library. // Otherwise, the player shuffles his or her library. this.getSpellAbility().addEffect(new NameACardEffect(NameACardEffect.TypeOfName.ALL)); this.getSpellAbility().addEffect(new TunnelVisionEffect()); @@ -74,7 +76,7 @@ public class TunnelVision extends CardImpl { class TunnelVisionEffect extends OneShotEffect { public TunnelVisionEffect() { - super(Outcome.Damage); + super(Outcome.Benefit); this.staticText = "Target player reveals cards from the top of his or her library until the named card is revealed. If it is, that player puts the rest of the revealed cards into his or her graveyard and puts the named card on top of his or her library. Otherwise, the player shuffles his or her library."; } @@ -90,16 +92,16 @@ class TunnelVisionEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { MageObject sourceObject = game.getObject(source.getSourceId()); - Player targetPlayer = game.getPlayer(source.getFirstTarget()); + Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); String cardName = (String) game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY); if (sourceObject == null || targetPlayer == null || cardName == null || cardName.isEmpty()) { return false; } Cards cardsToReveal = new CardsImpl(); - Cards cardsToBury = new CardsImpl(); + Set cardsToBury = new HashSet<>(); Card namedCard = null; - + // reveal until named card found // if named card found, put all revealed cards in grave and put named card on top of library // if named card not found, shuffle library @@ -117,15 +119,15 @@ class TunnelVisionEffect extends OneShotEffect { } } } - + targetPlayer.revealCards(sourceObject.getIdName(), cardsToReveal, game); if (namedCardFound) { targetPlayer.moveCards(cardsToBury, Zone.GRAVEYARD, source, game); targetPlayer.moveCards(namedCard, Zone.LIBRARY, source, game); } else { + targetPlayer.getLibrary().addAll(cardsToBury, game); targetPlayer.shuffleLibrary(source, game); } - return true; } } From 1d5105c0bde58024223dfe24c7f3a7d9aaea40a1 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 17 Sep 2017 23:11:38 +0200 Subject: [PATCH 157/182] Xmage 1.4.26V5 --- Mage.Common/src/main/java/mage/utils/MageVersion.java | 2 +- Mage/src/main/java/mage/cards/repository/CardRepository.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java index e0c0a9435a..5238bd4f7c 100644 --- a/Mage.Common/src/main/java/mage/utils/MageVersion.java +++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java @@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable { public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MINOR = 4; public final static int MAGE_VERSION_PATCH = 26; - public final static String MAGE_VERSION_MINOR_PATCH = "V4"; + public final static String MAGE_VERSION_MINOR_PATCH = "V5"; public final static String MAGE_VERSION_INFO = ""; private final int major; diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index 36a866cf23..87239f4c12 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -58,7 +58,7 @@ public enum CardRepository { // raise this if db structure was changed private static final long CARD_DB_VERSION = 51; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 91; + private static final long CARD_CONTENT_VERSION = 92; private Dao cardDao; private Set classNames; From 493b4ad65c38a6602ce106ba7e8014170c7fff47 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 17:07:00 -0400 Subject: [PATCH 158/182] Implemented Strongarm Tactics --- .../src/mage/cards/s/StrongarmTactics.java | 124 ++++++++++++++++++ Mage.Sets/src/mage/sets/Onslaught.java | 1 + 2 files changed, 125 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/StrongarmTactics.java diff --git a/Mage.Sets/src/mage/cards/s/StrongarmTactics.java b/Mage.Sets/src/mage/cards/s/StrongarmTactics.java new file mode 100644 index 0000000000..8cf580d96a --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StrongarmTactics.java @@ -0,0 +1,124 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.HashMap; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetDiscard; + +/** + * + * @author TheElk801 + */ +public class StrongarmTactics extends CardImpl { + + public StrongarmTactics(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); + + // Each player discards a card. Then each player who didn't discard a creature card this way loses 4 life. + this.getSpellAbility().addEffect(new StrongarmTacticsEffect()); + } + + public StrongarmTactics(final StrongarmTactics card) { + super(card); + } + + @Override + public StrongarmTactics copy() { + return new StrongarmTactics(this); + } +} + +class StrongarmTacticsEffect extends OneShotEffect { + + StrongarmTacticsEffect() { + super(Outcome.Discard); + this.staticText = "Each player discards a card. Then each player who didn't discard a creature card this way loses 4 life."; + } + + StrongarmTacticsEffect(final StrongarmTacticsEffect effect) { + super(effect); + } + + @Override + public StrongarmTacticsEffect copy() { + return new StrongarmTacticsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + // Store for each player the cards to discard, that's important because all discard shall happen at the same time + HashMap cardsToDiscard = new HashMap<>(); + if (controller != null) { + // choose cards to discard + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + int numberOfCardsToDiscard = Math.min(1, player.getHand().size()); + Cards cards = new CardsImpl(); + Target target = new TargetDiscard(numberOfCardsToDiscard, numberOfCardsToDiscard, new FilterCard(), playerId); + player.chooseTarget(outcome, target, source, game); + cards.addAll(target.getTargets()); + cardsToDiscard.put(playerId, cards); + } + } + // discard all choosen cards + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + Cards cardsPlayer = cardsToDiscard.get(playerId); + if (cardsPlayer != null) { + for (UUID cardId : cardsPlayer) { + Card card = game.getCard(cardId); + if (card != null) { + if (!(player.discard(card, source, game) && card.isCreature())) { + player.loseLife(4, game, false); + } + } + } + } + } + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Onslaught.java b/Mage.Sets/src/mage/sets/Onslaught.java index 493fbb2b48..b38d6a752e 100644 --- a/Mage.Sets/src/mage/sets/Onslaught.java +++ b/Mage.Sets/src/mage/sets/Onslaught.java @@ -276,6 +276,7 @@ public class Onslaught extends ExpansionSet { cards.add(new SetCardInfo("Starlit Sanctum", 325, Rarity.UNCOMMON, mage.cards.s.StarlitSanctum.class)); cards.add(new SetCardInfo("Starstorm", 238, Rarity.RARE, mage.cards.s.Starstorm.class)); cards.add(new SetCardInfo("Steely Resolve", 286, Rarity.RARE, mage.cards.s.SteelyResolve.class)); + cards.add(new SetCardInfo("Strongarm Tactics", 173, Rarity.RARE, mage.cards.s.StrongarmTactics.class)); cards.add(new SetCardInfo("Sunfire Balm", 56, Rarity.UNCOMMON, mage.cards.s.SunfireBalm.class)); cards.add(new SetCardInfo("Supreme Inquisitor", 117, Rarity.RARE, mage.cards.s.SupremeInquisitor.class)); cards.add(new SetCardInfo("Swamp", 339, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); From 1311cf52bbc950bc061bb5a92a51ecb372986381 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 18:02:54 -0400 Subject: [PATCH 159/182] Implemented Teferi's Veil --- Mage.Sets/src/mage/cards/t/TeferisVeil.java | 63 +++++++++++++++++++++ Mage.Sets/src/mage/sets/Weatherlight.java | 1 + 2 files changed, 64 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TeferisVeil.java diff --git a/Mage.Sets/src/mage/cards/t/TeferisVeil.java b/Mage.Sets/src/mage/cards/t/TeferisVeil.java new file mode 100644 index 0000000000..58ff55d718 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TeferisVeil.java @@ -0,0 +1,63 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.PhaseOutTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class TeferisVeil extends CardImpl { + + public TeferisVeil(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); + + // Whenever a creature you control attacks, it phases out at end of combat. + Effect effect = new CreateDelayedTriggeredAbilityEffect(new AtTheEndOfCombatDelayedTriggeredAbility(new PhaseOutTargetEffect("it", false))); + effect.setText("it phases out at end of combat"); + this.addAbility(new AttacksCreatureYouControlTriggeredAbility(effect, false, true)); + } + + public TeferisVeil(final TeferisVeil card) { + super(card); + } + + @Override + public TeferisVeil copy() { + return new TeferisVeil(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Weatherlight.java b/Mage.Sets/src/mage/sets/Weatherlight.java index b3a5344f6a..a27842ad07 100644 --- a/Mage.Sets/src/mage/sets/Weatherlight.java +++ b/Mage.Sets/src/mage/sets/Weatherlight.java @@ -178,6 +178,7 @@ public class Weatherlight extends ExpansionSet { cards.add(new SetCardInfo("Straw Golem", 158, Rarity.UNCOMMON, mage.cards.s.StrawGolem.class)); cards.add(new SetCardInfo("Striped Bears", 82, Rarity.COMMON, mage.cards.s.StripedBears.class)); cards.add(new SetCardInfo("Tariff", 144, Rarity.RARE, mage.cards.t.Tariff.class)); + cards.add(new SetCardInfo("Teferi's Veil", 53, Rarity.UNCOMMON, mage.cards.t.TeferisVeil.class)); cards.add(new SetCardInfo("Tendrils of Despair", 25, Rarity.COMMON, mage.cards.t.TendrilsOfDespair.class)); cards.add(new SetCardInfo("Thunderbolt", 115, Rarity.COMMON, mage.cards.t.Thunderbolt.class)); cards.add(new SetCardInfo("Thundermare", 116, Rarity.RARE, mage.cards.t.Thundermare.class)); From 473834b1da5a72d6f85b7c922247d5edc4279b0b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 18:11:50 -0400 Subject: [PATCH 160/182] updated Cyclonic Rift --- Mage.Sets/src/mage/cards/c/CyclonicRift.java | 44 +++----------------- 1 file changed, 6 insertions(+), 38 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CyclonicRift.java b/Mage.Sets/src/mage/cards/c/CyclonicRift.java index b9c1262408..826f7606dc 100644 --- a/Mage.Sets/src/mage/cards/c/CyclonicRift.java +++ b/Mage.Sets/src/mage/cards/c/CyclonicRift.java @@ -28,21 +28,17 @@ package mage.cards.c; import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.abilities.keyword.OverloadAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.TargetController; -import mage.constants.Zone; import mage.filter.common.FilterNonlandPermanent; import mage.filter.predicate.permanent.ControllerPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.common.TargetNonlandPermanent; /** @@ -58,14 +54,16 @@ public class CyclonicRift extends CardImpl { } public CyclonicRift(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Return target nonland permanent you don't control to its owner's hand. this.getSpellAbility().addTarget(new TargetNonlandPermanent(filter)); this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); // Overload {6}{U} (You may cast this spell for its overload cost. If you do, change its text by replacing all instances of "target" with "each.") - this.addAbility(new OverloadAbility(this, new CyclonicRiftEffect(), new ManaCostsImpl("{6}{U}"))); + Effect effect = new ReturnToHandFromBattlefieldAllEffect(filter); + effect.setText("Return each nonland permanent you don't control to its owner's hand"); + this.addAbility(new OverloadAbility(this, effect, new ManaCostsImpl("{6}{U}"))); } public CyclonicRift(final CyclonicRift card) { @@ -77,33 +75,3 @@ public class CyclonicRift extends CardImpl { return new CyclonicRift(this); } } - -class CyclonicRiftEffect extends OneShotEffect { - - private static final FilterNonlandPermanent filter = new FilterNonlandPermanent(); - - public CyclonicRiftEffect() { - super(Outcome.ReturnToHand); - staticText = "Return each nonland permanent you don't control to its owner's hand"; - } - - public CyclonicRiftEffect(final CyclonicRiftEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { - if (!creature.getControllerId().equals(source.getControllerId())) { - creature.moveToZone(Zone.HAND, source.getSourceId(), game, true); - } - - } - return true; - } - - @Override - public CyclonicRiftEffect copy() { - return new CyclonicRiftEffect(this); - } -} From 5a6ae913ecda3015b8f7e19d9d6d2f846cb8a639 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 18:40:18 -0400 Subject: [PATCH 161/182] Implemented Reborn Hero --- Mage.Sets/src/mage/cards/r/RebornHero.java | 91 ++++++++++++++++++++++ Mage.Sets/src/mage/sets/Torment.java | 1 + 2 files changed, 92 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RebornHero.java diff --git a/Mage.Sets/src/mage/cards/r/RebornHero.java b/Mage.Sets/src/mage/cards/r/RebornHero.java new file mode 100644 index 0000000000..36bbc8221f --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RebornHero.java @@ -0,0 +1,91 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class RebornHero extends CardImpl { + + public RebornHero(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Threshold - As long as seven or more cards are in your graveyard, Reborn Hero has "When Reborn Hero dies, you may pay {W}{W}. If you do, return Reborn Hero to the battlefield under your control." + Ability ability = new SimpleStaticAbility( + Zone.BATTLEFIELD, + new ConditionalContinuousEffect( + new GainAbilitySourceEffect(new DiesTriggeredAbility(new DoIfCostPaid( + new ReturnSourceFromGraveyardToBattlefieldEffect(), new ManaCostsImpl("{W}{W}") + ))), + new CardsInControllerGraveCondition(7), + "As long as seven or more cards are in your graveyard, " + + "{this} has \"When {this} dies, you may pay {W}{W}. " + + "If you do, return {this} to the battlefield under your control.\"" + ) + ); + ability.setAbilityWord(AbilityWord.THRESHOLD); + this.addAbility(ability); + } + + public RebornHero(final RebornHero card) { + super(card); + } + + @Override + public RebornHero copy() { + return new RebornHero(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Torment.java b/Mage.Sets/src/mage/sets/Torment.java index 3a579e84d1..7ece361cda 100644 --- a/Mage.Sets/src/mage/sets/Torment.java +++ b/Mage.Sets/src/mage/sets/Torment.java @@ -151,6 +151,7 @@ public class Torment extends ExpansionSet { cards.add(new SetCardInfo("Pyromania", 112, Rarity.UNCOMMON, mage.cards.p.Pyromania.class)); cards.add(new SetCardInfo("Radiate", 113, Rarity.RARE, mage.cards.r.Radiate.class)); cards.add(new SetCardInfo("Rancid Earth", 78, Rarity.COMMON, mage.cards.r.RancidEarth.class)); + cards.add(new SetCardInfo("Reborn Hero", 14, Rarity.RARE, mage.cards.r.RebornHero.class)); cards.add(new SetCardInfo("Restless Dreams", 79, Rarity.COMMON, mage.cards.r.RestlessDreams.class)); cards.add(new SetCardInfo("Sengir Vampire", 80, Rarity.RARE, mage.cards.s.SengirVampire.class)); cards.add(new SetCardInfo("Seton's Scout", 138, Rarity.UNCOMMON, mage.cards.s.SetonsScout.class)); From 6ab143c1236b30f5e488a6577af1839167a67439 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 18:55:06 -0400 Subject: [PATCH 162/182] Implemented Mine Layer --- Mage.Sets/src/mage/cards/m/MineLayer.java | 121 ++++++++++++++++++ Mage.Sets/src/mage/sets/Odyssey.java | 1 + .../main/java/mage/counters/CounterType.java | 1 + 3 files changed, 123 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MineLayer.java diff --git a/Mage.Sets/src/mage/cards/m/MineLayer.java b/Mage.Sets/src/mage/cards/m/MineLayer.java new file mode 100644 index 0000000000..1c2342f629 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MineLayer.java @@ -0,0 +1,121 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BecomesTappedTriggeredAbility; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.permanent.CounterPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author TheElk801 + */ +public class MineLayer extends CardImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent("land with a mine counter on it"); + + static { + filter.add(new CounterPredicate(CounterType.MINE)); + } + + public MineLayer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.DWARF); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {1}{R}, {tap}: Put a mine counter on target land. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.MINE.createInstance()), new TapSourceCost()); + ability.addCost(new ManaCostsImpl("{1}{R}")); + ability.addTarget(new TargetLandPermanent()); + this.addAbility(ability); + + // Whenever a land with a mine counter on it becomes tapped, destroy it. + this.addAbility(new BecomesTappedTriggeredAbility(new DestroyTargetEffect().setText("destroy that land"), false, filter, true)); + + // When Mine Layer leaves the battlefield, remove all mine counters from all lands. + this.addAbility(new LeavesBattlefieldTriggeredAbility(new RemoveAllMineCountersEffect(), false)); + } + + public MineLayer(final MineLayer card) { + super(card); + } + + @Override + public MineLayer copy() { + return new MineLayer(this); + } +} + +class RemoveAllMineCountersEffect extends OneShotEffect { + + public RemoveAllMineCountersEffect() { + super(Outcome.Neutral); + this.staticText = "remove all mine counters from all lands"; + } + + public RemoveAllMineCountersEffect(final RemoveAllMineCountersEffect effect) { + super(effect); + } + + @Override + public RemoveAllMineCountersEffect copy() { + return new RemoveAllMineCountersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(CardType.LAND)) { + if (permanent != null) { + permanent.getCounters(game).removeAllCounters(CounterType.MINE); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Odyssey.java b/Mage.Sets/src/mage/sets/Odyssey.java index e5a0611070..fdc27640f4 100644 --- a/Mage.Sets/src/mage/sets/Odyssey.java +++ b/Mage.Sets/src/mage/sets/Odyssey.java @@ -214,6 +214,7 @@ public class Odyssey extends ExpansionSet { cards.add(new SetCardInfo("Metamorphic Wurm", 250, Rarity.UNCOMMON, mage.cards.m.MetamorphicWurm.class)); cards.add(new SetCardInfo("Millikin", 302, Rarity.UNCOMMON, mage.cards.m.Millikin.class)); cards.add(new SetCardInfo("Mindslicer", 149, Rarity.RARE, mage.cards.m.Mindslicer.class)); + cards.add(new SetCardInfo("Mine Layer", 205, Rarity.RARE, mage.cards.m.MineLayer.class)); cards.add(new SetCardInfo("Minotaur Explorer", 206, Rarity.UNCOMMON, mage.cards.m.MinotaurExplorer.class)); cards.add(new SetCardInfo("Mirari", 303, Rarity.RARE, mage.cards.m.Mirari.class)); cards.add(new SetCardInfo("Molten Influence", 207, Rarity.RARE, mage.cards.m.MoltenInfluence.class)); diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index 51057ed86b..cc7ff45b3e 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -87,6 +87,7 @@ public enum CounterType { M1M1(new BoostCounter(-1, -1).name), M2M1(new BoostCounter(-2, -1).name), M2M2(new BoostCounter(-2, -2).name), + MINE("mine"), MINING("mining"), MIRE("mire"), MUSTER("muster"), From 1819c6e8a8e6dab68507ec01476cc1b40e3e6671 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 19:56:59 -0400 Subject: [PATCH 163/182] Implemented Game Preserve --- .../src/mage/cards/d/DuskmantleSeer.java | 11 +- Mage.Sets/src/mage/cards/g/GamePreserve.java | 113 ++++++++++++++++++ Mage.Sets/src/mage/sets/MercadianMasques.java | 1 + 3 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/g/GamePreserve.java diff --git a/Mage.Sets/src/mage/cards/d/DuskmantleSeer.java b/Mage.Sets/src/mage/cards/d/DuskmantleSeer.java index 2f1783b325..6fd7248a7e 100644 --- a/Mage.Sets/src/mage/cards/d/DuskmantleSeer.java +++ b/Mage.Sets/src/mage/cards/d/DuskmantleSeer.java @@ -40,6 +40,7 @@ import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; import mage.game.Game; +import mage.game.permanent.Permanent; import mage.players.Player; /** @@ -49,7 +50,7 @@ import mage.players.Player; public class DuskmantleSeer extends CardImpl { public DuskmantleSeer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{B}"); this.subtype.add(SubType.VAMPIRE); this.subtype.add(SubType.WIZARD); @@ -91,15 +92,15 @@ class DuskmantleSeerEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Card sourceCard = game.getCard(source.getSourceId()); + Permanent sourceCard = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (sourceCard == null) { return false; } - for (Player player: game.getPlayers().values()) { - if(player.getLibrary().hasCards()){ + for (Player player : game.getPlayers().values()) { + if (player.getLibrary().hasCards()) { Card card = player.getLibrary().removeFromTop(game); if (card != null) { - Cards cards = new CardsImpl(); + Cards cards = new CardsImpl(); cards.add(card); player.revealCards(sourceCard.getName() + ": Revealed by " + player.getName(), cards, game); player.loseLife(card.getConvertedManaCost(), game, false); diff --git a/Mage.Sets/src/mage/cards/g/GamePreserve.java b/Mage.Sets/src/mage/cards/g/GamePreserve.java new file mode 100644 index 0000000000..300ed6a40a --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GamePreserve.java @@ -0,0 +1,113 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class GamePreserve extends CardImpl { + + public GamePreserve(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); + + // At the beginning of your upkeep, each player reveals the top card of his or her library. If all cards revealed this way are creature cards, put those cards onto the battlefield under their owners' control. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DuskmarEffect(), TargetController.YOU, false)); + } + + public GamePreserve(final GamePreserve card) { + super(card); + } + + @Override + public GamePreserve copy() { + return new GamePreserve(this); + } +} + +class DuskmarEffect extends OneShotEffect { + + public DuskmarEffect() { + super(Outcome.Detriment); + this.staticText = "each player reveals the top card of his or her library. If all cards revealed this way are creature cards, put those cards onto the battlefield under their owners' control"; + } + + public DuskmarEffect(final DuskmarEffect effect) { + super(effect); + } + + @Override + public DuskmarEffect copy() { + return new DuskmarEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourceCard = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (sourceCard == null) { + return false; + } + boolean putToPlay = true; + Cards cards = new CardsImpl(); + for (Player player : game.getPlayers().values()) { + if (player.getLibrary().hasCards()) { + Card card = player.getLibrary().removeFromTop(game); + if (card != null) { + cards.add(card); + if (!card.isCreature()) { + putToPlay = false; + } + player.revealCards(sourceCard.getName() + ": Revealed by " + player.getName(), cards, game); + } + } else { + putToPlay = false; + } + } + if (putToPlay) { + game.getPlayers().values().iterator().next().moveCards(cards.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/MercadianMasques.java b/Mage.Sets/src/mage/sets/MercadianMasques.java index 8fb42c57ac..c759f2889e 100644 --- a/Mage.Sets/src/mage/sets/MercadianMasques.java +++ b/Mage.Sets/src/mage/sets/MercadianMasques.java @@ -151,6 +151,7 @@ public class MercadianMasques extends ExpansionSet { cards.add(new SetCardInfo("Fountain Watch", 19, Rarity.RARE, mage.cards.f.FountainWatch.class)); cards.add(new SetCardInfo("Fresh Volunteers", 20, Rarity.COMMON, mage.cards.f.FreshVolunteers.class)); cards.add(new SetCardInfo("Furious Assault", 191, Rarity.COMMON, mage.cards.f.FuriousAssault.class)); + cards.add(new SetCardInfo("Game Preserve", 248, Rarity.RARE, mage.cards.g.GamePreserve.class)); cards.add(new SetCardInfo("Gerrard's Irregulars", 192, Rarity.COMMON, mage.cards.g.GerrardsIrregulars.class)); cards.add(new SetCardInfo("Ghoul's Feast", 137, Rarity.UNCOMMON, mage.cards.g.GhoulsFeast.class)); cards.add(new SetCardInfo("Giant Caterpillar", 249, Rarity.COMMON, mage.cards.g.GiantCaterpillar.class)); From 356737075a8af9596db5ec1db76f59cffa484528 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 19:57:54 -0400 Subject: [PATCH 164/182] Revert "Skulk is now singleton" This reverts commit 6ca03a339a41bbbfcbd8ee806e9c332ca87160d1. --- .../src/mage/cards/b/BehindTheScenes.java | 2 +- .../src/mage/cards/f/FarbogRevenant.java | 2 +- Mage.Sets/src/mage/cards/f/Fogwalker.java | 2 +- .../src/mage/cards/f/ForgottenCreation.java | 2 +- .../src/mage/cards/f/FurtiveHomunculus.java | 2 +- .../src/mage/cards/o/OdricLunarchMarshal.java | 4 ++-- .../src/mage/cards/p/PaleRiderOfTrostad.java | 2 +- .../src/mage/cards/p/PersistentNightmare.java | 2 +- Mage.Sets/src/mage/cards/r/RancidRats.java | 2 +- Mage.Sets/src/mage/cards/s/SkeletonKey.java | 2 +- .../src/mage/cards/u/UninvitedGeist.java | 2 +- .../src/mage/cards/v/VampireCutthroat.java | 2 +- .../src/mage/cards/w/WharfInfiltrator.java | 2 +- .../abilities/add/GainAbilitiesTest.java | 22 ++++++++--------- .../mage/abilities/keyword/SkulkAbility.java | 24 +++++++------------ Utils/keywords.txt | 2 +- 16 files changed, 35 insertions(+), 41 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BehindTheScenes.java b/Mage.Sets/src/mage/cards/b/BehindTheScenes.java index 49aca371a8..2433120f34 100644 --- a/Mage.Sets/src/mage/cards/b/BehindTheScenes.java +++ b/Mage.Sets/src/mage/cards/b/BehindTheScenes.java @@ -52,7 +52,7 @@ public class BehindTheScenes extends CardImpl { // Creatures you control have skulk. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new GainAbilityControlledEffect(SkulkAbility.getInstance(), Duration.WhileOnBattlefield, FILTER_PERMANENT_CREATURES))); + new GainAbilityControlledEffect(new SkulkAbility(), Duration.WhileOnBattlefield, FILTER_PERMANENT_CREATURES))); // {4}{W}: Creatures you control get +1/+1 until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, diff --git a/Mage.Sets/src/mage/cards/f/FarbogRevenant.java b/Mage.Sets/src/mage/cards/f/FarbogRevenant.java index 6e4a727a08..3bdfb80d93 100644 --- a/Mage.Sets/src/mage/cards/f/FarbogRevenant.java +++ b/Mage.Sets/src/mage/cards/f/FarbogRevenant.java @@ -49,7 +49,7 @@ public class FarbogRevenant extends CardImpl { this.toughness = new MageInt(3); // Skulk - this.addAbility(SkulkAbility.getInstance()); + this.addAbility(new SkulkAbility()); // Lifelink this.addAbility(LifelinkAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/f/Fogwalker.java b/Mage.Sets/src/mage/cards/f/Fogwalker.java index 5ae2894020..eaf42be950 100644 --- a/Mage.Sets/src/mage/cards/f/Fogwalker.java +++ b/Mage.Sets/src/mage/cards/f/Fogwalker.java @@ -60,7 +60,7 @@ public class Fogwalker extends CardImpl { this.toughness = new MageInt(3); // Skulk - this.addAbility(SkulkAbility.getInstance()); + this.addAbility(new SkulkAbility()); // When Fogwalker enters the battlefield, target creature an opponent controls doesn't untap during it controler's next untap step. EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DontUntapInControllersNextUntapStepTargetEffect()); ability.addTarget(new TargetCreaturePermanent(filter)); diff --git a/Mage.Sets/src/mage/cards/f/ForgottenCreation.java b/Mage.Sets/src/mage/cards/f/ForgottenCreation.java index f5435fdc02..37bfc59efe 100644 --- a/Mage.Sets/src/mage/cards/f/ForgottenCreation.java +++ b/Mage.Sets/src/mage/cards/f/ForgottenCreation.java @@ -56,7 +56,7 @@ public class ForgottenCreation extends CardImpl { this.toughness = new MageInt(3); // Skulk - this.addAbility(SkulkAbility.getInstance()); + this.addAbility(new SkulkAbility()); // At the beginning of your upkeep, you may discard all the cards in your hand. If you do, draw that many cards. this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ForgottenCreationEffect(), TargetController.YOU, true)); } diff --git a/Mage.Sets/src/mage/cards/f/FurtiveHomunculus.java b/Mage.Sets/src/mage/cards/f/FurtiveHomunculus.java index 11fc20bf02..de4abdb094 100644 --- a/Mage.Sets/src/mage/cards/f/FurtiveHomunculus.java +++ b/Mage.Sets/src/mage/cards/f/FurtiveHomunculus.java @@ -48,7 +48,7 @@ public class FurtiveHomunculus extends CardImpl { this.toughness = new MageInt(1); // Skulk (This creature can't be blocked by creatures with greater power.) - this.addAbility(SkulkAbility.getInstance()); + this.addAbility(new SkulkAbility()); } public FurtiveHomunculus(final FurtiveHomunculus card) { diff --git a/Mage.Sets/src/mage/cards/o/OdricLunarchMarshal.java b/Mage.Sets/src/mage/cards/o/OdricLunarchMarshal.java index 353a072d4b..a88797dcdc 100644 --- a/Mage.Sets/src/mage/cards/o/OdricLunarchMarshal.java +++ b/Mage.Sets/src/mage/cards/o/OdricLunarchMarshal.java @@ -171,7 +171,7 @@ class OdricLunarchMarshalEffect extends OneShotEffect { // Skulk if (game.getBattlefield().contains(filterSkulk, source.getControllerId(), 1, game)) { - game.addEffect(new GainAbilityControlledEffect(SkulkAbility.getInstance(), Duration.EndOfTurn, filterCreatures), source); + game.addEffect(new GainAbilityControlledEffect(new SkulkAbility(), Duration.EndOfTurn, filterCreatures), source); } // Trample @@ -185,4 +185,4 @@ class OdricLunarchMarshalEffect extends OneShotEffect { } return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/p/PaleRiderOfTrostad.java b/Mage.Sets/src/mage/cards/p/PaleRiderOfTrostad.java index e270688f21..f09cf4f27b 100644 --- a/Mage.Sets/src/mage/cards/p/PaleRiderOfTrostad.java +++ b/Mage.Sets/src/mage/cards/p/PaleRiderOfTrostad.java @@ -50,7 +50,7 @@ public class PaleRiderOfTrostad extends CardImpl { this.toughness = new MageInt(3); // Skulk - this.addAbility(SkulkAbility.getInstance()); + this.addAbility(new SkulkAbility()); // When Pale Rider of Trostad enters the battlefield, discard a card. this.addAbility(new EntersBattlefieldTriggeredAbility(new DiscardControllerEffect(1), false)); diff --git a/Mage.Sets/src/mage/cards/p/PersistentNightmare.java b/Mage.Sets/src/mage/cards/p/PersistentNightmare.java index 59a76bd4ff..efaf3951a0 100644 --- a/Mage.Sets/src/mage/cards/p/PersistentNightmare.java +++ b/Mage.Sets/src/mage/cards/p/PersistentNightmare.java @@ -54,7 +54,7 @@ public class PersistentNightmare extends CardImpl { this.nightCard = true; // Skulk - this.addAbility(SkulkAbility.getInstance()); + this.addAbility(new SkulkAbility()); // When Persistent Nightmare deals combat damage to a player, return it to its owner's hand. this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnToHandSourceEffect(), false)); diff --git a/Mage.Sets/src/mage/cards/r/RancidRats.java b/Mage.Sets/src/mage/cards/r/RancidRats.java index 630cf94c5c..4dfdb9d069 100644 --- a/Mage.Sets/src/mage/cards/r/RancidRats.java +++ b/Mage.Sets/src/mage/cards/r/RancidRats.java @@ -50,7 +50,7 @@ public class RancidRats extends CardImpl { this.toughness = new MageInt(1); // Skulk - this.addAbility(SkulkAbility.getInstance()); + this.addAbility(new SkulkAbility()); // Deathtouch this.addAbility(DeathtouchAbility.getInstance()); } diff --git a/Mage.Sets/src/mage/cards/s/SkeletonKey.java b/Mage.Sets/src/mage/cards/s/SkeletonKey.java index dc3774257d..72dc2d91d3 100644 --- a/Mage.Sets/src/mage/cards/s/SkeletonKey.java +++ b/Mage.Sets/src/mage/cards/s/SkeletonKey.java @@ -57,7 +57,7 @@ public class SkeletonKey extends CardImpl { this.subtype.add(SubType.EQUIPMENT); // Equipped creature has skulk. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(SkulkAbility.getInstance(), AttachmentType.EQUIPMENT))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(new SkulkAbility(), AttachmentType.EQUIPMENT))); // Whenever equipped creature deals combat damage to a player, you may draw a card. if you do, discard a card. Ability ability = new DealsDamageToAPlayerAttachedTriggeredAbility(new DrawCardSourceControllerEffect(1), "equipped creature", true); diff --git a/Mage.Sets/src/mage/cards/u/UninvitedGeist.java b/Mage.Sets/src/mage/cards/u/UninvitedGeist.java index 037328203e..4dd1c9776e 100644 --- a/Mage.Sets/src/mage/cards/u/UninvitedGeist.java +++ b/Mage.Sets/src/mage/cards/u/UninvitedGeist.java @@ -54,7 +54,7 @@ public class UninvitedGeist extends CardImpl { this.secondSideCardClazz = UnimpededTrespasser.class; // Skulk (This creature can't be blocked by creatures with greater power.) - this.addAbility(SkulkAbility.getInstance()); + this.addAbility(new SkulkAbility()); // When Uninvited Geist deals combat damage to a player, transform it. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/v/VampireCutthroat.java b/Mage.Sets/src/mage/cards/v/VampireCutthroat.java index b57163f93c..a83227695c 100644 --- a/Mage.Sets/src/mage/cards/v/VampireCutthroat.java +++ b/Mage.Sets/src/mage/cards/v/VampireCutthroat.java @@ -50,7 +50,7 @@ public class VampireCutthroat extends CardImpl { this.toughness = new MageInt(1); // Skulk - this.addAbility(SkulkAbility.getInstance()); + this.addAbility(new SkulkAbility()); // Lifelink this.addAbility(LifelinkAbility.getInstance()); } diff --git a/Mage.Sets/src/mage/cards/w/WharfInfiltrator.java b/Mage.Sets/src/mage/cards/w/WharfInfiltrator.java index 9c49a67b5d..9e3116fc85 100644 --- a/Mage.Sets/src/mage/cards/w/WharfInfiltrator.java +++ b/Mage.Sets/src/mage/cards/w/WharfInfiltrator.java @@ -62,7 +62,7 @@ public class WharfInfiltrator extends CardImpl { this.toughness = new MageInt(1); // Skulk - this.addAbility(SkulkAbility.getInstance()); + this.addAbility(new SkulkAbility()); // Whenever Wharf Infiltrator deals combat damage to a player, you may draw a card. If you do, discard a card. Effect effect = new DrawDiscardControllerEffect(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/add/GainAbilitiesTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/add/GainAbilitiesTest.java index 8096df1ee3..8b519b9416 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/add/GainAbilitiesTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/add/GainAbilitiesTest.java @@ -14,34 +14,34 @@ public class GainAbilitiesTest extends CardTestPlayerBase { /* Reported bug: Behind the Scenes grants skulk to all creatures instead of just ones under owner's control - */ + */ @Test public void behindTheScenesShouldOnlyGrantSkulkToCreaturesYouControl() { - + /* Behind the Scenes {2}{B} Enchantment Creatures you control have skulk. (They can't be blocked by creatures with greater power.) {4}{W}: Creatures you control get +1/+1 until end of turn - */ - String bScenes = "Behind the Scenes"; + */ + String bScenes = "Behind the Scenes"; String hGiant = "Hill Giant"; // {3}{R} 3/3 String bSable = "Bronze Sable"; // {2} 2/1 String memnite = "Memnite"; // {0} 1/1 String gBears = "Grizzly Bears"; // {1}{G} 2/2 - + addCard(Zone.BATTLEFIELD, playerA, bScenes); addCard(Zone.BATTLEFIELD, playerA, hGiant); addCard(Zone.BATTLEFIELD, playerA, bSable); addCard(Zone.BATTLEFIELD, playerB, memnite); addCard(Zone.BATTLEFIELD, playerB, gBears); - + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); execute(); - - assertAbility(playerA, hGiant, SkulkAbility.getInstance(), true); - assertAbility(playerA, bSable, SkulkAbility.getInstance(), true); - assertAbility(playerB, memnite, SkulkAbility.getInstance(), false); - assertAbility(playerB, gBears, SkulkAbility.getInstance(), false); + + assertAbility(playerA, hGiant, new SkulkAbility(), true); + assertAbility(playerA, bSable, new SkulkAbility(), true); + assertAbility(playerB, memnite, new SkulkAbility(), false); + assertAbility(playerB, gBears, new SkulkAbility(), false); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/SkulkAbility.java b/Mage/src/main/java/mage/abilities/keyword/SkulkAbility.java index f97d4763a9..2378f0a9db 100644 --- a/Mage/src/main/java/mage/abilities/keyword/SkulkAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/SkulkAbility.java @@ -5,12 +5,11 @@ */ package mage.abilities.keyword; -import java.io.ObjectStreamException; import mage.abilities.Ability; -import mage.abilities.EvasionAbility; -import mage.abilities.MageSingleton; +import mage.abilities.StaticAbility; import mage.abilities.effects.RestrictionEffect; import mage.constants.Duration; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; @@ -18,31 +17,26 @@ import mage.game.permanent.Permanent; * * @author LevelX2 */ -public class SkulkAbility extends EvasionAbility implements MageSingleton { +public class SkulkAbility extends StaticAbility { - private static final SkulkAbility instance = new SkulkAbility(); - - private Object readResolve() throws ObjectStreamException { - return instance; + public SkulkAbility() { + super(Zone.BATTLEFIELD, new SkulkEffect(Duration.WhileOnBattlefield)); } - public static SkulkAbility getInstance() { - return instance; - } - - private SkulkAbility() { - this.addEffect(new SkulkEffect(Duration.WhileOnBattlefield)); + public SkulkAbility(final SkulkAbility ability) { + super(ability); } @Override public Ability copy() { - return instance; + return new SkulkAbility(this); } @Override public String getRule() { return "Skulk (This creature can't be blocked by creatures with greater power.)"; } + } class SkulkEffect extends RestrictionEffect { diff --git a/Utils/keywords.txt b/Utils/keywords.txt index f2c980846b..875ab52c00 100644 --- a/Utils/keywords.txt +++ b/Utils/keywords.txt @@ -76,7 +76,7 @@ Shadow|instance| Shroud|instance| Soulbond|instance| Soulshift|number| -Skulk|instance| +Skulk|new| Storm|new| Sunburst|new| Swampcycling|cost| From 4af72a855fb2b4f04facd0df1f386f74fe013b2d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 21:24:26 -0400 Subject: [PATCH 165/182] Implemented Cultural Exchange --- .../src/mage/cards/c/CulturalExchange.java | 136 ++++++++++++++++++ Mage.Sets/src/mage/sets/Odyssey.java | 1 + 2 files changed, 137 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CulturalExchange.java diff --git a/Mage.Sets/src/mage/cards/c/CulturalExchange.java b/Mage.Sets/src/mage/cards/c/CulturalExchange.java new file mode 100644 index 0000000000..bb81b4b40a --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CulturalExchange.java @@ -0,0 +1,136 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class CulturalExchange extends CardImpl { + + public CulturalExchange(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}{U}"); + + // Choose any number of creatures target player controls. Choose the same number of creatures another target player controls. Those players exchange control of those creatures. + this.getSpellAbility().addEffect(new CulturalExchangeEffect()); + this.getSpellAbility().addTarget(new TargetPlayer(2)); + } + + public CulturalExchange(final CulturalExchange card) { + super(card); + } + + @Override + public CulturalExchange copy() { + return new CulturalExchange(this); + } +} + +class CulturalExchangeEffect extends OneShotEffect { + + CulturalExchangeEffect() { + super(Outcome.Benefit); + this.staticText = "Choose any number of creatures target player controls. " + + "Choose the same number of creatures another target player controls. " + + "Those players exchange control of those creatures."; + } + + CulturalExchangeEffect(final CulturalExchangeEffect effect) { + super(effect); + } + + @Override + public CulturalExchangeEffect copy() { + return new CulturalExchangeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player1 = game.getPlayer(targetPointer.getTargets(game, source).get(0)); + Player player2 = game.getPlayer(targetPointer.getTargets(game, source).get(1)); + Player controller = game.getPlayer(source.getControllerId()); + if (player1 == null || player2 == null || controller == null) { + return false; + } + FilterCreaturePermanent filter1 = new FilterCreaturePermanent("creatures " + player1.getLogName() + " controls"); + FilterCreaturePermanent filter2 = new FilterCreaturePermanent("creatures " + player2.getLogName() + " controls"); + filter1.add(new ControllerIdPredicate(player1.getId())); + filter2.add(new ControllerIdPredicate(player2.getId())); + int creatureCount1 = game.getBattlefield().count(filter1, source.getSourceId(), source.getControllerId(), game); + int creatureCount2 = game.getBattlefield().count(filter2, source.getSourceId(), source.getControllerId(), game); + int creaturesToSwitch = Math.min(creatureCount1, creatureCount2); + if (creaturesToSwitch == 0) { + return true; + } + TargetCreaturePermanent target1 = new TargetCreaturePermanent(0, creaturesToSwitch, filter1, true); + if (target1.choose(Outcome.Benefit, controller.getId(), source.getSourceId(), game)) { + int otherToSwitch = target1.getTargets().size(); + TargetCreaturePermanent target2 = new TargetCreaturePermanent(otherToSwitch, otherToSwitch, filter2, true); + if (target2.choose(Outcome.Benefit, controller.getId(), source.getSourceId(), game)) { + for (UUID creatureId : target1.getTargets()) { + Permanent creature = game.getPermanent(creatureId); + if (creature != null) { + ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, player2.getId()); + game.informPlayers(player2.getLogName() + " gains control of " + creature.getLogName()); + effect.setTargetPointer(new FixedTarget(creature, game)); + game.addEffect(effect, source); + } + } + for (UUID creatureId : target2.getTargets()) { + Permanent creature = game.getPermanent(creatureId); + if (creature != null) { + ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, player1.getId()); + game.informPlayers(player1.getLogName() + " gains control of " + creature.getLogName()); + effect.setTargetPointer(new FixedTarget(creature, game)); + game.addEffect(effect, source); + } + } + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Odyssey.java b/Mage.Sets/src/mage/sets/Odyssey.java index fdc27640f4..70f7add0ba 100644 --- a/Mage.Sets/src/mage/sets/Odyssey.java +++ b/Mage.Sets/src/mage/sets/Odyssey.java @@ -120,6 +120,7 @@ public class Odyssey extends ExpansionSet { cards.add(new SetCardInfo("Crashing Centaur", 235, Rarity.UNCOMMON, mage.cards.c.CrashingCentaur.class)); cards.add(new SetCardInfo("Crypt Creeper", 125, Rarity.COMMON, mage.cards.c.CryptCreeper.class)); cards.add(new SetCardInfo("Crystal Quarry", 318, Rarity.RARE, mage.cards.c.CrystalQuarry.class)); + cards.add(new SetCardInfo("Cultural Exchange", 79, Rarity.RARE, mage.cards.c.CulturalExchange.class)); cards.add(new SetCardInfo("Cursed Monstrosity", 126, Rarity.RARE, mage.cards.c.CursedMonstrosity.class)); cards.add(new SetCardInfo("Darkwater Catacombs", 319, Rarity.RARE, mage.cards.d.DarkwaterCatacombs.class)); cards.add(new SetCardInfo("Darkwater Egg", 299, Rarity.UNCOMMON, mage.cards.d.DarkwaterEgg.class)); From 943004ea37b4bddb522169ad6c07ed1f1621957c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 17 Sep 2017 22:32:55 -0400 Subject: [PATCH 166/182] fixed Entrancing Melody being an instant instead of a sorcery --- Mage.Sets/src/mage/cards/e/EntrancingMelody.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/e/EntrancingMelody.java b/Mage.Sets/src/mage/cards/e/EntrancingMelody.java index 8a49d375f0..04eed25ce3 100644 --- a/Mage.Sets/src/mage/cards/e/EntrancingMelody.java +++ b/Mage.Sets/src/mage/cards/e/EntrancingMelody.java @@ -48,7 +48,7 @@ import mage.target.common.TargetCreaturePermanent; public class EntrancingMelody extends CardImpl { public EntrancingMelody(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}{U}"); // Gain control of target creature with converted mana cost X. this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.Custom, true)); From 8586956552752fe2353e4bb0d190e658de8eb510 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 09:36:46 -0400 Subject: [PATCH 167/182] fixed Search for Azcanta trigger options --- Mage.Sets/src/mage/cards/s/SearchForAzcanta.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java b/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java index 1fe5f694a8..d4b7ea1ec2 100644 --- a/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java +++ b/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java @@ -31,8 +31,6 @@ import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.condition.common.CardsInControllerGraveCondition; -import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; @@ -64,9 +62,7 @@ public class SearchForAzcanta extends CardImpl { this.addSuperType(SuperType.LEGENDARY); // At the beginning of your upkeep, look at the top card of your library. You may put it into your graveyard. Then if you have seven or more cards in your graveyard, you may transform Search for Azcanta. - Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SearchForAzcantaLookLibraryEffect(), TargetController.YOU, true); - ability.addEffect(new ConditionalOneShotEffect(new TransformSourceEffect(true), new CardsInControllerGraveCondition(7), - "Then if you have seven or more cards in your graveyard, you may transform {this}")); + Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SearchForAzcantaLookLibraryEffect(), TargetController.YOU, false); this.addAbility(ability); this.addAbility(new TransformAbility()); } @@ -85,7 +81,8 @@ class SearchForAzcantaLookLibraryEffect extends OneShotEffect { public SearchForAzcantaLookLibraryEffect() { super(Outcome.DrawCard); - this.staticText = "look at the top card of your library. You may put that card into your graveyard"; + this.staticText = "look at the top card of your library. You may put that card into your graveyard. " + + "Then if you have seven or more cards in your graveyard, you may transform {this}."; } public SearchForAzcantaLookLibraryEffect(final SearchForAzcantaLookLibraryEffect effect) { @@ -109,9 +106,11 @@ class SearchForAzcantaLookLibraryEffect extends OneShotEffect { cards.add(card); controller.lookAtCards(sourceObject.getIdName(), cards, game); if (controller.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", source, game)) { - return controller.moveCards(card, Zone.GRAVEYARD, source, game); + controller.moveCards(card, Zone.GRAVEYARD, source, game); + } + if (controller.getGraveyard().size() > 6 && controller.chooseUse(Outcome.Neutral, "Transform " + sourceObject.getLogName() + "?", source, game)) { + new TransformSourceEffect(true).apply(game, source); } - } } return true; From 6f4d77fc0f4228ce2d8cd618d6d1f05ee9474a98 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 10:40:15 -0400 Subject: [PATCH 168/182] Implemented Gemini Engine --- Mage.Sets/src/mage/cards/g/GeminiEngine.java | 117 ++++++++++++++++++ Mage.Sets/src/mage/sets/Darksteel.java | 1 + .../token/GeminiEngineTwinToken.java | 17 +++ 3 files changed, 135 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GeminiEngine.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/GeminiEngineTwinToken.java diff --git a/Mage.Sets/src/mage/cards/g/GeminiEngine.java b/Mage.Sets/src/mage/cards/g/GeminiEngine.java new file mode 100644 index 0000000000..d7939a3a13 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GeminiEngine.java @@ -0,0 +1,117 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SacrificeTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.GeminiEngineTwinToken; +import mage.game.permanent.token.Token; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class GeminiEngine extends CardImpl { + + public GeminiEngine(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}"); + + this.subtype.add(SubType.CONSTRUCT); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Whenever Gemini Engine attacks, create a colorless Construct artifact creature token named Twin that's attacking. Its power is equal to Gemini Engine's power and its toughness is equal to Gemini Engine's toughness. Sacrifice the token at end of combat. + this.addAbility(new AttacksTriggeredAbility(new GeminiEngineCreateTokenEffect(), false)); + } + + public GeminiEngine(final GeminiEngine card) { + super(card); + } + + @Override + public GeminiEngine copy() { + return new GeminiEngine(this); + } +} + +class GeminiEngineCreateTokenEffect extends OneShotEffect { + + GeminiEngineCreateTokenEffect() { + super(Outcome.Benefit); + this.staticText = "create a colorless Construct artifact creature token named Twin that's attacking. Its power is equal to {this}'s power and its toughness is equal to {this}'s toughness. Sacrifice the token at end of combat."; + } + + GeminiEngineCreateTokenEffect(final GeminiEngineCreateTokenEffect effect) { + super(effect); + } + + @Override + public GeminiEngineCreateTokenEffect copy() { + return new GeminiEngineCreateTokenEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + Token token; + if (permanent != null) { + token = new GeminiEngineTwinToken(permanent.getPower().getValue(), permanent.getToughness().getValue()); + } else { + token = new GeminiEngineTwinToken(0, 0); + } + token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId(), false, true); + for (UUID tokenId : token.getLastAddedTokenIds()) { + Permanent tokenPerm = game.getPermanent(tokenId); + if (tokenPerm != null) { + Effect effect = new SacrificeTargetEffect("sacrifice " + tokenPerm.getLogName(), player.getId()); + effect.setTargetPointer(new FixedTarget(tokenPerm, game)); + game.addDelayedTriggeredAbility(new AtTheEndOfCombatDelayedTriggeredAbility(effect), source); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Darksteel.java b/Mage.Sets/src/mage/sets/Darksteel.java index d26fe1ecd7..9957d16d78 100644 --- a/Mage.Sets/src/mage/sets/Darksteel.java +++ b/Mage.Sets/src/mage/sets/Darksteel.java @@ -78,6 +78,7 @@ public class Darksteel extends ExpansionSet { cards.add(new SetCardInfo("Fireball", 60, Rarity.UNCOMMON, mage.cards.f.Fireball.class)); cards.add(new SetCardInfo("Flamebreak", 61, Rarity.RARE, mage.cards.f.Flamebreak.class)); cards.add(new SetCardInfo("Furnace Dragon", 62, Rarity.RARE, mage.cards.f.FurnaceDragon.class)); + cards.add(new SetCardInfo("Gemini Engine", 121, Rarity.RARE, mage.cards.g.GeminiEngine.class)); cards.add(new SetCardInfo("Genesis Chamber", 122, Rarity.UNCOMMON, mage.cards.g.GenesisChamber.class)); cards.add(new SetCardInfo("Geth's Grimoire", 123, Rarity.UNCOMMON, mage.cards.g.GethsGrimoire.class)); cards.add(new SetCardInfo("Goblin Archaeologist", 63, Rarity.UNCOMMON, mage.cards.g.GoblinArchaeologist.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/GeminiEngineTwinToken.java b/Mage/src/main/java/mage/game/permanent/token/GeminiEngineTwinToken.java new file mode 100644 index 0000000000..b7f169cde1 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/GeminiEngineTwinToken.java @@ -0,0 +1,17 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +public class GeminiEngineTwinToken extends Token { + + public GeminiEngineTwinToken(int power, int toughness) { + super("Twin", "colorless Construct artifact creature token named Twin that's attacking. Its power is equal to Gemini Engine's power and its toughness is equal to Gemini Engine's toughness."); + cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); + subtype.add(SubType.CONSTRUCT); + this.power = new MageInt(power); + this.toughness = new MageInt(toughness); + } +} From b0254a12a589e1407b14daae69f1fce6f0018949 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 11:05:12 -0400 Subject: [PATCH 169/182] Implemented Mindstorm Crown --- .../src/mage/cards/m/MindstormCrown.java | 143 ++++++++++++++++++ Mage.Sets/src/mage/sets/Mirrodin.java | 1 + 2 files changed, 144 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MindstormCrown.java diff --git a/Mage.Sets/src/mage/cards/m/MindstormCrown.java b/Mage.Sets/src/mage/cards/m/MindstormCrown.java new file mode 100644 index 0000000000..4170b7a6cd --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MindstormCrown.java @@ -0,0 +1,143 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.watchers.Watcher; + +/** + * + * @author TheElk801 + */ +public class MindstormCrown extends CardImpl { + + public MindstormCrown(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + // At the beginning of your upkeep, draw a card if you had no cards in hand at the beginning of this turn. If you had a card in hand, Mindstorm Crown deals 1 damage to you. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new MindstormCrownEffect(), TargetController.YOU, false), new MindstormCrownWatcher()); + } + + public MindstormCrown(final MindstormCrown card) { + super(card); + } + + @Override + public MindstormCrown copy() { + return new MindstormCrown(this); + } +} + +class MindstormCrownEffect extends OneShotEffect { + + MindstormCrownEffect() { + super(Outcome.Benefit); + this.staticText = ""; + } + + MindstormCrownEffect(final MindstormCrownEffect effect) { + super(effect); + } + + @Override + public MindstormCrownEffect copy() { + return new MindstormCrownEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (player == null) { + return false; + } + MindstormCrownWatcher watcher = (MindstormCrownWatcher) game.getState().getWatchers().get(MindstormCrownWatcher.class.getSimpleName()); + if (watcher != null && watcher.getCardsInHandCount() == 0) { + player.drawCards(1, game); + } else { + if (permanent != null) { + player.damage(2, permanent.getId(), game, false, true); + } + } + return true; + } +} + +class MindstormCrownWatcher extends Watcher { + + private int cardsInHandCount; + + public MindstormCrownWatcher() { + super(MindstormCrownWatcher.class.getSimpleName(), WatcherScope.GAME); + } + + public MindstormCrownWatcher(final MindstormCrownWatcher watcher) { + super(watcher); + cardsInHandCount = watcher.cardsInHandCount; + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.BEGINNING_PHASE_PRE + && game.getPhase() != null) { + Player player = game.getPlayer(game.getActivePlayerId()); + int cardsInHand = 0; + if (player != null) { + cardsInHand = player.getHand().size(); + } + cardsInHandCount = cardsInHand; + } + } + + public int getCardsInHandCount() { + return cardsInHandCount; + } + + @Override + public void reset() { + cardsInHandCount = 0; + } + + @Override + public MindstormCrownWatcher copy() { + return new MindstormCrownWatcher(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Mirrodin.java b/Mage.Sets/src/mage/sets/Mirrodin.java index 3a7768c523..7a65892921 100644 --- a/Mage.Sets/src/mage/sets/Mirrodin.java +++ b/Mage.Sets/src/mage/sets/Mirrodin.java @@ -160,6 +160,7 @@ public class Mirrodin extends ExpansionSet { cards.add(new SetCardInfo("Mesmeric Orb", 204, Rarity.RARE, mage.cards.m.MesmericOrb.class)); cards.add(new SetCardInfo("Mind's Eye", 205, Rarity.RARE, mage.cards.m.MindsEye.class)); cards.add(new SetCardInfo("Mindslaver", 206, Rarity.RARE, mage.cards.m.Mindslaver.class)); + cards.add(new SetCardInfo("Mindstorm Crown", 207, Rarity.UNCOMMON, mage.cards.m.MindstormCrown.class)); cards.add(new SetCardInfo("Molder Slug", 125, Rarity.RARE, mage.cards.m.MolderSlug.class)); cards.add(new SetCardInfo("Molten Rain", 101, Rarity.COMMON, mage.cards.m.MoltenRain.class)); cards.add(new SetCardInfo("Moriok Scavenger", 68, Rarity.COMMON, mage.cards.m.MoriokScavenger.class)); From 89317bc9b045f719d458aea14154121da613d507 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 11:15:21 -0400 Subject: [PATCH 170/182] Implemented Reveille Squad --- Mage.Sets/src/mage/cards/r/ReveilleSquad.java | 107 ++++++++++++++++++ Mage.Sets/src/mage/sets/Prophecy.java | 1 + 2 files changed, 108 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/ReveilleSquad.java diff --git a/Mage.Sets/src/mage/cards/r/ReveilleSquad.java b/Mage.Sets/src/mage/cards/r/ReveilleSquad.java new file mode 100644 index 0000000000..3c7aa5d44c --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/ReveilleSquad.java @@ -0,0 +1,107 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.condition.InvertCondition; +import mage.abilities.condition.common.SourceTappedCondition; +import mage.abilities.effects.common.UntapAllControllerEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author TheElk801 + */ +public class ReveilleSquad extends CardImpl { + + public ReveilleSquad(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.REBEL); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Whenever one or more creatures attack you, if Reveille Squad is untapped, you may untap all creatures you control. + this.addAbility(new ReveilleSquadTriggeredAbility()); + } + + public ReveilleSquad(final ReveilleSquad card) { + super(card); + } + + @Override + public ReveilleSquad copy() { + return new ReveilleSquad(this); + } +} + +class ReveilleSquadTriggeredAbility extends TriggeredAbilityImpl { + + public ReveilleSquadTriggeredAbility() { + super(Zone.BATTLEFIELD, new UntapAllControllerEffect(new FilterCreaturePermanent("all creatures you control")), true); + } + + public ReveilleSquadTriggeredAbility(final ReveilleSquadTriggeredAbility ability) { + super(ability); + } + + @Override + public ReveilleSquadTriggeredAbility copy() { + return new ReveilleSquadTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return game.getCombat().getDefenders().contains(controllerId); + } + + @Override + public boolean checkInterveningIfClause(Game game) { + return new InvertCondition(SourceTappedCondition.instance).apply(game, this); + } + + @Override + public String getRule() { + return "Whenever one or more creatures attack you, if {this} is untapped, you may untap all creatures you control."; + } +} diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index b238baeb12..d9043b28ad 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -123,6 +123,7 @@ public class Prophecy extends ExpansionSet { cards.add(new SetCardInfo("Quicksilver Wall", 41, Rarity.UNCOMMON, mage.cards.q.QuicksilverWall.class)); cards.add(new SetCardInfo("Rebel Informer", 75, Rarity.RARE, mage.cards.r.RebelInformer.class)); cards.add(new SetCardInfo("Rethink", 42, Rarity.COMMON, mage.cards.r.Rethink.class)); + cards.add(new SetCardInfo("Reveille Squad", 18, Rarity.UNCOMMON, mage.cards.r.ReveilleSquad.class)); cards.add(new SetCardInfo("Rhystic Circle", 19, Rarity.COMMON, mage.cards.r.RhysticCircle.class)); cards.add(new SetCardInfo("Rhystic Study", 45, Rarity.COMMON, mage.cards.r.RhysticStudy.class)); cards.add(new SetCardInfo("Rhystic Tutor", 77, Rarity.RARE, mage.cards.r.RhysticTutor.class)); From 626304234b09e59c9f9fdcd0b0733f9523cb0863 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 11:35:02 -0400 Subject: [PATCH 171/182] Implemented Stalking Yeti --- Mage.Sets/src/mage/cards/s/StalkingYeti.java | 118 +++++++++++++++++++ Mage.Sets/src/mage/sets/Coldsnap.java | 1 + 2 files changed, 119 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/StalkingYeti.java diff --git a/Mage.Sets/src/mage/cards/s/StalkingYeti.java b/Mage.Sets/src/mage/cards/s/StalkingYeti.java new file mode 100644 index 0000000000..edb00ec5c5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StalkingYeti.java @@ -0,0 +1,118 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.SourceOnBattlefieldCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetOpponentsCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class StalkingYeti extends CardImpl { + + public StalkingYeti(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + + this.addSuperType(SuperType.SNOW); + this.subtype.add(SubType.YETI); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When Stalking Yeti enters the battlefield, if it's on the battlefield, it deals damage equal to its power to target creature an opponent controls and that creature deals damage equal to its power to Stalking Yeti. + Ability ability = new ConditionalTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new StalkingYetiEffect()), + SourceOnBattlefieldCondition.instance, + "When {this} enters the battlefield, if it's on the battlefield, " + + "it deals damage equal to its power to target creature an opponent controls " + + "and that creature deals damage equal to its power to {this}." + ); + ability.addTarget(new TargetOpponentsCreaturePermanent()); + this.addAbility(ability); + + // {2}{snow}: Return Stalking Yeti to its owner's hand. Activate this ability only any time you could cast a sorcery. + this.addAbility(new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), new ManaCostsImpl("{2}{S}"))); + } + + public StalkingYeti(final StalkingYeti card) { + super(card); + } + + @Override + public StalkingYeti copy() { + return new StalkingYeti(this); + } +} + +class StalkingYetiEffect extends OneShotEffect { + + StalkingYetiEffect() { + super(Outcome.Benefit); + this.staticText = "it deals damage equal to its power to target creature an opponent controls " + + "and that creature deals damage equal to its power to {this}"; + } + + StalkingYetiEffect(final StalkingYetiEffect effect) { + super(effect); + } + + @Override + public StalkingYetiEffect copy() { + return new StalkingYetiEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent thisCreature = game.getPermanent(source.getSourceId()); + Permanent thatCreature = game.getPermanent(source.getFirstTarget()); + if (thisCreature == null || thatCreature == null) { + return false; + } + thatCreature.damage(thisCreature.getPower().getValue(), thisCreature.getId(), game, false, true); + thisCreature.damage(thatCreature.getPower().getValue(), thatCreature.getId(), game, false, true); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Coldsnap.java b/Mage.Sets/src/mage/sets/Coldsnap.java index ee0b109eb1..763d832d9d 100644 --- a/Mage.Sets/src/mage/sets/Coldsnap.java +++ b/Mage.Sets/src/mage/sets/Coldsnap.java @@ -158,6 +158,7 @@ public class Coldsnap extends ExpansionSet { cards.add(new SetCardInfo("Snow-Covered Swamp", 153, Rarity.COMMON, mage.cards.s.SnowCoveredSwamp.class)); cards.add(new SetCardInfo("Soul Spike", 70, Rarity.RARE, mage.cards.s.SoulSpike.class)); cards.add(new SetCardInfo("Squall Drifter", 17, Rarity.COMMON, mage.cards.s.SquallDrifter.class)); + cards.add(new SetCardInfo("Stalking Yeti", 98, Rarity.UNCOMMON, mage.cards.s.StalkingYeti.class)); cards.add(new SetCardInfo("Steam Spitter", 124, Rarity.UNCOMMON, mage.cards.s.SteamSpitter.class)); cards.add(new SetCardInfo("Stromgald Crusader", 71, Rarity.UNCOMMON, mage.cards.s.StromgaldCrusader.class)); cards.add(new SetCardInfo("Sun's Bounty", 18, Rarity.COMMON, mage.cards.s.SunsBounty.class)); From 4dd2d300be5334c151dfc7ee95aff238c621cf3f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 12:02:36 -0400 Subject: [PATCH 172/182] Implemented Blood Oath --- Mage.Sets/src/mage/cards/b/BloodOath.java | 145 ++++++++++++++++++ Mage.Sets/src/mage/sets/MercadianMasques.java | 1 + 2 files changed, 146 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BloodOath.java diff --git a/Mage.Sets/src/mage/cards/b/BloodOath.java b/Mage.Sets/src/mage/cards/b/BloodOath.java new file mode 100644 index 0000000000..d90fc31807 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BloodOath.java @@ -0,0 +1,145 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.choices.Choice; +import mage.choices.ChoiceImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class BloodOath extends CardImpl { + + public BloodOath(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}"); + + // Choose a card type. Target opponent reveals his or her hand. Blood Oath deals 3 damage to that player for each card of the chosen type revealed this way. + this.getSpellAbility().addEffect(new BloodOathEffect()); + } + + public BloodOath(final BloodOath card) { + super(card); + } + + @Override + public BloodOath copy() { + return new BloodOath(this); + } +} + +class BloodOathEffect extends OneShotEffect { + + private static final Set choice = new LinkedHashSet<>(); + + static { + choice.add(CardType.ARTIFACT.toString()); + choice.add(CardType.CREATURE.toString()); + choice.add(CardType.ENCHANTMENT.toString()); + choice.add(CardType.INSTANT.toString()); + choice.add(CardType.LAND.toString()); + choice.add(CardType.PLANESWALKER.toString()); + choice.add(CardType.SORCERY.toString()); + choice.add(CardType.TRIBAL.toString()); + } + + public BloodOathEffect() { + super(Outcome.Benefit); + staticText = "Choose a card type. Target opponent reveals his or her hand. {this} deals 3 damage to that player for each card of the chosen type revealed this way"; + } + + public BloodOathEffect(final BloodOathEffect effect) { + super(effect); + } + + @Override + public BloodOathEffect copy() { + return new BloodOathEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + MageObject sourceObject = game.getObject(source.getSourceId()); + Player player = game.getPlayer(source.getControllerId()); + Player opponent = game.getPlayer(source.getFirstTarget()); + if (player != null && opponent != null && sourceObject != null) { + Choice choiceImpl = new ChoiceImpl(); + choiceImpl.setChoices(choice); + while (player.canRespond() && !player.choose(Outcome.Neutral, choiceImpl, game)) { + } + CardType type = null; + String choosenType = choiceImpl.getChoice(); + + if (choosenType.equals(CardType.ARTIFACT.toString())) { + type = CardType.ARTIFACT; + } else if (choosenType.equals(CardType.LAND.toString())) { + type = CardType.LAND; + } else if (choosenType.equals(CardType.CREATURE.toString())) { + type = CardType.CREATURE; + } else if (choosenType.equals(CardType.ENCHANTMENT.toString())) { + type = CardType.ENCHANTMENT; + } else if (choosenType.equals(CardType.INSTANT.toString())) { + type = CardType.INSTANT; + } else if (choosenType.equals(CardType.SORCERY.toString())) { + type = CardType.SORCERY; + } else if (choosenType.equals(CardType.PLANESWALKER.toString())) { + type = CardType.PLANESWALKER; + } else if (choosenType.equals(CardType.TRIBAL.toString())) { + type = CardType.TRIBAL; + } + if (type != null) { + Cards hand = opponent.getHand(); + opponent.revealCards(sourceObject.getIdName(), hand, game); + Set cards = hand.getCards(game); + int count = 0; + for (Card card : cards) { + if (card != null && card.getCardType().contains(type)) { + count += 1; + } + } + opponent.damage(count * 3, source.getSourceId(), game, false, true); + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/MercadianMasques.java b/Mage.Sets/src/mage/sets/MercadianMasques.java index c759f2889e..3e9b6c0588 100644 --- a/Mage.Sets/src/mage/sets/MercadianMasques.java +++ b/Mage.Sets/src/mage/sets/MercadianMasques.java @@ -67,6 +67,7 @@ public class MercadianMasques extends ExpansionSet { cards.add(new SetCardInfo("Blaster Mage", 175, Rarity.COMMON, mage.cards.b.BlasterMage.class)); cards.add(new SetCardInfo("Blockade Runner", 60, Rarity.COMMON, mage.cards.b.BlockadeRunner.class)); cards.add(new SetCardInfo("Blood Hound", 176, Rarity.RARE, mage.cards.b.BloodHound.class)); + cards.add(new SetCardInfo("Blood Oath", 177, Rarity.RARE, mage.cards.b.BloodOath.class)); cards.add(new SetCardInfo("Boa Constrictor", 231, Rarity.UNCOMMON, mage.cards.b.BoaConstrictor.class)); cards.add(new SetCardInfo("Bog Smugglers", 117, Rarity.COMMON, mage.cards.b.BogSmugglers.class)); cards.add(new SetCardInfo("Bog Witch", 118, Rarity.COMMON, mage.cards.b.BogWitch.class)); From a5f71ba3f35fd1e1999b18800ae2b81d1bb8f559 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 12:41:05 -0400 Subject: [PATCH 173/182] Implemented Flesh Reaver --- Mage.Sets/src/mage/cards/f/FleshReaver.java | 146 ++++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 1 + 2 files changed, 147 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FleshReaver.java diff --git a/Mage.Sets/src/mage/cards/f/FleshReaver.java b/Mage.Sets/src/mage/cards/f/FleshReaver.java new file mode 100644 index 0000000000..eb5448509d --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FleshReaver.java @@ -0,0 +1,146 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class FleshReaver extends CardImpl { + + public FleshReaver(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add(SubType.HORROR); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Whenever Flesh Reaver deals damage to a creature or opponent, Flesh Reaver deals that much damage to you. + this.addAbility(new FleshReaverTriggeredAbility()); + } + + public FleshReaver(final FleshReaver card) { + super(card); + } + + @Override + public FleshReaver copy() { + return new FleshReaver(this); + } +} + +class FleshReaverTriggeredAbility extends TriggeredAbilityImpl { + + FleshReaverTriggeredAbility() { + super(Zone.BATTLEFIELD, new FleshReaverEffect()); + } + + FleshReaverTriggeredAbility(final FleshReaverTriggeredAbility effect) { + super(effect); + } + + @Override + public FleshReaverTriggeredAbility copy() { + return new FleshReaverTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_CREATURE || event.getType() == GameEvent.EventType.DAMAGED_PLAYER; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (!event.getSourceId().equals(sourceId)) { + return false; + } + if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER) { + if (event.getTargetId().equals(controllerId)) { + return false; + } + } + for (Effect effect : this.getEffects()) { + effect.setValue("damage", event.getAmount()); + } + return true; + } + + @Override + public String getRule() { + return "Whenever {this} deals damage to a creature or opponent, {this} deals that much damage to you."; + } + +} + +class FleshReaverEffect extends OneShotEffect { + + FleshReaverEffect() { + super(Outcome.Detriment); + this.staticText = "{this} deals that much damage to you."; + } + + FleshReaverEffect(final FleshReaverEffect effect) { + super(effect); + } + + @Override + public FleshReaverEffect copy() { + return new FleshReaverEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent creature = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (creature == null || controller == null) { + return false; + } + int damageToDeal = (Integer) getValue("damage"); + if (damageToDeal > 0) { + controller.damage(damageToDeal, source.getSourceId(), game, false, true); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index 6351e0fbe4..5f2187a3c7 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -150,6 +150,7 @@ public class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Fertile Ground", 252, Rarity.COMMON, mage.cards.f.FertileGround.class)); cards.add(new SetCardInfo("Fiery Mantle", 186, Rarity.COMMON, mage.cards.f.FieryMantle.class)); cards.add(new SetCardInfo("Fire Ants", 187, Rarity.UNCOMMON, mage.cards.f.FireAnts.class)); + cards.add(new SetCardInfo("Flesh Reaver", 136, Rarity.UNCOMMON, mage.cards.f.FleshReaver.class)); cards.add(new SetCardInfo("Fluctuator", 295, Rarity.RARE, mage.cards.f.Fluctuator.class)); cards.add(new SetCardInfo("Fog Bank", 75, Rarity.UNCOMMON, mage.cards.f.FogBank.class)); cards.add(new SetCardInfo("Forest", 347, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); From 4e194d965e9e44647f5dce5dd1cb6dbe859ab850 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 14:45:56 -0400 Subject: [PATCH 174/182] fixed error with Sunbird's Invocation (#4022) --- Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index e451faaa09..77e7a088f6 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -92,7 +92,7 @@ class SunbirdsInvocationTriggeredAbility extends SpellCastControllerTriggeredAbi if (spell != null && spell.getFromZone() == Zone.HAND) { if (spell.getCard() != null) { for (Effect effect : getEffects()) { - effect.setTargetPointer(new FixedTarget(spell.getId(), spell.getZoneChangeCounter(game))); + effect.setTargetPointer(new FixedTarget(spell.getId())); } return true; } @@ -125,8 +125,16 @@ class SunbirdsInvocationEffect extends OneShotEffect { if (controller == null || sourceObject == null) { return false; } + Spell spell = game.getStack().getSpell(this.getTargetPointer().getFirst(game, source)); + int xValue = 0; + if (spell == null) { + spell = (Spell) game.getLastKnownInformation(this.getTargetPointer().getFirst(game, source), Zone.STACK); + } + if (spell == null) { + return false; + } + xValue = spell.getConvertedManaCost(); Cards cards = new CardsImpl(); - int xValue = game.getLastKnownInformation(this.getTargetPointer().getFirst(game, source), Zone.STACK).getConvertedManaCost(); cards.addAll(controller.getLibrary().getTopCards(game, xValue)); if (!cards.isEmpty()) { controller.revealCards(sourceObject.getIdName(), cards, game); @@ -138,7 +146,7 @@ class SunbirdsInvocationEffect extends OneShotEffect { if (controller.chooseTarget(Outcome.PlayForFree, cards, target, source, game)) { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { - if (controller.chooseUse(outcome, "Do you wish to cast " + card.getName(), source, game)) { + if (controller.chooseUse(outcome, "Cast " + card.getLogName() + " without paying its mana cost?", source, game)) { controller.cast(card.getSpellAbility(), game, true); cards.remove(card); } From e3245c496c2e4f0f6df67ee48be2c801c3b1479c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 15:29:19 -0400 Subject: [PATCH 175/182] fixed Ixalan's Binding preventing both players from casting spells --- Mage.Sets/src/mage/cards/i/IxalansBinding.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mage.Sets/src/mage/cards/i/IxalansBinding.java b/Mage.Sets/src/mage/cards/i/IxalansBinding.java index 0e562625f0..1e41ce332e 100644 --- a/Mage.Sets/src/mage/cards/i/IxalansBinding.java +++ b/Mage.Sets/src/mage/cards/i/IxalansBinding.java @@ -107,6 +107,9 @@ class IxalansBindingReplacementEffect extends ContinuousRuleModifyingEffectImpl public boolean applies(GameEvent event, Ability source, Game game) { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Card card = game.getCard(event.getSourceId()); + if(event.getPlayerId().equals(source.getControllerId())){ + return false; + } if (sourcePermanent != null && card != null) { UUID exileZone = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); if (exileZone != null) { From f307572a86f4e9eca41447c6a4ea85bb8fd51a5b Mon Sep 17 00:00:00 2001 From: Plopman <> Date: Mon, 18 Sep 2017 23:00:25 +0200 Subject: [PATCH 176/182] Fix #3414 Soul Conduit --- Mage.Sets/src/mage/cards/s/SoulConduit.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SoulConduit.java b/Mage.Sets/src/mage/cards/s/SoulConduit.java index 0c0f79edf5..9fbf7f21ff 100644 --- a/Mage.Sets/src/mage/cards/s/SoulConduit.java +++ b/Mage.Sets/src/mage/cards/s/SoulConduit.java @@ -54,8 +54,7 @@ public class SoulConduit extends CardImpl { // {6}, {tap}: Two target players exchange life totals. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SoulConduitEffect(), new GenericManaCost(6)); ability.addCost(new TapSourceCost()); - ability.addTarget(new TargetPlayer()); - ability.addTarget(new TargetPlayer()); + ability.addTarget(new TargetPlayer(2)); this.addAbility(ability); } @@ -87,8 +86,8 @@ class SoulConduitEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player1 = game.getPlayer(source.getFirstTarget()); - Player player2 = game.getPlayer(source.getTargets().get(1).getFirstTarget()); + Player player1 = game.getPlayer(source.getTargets().get(0).getTargets().get(0)); + Player player2 = game.getPlayer(source.getTargets().get(0).getTargets().get(1)); if (player1 != null && player2 != null) { int lifePlayer1 = player1.getLife(); int lifePlayer2 = player2.getLife(); From 7bb7754bb31a9c4b6f10473520b591c2786bc95e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 17:02:55 -0400 Subject: [PATCH 177/182] Updated how spell triggers get information about the spell that triggered them. This prevents countering the spell from removing the effect of the trigger. --- Mage.Sets/src/mage/cards/b/BloodbondMarch.java | 2 +- Mage.Sets/src/mage/cards/b/BounteousKirin.java | 4 ++-- Mage.Sets/src/mage/cards/c/CelestialKirin.java | 4 ++-- .../src/mage/cards/c/ChandraTheFirebrand.java | 2 +- Mage.Sets/src/mage/cards/c/CloudhoofKirin.java | 6 +++--- Mage.Sets/src/mage/cards/c/ClovenCasting.java | 2 +- Mage.Sets/src/mage/cards/c/CurseOfEchoes.java | 4 ++-- Mage.Sets/src/mage/cards/d/Dovescape.java | 6 +----- .../src/mage/cards/e/EndrekSahrMasterBreeder.java | 6 +----- Mage.Sets/src/mage/cards/h/HiveMind.java | 8 ++------ Mage.Sets/src/mage/cards/h/HowlOfTheHorde.java | 2 +- Mage.Sets/src/mage/cards/i/InfernalKirin.java | 8 ++++---- .../src/mage/cards/k/KaervekTheMerciless.java | 9 ++++----- .../src/mage/cards/m/MetallurgicSummonings.java | 6 +----- Mage.Sets/src/mage/cards/m/Mirari.java | 2 +- Mage.Sets/src/mage/cards/p/PrimalWellspring.java | 2 +- .../src/mage/cards/p/PyromancerAscension.java | 2 +- .../src/mage/cards/p/PyromancersGoggles.java | 2 +- Mage.Sets/src/mage/cards/r/RamosDragonEngine.java | 2 +- .../src/mage/cards/r/RikuOfTwoReflections.java | 2 +- .../src/mage/cards/s/SunbirdsInvocation.java | 8 ++------ Mage.Sets/src/mage/cards/s/SwarmIntelligence.java | 2 +- Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java | 5 +---- .../effects/common/CopyTargetSpellEffect.java | 15 ++++++++++++++- Mage/src/main/java/mage/game/Game.java | 5 +++++ Mage/src/main/java/mage/game/GameImpl.java | 14 ++++++++++++++ 26 files changed, 69 insertions(+), 61 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BloodbondMarch.java b/Mage.Sets/src/mage/cards/b/BloodbondMarch.java index da7b086ba9..de0ab798e8 100644 --- a/Mage.Sets/src/mage/cards/b/BloodbondMarch.java +++ b/Mage.Sets/src/mage/cards/b/BloodbondMarch.java @@ -85,7 +85,7 @@ public class BloodbondMarch extends CardImpl { return false; } - Spell spell = (Spell) game.getStack().getStackObject(targetPointer.getFirst(game, source)); + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); if (spell == null) { return false; diff --git a/Mage.Sets/src/mage/cards/b/BounteousKirin.java b/Mage.Sets/src/mage/cards/b/BounteousKirin.java index afcd8911c1..5a3ae7a8fa 100644 --- a/Mage.Sets/src/mage/cards/b/BounteousKirin.java +++ b/Mage.Sets/src/mage/cards/b/BounteousKirin.java @@ -48,7 +48,7 @@ import mage.players.Player; public class BounteousKirin extends CardImpl { public BounteousKirin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.KIRIN, SubType.SPIRIT); @@ -89,7 +89,7 @@ class BounteousKirinEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getState().getStack().getSpell(getTargetPointer().getFirst(game, source)); + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); if (spell != null) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { diff --git a/Mage.Sets/src/mage/cards/c/CelestialKirin.java b/Mage.Sets/src/mage/cards/c/CelestialKirin.java index 678da2418d..3082e74b94 100644 --- a/Mage.Sets/src/mage/cards/c/CelestialKirin.java +++ b/Mage.Sets/src/mage/cards/c/CelestialKirin.java @@ -50,7 +50,7 @@ import mage.game.stack.Spell; public class CelestialKirin extends CardImpl { public CelestialKirin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.KIRIN); this.subtype.add(SubType.SPIRIT); @@ -92,7 +92,7 @@ class CelestialKirinEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getState().getStack().getSpell(getTargetPointer().getFirst(game, source)); + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); if (spell != null) { int cmc = spell.getConvertedManaCost(); FilterPermanent filter = new FilterPermanent(); diff --git a/Mage.Sets/src/mage/cards/c/ChandraTheFirebrand.java b/Mage.Sets/src/mage/cards/c/ChandraTheFirebrand.java index e98cd3a959..1d474d1b25 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraTheFirebrand.java +++ b/Mage.Sets/src/mage/cards/c/ChandraTheFirebrand.java @@ -91,7 +91,7 @@ public class ChandraTheFirebrand extends CardImpl { class ChandraTheFirebrandAbility extends DelayedTriggeredAbility { ChandraTheFirebrandAbility() { - super(new CopyTargetSpellEffect(), Duration.EndOfTurn); + super(new CopyTargetSpellEffect(true), Duration.EndOfTurn); } ChandraTheFirebrandAbility(final ChandraTheFirebrandAbility ability) { diff --git a/Mage.Sets/src/mage/cards/c/CloudhoofKirin.java b/Mage.Sets/src/mage/cards/c/CloudhoofKirin.java index 8cc24f3b14..2494270a62 100644 --- a/Mage.Sets/src/mage/cards/c/CloudhoofKirin.java +++ b/Mage.Sets/src/mage/cards/c/CloudhoofKirin.java @@ -54,7 +54,7 @@ import mage.target.TargetPlayer; public class CloudhoofKirin extends CardImpl { public CloudhoofKirin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.KIRIN); this.subtype.add(SubType.SPIRIT); @@ -98,10 +98,10 @@ class CloudhoofKirinEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); if (spell != null) { Player targetPlayer = null; - for(Target target: source.getTargets()) { + for (Target target : source.getTargets()) { if (target instanceof TargetPlayer) { targetPlayer = game.getPlayer(target.getFirstTarget()); } diff --git a/Mage.Sets/src/mage/cards/c/ClovenCasting.java b/Mage.Sets/src/mage/cards/c/ClovenCasting.java index eea8864f43..107ed2c49d 100644 --- a/Mage.Sets/src/mage/cards/c/ClovenCasting.java +++ b/Mage.Sets/src/mage/cards/c/ClovenCasting.java @@ -60,7 +60,7 @@ public class ClovenCasting extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{5}{U}{R}"); // Whenever you cast a multicolored instant or sorcery spell, you may pay {1}. If you do, copy that spell. You may choose new targets for the copy. - Effect effect = new CopyTargetSpellEffect(); + Effect effect = new CopyTargetSpellEffect(true); effect.setText("copy that spell. You may choose new targets for the copy"); this.addAbility(new SpellCastControllerTriggeredAbility(new DoIfCostPaid(effect, new GenericManaCost(1)), filter, true, true)); } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfEchoes.java b/Mage.Sets/src/mage/cards/c/CurseOfEchoes.java index b7f238deb8..96e43762b9 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfEchoes.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfEchoes.java @@ -58,7 +58,7 @@ import mage.target.targetpointer.FixedTarget; public class CurseOfEchoes extends CardImpl { public CurseOfEchoes(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{U}"); this.subtype.add(SubType.AURA, SubType.CURSE); // Enchant player @@ -143,7 +143,7 @@ class CurseOfEchoesEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); if (spell != null) { String chooseMessage = "Copy target spell? You may choose new targets for the copy."; for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { diff --git a/Mage.Sets/src/mage/cards/d/Dovescape.java b/Mage.Sets/src/mage/cards/d/Dovescape.java index 1b97b32810..2b8e339aa4 100644 --- a/Mage.Sets/src/mage/cards/d/Dovescape.java +++ b/Mage.Sets/src/mage/cards/d/Dovescape.java @@ -36,7 +36,6 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SetTargetPointer; -import mage.constants.Zone; import mage.filter.FilterSpell; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -92,12 +91,9 @@ class DovescapeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(this.getTargetPointer().getFirst(game, source)); + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); int spellCMC = 0; UUID spellControllerID = null; - if (spell == null) { - spell = (Spell) game.getLastKnownInformation(this.getTargetPointer().getFirst(game, source), Zone.STACK); - } if (spell != null) { spellCMC = spell.getConvertedManaCost(); spellControllerID = spell.getControllerId(); diff --git a/Mage.Sets/src/mage/cards/e/EndrekSahrMasterBreeder.java b/Mage.Sets/src/mage/cards/e/EndrekSahrMasterBreeder.java index 8ee17fad26..931f6885b0 100644 --- a/Mage.Sets/src/mage/cards/e/EndrekSahrMasterBreeder.java +++ b/Mage.Sets/src/mage/cards/e/EndrekSahrMasterBreeder.java @@ -43,7 +43,6 @@ import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.token.ThrullToken; import mage.game.stack.Spell; -import mage.target.targetpointer.FixedTarget; /** * @author LevelX2 @@ -95,10 +94,7 @@ class EndrekSahrMasterBreederEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); - if (spell == null) { - spell = (Spell) game.getLastKnownInformation(((FixedTarget) getTargetPointer()).getTarget(), Zone.STACK); - } + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); if (spell != null) { int cmc = spell.getConvertedManaCost(); if (cmc > 0) { diff --git a/Mage.Sets/src/mage/cards/h/HiveMind.java b/Mage.Sets/src/mage/cards/h/HiveMind.java index d0694c3801..a2549bea8d 100644 --- a/Mage.Sets/src/mage/cards/h/HiveMind.java +++ b/Mage.Sets/src/mage/cards/h/HiveMind.java @@ -50,7 +50,7 @@ import mage.target.targetpointer.FixedTarget; public class HiveMind extends CardImpl { public HiveMind(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{5}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{U}"); // Whenever a player casts an instant or sorcery spell, each other player copies that spell. Each of those players may choose new targets for his or her copy. this.addAbility(new HiveMindTriggeredAbility()); @@ -125,11 +125,7 @@ class HiveMindEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell; - spell = game.getStack().getSpell(((FixedTarget) getTargetPointer()).getTarget()); - if (spell == null) { // if spell e.g. was countered - spell = (Spell) game.getLastKnownInformation(((FixedTarget) getTargetPointer()).getTarget(), Zone.STACK); - } + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); Player player = game.getPlayer(source.getControllerId()); if (spell != null && player != null) { for (UUID playerId : game.getState().getPlayersInRange(player.getId(), game)) { diff --git a/Mage.Sets/src/mage/cards/h/HowlOfTheHorde.java b/Mage.Sets/src/mage/cards/h/HowlOfTheHorde.java index 5dba37f4c3..d6e46210fa 100644 --- a/Mage.Sets/src/mage/cards/h/HowlOfTheHorde.java +++ b/Mage.Sets/src/mage/cards/h/HowlOfTheHorde.java @@ -77,7 +77,7 @@ public class HowlOfTheHorde extends CardImpl { class HowlOfTheHordeDelayedTriggeredAbility extends DelayedTriggeredAbility { HowlOfTheHordeDelayedTriggeredAbility() { - super(new CopyTargetSpellEffect(), Duration.EndOfTurn); + super(new CopyTargetSpellEffect(true), Duration.EndOfTurn); } HowlOfTheHordeDelayedTriggeredAbility(final HowlOfTheHordeDelayedTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/cards/i/InfernalKirin.java b/Mage.Sets/src/mage/cards/i/InfernalKirin.java index 90104521c5..8ac95b840b 100644 --- a/Mage.Sets/src/mage/cards/i/InfernalKirin.java +++ b/Mage.Sets/src/mage/cards/i/InfernalKirin.java @@ -55,7 +55,7 @@ import mage.target.TargetPlayer; public class InfernalKirin extends CardImpl { public InfernalKirin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.KIRIN); this.subtype.add(SubType.SPIRIT); @@ -100,11 +100,11 @@ class InfernalKirinEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); if (spell != null) { int cmc = spell.getConvertedManaCost(); Player targetPlayer = null; - for(Target target: source.getTargets()) { + for (Target target : source.getTargets()) { if (target instanceof TargetPlayer) { targetPlayer = game.getPlayer(target.getFirstTarget()); } @@ -112,7 +112,7 @@ class InfernalKirinEffect extends OneShotEffect { if (targetPlayer != null) { if (!targetPlayer.getHand().isEmpty()) { targetPlayer.revealCards("Infernal Kirin", targetPlayer.getHand(), game); - for (UUID uuid: targetPlayer.getHand().copy()) { + for (UUID uuid : targetPlayer.getHand().copy()) { Card card = game.getCard(uuid); if (card != null && card.getConvertedManaCost() == cmc) { targetPlayer.discard(card, source, game); diff --git a/Mage.Sets/src/mage/cards/k/KaervekTheMerciless.java b/Mage.Sets/src/mage/cards/k/KaervekTheMerciless.java index fb626204b3..a196c1f169 100644 --- a/Mage.Sets/src/mage/cards/k/KaervekTheMerciless.java +++ b/Mage.Sets/src/mage/cards/k/KaervekTheMerciless.java @@ -29,7 +29,6 @@ package mage.cards.k; import java.util.UUID; import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SpellCastOpponentTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -51,7 +50,7 @@ import mage.target.common.TargetCreatureOrPlayer; public class KaervekTheMerciless extends CardImpl { public KaervekTheMerciless(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{B}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{R}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SHAMAN); @@ -94,9 +93,9 @@ class KaervekTheMercilessEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - MageObject spellCast = game.getObject(getTargetPointer().getFirst(game, source)); - if (spellCast instanceof Spell) { - int cost = ((Spell) spellCast).getConvertedManaCost(); + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); + if (spell != null) { + int cost = spell.getConvertedManaCost(); Player target = game.getPlayer(source.getFirstTarget()); if (target != null) { target.damage(cost, source.getSourceId(), game, false, true); diff --git a/Mage.Sets/src/mage/cards/m/MetallurgicSummonings.java b/Mage.Sets/src/mage/cards/m/MetallurgicSummonings.java index 56c3273bad..cdd7b429e6 100644 --- a/Mage.Sets/src/mage/cards/m/MetallurgicSummonings.java +++ b/Mage.Sets/src/mage/cards/m/MetallurgicSummonings.java @@ -51,7 +51,6 @@ import mage.game.Game; import mage.game.permanent.token.MetallurgicSummoningsConstructToken; import mage.game.stack.Spell; import mage.players.Player; -import mage.target.targetpointer.FixedTarget; /** * @@ -106,10 +105,7 @@ class MetallurgicSummoningsTokenEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); - if (spell == null) { - spell = (Spell) game.getLastKnownInformation(((FixedTarget) getTargetPointer()).getTarget(), Zone.STACK); - } + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); if (spell != null) { int cmc = spell.getConvertedManaCost(); if (cmc > 0) { diff --git a/Mage.Sets/src/mage/cards/m/Mirari.java b/Mage.Sets/src/mage/cards/m/Mirari.java index 7a657a5fd8..f973289909 100644 --- a/Mage.Sets/src/mage/cards/m/Mirari.java +++ b/Mage.Sets/src/mage/cards/m/Mirari.java @@ -84,7 +84,7 @@ class MirariTriggeredAbility extends TriggeredAbilityImpl { } MirariTriggeredAbility() { - super(Zone.BATTLEFIELD, new DoIfCostPaid(new CopyTargetSpellEffect(), new GenericManaCost(3)), false); + super(Zone.BATTLEFIELD, new DoIfCostPaid(new CopyTargetSpellEffect(true), new GenericManaCost(3)), false); this.addTarget(new TargetSpell(filter)); } diff --git a/Mage.Sets/src/mage/cards/p/PrimalWellspring.java b/Mage.Sets/src/mage/cards/p/PrimalWellspring.java index cbdbae5b85..fe6bcfba62 100644 --- a/Mage.Sets/src/mage/cards/p/PrimalWellspring.java +++ b/Mage.Sets/src/mage/cards/p/PrimalWellspring.java @@ -59,7 +59,7 @@ public class PrimalWellspring extends CardImpl { this.addAbility(ability); // When that mana is spent to cast an instant or sorcery spell, copy that spell and you may choose new targets for the copy. - Effect effect = new CopyTargetSpellEffect(); + Effect effect = new CopyTargetSpellEffect(true); effect.setText("copy that spell and you may choose new targets for the copy"); this.addAbility(new PyrimalWellspringTriggeredAbility(ability.getOriginalId(), effect)); } diff --git a/Mage.Sets/src/mage/cards/p/PyromancerAscension.java b/Mage.Sets/src/mage/cards/p/PyromancerAscension.java index 556835d047..21a6ac5d85 100644 --- a/Mage.Sets/src/mage/cards/p/PyromancerAscension.java +++ b/Mage.Sets/src/mage/cards/p/PyromancerAscension.java @@ -127,7 +127,7 @@ class PyromancerAscensionQuestTriggeredAbility extends TriggeredAbilityImpl { class PyromancerAscensionCopyTriggeredAbility extends TriggeredAbilityImpl { PyromancerAscensionCopyTriggeredAbility() { - super(Zone.BATTLEFIELD, new CopyTargetSpellEffect(), true); + super(Zone.BATTLEFIELD, new CopyTargetSpellEffect(true), true); } PyromancerAscensionCopyTriggeredAbility(final PyromancerAscensionCopyTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java b/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java index fd658c276e..bc8b042989 100644 --- a/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java +++ b/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java @@ -62,7 +62,7 @@ public class PyromancersGoggles extends CardImpl { this.addAbility(ability); // When that mana is used to cast a red instant or sorcery spell, copy that spell and you may choose new targets for the copy. - Effect effect = new CopyTargetSpellEffect(); + Effect effect = new CopyTargetSpellEffect(true); effect.setText("copy that spell and you may choose new targets for the copy"); this.addAbility(new PyromancersGogglesTriggeredAbility(ability.getOriginalId(), effect)); diff --git a/Mage.Sets/src/mage/cards/r/RamosDragonEngine.java b/Mage.Sets/src/mage/cards/r/RamosDragonEngine.java index e6fc90f0e1..7453ae445f 100644 --- a/Mage.Sets/src/mage/cards/r/RamosDragonEngine.java +++ b/Mage.Sets/src/mage/cards/r/RamosDragonEngine.java @@ -101,7 +101,7 @@ class RamosDragonEngineAddCountersEffect extends OneShotEffect { Player you = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(source.getSourceId()); if (you != null && permanent != null) { - Spell spell = game.getStack().getSpell(this.getTargetPointer().getFirst(game, source)); + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); if (spell != null) { int amount = 0; if (spell.getColor(game).isWhite()) { diff --git a/Mage.Sets/src/mage/cards/r/RikuOfTwoReflections.java b/Mage.Sets/src/mage/cards/r/RikuOfTwoReflections.java index b9c2139234..78b85688e7 100644 --- a/Mage.Sets/src/mage/cards/r/RikuOfTwoReflections.java +++ b/Mage.Sets/src/mage/cards/r/RikuOfTwoReflections.java @@ -78,7 +78,7 @@ public class RikuOfTwoReflections extends CardImpl { this.toughness = new MageInt(2); // Whenever you cast an instant or sorcery spell, you may pay {U}{R}. If you do, copy that spell. You may choose new targets for the copy. - Effect effect = new CopyTargetSpellEffect(); + Effect effect = new CopyTargetSpellEffect(true); effect.setText("copy that spell. You may choose new targets for the copy"); this.addAbility(new SpellCastControllerTriggeredAbility(new DoIfCostPaid(effect, new ManaCostsImpl("{U}{R}")), filter, false, true)); diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index 77e7a088f6..0b934660f8 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -125,15 +125,11 @@ class SunbirdsInvocationEffect extends OneShotEffect { if (controller == null || sourceObject == null) { return false; } - Spell spell = game.getStack().getSpell(this.getTargetPointer().getFirst(game, source)); - int xValue = 0; - if (spell == null) { - spell = (Spell) game.getLastKnownInformation(this.getTargetPointer().getFirst(game, source), Zone.STACK); - } + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); if (spell == null) { return false; } - xValue = spell.getConvertedManaCost(); + int xValue = spell.getConvertedManaCost(); Cards cards = new CardsImpl(); cards.addAll(controller.getLibrary().getTopCards(game, xValue)); if (!cards.isEmpty()) { diff --git a/Mage.Sets/src/mage/cards/s/SwarmIntelligence.java b/Mage.Sets/src/mage/cards/s/SwarmIntelligence.java index b6418efb89..4c1c1064b6 100644 --- a/Mage.Sets/src/mage/cards/s/SwarmIntelligence.java +++ b/Mage.Sets/src/mage/cards/s/SwarmIntelligence.java @@ -46,7 +46,7 @@ public class SwarmIntelligence extends CardImpl { // Whenever you cast an instant or sorcery spell, you may copy that spell. You may choose new targets for the copy. this.addAbility(new SpellCastControllerTriggeredAbility( - new CopyTargetSpellEffect().setText("you may copy that spell. You may choose new targets for the copy"), new FilterInstantOrSorcerySpell("an instant or sorcery spell"), true, true)); + new CopyTargetSpellEffect(true).setText("you may copy that spell. You may choose new targets for the copy"), new FilterInstantOrSorcerySpell("an instant or sorcery spell"), true, true)); } public SwarmIntelligence(final SwarmIntelligence card) { diff --git a/Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java b/Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java index 90ffe363c1..d4498f3f01 100644 --- a/Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java +++ b/Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java @@ -154,10 +154,7 @@ class ZadaHedronGrinderEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); - if (spell == null) { - spell = (Spell) game.getLastKnownInformation(targetPointer.getFirst(game, source), Zone.STACK); - } + Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); if (spell != null && controller != null) { // search the target that targets source diff --git a/Mage/src/main/java/mage/abilities/effects/common/CopyTargetSpellEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CopyTargetSpellEffect.java index 567dac9b35..56d50b8c40 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CopyTargetSpellEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CopyTargetSpellEffect.java @@ -43,17 +43,30 @@ import mage.players.Player; */ public class CopyTargetSpellEffect extends OneShotEffect { + private boolean useLKI = false; + public CopyTargetSpellEffect() { super(Outcome.Copy); } + public CopyTargetSpellEffect(boolean useLKI) { + super(Outcome.Copy); + this.useLKI = useLKI; + } + public CopyTargetSpellEffect(final CopyTargetSpellEffect effect) { super(effect); + this.useLKI = effect.useLKI; } @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); + Spell spell; + if (useLKI) { + spell = game.getSpellOrLKIStack(targetPointer.getFirst(game, source)); + } else { + spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); + } if (spell == null) { spell = (Spell) game.getLastKnownInformation(targetPointer.getFirst(game, source), Zone.STACK); } diff --git a/Mage/src/main/java/mage/game/Game.java b/Mage/src/main/java/mage/game/Game.java index 9ac4302df8..044e6a3ae7 100644 --- a/Mage/src/main/java/mage/game/Game.java +++ b/Mage/src/main/java/mage/game/Game.java @@ -57,6 +57,7 @@ import mage.game.match.MatchType; import mage.game.permanent.Battlefield; import mage.game.permanent.Permanent; import mage.game.permanent.PermanentCard; +import mage.game.stack.Spell; import mage.game.stack.SpellStack; import mage.game.turn.Phase; import mage.game.turn.Step; @@ -106,6 +107,10 @@ public interface Game extends MageItem, Serializable { UUID getOwnerId(MageObject object); + Spell getSpell(UUID spellId); + + Spell getSpellOrLKIStack(UUID spellId); + Permanent getPermanent(UUID permanentId); Permanent getPermanentOrLKIBattlefield(UUID permanentId); diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index b1856a43dc..bf310a6d29 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -445,6 +445,20 @@ public abstract class GameImpl implements Game, Serializable { return null; } + @Override + public Spell getSpell(UUID spellId) { + return state.getStack().getSpell(spellId); + } + + @Override + public Spell getSpellOrLKIStack(UUID spellId) { + Spell spell = state.getStack().getSpell(spellId); + if (spell == null) { + spell = (Spell) this.getLastKnownInformation(spellId, Zone.STACK); + } + return spell; + } + @Override public Permanent getPermanent(UUID permanentId) { return state.getPermanent(permanentId); From b7611d2e61be5b5ae98e388de5d5c9e64115c41f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 18:41:03 -0400 Subject: [PATCH 178/182] Implemented Weaver of Lies --- Mage.Sets/src/mage/cards/w/WeaverOfLies.java | 121 +++++++++++++++++++ Mage.Sets/src/mage/sets/Legions.java | 1 + 2 files changed, 122 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WeaverOfLies.java diff --git a/Mage.Sets/src/mage/cards/w/WeaverOfLies.java b/Mage.Sets/src/mage/cards/w/WeaverOfLies.java new file mode 100644 index 0000000000..f43b429040 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WeaverOfLies.java @@ -0,0 +1,121 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility; +import mage.constants.SubType; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureAllEffect; +import mage.abilities.keyword.MorphAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.game.Game; +import mage.target.Target; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class WeaverOfLies extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other creatures with a morph ability"); + + static { + filter.add(new AbilityPredicate(MorphAbility.class)); + filter.add(new AnotherPredicate()); + } + + public WeaverOfLies(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}"); + + this.subtype.add(SubType.BEAST); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Morph {4}{U} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{4}{U}"))); + + // When Weaver of Lies is turned face up, turn any number of target creatures with a morph ability other than Weaver of Lies face down. + Ability ability = new TurnedFaceUpSourceTriggeredAbility(new WeaverOfLiesEffect(), false, false); + ability.addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE, filter, false)); + this.addAbility(ability); + } + + public WeaverOfLies(final WeaverOfLies card) { + super(card); + } + + @Override + public WeaverOfLies copy() { + return new WeaverOfLies(this); + } +} + +class WeaverOfLiesEffect extends OneShotEffect { + + WeaverOfLiesEffect() { + super(Outcome.Benefit); + this.staticText = "turn any number of target creatures with a morph ability other than {this} face down"; + } + + WeaverOfLiesEffect(final WeaverOfLiesEffect effect) { + super(effect); + } + + @Override + public WeaverOfLiesEffect copy() { + return new WeaverOfLiesEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Predicate pred = new PermanentIdPredicate(UUID.randomUUID()); + for (Target target : source.getTargets()) { + for (UUID targetId : target.getTargets()) { + pred = Predicates.or(pred, new PermanentIdPredicate(targetId)); + } + } + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(pred); + game.addEffect(new BecomesFaceDownCreatureAllEffect(filter), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Legions.java b/Mage.Sets/src/mage/sets/Legions.java index fe75ca609d..f6826dc59d 100644 --- a/Mage.Sets/src/mage/sets/Legions.java +++ b/Mage.Sets/src/mage/sets/Legions.java @@ -178,6 +178,7 @@ public class Legions extends ExpansionSet { cards.add(new SetCardInfo("Wall of Hope", 24, Rarity.COMMON, mage.cards.w.WallOfHope.class)); cards.add(new SetCardInfo("Warbreak Trumpeter", 116, Rarity.UNCOMMON, mage.cards.w.WarbreakTrumpeter.class)); cards.add(new SetCardInfo("Ward Sliver", 25, Rarity.UNCOMMON, mage.cards.w.WardSliver.class)); + cards.add(new SetCardInfo("Weaver of Lies", 57, Rarity.RARE, mage.cards.w.WeaverOfLies.class)); cards.add(new SetCardInfo("White Knight", 27, Rarity.UNCOMMON, mage.cards.w.WhiteKnight.class)); cards.add(new SetCardInfo("Willbender", 58, Rarity.UNCOMMON, mage.cards.w.Willbender.class)); cards.add(new SetCardInfo("Windborn Muse", 28, Rarity.RARE, mage.cards.w.WindbornMuse.class)); From ed7923c471e0ec1d35754ed2912cf2b23f7f017c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 18:47:02 -0400 Subject: [PATCH 179/182] Implemented Backslide --- Mage.Sets/src/mage/cards/b/Backslide.java | 113 ++++++++++++++++++++++ Mage.Sets/src/mage/sets/Onslaught.java | 1 + 2 files changed, 114 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/Backslide.java diff --git a/Mage.Sets/src/mage/cards/b/Backslide.java b/Mage.Sets/src/mage/cards/b/Backslide.java new file mode 100644 index 0000000000..deaf789121 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/Backslide.java @@ -0,0 +1,113 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureAllEffect; +import mage.abilities.keyword.CyclingAbility; +import mage.abilities.keyword.MorphAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.game.Game; +import mage.target.Target; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class Backslide extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with a morph ability"); + + static { + filter.add(new AbilityPredicate(MorphAbility.class)); + } + + public Backslide(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + // Turn target creature with a morph ability face down. + this.getSpellAbility().addEffect(new BackslideEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + + // Cycling {U} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{U}"))); + + } + + public Backslide(final Backslide card) { + super(card); + } + + @Override + public Backslide copy() { + return new Backslide(this); + } +} + +class BackslideEffect extends OneShotEffect { + + BackslideEffect() { + super(Outcome.Benefit); + this.staticText = "Turn target creature with a morph ability face down."; + } + + BackslideEffect(final BackslideEffect effect) { + super(effect); + } + + @Override + public BackslideEffect copy() { + return new BackslideEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Predicate pred = new PermanentIdPredicate(UUID.randomUUID()); + for (Target target : source.getTargets()) { + for (UUID targetId : target.getTargets()) { + pred = Predicates.or(pred, new PermanentIdPredicate(targetId)); + } + } + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(pred); + game.addEffect(new BecomesFaceDownCreatureAllEffect(filter), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Onslaught.java b/Mage.Sets/src/mage/sets/Onslaught.java index b38d6a752e..0a94569ee2 100644 --- a/Mage.Sets/src/mage/sets/Onslaught.java +++ b/Mage.Sets/src/mage/sets/Onslaught.java @@ -46,6 +46,7 @@ public class Onslaught extends ExpansionSet { cards.add(new SetCardInfo("Aven Brigadier", 7, Rarity.RARE, mage.cards.a.AvenBrigadier.class)); cards.add(new SetCardInfo("Aven Fateshaper", 69, Rarity.UNCOMMON, mage.cards.a.AvenFateshaper.class)); cards.add(new SetCardInfo("Aven Soulgazer", 8, Rarity.UNCOMMON, mage.cards.a.AvenSoulgazer.class)); + cards.add(new SetCardInfo("Backslide", 70, Rarity.COMMON, mage.cards.b.Backslide.class)); cards.add(new SetCardInfo("Barkhide Mauler", 246, Rarity.COMMON, mage.cards.b.BarkhideMauler.class)); cards.add(new SetCardInfo("Barren Moor", 312, Rarity.COMMON, mage.cards.b.BarrenMoor.class)); cards.add(new SetCardInfo("Battering Craghorn", 188, Rarity.COMMON, mage.cards.b.BatteringCraghorn.class)); From 588dcc735ad034e4c32a19a56b3f30eb05bb8b14 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 18:57:37 -0400 Subject: [PATCH 180/182] Implemented Master of the Veil --- .../src/mage/cards/m/MasterOfTheVeil.java | 120 ++++++++++++++++++ Mage.Sets/src/mage/sets/Legions.java | 1 + 2 files changed, 121 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MasterOfTheVeil.java diff --git a/Mage.Sets/src/mage/cards/m/MasterOfTheVeil.java b/Mage.Sets/src/mage/cards/m/MasterOfTheVeil.java new file mode 100644 index 0000000000..4796929231 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MasterOfTheVeil.java @@ -0,0 +1,120 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility; +import mage.constants.SubType; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureAllEffect; +import mage.abilities.keyword.MorphAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.game.Game; +import mage.target.Target; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class MasterOfTheVeil extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with a morph ability"); + + static { + filter.add(new AbilityPredicate(MorphAbility.class)); + } + + public MasterOfTheVeil(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Morph {2}{U} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{2}{U}"))); + + // When Master of the Veil is turned face up, you may turn target creature with a morph ability face down. + Ability ability = new TurnedFaceUpSourceTriggeredAbility(new MasterOfTheVeilEffect(), false, true); + ability.addTarget(new TargetCreaturePermanent(1, 1, filter, false)); + this.addAbility(ability); + } + + public MasterOfTheVeil(final MasterOfTheVeil card) { + super(card); + } + + @Override + public MasterOfTheVeil copy() { + return new MasterOfTheVeil(this); + } +} + +class MasterOfTheVeilEffect extends OneShotEffect { + + MasterOfTheVeilEffect() { + super(Outcome.Benefit); + this.staticText = "turn target creature with a morph ability face down"; + } + + MasterOfTheVeilEffect(final MasterOfTheVeilEffect effect) { + super(effect); + } + + @Override + public MasterOfTheVeilEffect copy() { + return new MasterOfTheVeilEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Predicate pred = new PermanentIdPredicate(UUID.randomUUID()); + for (Target target : source.getTargets()) { + for (UUID targetId : target.getTargets()) { + pred = Predicates.or(pred, new PermanentIdPredicate(targetId)); + } + } + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(pred); + game.addEffect(new BecomesFaceDownCreatureAllEffect(filter), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Legions.java b/Mage.Sets/src/mage/sets/Legions.java index f6826dc59d..07fb01d460 100644 --- a/Mage.Sets/src/mage/sets/Legions.java +++ b/Mage.Sets/src/mage/sets/Legions.java @@ -133,6 +133,7 @@ public class Legions extends ExpansionSet { cards.add(new SetCardInfo("Lowland Tracker", 17, Rarity.COMMON, mage.cards.l.LowlandTracker.class)); cards.add(new SetCardInfo("Macetail Hystrodon", 106, Rarity.COMMON, mage.cards.m.MacetailHystrodon.class)); cards.add(new SetCardInfo("Magma Sliver", 107, Rarity.RARE, mage.cards.m.MagmaSliver.class)); + cards.add(new SetCardInfo("Master of the Veil", 43, Rarity.UNCOMMON, mage.cards.m.MasterOfTheVeil.class)); cards.add(new SetCardInfo("Merchant of Secrets", 44, Rarity.COMMON, mage.cards.m.MerchantOfSecrets.class)); cards.add(new SetCardInfo("Mistform Sliver", 46, Rarity.COMMON, mage.cards.m.MistformSliver.class)); cards.add(new SetCardInfo("Mistform Ultimus", 47, Rarity.RARE, mage.cards.m.MistformUltimus.class)); From 06ad8e65abf3a6d2a826ef10daf11e3a32b187c8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 20:16:24 -0400 Subject: [PATCH 181/182] Reverted Atarka, Worldrender to before text change implementation --- .../src/mage/cards/a/AtarkaWorldRender.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java b/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java index b9348f249a..7cc32c280d 100644 --- a/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java +++ b/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java @@ -35,14 +35,11 @@ import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.TrampleAbility; -import mage.abilities.text.TextPartSubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.TextPartSubtypePredicate; -import mage.filter.predicate.permanent.TappedPredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -68,11 +65,7 @@ public class AtarkaWorldRender extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Whenever a Dragon you control attacks, it gains double strike until end of turn. - TextPartSubType textPart1 = (TextPartSubType) addTextPart(new TextPartSubType(SubType.DRAGON)); - FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Dragon you control"); - filter.add(new TextPartSubtypePredicate(textPart1)); - filter.add(Predicates.not(new TappedPredicate())); - this.addAbility(new AtarkaWorldRenderEffect(filter)); + this.addAbility(new AtarkaWorldRenderEffect()); } @@ -88,16 +81,18 @@ public class AtarkaWorldRender extends CardImpl { class AtarkaWorldRenderEffect extends TriggeredAbilityImpl { - FilterControlledCreaturePermanent filter; + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("dragon you control"); - public AtarkaWorldRenderEffect(FilterControlledCreaturePermanent filter) { + static { + filter.add(new SubtypePredicate(SubType.DRAGON)); + } + + public AtarkaWorldRenderEffect() { super(Zone.BATTLEFIELD, new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn)); - this.filter = filter; } public AtarkaWorldRenderEffect(final AtarkaWorldRenderEffect ability) { super(ability); - this.filter = ability.filter.copy(); } @Override From 96f3896d56fd504124f138a66b1697f61c70c49e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 18 Sep 2017 22:22:52 -0400 Subject: [PATCH 182/182] fixed Mavren Fein triggering on opponent's attacks (#4023) --- Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java b/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java index bd1251ac89..5f0834f82b 100644 --- a/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java +++ b/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java @@ -79,7 +79,7 @@ public class MavrenFeinDuskApostle extends CardImpl { class MavrenFeinDuskApostleTriggeredAbility extends TriggeredAbilityImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken Vampire you control"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken Vampires you control"); static { filter.add(new SubtypePredicate(SubType.VAMPIRE)); @@ -109,7 +109,7 @@ class MavrenFeinDuskApostleTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { for (UUID creatureId : game.getCombat().getAttackers()) { Permanent creature = game.getPermanent(creatureId); - if (creature != null && filter.match(creature, game)) { + if (creature != null && filter.match(creature, game) && creature.getControllerId().equals(controllerId)) { return true; } }