diff --git a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java index af83e6775bd..7ca2057605b 100644 --- a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java @@ -1083,10 +1083,10 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } repaint(); } - + private void chooseMatching() { Collection toMatch = dragCardList(); - + for (DragCardGridListener l : listeners) { for (CardView card : allCards) { for (CardView aMatch : toMatch) { @@ -1337,6 +1337,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg public void analyseDeck() { HashMap qtys = new HashMap<>(); HashMap pips = new HashMap<>(); + HashMap pips_at_cmcs = new HashMap<>(); HashMap sourcePips = new HashMap<>(); HashMap manaCounts = new HashMap<>(); pips.put("#w}", 0); @@ -1396,11 +1397,40 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } mc = mc.replaceAll("\\{([WUBRG]).([WUBRG])\\}", "{$1}{$2}"); mc = mc.replaceAll("\\{", "#"); + mc = mc.replaceAll("#2\\/", "#"); + mc = mc.replaceAll("p}", "}"); mc = mc.toLowerCase(Locale.ENGLISH); + int cmc = card.getConvertedManaCost(); + + // Do colorless mana pips + Pattern regex = Pattern.compile("#([0-9]+)}"); + Matcher regexMatcher = regex.matcher(mc); + while (regexMatcher.find()) { + String val = regexMatcher.group(1); + int colorless_val = Integer.parseInt(val); + + int total_c_pip = 0; + if (pips.get("#c}") != null) { + total_c_pip = pips.get("#c}"); + } + pips.put("#c}", colorless_val + total_c_pip); + + int cmc_pip_value = 0; + if (pips_at_cmcs.get(cmc + "##c}") != null) { + cmc_pip_value = pips_at_cmcs.get(cmc + "##c}"); + } + pips_at_cmcs.put(cmc + "##c}", colorless_val + cmc_pip_value); + } + for (String pip : pips.keySet()) { int value = pips.get(pip); while (mc.toLowerCase(Locale.ENGLISH).contains(pip)) { pips.put(pip, ++value); + int pip_value = 0; + if (pips_at_cmcs.get(cmc + "#" + pip) != null) { + pip_value = pips_at_cmcs.get(cmc + "#" + pip); + } + pips_at_cmcs.put(cmc + "#" + pip, ++pip_value); mc = mc.replaceFirst(pip, ""); } } @@ -1448,9 +1478,17 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg panel4.add(new JLabel("Mana sources found:")); panel4.add(chart3); + JPanel panel5 = new JPanel(); + panel5.setLayout(new BoxLayout(panel5, BoxLayout.Y_AXIS)); + ManaBarChart chart4 = new ManaBarChart(pips_at_cmcs); + chart4.setMinimumSize(new Dimension(200, 200)); + panel5.add(new JLabel("Mana distribution:")); + panel5.add(chart4); + panel.add(panel2); panel.add(panel3); panel.add(panel4); + panel.add(panel5); JFrame frame = new JFrame("JOptionPane showMessageDialog component example"); JOptionPane.showMessageDialog(frame, panel, "This is the distribution of colors found", JOptionPane.INFORMATION_MESSAGE); @@ -1719,7 +1757,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg JMenuItem invertSelection = new JMenuItem("Invert Selection"); invertSelection.addActionListener(e2 -> invertSelection()); menu.add(invertSelection); - + JMenuItem chooseMatching = new JMenuItem("Choose Matching"); chooseMatching.addActionListener(e2 -> chooseMatching()); menu.add(chooseMatching); diff --git a/Mage.Client/src/main/java/mage/client/cards/ManaBarChart.java b/Mage.Client/src/main/java/mage/client/cards/ManaBarChart.java new file mode 100644 index 00000000000..15ae7abb539 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/cards/ManaBarChart.java @@ -0,0 +1,151 @@ +package mage.client.cards; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Stroke; +import java.awt.geom.Rectangle2D; +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.swing.JComponent; + +public class ManaBarChart extends JComponent { + + HashMap pips_at_cmcs = new HashMap(); + + ManaBarChart() { + } + + ManaBarChart(HashMap pips_at_cmcs) { + this.pips_at_cmcs = pips_at_cmcs; + } + + @Override + public Dimension getPreferredSize() { + Dimension preferred = super.getPreferredSize(); + Dimension minimum = getMinimumSize(); + Dimension maximum = getMaximumSize(); + preferred.width = Math.min(Math.max(preferred.width, minimum.width), maximum.width); + preferred.height = Math.min(Math.max(preferred.height, minimum.height), maximum.height); + return preferred; + } + + public void paint(Graphics g) { + drawBar((Graphics2D) g, getBounds()); + } + + void drawBar(Graphics2D g, Rectangle area) { + Pattern regex = Pattern.compile("^([0-9]+)##(.)}"); + HashMap totals_at_cmcs = new HashMap(); + int max_num_pips = 0; + int max_cmc = 0; + + for (String key : pips_at_cmcs.keySet()) { + Matcher regexMatcher = regex.matcher(key); + int num_pips = pips_at_cmcs.get(key); + while (regexMatcher.find()) { + String cmc = regexMatcher.group(1); + int cmc_num = Integer.parseInt(cmc); + if (max_cmc < cmc_num) { + max_cmc = cmc_num; + } + + int total_at_cmc = 0; + if (totals_at_cmcs.get(cmc_num) != null) { + total_at_cmc = totals_at_cmcs.get(cmc_num); + } + totals_at_cmcs.put(cmc_num, total_at_cmc + num_pips); + if (max_num_pips < total_at_cmc + num_pips) { + max_num_pips = total_at_cmc + num_pips; + } + } + } + + if (max_num_pips <= 0) { + max_num_pips = 1; + } + int height_factor = 200 / max_num_pips; + int width_factor = 200 / (max_cmc + 2); + if (width_factor > 20) { + width_factor = 20; + } + if (width_factor < 11) { + width_factor = 11; + } + + g.setColor(new Color(130, 130, 130)); + for (int i = 0; i < max_num_pips; i++) { + if (max_num_pips > 10) { + if (i % 10 == 0) { + g.drawLine(0, 200 - 1 - i * height_factor, 400, 200 - 1 - i * height_factor); + } else if (i % 10 == 5) { + Stroke dashed = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{5}, 0); + Stroke oldstroke = g.getStroke(); + g.setStroke(dashed); + g.drawLine(0, 200 - 1 - i * height_factor, 400, 200 - 1 - i * height_factor); + g.setStroke(oldstroke); + } + } else if (i % 2 == 0) { + g.drawLine(0, 200 - 1 - i * height_factor, 400, 200 - 1 - i * height_factor); + } else if (i % 2 == 1) { + Stroke dashed = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{5}, 0); + Stroke oldstroke = g.getStroke(); + g.setStroke(dashed); + g.drawLine(0, 200 - 1 - i * height_factor, 400, 200 - 1 - i * height_factor); + g.setStroke(oldstroke); + } + } + + for (int i = 0; i < 17; i++) { + if (i % 5 == 0) { + g.drawLine(width_factor * i, 200, width_factor * i, 190); + } else { + g.drawLine(width_factor * i, 200, width_factor * i, 195); + } + + } + + HashMap running_totals_at_cmcs = new HashMap(); + for (String key : pips_at_cmcs.keySet()) { + Matcher regexMatcher = regex.matcher(key); + int num_pips = pips_at_cmcs.get(key); + while (regexMatcher.find()) { + String cmc = regexMatcher.group(1); + int cmc_num = Integer.parseInt(cmc); + String color = regexMatcher.group(2); + + int total_at_cmc = 0; + if (running_totals_at_cmcs.get(cmc_num) != null) { + total_at_cmc = running_totals_at_cmcs.get(cmc_num); + } + + if (color.equalsIgnoreCase("w")) { + g.setColor(Color.WHITE); + } + if (color.equalsIgnoreCase("u")) { + g.setColor(Color.BLUE); + } + if (color.equalsIgnoreCase("b")) { + g.setColor(Color.BLACK); + } + if (color.equalsIgnoreCase("r")) { + g.setColor(Color.RED); + } + if (color.equalsIgnoreCase("g")) { + g.setColor(Color.GREEN); + } + if (color.equalsIgnoreCase("c")) { + g.setColor(Color.DARK_GRAY); + } + g.fill(new Rectangle2D.Double(cmc_num * width_factor, 200 - 1 - total_at_cmc - num_pips * height_factor, 10, num_pips * height_factor)); + running_totals_at_cmcs.put(cmc_num, total_at_cmc + num_pips * height_factor); + } + } + + } +} diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/DownloadGui.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/DownloadGui.java index a8438a706af..e3ff2ca179d 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/DownloadGui.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/DownloadGui.java @@ -158,6 +158,7 @@ public class DownloadGui extends JPanel { b.addActionListener(e -> { switch(this.job.getState()) { case NEW: + case PREPARING: case WORKING: this.job.setState(State.ABORTED); } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/DownloadJob.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/DownloadJob.java index 6efcfd3eef4..c39fb6d1633 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/DownloadJob.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/DownloadJob.java @@ -23,16 +23,16 @@ import org.mage.plugins.card.utils.CardImageUtils; * The class DownloadJob. * * @version V0.0 25.08.2010 - * @author Clemens Koza + * @author Clemens Koza, JayDi85 */ public class DownloadJob extends AbstractLaternaBean { public enum State { - NEW, WORKING, FINISHED, ABORTED + NEW, PREPARING, WORKING, FINISHED, ABORTED } private final String name; - private final Source source; + private Source source; private final Destination destination; private final Property state = properties.property("state", State.NEW); private final Property message = properties.property("message"); @@ -98,6 +98,36 @@ public class DownloadJob extends AbstractLaternaBean { this.message.setValue(message); } + /** + * Inner prepare cycle from new to working + */ + public void doPrepareAndStartWork() { + if (this.state.getValue() != State.NEW) { + setError("Can't call prepare at this point."); + return; + } + + this.state.setValue(State.PREPARING); + + try { + onPreparing(); + } catch (Exception e) { + setError("Prepare error: " + e.getMessage(), e); + return; + } + + // change to working state on good prepare call + this.state.setValue(State.WORKING); + } + + + /** + * Prepare code to override in custom download tasks (it's calls before work start) + */ + public void onPreparing() throws Exception { + return; + } + /** * Sets the job's message. * @@ -131,6 +161,10 @@ public class DownloadJob extends AbstractLaternaBean { return source; } + public void setSource(Source source) { + this.source = source; + } + public Destination getDestination() { return destination; } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/Downloader.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/Downloader.java index 4b71a8d16c0..497ee62d62b 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/Downloader.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/Downloader.java @@ -60,6 +60,7 @@ public class Downloader extends AbstractLaternaBean implements Disposable { for (DownloadJob j : jobs) { switch (j.getState()) { case NEW: + case PREPARING: case WORKING: j.setState(State.ABORTED); } @@ -82,8 +83,11 @@ public class Downloader extends AbstractLaternaBean implements Disposable { } public void add(DownloadJob job) { + if (job.getState() == State.PREPARING) { + throw new IllegalArgumentException("Job already preparing"); + } if (job.getState() == State.WORKING) { - throw new IllegalArgumentException("Job already running"); + throw new IllegalArgumentException("Job already working"); } if (job.getState() == State.FINISHED) { throw new IllegalArgumentException("Job already finished"); @@ -106,13 +110,22 @@ public class Downloader extends AbstractLaternaBean implements Disposable { @Override public void onMessage(DownloadJob job) { - //the job won't be processed by multiple threads + + // start to work + // the job won't be processed by multiple threads synchronized (job) { if (job.getState() != State.NEW) { return; } - job.setState(State.WORKING); + + job.doPrepareAndStartWork(); + + if (job.getState() != State.WORKING) { + return; + } } + + // download and save data try { Source src = job.getSource(); Destination dst = job.getDestination(); diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CopyPasteImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CopyPasteImageSource.java new file mode 100644 index 00000000000..0fc6561b978 --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CopyPasteImageSource.java @@ -0,0 +1,255 @@ +package org.mage.plugins.card.dl.sources; + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.swing.JOptionPane; +import mage.cards.Sets; +import org.mage.plugins.card.images.CardDownloadData; + +/** + * + * @author spjspj + */ +public enum CopyPasteImageSource implements CardImageSource { + + instance; + + private Set supportedSets = new LinkedHashSet(); + private Set missingCards = new LinkedHashSet(); + HashMap singleLinks = null; + boolean loadedFromDialog = false; + boolean viewMissingCards = true; + HashMap singleLinksDone = null; + private static int maxTimes = 2; + + @Override + public String getSourceName() { + return ""; + } + + @Override + public float getAverageSize() { + return 260.7f; + } + + @Override + public String getNextHttpImageUrl() { + if (singleLinks == null) { + setupLinks(); + } + + for (String key : singleLinksDone.keySet()) { + if (singleLinksDone.get(key) < maxTimes) { + singleLinksDone.put(key, maxTimes); + return key; + } + } + if (maxTimes < 2) { + maxTimes++; + } + for (String key : singleLinksDone.keySet()) { + if (singleLinksDone.get(key) < maxTimes) { + singleLinksDone.put(key, maxTimes); + return key; + } + } + return null; + } + + @Override + public String getFileForHttpImage(String httpImageUrl) { + String copy = httpImageUrl; + if (copy != null) { + return singleLinks.get(copy); + } + return null; + } + + @Override + public CardImageUrls generateURL(CardDownloadData card) throws Exception { + if (singleLinks == null) { + setupLinks(); + } + String url = singleLinks.get(card.getSet() + "/" + card.getName()); + if (url != null && url.length() > 0) { + return new CardImageUrls(url); + } + url = singleLinks.get(card.getSet() + "/" + card.getName() + "." + card.getCollectorId()); + if (url != null && url.length() > 0) { + return new CardImageUrls(url); + } + return null; + } + + int ls_size_mc = 0; + int ls_size_ss = 0; + int ls_size_sl = 0; + int num_nos = 0; + + private boolean isDifferent() { + boolean isdiff = false; + if (ls_size_mc != missingCards.size()) { + ls_size_mc = missingCards.size(); + isdiff = true; + } + if (ls_size_ss != supportedSets.size()) { + ls_size_ss = supportedSets.size(); + isdiff = true; + } + if (ls_size_sl != singleLinks.size()) { + ls_size_sl = singleLinks.size(); + isdiff = true; + } + num_nos++; + if (num_nos > 2) { + num_nos = 0; + isdiff = true; + } + return isdiff; + } + + private void setupLinks() { + if (singleLinks != null && loadedFromDialog) { + if (!viewMissingCards) { + if (isDifferent() && JOptionPane.showConfirmDialog(null, + "View your missing cards and reset the list of card images to download again?", + "View missing cards (found " + missingCards.size() + ") / Reset URLs to download ", JOptionPane.YES_NO_OPTION) + == JOptionPane.YES_OPTION) { + viewMissingCards = true; + singleLinks.clear(); + loadedFromDialog = false; + supportedSets.clear(); + } else { + return; + } + } + if (!(viewMissingCards && missingCards.size() > 0)) { + return; + } + } + singleLinks = new HashMap<>(); + loadedFromDialog = false; + + final CopyPasteImageSourceDialog dialog = new CopyPasteImageSourceDialog(); + dialog.pack(); + int count = 0; + if (viewMissingCards && missingCards.size() > 0 && singleLinks.size() == 0) { + viewMissingCards = false; + String displayMissingCardsStr = "Up to the first 20 cards are:\n"; + String missingCardsStr = ""; + if (this.missingCards != null) { + for (String card : this.missingCards) { + if (count < 20) { + displayMissingCardsStr = displayMissingCardsStr + card + "\n"; + } + missingCardsStr = missingCardsStr + card + "\n"; + + count++; + } + } + StringSelection stringSelection = new StringSelection(missingCardsStr); + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(stringSelection, null); + + if (isDifferent() && JOptionPane.showConfirmDialog(null, + displayMissingCardsStr + "\n\nReset the list again?\n(NB: The full list has been copied to the clipboard)", + "Your missing cards (found " + missingCards.size() + "): ", JOptionPane.YES_NO_OPTION) + == JOptionPane.YES_OPTION) { + viewMissingCards = true; + singleLinks.clear(); + loadedFromDialog = false; + supportedSets.clear(); + } else { + return; + } + } + dialog.setVisible(true); + String[] lines = dialog.getPastedData().split(System.getProperty("line.separator")); + + for (String line : lines) { + // Break into >> "\1", "\2" + Pattern regex = Pattern.compile("\\s*\"(.*?)/(.*?)\"\\s*,\\s*\"(.*?)\""); + Matcher regexMatcher = regex.matcher(line); + while (regexMatcher.find()) { + String setCode = regexMatcher.group(1); + String cardName = regexMatcher.group(2); + String imageURL = regexMatcher.group(3); + supportedSets.add(setCode); + singleLinks.put(setCode + "/" + cardName, imageURL); + isDifferent(); + } + } + + loadedFromDialog = true; + if (lines.length == 0) { + loadedFromDialog = false; + viewMissingCards = true; + } + } + + @Override + public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException { + try { + return generateURL(card); + } catch (Exception ex) { + } + return null; + } + + @Override + public int getTotalImages() { + if (singleLinks == null) { + setupLinks(); + } + if (singleLinks != null) { + return singleLinks.size(); + } + return -1; + } + + @Override + public boolean isTokenSource() { + return false; + } + + @Override + public ArrayList getSupportedSets() { + setupLinks(); + ArrayList supportedSetsCopy = new ArrayList<>(); + if (supportedSets.size() == 0) { + for (String setCode : Sets.getInstance().keySet()) { + supportedSets.add(setCode); + } + } + + supportedSetsCopy.addAll(supportedSets); + return supportedSetsCopy; + } + + @Override + public void doPause(String httpImageUrl) { + } + + @Override + public boolean isImageProvided(String setCode, String cardName) { + missingCards.add(setCode + "/" + cardName); + + if (singleLinks != null) { + return singleLinks.containsKey(setCode + "/" + cardName) || singleLinks.containsKey(setCode + "/" + cardName + "-a"); + } + return false; + } + + @Override + public boolean isSetSupportedComplete(String setCode) { + return false; + } +} diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CopyPasteImageSourceDialog.form b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CopyPasteImageSourceDialog.form new file mode 100644 index 00000000000..fe9fa3cf9bd --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CopyPasteImageSourceDialog.form @@ -0,0 +1,79 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CopyPasteImageSourceDialog.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CopyPasteImageSourceDialog.java new file mode 100644 index 00000000000..b64d7cc8105 --- /dev/null +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CopyPasteImageSourceDialog.java @@ -0,0 +1,182 @@ +package org.mage.plugins.card.dl.sources; + +import mage.util.StreamUtils; + +import java.awt.*; +import java.awt.event.*; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Set; +import javax.swing.*; + +public class CopyPasteImageSourceDialog extends JDialog { + + private JPanel contentPane; + private JButton buttonOK; + private JButton buttonCancel; + private JEditorPane txtDeckList; + + private String tmpPath; + + public CopyPasteImageSourceDialog() { + initComponents(); + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + + buttonOK.addActionListener(e -> onOK()); + buttonCancel.addActionListener(e -> onCancel()); + + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + // Close on "ESC" + contentPane.registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + } + + private void onOK() { + BufferedWriter bw = null; + try { + File temp = File.createTempFile("import_images_from_url", ".txt"); + bw = new BufferedWriter(new FileWriter(temp)); + bw.write(txtDeckList.getText()); + tmpPath = temp.getPath(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + StreamUtils.closeQuietly(bw); + } + + dispose(); + } + + private void onCancel() { + dispose(); + } + + public String getTmpPath() { + return tmpPath; + } + + private void initComponents() { + contentPane = new JPanel(); + JPanel panel1 = new JPanel(); + JPanel panel2 = new JPanel(); + buttonOK = new JButton(); + buttonCancel = new JButton(); + JPanel panel3 = new JPanel(); + txtDeckList = new JEditorPane(); + + { + contentPane.setMinimumSize(new Dimension(540, 450)); + + contentPane.setBorder(new javax.swing.border.CompoundBorder( + new javax.swing.border.TitledBorder(new javax.swing.border.EmptyBorder(0, 0, 0, 0), + "Download Images from Copy/Pasted Text", javax.swing.border.TitledBorder.CENTER, + javax.swing.border.TitledBorder.TOP, new java.awt.Font("Dialog", java.awt.Font.PLAIN, 12), + java.awt.Color.BLACK), contentPane.getBorder())); + + contentPane.addPropertyChangeListener(e -> { + if ("border".equals(e.getPropertyName())) { + throw new RuntimeException(); + } + }); + + contentPane.addPropertyChangeListener(e -> { + if ("border".equals(e.getPropertyName())) { + throw new RuntimeException(); + } + }); + + contentPane.setLayout(new GridBagLayout()); + ((GridBagLayout) contentPane.getLayout()).columnWidths = new int[]{0, 0}; + ((GridBagLayout) contentPane.getLayout()).rowHeights = new int[]{0, 0, 0}; + ((GridBagLayout) contentPane.getLayout()).columnWeights = new double[]{0.01, 1.0E-4}; + ((GridBagLayout) contentPane.getLayout()).rowWeights = new double[]{0.01, 0.0, 1.0E-4}; + + { + panel1.setLayout(new GridBagLayout()); + ((GridBagLayout) panel1.getLayout()).columnWidths = new int[]{0, 0, 0}; + ((GridBagLayout) panel1.getLayout()).rowHeights = new int[]{0, 0}; + ((GridBagLayout) panel1.getLayout()).columnWeights = new double[]{0.0, 0.01, 1.0E-4}; + ((GridBagLayout) panel1.getLayout()).rowWeights = new double[]{0.01, 1.0E-4}; + + { + panel2.setLayout(new GridBagLayout()); + ((GridBagLayout) panel2.getLayout()).columnWidths = new int[]{0, 4, 0, 0}; + ((GridBagLayout) panel2.getLayout()).rowHeights = new int[]{0, 0}; + ((GridBagLayout) panel2.getLayout()).columnWeights = new double[]{0.01, 0.0, 0.01, 1.0E-4}; + ((GridBagLayout) panel2.getLayout()).rowWeights = new double[]{0.0, 1.0E-4}; + + //---- buttonOK ---- + buttonOK.setText("Download from URLs"); + panel2.add(buttonOK, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + + //---- buttonCancel ---- + buttonCancel.setText("Cancel"); + panel2.add(buttonCancel, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + } + panel1.add(panel2, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(0, 0, 0, 0), 0, 0)); + } + contentPane.add(panel1, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(0, 0, 0, 0), 0, 0)); + + { + panel3.setLayout(new GridBagLayout()); + ((GridBagLayout) panel3.getLayout()).columnWidths = new int[]{0, 0}; + ((GridBagLayout) panel3.getLayout()).rowHeights = new int[]{0, 0}; + ((GridBagLayout) panel3.getLayout()).columnWeights = new double[]{0.0, 1.0E-4}; + ((GridBagLayout) panel3.getLayout()).rowWeights = new double[]{1.0, 1.0E-4}; + + txtDeckList.setMinimumSize(new Dimension(250, 400)); + txtDeckList.setPreferredSize(new Dimension(550, 400)); + + txtDeckList.setText("// Example follows. \nNB: **DELETE ALL TEXT AND GO SELECT THIS SOURCE AGAIN TO SEE THE NAMES CARDS YOU'RE MISSING IMAGES FOR!!!***\n\"SWS/Might of the Wild\", \"http://i.imgur.com/eNXOdxp.jpg\"\n\"PTC/Wolf of Devil's Breach\", \"https://img.scryfall.com/cards/large/en/psoi/192s.jpg\"\n\nExpected columns: Name of Card (Set Trigraph\\Name), URL of image\n\n\n"); + + JScrollPane txtScrollableDeckList = new JScrollPane(txtDeckList); + panel3.add(txtScrollableDeckList, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(0, 0, 0, 0), 0, 0)); + } + contentPane.add(panel3, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(0, 0, 5, 0), 0, 0)); + } + } + + Set missingCards = null; + + public void addMissingCards(Set missingCards) { + this.missingCards = missingCards; + String missingCardsStr = ""; + boolean found = false; + if (this.missingCards != null) { + for (String card : this.missingCards) { + found = true; + missingCardsStr = missingCardsStr + card + "\n"; + } + } + if (found == false) { + missingCardsStr = "\n\nNote: Leave blank to see your missing card names!\n"; + } + txtDeckList.setText(txtDeckList.getText() + "\n\nYour missing card images are:\n" + missingCardsStr); + } + + public String getPastedData() { + return txtDeckList.getText(); + } +} diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallSymbolsSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallSymbolsSource.java index e90d1cf9c5d..483bb27e866 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallSymbolsSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallSymbolsSource.java @@ -9,8 +9,13 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import mage.MageException; import mage.util.StreamUtils; +import org.jsoup.select.Elements; import org.mage.plugins.card.dl.DownloadJob; +import org.mage.plugins.card.utils.CardImageUtils; + +import javax.swing.text.Document; import static org.mage.card.arcane.ManaSymbols.getSymbolFileNameAsSVG; import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; @@ -18,14 +23,14 @@ import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; // TODO: add force to download symbols (rewrite exist files) /** - * - * @author jaydi85@gmail.com - * + * @author JayDi85 */ public class ScryfallSymbolsSource implements Iterable { - static final String SOURCE_URL = "https://assets.scryfall.com/assets/scryfall.css"; // search css-file on https://scryfall.com/docs/api/colors + //static final String SOURCE_URL = "https://assets.scryfall.com/assets/scryfall.css"; // old version with direct css-file on https://scryfall.com/docs/api/colors + static final String CSS_SOURCE_URL = "https://scryfall.com/docs/api/colors"; + static final String CSS_SOURCE_SELECTOR = "link[rel=stylesheet]"; // static final String STATE_PROP_NAME = "state"; static final String DOWNLOAD_TEMP_FILE = getImagesDir() + File.separator + "temp" + File.separator + "scryfall-symbols-source.txt"; @@ -55,21 +60,21 @@ public class ScryfallSymbolsSource implements Iterable { return jobs.iterator(); } - private void parseData(String sourcePath){ + private void parseData(String sourcePath) { String sourceData = ""; try { sourceData = new String(Files.readAllBytes(Paths.get(sourcePath))); - }catch (IOException e) { + } catch (IOException e) { LOGGER.error("Can't open file to parse data: " + sourcePath + " , reason: " + e.getMessage()); } // gen symbols list ArrayList allMageSymbols = new ArrayList<>(); - for(int i = 0; i < SYMBOLS_LIST.length; i++){ + for (int i = 0; i < SYMBOLS_LIST.length; i++) { allMageSymbols.add(SYMBOLS_LIST[i]); } - for(Integer i = SYMBOLS_NUMBER_START; i <= SYMBOLS_NUMBER_END; i++){ + for (Integer i = SYMBOLS_NUMBER_START; i <= SYMBOLS_NUMBER_END; i++) { allMageSymbols.add(String.valueOf(SYMBOLS_NUMBER_START + i)); } @@ -88,23 +93,22 @@ public class ScryfallSymbolsSource implements Iterable { // dirs maker File dir = getSymbolFileNameAsSVG("W").getParentFile(); - if(!dir.exists()){ + if (!dir.exists()) { dir.mkdirs(); } // decode and save data (only if not exist) - for(String needCode: allMageSymbols){ + for (String needCode : allMageSymbols) { String searchCode = needCode.replace("/", ""); - if(!foundedData.containsKey(searchCode)) - { + if (!foundedData.containsKey(searchCode)) { LOGGER.warn("Can't found symbol code from scryfall: " + searchCode); continue; } File destFile = getSymbolFileNameAsSVG(searchCode); - if (destFile.exists() && (destFile.length() > 0)){ + if (destFile.exists() && (destFile.length() > 0)) { continue; } FileOutputStream stream = null; @@ -118,7 +122,7 @@ public class ScryfallSymbolsSource implements Iterable { stream.write(fileData); LOGGER.info("New svg symbol downloaded: " + needCode); - } catch (Exception e) { + } catch (Exception e) { LOGGER.error("Can't decode svg icon and save to file: " + destFile.getPath() + ", reason: " + e.getMessage()); } finally { StreamUtils.closeQuietly(stream); @@ -127,23 +131,26 @@ public class ScryfallSymbolsSource implements Iterable { } - private class ScryfallSymbolsDownloadJob extends DownloadJob{ + private class ScryfallSymbolsDownloadJob extends DownloadJob { + + private String cssUrl = ""; // need to find url from colors page https://scryfall.com/docs/api/colors // listener for data parse after download complete - private class ScryDownloadOnFinishedListener implements PropertyChangeListener { + private class ScryfallDownloadOnFinishedListener implements PropertyChangeListener { private String downloadedFile; - public ScryDownloadOnFinishedListener(String ADestFile){ + public ScryfallDownloadOnFinishedListener(String ADestFile) { this.downloadedFile = ADestFile; } @Override public void propertyChange(PropertyChangeEvent evt) { - if (!evt.getPropertyName().equals(STATE_PROP_NAME)){ + + if (!evt.getPropertyName().equals(STATE_PROP_NAME)) { throw new IllegalArgumentException("Unknown download property " + evt.getPropertyName()); } - if (evt.getNewValue() != State.FINISHED){ + if (evt.getNewValue() != State.FINISHED) { return; } @@ -152,16 +159,34 @@ public class ScryfallSymbolsSource implements Iterable { } } + @Override + public void onPreparing() throws Exception { + this.cssUrl = ""; + + org.jsoup.nodes.Document doc = CardImageUtils.downloadHtmlDocument(CSS_SOURCE_URL); + org.jsoup.select.Elements cssList = doc.select(CSS_SOURCE_SELECTOR); + if (cssList.size() == 1) { + this.cssUrl = cssList.first().attr("href").toString(); + } + + if (this.cssUrl.isEmpty()) { + throw new IllegalStateException("Can't find stylesheet url from scryfall colors page."); + } else { + this.setSource(fromURL(this.cssUrl)); + } + } + private String destFile = ""; public ScryfallSymbolsDownloadJob() { - super("Scryfall symbols source", fromURL(SOURCE_URL), toFile(DOWNLOAD_TEMP_FILE)); + // download init + super("Scryfall symbols source", fromURL(""), toFile(DOWNLOAD_TEMP_FILE)); // url setup on preparing stage this.destFile = DOWNLOAD_TEMP_FILE; - this.addPropertyChangeListener(STATE_PROP_NAME, new ScryDownloadOnFinishedListener(this.destFile)); + this.addPropertyChangeListener(STATE_PROP_NAME, new ScryfallDownloadOnFinishedListener(this.destFile)); // clear dest file (always download new data) File file = new File(this.destFile); - if (file.exists()){ + if (file.exists()) { file.delete(); } } 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 dff6ed8304c..e4103359ba9 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 @@ -35,6 +35,7 @@ import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import org.mage.plugins.card.images.CardDownloadData; +import org.mage.plugins.card.utils.CardImageUtils; /** * @author North @@ -535,7 +536,7 @@ public enum WizardCardsImageSource implements CardImageSource { while (page < 999) { 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); + Document doc = CardImageUtils.downloadHtmlDocument(searchUrl); Elements cardsImages = doc.select("img[src^=../../Handlers/]"); if (cardsImages.isEmpty()) { break; @@ -587,33 +588,6 @@ public enum WizardCardsImageSource implements CardImageSource { return setLinks; } - private Document getDocument(String urlString) throws NumberFormatException, IOException { - Preferences prefs = MageFrame.getPreferences(); - Connection.ProxyType proxyType = Connection.ProxyType.valueByText(prefs.get("proxyType", "None")); - Document doc; - if (proxyType == ProxyType.NONE) { - 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; - StringBuffer tmp = new StringBuffer(); - BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream())); - while ((line = in.readLine()) != null) { - tmp.append(line); - } - doc = Jsoup.parse(String.valueOf(tmp)); - } - return doc; - } - private void getLandVariations(LinkedHashMap setLinks, String cardSet, int multiverseId, String cardName) throws IOException, NumberFormatException { CardCriteria criteria = new CardCriteria(); criteria.nameExact(cardName); @@ -621,7 +595,7 @@ public enum WizardCardsImageSource implements CardImageSource { List cards = CardRepository.instance.findCards(criteria); String urlLandDocument = "http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=" + multiverseId; - Document landDoc = getDocument(urlLandDocument); + Document landDoc = CardImageUtils.downloadHtmlDocument(urlLandDocument); Elements variations = landDoc.select("a.variationlink"); if (!variations.isEmpty()) { if (variations.size() > cards.size()) { @@ -668,7 +642,7 @@ public enum WizardCardsImageSource implements CardImageSource { private HashMap getlocalizedMultiverseIds(Integer englishMultiverseId) throws IOException { String cardLanguagesUrl = "http://gatherer.wizards.com/Pages/Card/Languages.aspx?multiverseid=" + englishMultiverseId; - Document cardLanguagesDoc = getDocument(cardLanguagesUrl); + Document cardLanguagesDoc = CardImageUtils.downloadHtmlDocument(cardLanguagesUrl); Elements languageTableRows = cardLanguagesDoc.select("tr.cardItem"); HashMap localizedIds = new HashMap<>(); if (!languageTableRows.isEmpty()) { 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 0e9556dd902..7be47db2d1f 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 @@ -84,7 +84,8 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab MAGIDEX("4. magidex.com - high quality CARDS", MagidexImageSource.instance), GRAB_BAG("5. GrabBag - STAR WARS cards and tokens", GrabbagImageSource.instance), MYTHICSPOILER("6. mythicspoiler.com", MythicspoilerComSource.instance), - ALTERNATIVE("7. alternative.mtg.onl", AltMtgOnlTokensImageSource.instance); + ALTERNATIVE("7. alternative.mtg.onl", AltMtgOnlTokensImageSource.instance), + COPYPASTE("8. Copy and Paste Image URLs", CopyPasteImageSource.instance); // MTG_ONL("mtg.onl", MtgOnlTokensImageSource.instance), Not working correctly yet // MAGICCARDS("magiccards.info", MagicCardsImageSource.instance) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java index 6b7c74587a8..fb7c42aa090 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java @@ -1,11 +1,17 @@ package org.mage.plugins.card.utils; +import java.io.BufferedReader; import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.Proxy; +import java.net.URL; import java.util.HashMap; import java.util.Locale; import java.util.prefs.Preferences; + import mage.client.MageFrame; import mage.client.constants.Constants; import mage.client.dialog.PreferencesDialog; @@ -13,6 +19,8 @@ import mage.remote.Connection; import mage.remote.Connection.ProxyType; import net.java.truevfs.access.TFile; import org.apache.log4j.Logger; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.properties.SettingsManager; @@ -22,7 +30,6 @@ public final class CardImageUtils { private static final Logger log = Logger.getLogger(CardImageUtils.class); /** - * * @param card * @return String if image exists, else null */ @@ -54,7 +61,6 @@ public final class CardImageUtils { } /** - * * @param card * @return String regardless of whether image exists */ @@ -280,4 +286,31 @@ public final class CardImageUtils { } return null; } + + public static Document downloadHtmlDocument(String urlString) throws NumberFormatException, IOException { + Preferences prefs = MageFrame.getPreferences(); + Connection.ProxyType proxyType = Connection.ProxyType.valueByText(prefs.get("proxyType", "None")); + Document doc; + if (proxyType == ProxyType.NONE) { + 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; + StringBuffer tmp = new StringBuffer(); + BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream())); + while ((line = in.readLine()) != null) { + tmp.append(line); + } + doc = Jsoup.parse(String.valueOf(tmp)); + } + return doc; + } } diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java index 83c66f8e409..0cc812c6857 100644 --- a/Mage.Common/src/main/java/mage/utils/MageVersion.java +++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java @@ -14,7 +14,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 = 30; - public final static String MAGE_VERSION_MINOR_PATCH = "V5"; + public final static String MAGE_VERSION_MINOR_PATCH = "V6"; public final static String MAGE_VERSION_INFO = ""; private final int major; diff --git a/Mage.Common/src/main/java/mage/view/CardsView.java b/Mage.Common/src/main/java/mage/view/CardsView.java index ce01784dd03..2a1264f0ce5 100644 --- a/Mage.Common/src/main/java/mage/view/CardsView.java +++ b/Mage.Common/src/main/java/mage/view/CardsView.java @@ -73,7 +73,7 @@ public class CardsView extends LinkedHashMap { case BATTLEFIELD: sourceObject = game.getPermanent(ability.getSourceId()); if (sourceObject == null) { - sourceObject = (Permanent) game.getLastKnownInformation(ability.getSourceId(), Zone.BATTLEFIELD); + sourceObject = game.getLastKnownInformation(ability.getSourceId(), Zone.BATTLEFIELD); } isPermanent = true; break; diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java index c0297b0ad37..7e136506588 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Brawl.java @@ -3,11 +3,8 @@ package mage.deck; import java.util.*; import mage.abilities.common.CanBeYourCommanderAbility; import mage.cards.Card; -import mage.cards.ExpansionSet; -import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; -import mage.constants.SetType; import mage.filter.FilterMana; /** @@ -22,50 +19,11 @@ public class Brawl extends Constructed { super("Brawl"); // Copy of standard sets - GregorianCalendar current = new GregorianCalendar(); - List sets = new ArrayList(Sets.getInstance().values()); - Collections.sort(sets, new Comparator() { - @Override - public int compare(final ExpansionSet lhs, ExpansionSet rhs) { - return lhs.getReleaseDate().after(rhs.getReleaseDate()) ? -1 : 1; - } - }); - int fallSetsAdded = 0; - Date earliestDate = null; - // Get the second most recent fall set that's been released. - for (ExpansionSet set : sets) { - if (set.getReleaseDate().after(current.getTime())) { - continue; - } - if (isFallSet(set)) { - fallSetsAdded++; - if (fallSetsAdded == 2) { - earliestDate = set.getReleaseDate(); - break; - } - } - } - // Get all sets released on or after the second most recent fall set's release - for (ExpansionSet set : sets) { - if ((set.getSetType() == SetType.CORE - || set.getSetType() == SetType.EXPANSION - || set.getSetType() == SetType.SUPPLEMENTAL_STANDARD_LEGAL) - && (!set.getReleaseDate().before(earliestDate) - && !set.getReleaseDate().after(current.getTime()))) { - setCodes.add(set.getCode()); - } - } + setCodes.addAll(Standard.makeLegalSets()); + banned.add("Baral, Chief of Compliance"); banned.add("Smuggler's Copter"); - banned.add("Sorcerers' Spyglass"); - } - - private static boolean isFallSet(ExpansionSet set) { - Calendar cal = Calendar.getInstance(); - cal.setTime(set.getReleaseDate()); - // Fall sets are normally released during or after September - return set.getSetType() == SetType.EXPANSION - && (cal.get(Calendar.MONTH) > 7); + banned.add("Sorcerous Spyglass"); } public Brawl(String name) { diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Legacy.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Legacy.java index c2e9a7e7a62..90f4ee51ba8 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Legacy.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Legacy.java @@ -1,4 +1,3 @@ - package mage.deck; import mage.cards.ExpansionSet; @@ -32,6 +31,7 @@ public class Legacy extends Constructed { banned.add("Chaos Orb"); banned.add("Contract from Below"); banned.add("Darkpact"); + banned.add("Deathrite Shaman"); banned.add("Demonic Attorney"); banned.add("Demonic Consultation"); banned.add("Demonic Tutor"); @@ -42,6 +42,7 @@ public class Legacy extends Constructed { banned.add("Fastbond"); banned.add("Flash"); banned.add("Frantic Search"); + banned.add("Gitaxian Probe"); banned.add("Goblin Recruiter"); banned.add("Gush"); banned.add("Hermit Druid"); diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java index 0e2c21598ea..2e2098244a1 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Standard.java @@ -20,6 +20,28 @@ public class Standard extends Constructed { public Standard() { super("Constructed - Standard"); + + setCodes.addAll(makeLegalSets()); + + banned.add("Attune with Aether"); // since 2018-01-15 + banned.add("Aetherworks Marvel"); + banned.add("Felidar Guardian"); + banned.add("Rampaging Ferocidon"); // since 2018-01-15 + banned.add("Ramunap Ruins"); // since 2018-01-15 + banned.add("Rogue Refiner"); // since 2018-01-15 + banned.add("Smuggler's Copter"); + } + + private static boolean isFallSet(ExpansionSet set) { + Calendar cal = Calendar.getInstance(); + cal.setTime(set.getReleaseDate()); + // Fall sets are normally released during or after September + return set.getSetType() == SetType.EXPANSION + && (cal.get(Calendar.MONTH) > 7); + } + + public static List makeLegalSets() { + List codes = new ArrayList(); GregorianCalendar current = new GregorianCalendar(); List sets = new ArrayList(Sets.getInstance().values()); Collections.sort(sets, new Comparator() { @@ -48,25 +70,11 @@ public class Standard extends Constructed { if ((set.getSetType() == SetType.CORE || set.getSetType() == SetType.EXPANSION || set.getSetType() == SetType.SUPPLEMENTAL_STANDARD_LEGAL) - && (!set.getReleaseDate().before(earliestDate) - && !set.getReleaseDate().after(current.getTime()))) { - setCodes.add(set.getCode()); + && !set.getReleaseDate().before(earliestDate)) { +// && !set.getReleaseDate().after(current.getTime()))) { + codes.add(set.getCode()); } } - banned.add("Attune with Aether"); // since 2018-01-15 - banned.add("Aetherworks Marvel"); - banned.add("Felidar Guardian"); - banned.add("Rampaging Ferocidon"); // since 2018-01-15 - banned.add("Ramunap Ruins"); // since 2018-01-15 - banned.add("Rogue Refiner"); // since 2018-01-15 - banned.add("Smuggler's Copter"); - } - - private static boolean isFallSet(ExpansionSet set) { - Calendar cal = Calendar.getInstance(); - cal.setTime(set.getReleaseDate()); - // Fall sets are normally released during or after September - return set.getSetType() == SetType.EXPANSION - && (cal.get(Calendar.MONTH) > 7); + return codes; } } diff --git a/Mage.Server.Plugins/Mage.Game.BrawlDuel/src/mage/game/BrawlDuelMatch.java b/Mage.Server.Plugins/Mage.Game.BrawlDuel/src/mage/game/BrawlDuelMatch.java index 1650d6fb20f..e0a56eb0e23 100644 --- a/Mage.Server.Plugins/Mage.Game.BrawlDuel/src/mage/game/BrawlDuelMatch.java +++ b/Mage.Server.Plugins/Mage.Game.BrawlDuel/src/mage/game/BrawlDuelMatch.java @@ -16,7 +16,7 @@ public class BrawlDuelMatch extends MatchImpl { @Override public void startGame() throws GameException { - int startLife = 20; + int startLife = 25; boolean alsoHand = true; BrawlDuel game = new BrawlDuel(options.getAttackOption(), options.getRange(), options.getFreeMulligans(), startLife); game.setCheckCommanderDamage(false); diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java index 05a410dd3a6..f38270bec6f 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java @@ -136,7 +136,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ { sb.setLength(0); sb.append("-> Permanents: ["); for (Permanent permanent : game.getBattlefield().getAllPermanents()) { - if (permanent.getOwnerId().equals(player.getId())) { + if (permanent.isOwnedBy(player.getId())) { sb.append(permanent.getName()); if (permanent.isTapped()) { sb.append("(tapped)"); @@ -254,7 +254,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ { } else if (stepFinished) { logger.debug("Step finished"); int testScore = GameStateEvaluator2.evaluate(playerId, game); - if (game.getActivePlayerId().equals(playerId)) { + if (game.isActivePlayer(playerId)) { if (testScore < currentScore) { // if score at end of step is worse than original score don't check further //logger.debug("Add Action -- abandoning check, no immediate benefit"); diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java index a9d0f29657e..628472299c1 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java @@ -54,7 +54,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 { pass(game); return false; case PRECOMBAT_MAIN: - if (game.getActivePlayerId().equals(playerId)) { + if (game.isActivePlayer(playerId)) { printOutState(game); if (actions.isEmpty()) { logger.info("Sim Calculate pre combat actions ----------------------------------------------------- "); 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 e5dd0c6b0ea..8362963995a 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 @@ -987,7 +987,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { private boolean priorityPlay(Game game) { UUID opponentId = game.getOpponents(playerId).iterator().next(); - if (game.getActivePlayerId().equals(playerId)) { + if (game.isActivePlayer(playerId)) { if (game.isMainPhase() && game.getStack().isEmpty()) { playLand(game); } diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java index 53b6533a58f..257d3adb828 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java +++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java @@ -348,7 +348,7 @@ public class ComputerPlayerMCTS extends ComputerPlayer implements Player { thinkTime = maxThinkTime / 2; } } - else if (game.getActivePlayerId().equals(playerId) && (curStep == PhaseStep.PRECOMBAT_MAIN || curStep == PhaseStep.POSTCOMBAT_MAIN) && game.getStack().isEmpty()) { + else if (game.isActivePlayer(playerId) && (curStep == PhaseStep.PRECOMBAT_MAIN || curStep == PhaseStep.POSTCOMBAT_MAIN) && game.getStack().isEmpty()) { if (nodeSizeRatio < THINK_MIN_RATIO) { thinkTime = maxThinkTime; } diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java index 52ceb958dba..28e8f8e0125 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer3.java @@ -50,7 +50,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player { pass(game); return false; case PRECOMBAT_MAIN: - if (game.getActivePlayerId().equals(playerId)) { + if (game.isActivePlayer(playerId)) { if (actions.isEmpty()) { calculatePreCombatActions(game); } @@ -64,7 +64,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player { pass(game); return false; case DECLARE_ATTACKERS: - if (!game.getActivePlayerId().equals(playerId)) { + if (!game.isActivePlayer(playerId)) { if (actions.isEmpty()) { calculatePreCombatActions(game); } @@ -81,7 +81,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player { pass(game); return false; case POSTCOMBAT_MAIN: - if (game.getActivePlayerId().equals(playerId)) { + if (game.isActivePlayer(playerId)) { if (actions.isEmpty()) { calculatePostCombatActions(game); } @@ -184,7 +184,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player { else if (stepFinished) { logger.debug(indent(node.depth) + "step finished"); int testScore = GameStateEvaluator.evaluate(playerId, game); - if (game.getActivePlayerId().equals(playerId)) { + if (game.isActivePlayer(playerId)) { if (testScore < currentScore) { // if score at end of step is worse than original score don't check further logger.debug(indent(node.depth) + "simulating -- abandoning check, no immediate benefit"); 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 ab2848376dc..a8122e52b4f 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 @@ -341,8 +341,18 @@ public class HumanPlayer extends PlayerImpl { replacementEffectChoice.getChoices().clear(); replacementEffectChoice.setKeyChoices(rEffects); + + // Check if there are different ones + int differentChoices = 0; + String lastChoice = ""; + for (String value : replacementEffectChoice.getKeyChoices().values()) { + if (!lastChoice.equalsIgnoreCase(value)) { + lastChoice = value; + differentChoices++; + } + } - while (!abort) { + while (!abort && differentChoices > 1) { updateGameStatePriority("chooseEffect", game); prepareForResponse(game); if (!isExecutingMacro()) { @@ -1943,7 +1953,7 @@ public class HumanPlayer extends PlayerImpl { if (userData.confirmEmptyManaPool() && game.getStack().isEmpty() && getManaPool().count() > 0) { String activePlayerText; - if (game.getActivePlayerId().equals(playerId)) { + if (game.isActivePlayer(playerId)) { activePlayerText = "Your turn"; } else { activePlayerText = game.getPlayer(game.getActivePlayerId()).getName() + "'s turn"; diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java index 78ce2b7dc5b..a9593816c70 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameController.java +++ b/Mage.Server/src/main/java/mage/server/game/GameController.java @@ -1,4 +1,3 @@ - package mage.server.game; import java.io.*; @@ -1149,7 +1148,7 @@ public class GameController implements GameCallback { sb.append(state.getTurnMods()); sb.append("
getTurnNum: "); sb.append(state.getTurnNum()); - + sb.append("
Using plane chase?:" + state.isPlaneChase()); if (state.isPlaneChase()) { Plane currentPlane = state.getCurrentPlane(); @@ -1157,7 +1156,7 @@ public class GameController implements GameCallback { sb.append("
Current plane:" + currentPlane.getName()); } } - + sb.append("
Future Timeout:"); if (futureTimeout != null) { sb.append("Cancelled?="); @@ -1188,8 +1187,13 @@ public class GameController implements GameCallback { sb.append("
Active player is: "); sb.append(game.getPlayer(state.getActivePlayerId()).getName()); + PassAbility pass = new PassAbility(); if (game.getPlayer(state.getActivePlayerId()).hasLeft()) { + Player p = game.getPlayer(state.getActivePlayerId()); + if (p != null) { + p.concede(game); + } Phase currentPhase = game.getPhase(); if (currentPhase != null) { currentPhase.getStep().skipStep(game, state.getActivePlayerId()); @@ -1204,6 +1208,10 @@ public class GameController implements GameCallback { sb.append("
getChoosingPlayerId: "); if (state.getChoosingPlayerId() != null) { if (game.getPlayer(state.getChoosingPlayerId()).hasLeft()) { + Player p = game.getPlayer(state.getChoosingPlayerId()); + if (p != null) { + p.concede(game); + } Phase currentPhase = game.getPhase(); if (currentPhase != null && !fixedAlready) { currentPhase.getStep().endStep(game, state.getActivePlayerId()); @@ -1218,7 +1226,11 @@ public class GameController implements GameCallback { sb.append("
Player with Priority is: "); if (state.getPriorityPlayerId() != null) { - if (game.getPlayer(state.getPriorityPlayerId()).hasLeft()) { + if (game.getPlayer(state.getPriorityPlayerId()).hasLeft()) { + Player p = game.getPlayer(state.getPriorityPlayerId()); + if (p != null) { + p.concede(game); + } Phase currentPhase = game.getPhase(); if (currentPhase != null && !fixedAlready) { currentPhase.getStep().skipStep(game, state.getActivePlayerId()); @@ -1228,7 +1240,7 @@ public class GameController implements GameCallback { } sb.append(game.getPlayer(state.getPriorityPlayerId()).getName()); sb.append(""); - } + } sb.append("
Future Timeout:"); if (futureTimeout != null) { diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentFactory.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentFactory.java index 135bcac1ee7..12bf551a7b2 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentFactory.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentFactory.java @@ -40,7 +40,7 @@ public enum TournamentFactory { Map setInfo = new LinkedHashMap<>(); for (String setCode: options.getLimitedOptions().getSetCodes()) { tournament.getSets().add(Sets.findSet(setCode)); - int count = setInfo.containsKey(setCode) ? setInfo.get(setCode) : 0; + int count = setInfo.getOrDefault(setCode, 0); setInfo.put(setCode, count + 1); } tournament.getOptions().getLimitedOptions().setNumberBoosters(tournament.getTournamentType().getNumBoosters()); diff --git a/Mage.Sets/src/mage/cards/a/AbandonedSarcophagus.java b/Mage.Sets/src/mage/cards/a/AbandonedSarcophagus.java index a73a5b031f8..5d44aa8dd68 100644 --- a/Mage.Sets/src/mage/cards/a/AbandonedSarcophagus.java +++ b/Mage.Sets/src/mage/cards/a/AbandonedSarcophagus.java @@ -155,7 +155,7 @@ class AbandonedSarcophagusReplacementEffect extends ReplacementEffectImpl { Card card = game.getCard(event.getTargetId()); if (card != null && watcher != null - && card.getOwnerId().equals(controller.getId())) { + && card.isOwnedBy(controller.getId())) { for (Ability ability : card.getAbilities()) { if (ability instanceof CyclingAbility) { cardHasCycling = true; @@ -199,7 +199,7 @@ class AbandonedSarcophagusWatcher extends Watcher { Player controller = game.getPlayer(event.getPlayerId()); if (card != null && controller != null - && card.getOwnerId().equals(controller.getId())) { + && card.isOwnedBy(controller.getId())) { Cards c = getCardsCycledThisTurn(event.getPlayerId()); c.add(card); cycledCardsThisTurn.put(event.getPlayerId(), c); diff --git a/Mage.Sets/src/mage/cards/a/AbbotOfKeralKeep.java b/Mage.Sets/src/mage/cards/a/AbbotOfKeralKeep.java index f7ae5aec0a8..c8a371940d5 100644 --- a/Mage.Sets/src/mage/cards/a/AbbotOfKeralKeep.java +++ b/Mage.Sets/src/mage/cards/a/AbbotOfKeralKeep.java @@ -108,7 +108,7 @@ class AbbotOfKeralKeepCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && objectId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/a/AcidicSoil.java b/Mage.Sets/src/mage/cards/a/AcidicSoil.java index a18d1636248..cbb5e62189c 100644 --- a/Mage.Sets/src/mage/cards/a/AcidicSoil.java +++ b/Mage.Sets/src/mage/cards/a/AcidicSoil.java @@ -57,7 +57,7 @@ class AcidicSoilEffect extends OneShotEffect { if (player != null) { int amount = 0; for (Permanent permanent : permanents) { - if (permanent.getControllerId().equals(playerId)) { + if (permanent.isControlledBy(playerId)) { amount++; } } diff --git a/Mage.Sets/src/mage/cards/a/AegisOfTheHeavens.java b/Mage.Sets/src/mage/cards/a/AegisOfTheHeavens.java index b31d109eb75..c66d70d625e 100644 --- a/Mage.Sets/src/mage/cards/a/AegisOfTheHeavens.java +++ b/Mage.Sets/src/mage/cards/a/AegisOfTheHeavens.java @@ -18,7 +18,7 @@ public final class AegisOfTheHeavens extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); // Target creature gets +1/+7 until end of turn. - this.getSpellAbility().addEffect(new BoostTargetEffect(3, 3, Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new BoostTargetEffect(1, 7, Duration.EndOfTurn)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/cards/a/AerialCaravan.java b/Mage.Sets/src/mage/cards/a/AerialCaravan.java index 8dadcf7bb7d..933595fcd9b 100644 --- a/Mage.Sets/src/mage/cards/a/AerialCaravan.java +++ b/Mage.Sets/src/mage/cards/a/AerialCaravan.java @@ -114,7 +114,7 @@ class AerialCaravanCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && objectId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/a/AetherCharge.java b/Mage.Sets/src/mage/cards/a/AetherCharge.java index e2ce3a6dd38..6563c83d149 100644 --- a/Mage.Sets/src/mage/cards/a/AetherCharge.java +++ b/Mage.Sets/src/mage/cards/a/AetherCharge.java @@ -70,7 +70,7 @@ class AetherChargeTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent.isCreature() && permanent.hasSubtype(SubType.BEAST, game) - && permanent.getControllerId().equals(this.controllerId)) { + && permanent.isControlledBy(this.controllerId)) { Effect effect = this.getEffects().get(0); effect.setValue("damageSource", event.getTargetId()); return true; diff --git a/Mage.Sets/src/mage/cards/a/AetherflameWall.java b/Mage.Sets/src/mage/cards/a/AetherflameWall.java new file mode 100644 index 00000000000..9579f21ccc2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AetherflameWall.java @@ -0,0 +1,50 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CanBlockAsThoughtItHadShadowEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.DefenderAbility; +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 java.util.UUID; + +/** + * + * @author noahg + */ +public final class AetherflameWall extends CardImpl { + + public AetherflameWall(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.WALL); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + + // Aetherflame Wall can block creatures with shadow as though they didn’t have shadow. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockAsThoughtItHadShadowEffect(Duration.WhileOnBattlefield))); + + // {R}: Aetherflame Wall gets +1/+0 until end of turn. + this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{R}"))); + } + + public AetherflameWall(final AetherflameWall card) { + super(card); + } + + @Override + public AetherflameWall copy() { + return new AetherflameWall(this); + } +} diff --git a/Mage.Sets/src/mage/cards/a/Aetherplasm.java b/Mage.Sets/src/mage/cards/a/Aetherplasm.java new file mode 100644 index 00000000000..6864f3c98fd --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/Aetherplasm.java @@ -0,0 +1,98 @@ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.BlocksTriggeredAbility; +import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.cards.Card; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.combat.CombatGroup; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInHand; + +/** + * + * @author noahg + */ +public final class Aetherplasm extends CardImpl { + + public Aetherplasm(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); + + this.subtype.add(SubType.ILLUSION); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Whenever Aetherplasm blocks a creature, you may return Aetherplasm to its owner's hand. If you do, you may put a creature card from your hand onto the battlefield blocking that creature. + this.addAbility(new BlocksTriggeredAbility + (new DoIfCostPaid(new AetherplasmEffect(), new ReturnToHandFromBattlefieldSourceCost()), false, true)); + } + + public Aetherplasm(final Aetherplasm card) { + super(card); + } + + @Override + public Aetherplasm copy() { + return new Aetherplasm(this); + } +} + +class AetherplasmEffect extends OneShotEffect { + + public AetherplasmEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "you may put a creature card from your hand onto the battlefield blocking that creature"; + } + + public AetherplasmEffect(AetherplasmEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent blockedCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (player == null) { + return false; + } + if (player.chooseUse(Outcome.PutCardInPlay, "Put a creature card from your hand onto the battlefield?", source, game)) { + TargetCardInHand target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A); + if (player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + if(player.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, false, null) + && game.getCombat() != null && blockedCreature != null){ + CombatGroup attacker = game.getCombat().findGroup(blockedCreature.getId()); + Permanent putIntoPlay = game.getPermanent(target.getFirstTarget()); + if (putIntoPlay != null && putIntoPlay.isCreature() &&attacker != null) { + game.getCombat().findGroup(blockedCreature.getId()).addBlocker(putIntoPlay.getId(), source.getControllerId(), game); + return true; + } + } + } + } + } + return false; + } + + @Override + public AetherplasmEffect copy() { + return new AetherplasmEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/a/Aetherspouts.java b/Mage.Sets/src/mage/cards/a/Aetherspouts.java index d7988ad0f3d..4c565abaad6 100644 --- a/Mage.Sets/src/mage/cards/a/Aetherspouts.java +++ b/Mage.Sets/src/mage/cards/a/Aetherspouts.java @@ -81,7 +81,7 @@ class AetherspoutsEffect extends OneShotEffect { List permanentsToTop = new ArrayList<>(); List permanentsToBottom = new ArrayList<>(); for (Permanent permanent:game.getState().getBattlefield().getActivePermanents(new FilterAttackingCreature(), player.getId(), source.getSourceId(), game)) { - if (permanent.getOwnerId().equals(player.getId())) { + if (permanent.isOwnedBy(player.getId())) { if (player.chooseUse(outcome, "Put " + permanent.getLogName() + " to the top? (else it goes to bottom)", source, game)) { permanentsToTop.add(permanent); game.informPlayers(permanent.getLogName() + " goes to the top of " + player.getLogName() + "'s library"); diff --git a/Mage.Sets/src/mage/cards/a/AjanisLastStand.java b/Mage.Sets/src/mage/cards/a/AjanisLastStand.java index dbc1187136b..8be2b128f18 100644 --- a/Mage.Sets/src/mage/cards/a/AjanisLastStand.java +++ b/Mage.Sets/src/mage/cards/a/AjanisLastStand.java @@ -85,7 +85,7 @@ class AjanisLastStandTriggeredAbility extends TriggeredAbilityImpl { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { - if (zEvent.getTarget().getControllerId().equals(controllerId) + if (zEvent.getTarget().isControlledBy(controllerId) && (zEvent.getTarget().isCreature() || zEvent.getTarget().isPlaneswalker())) { return true; diff --git a/Mage.Sets/src/mage/cards/a/AkoumFirebird.java b/Mage.Sets/src/mage/cards/a/AkoumFirebird.java index 53b699b5281..9a7d5c7f437 100644 --- a/Mage.Sets/src/mage/cards/a/AkoumFirebird.java +++ b/Mage.Sets/src/mage/cards/a/AkoumFirebird.java @@ -79,7 +79,7 @@ class AkoumFirebirdLandfallAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); - return permanent != null && permanent.isLand() && permanent.getControllerId().equals(this.controllerId); + return permanent != null && permanent.isLand() && permanent.isControlledBy(this.controllerId); } @Override diff --git a/Mage.Sets/src/mage/cards/a/AkoumHellkite.java b/Mage.Sets/src/mage/cards/a/AkoumHellkite.java index 86698bc1f95..24a13cc1423 100644 --- a/Mage.Sets/src/mage/cards/a/AkoumHellkite.java +++ b/Mage.Sets/src/mage/cards/a/AkoumHellkite.java @@ -82,7 +82,7 @@ class AkoumHellkiteTriggeredAbility extends TriggeredAbilityImpl { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.isLand() - && permanent.getControllerId().equals(getControllerId())) { + && permanent.isControlledBy(getControllerId())) { Permanent sourcePermanent = game.getPermanent(getSourceId()); if (sourcePermanent != null) { for (Effect effect : getEffects()) { diff --git a/Mage.Sets/src/mage/cards/a/AladdinsLamp.java b/Mage.Sets/src/mage/cards/a/AladdinsLamp.java index 040d1cf38bd..6db19c46d5e 100644 --- a/Mage.Sets/src/mage/cards/a/AladdinsLamp.java +++ b/Mage.Sets/src/mage/cards/a/AladdinsLamp.java @@ -87,6 +87,6 @@ class AladdinsLampEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } } diff --git a/Mage.Sets/src/mage/cards/a/AlhammarretsArchive.java b/Mage.Sets/src/mage/cards/a/AlhammarretsArchive.java index 557b806e6ad..02b087e0ab3 100644 --- a/Mage.Sets/src/mage/cards/a/AlhammarretsArchive.java +++ b/Mage.Sets/src/mage/cards/a/AlhammarretsArchive.java @@ -111,7 +111,7 @@ class AlhammarretsArchiveReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getPlayerId().equals(source.getControllerId())) { - if (game.getActivePlayerId().equals(event.getPlayerId()) + if (game.isActivePlayer(event.getPlayerId()) && game.getPhase().getStep().getType() == PhaseStep.DRAW) { CardsDrawnDuringDrawStepWatcher watcher = (CardsDrawnDuringDrawStepWatcher) game.getState().getWatchers().get(CardsDrawnDuringDrawStepWatcher.class.getSimpleName()); if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) > 0) { diff --git a/Mage.Sets/src/mage/cards/a/Aluren.java b/Mage.Sets/src/mage/cards/a/Aluren.java index b032bdf8f3a..8397fa65c91 100644 --- a/Mage.Sets/src/mage/cards/a/Aluren.java +++ b/Mage.Sets/src/mage/cards/a/Aluren.java @@ -74,7 +74,7 @@ class AlurenRuleEffect extends ContinuousEffectImpl { public AlurenRuleEffect() { super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "Any player may play creature cards with converted mana cost 3 or less without paying their mana cost"; + staticText = "Any player may cast creature cards with converted mana cost 3 or less without paying their mana cost"; } public AlurenRuleEffect(final AlurenRuleEffect effect) { diff --git a/Mage.Sets/src/mage/cards/a/AmbuscadeShaman.java b/Mage.Sets/src/mage/cards/a/AmbuscadeShaman.java index fc57daa583c..2c8e04683a3 100644 --- a/Mage.Sets/src/mage/cards/a/AmbuscadeShaman.java +++ b/Mage.Sets/src/mage/cards/a/AmbuscadeShaman.java @@ -75,7 +75,7 @@ class AmbuscadeShamanTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { UUID targetId = event.getTargetId(); Permanent permanent = game.getPermanent(targetId); - if (permanent.getControllerId().equals(this.controllerId) + if (permanent.isControlledBy(this.controllerId) && permanent.isCreature()) { this.getEffects().setTargetPointer(new FixedTarget(permanent, game)); return true; diff --git a/Mage.Sets/src/mage/cards/a/AmuletOfVigor.java b/Mage.Sets/src/mage/cards/a/AmuletOfVigor.java index 046b2b44c55..0915957d35b 100644 --- a/Mage.Sets/src/mage/cards/a/AmuletOfVigor.java +++ b/Mage.Sets/src/mage/cards/a/AmuletOfVigor.java @@ -58,7 +58,7 @@ class AmuletOfVigorTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent p = game.getPermanent(event.getTargetId()); - if (p != null && p.isTapped() && p.getControllerId().equals(this.controllerId)) { + if (p != null && p.isTapped() && p.isControlledBy(this.controllerId)) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getTargetId())); } diff --git a/Mage.Sets/src/mage/cards/a/AngelicArbiter.java b/Mage.Sets/src/mage/cards/a/AngelicArbiter.java index 0415e145bf3..75693f80c0f 100644 --- a/Mage.Sets/src/mage/cards/a/AngelicArbiter.java +++ b/Mage.Sets/src/mage/cards/a/AngelicArbiter.java @@ -65,7 +65,7 @@ class AngelicArbiterCantAttackTargetEffect extends RestrictionEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { - if (game.getActivePlayerId().equals(permanent.getControllerId()) && game.getOpponents(source.getControllerId()).contains(permanent.getControllerId())) { + if (game.isActivePlayer(permanent.getControllerId()) && game.getOpponents(source.getControllerId()).contains(permanent.getControllerId())) { CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName()); if (watcher != null && watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(permanent.getControllerId()) > 0) { return true; @@ -113,7 +113,7 @@ class AngelicArbiterEffect2 extends ContinuousRuleModifyingEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (game.getActivePlayerId().equals(event.getPlayerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { + if (game.isActivePlayer(event.getPlayerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { PlayerAttackedWatcher watcher = (PlayerAttackedWatcher) game.getState().getWatchers().get(PlayerAttackedWatcher.class.getSimpleName()); if (watcher != null && watcher.getNumberOfAttackersCurrentTurn(event.getPlayerId()) > 0) { return true; diff --git a/Mage.Sets/src/mage/cards/a/AngelicBenediction.java b/Mage.Sets/src/mage/cards/a/AngelicBenediction.java index fdd6db3234a..82717661470 100644 --- a/Mage.Sets/src/mage/cards/a/AngelicBenediction.java +++ b/Mage.Sets/src/mage/cards/a/AngelicBenediction.java @@ -62,7 +62,7 @@ class AngelicBenedictionTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getActivePlayerId().equals(this.controllerId)) { + if (game.isActivePlayer(this.controllerId)) { if (game.getCombat().attacksAlone()) { return true; } diff --git a/Mage.Sets/src/mage/cards/a/AngelicChorus.java b/Mage.Sets/src/mage/cards/a/AngelicChorus.java index 077345b9f27..7bf37261066 100644 --- a/Mage.Sets/src/mage/cards/a/AngelicChorus.java +++ b/Mage.Sets/src/mage/cards/a/AngelicChorus.java @@ -58,7 +58,7 @@ class AngelicChorusTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent.isCreature() - && permanent.getControllerId().equals(this.controllerId)) { + && permanent.isControlledBy(this.controllerId)) { this.getEffects().get(0).setValue("lifeSource", event.getTargetId()); return true; } diff --git a/Mage.Sets/src/mage/cards/a/AnimarSoulOfElements.java b/Mage.Sets/src/mage/cards/a/AnimarSoulOfElements.java index 986e8d695d1..89381973065 100644 --- a/Mage.Sets/src/mage/cards/a/AnimarSoulOfElements.java +++ b/Mage.Sets/src/mage/cards/a/AnimarSoulOfElements.java @@ -84,7 +84,7 @@ class AnimarCostReductionEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { - if (abilityToModify.getControllerId().equals(source.getControllerId())) { + if (abilityToModify.isControlledBy(source.getControllerId())) { Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); if (spell != null) { return spell.isCreature(); diff --git a/Mage.Sets/src/mage/cards/a/AnimationModule.java b/Mage.Sets/src/mage/cards/a/AnimationModule.java index 877681d2e02..2263af2ca3c 100644 --- a/Mage.Sets/src/mage/cards/a/AnimationModule.java +++ b/Mage.Sets/src/mage/cards/a/AnimationModule.java @@ -84,7 +84,7 @@ class AnimationModuleTriggeredAbility extends TriggeredAbilityImpl { if (permanent == null) { permanent = game.getPermanentEntering(event.getTargetId()); } - return permanent != null && permanent.getControllerId().equals(this.getControllerId()); + return permanent != null && permanent.isControlledBy(this.getControllerId()); } return false; } diff --git a/Mage.Sets/src/mage/cards/a/ApexOfPower.java b/Mage.Sets/src/mage/cards/a/ApexOfPower.java index 81c7222911e..7cedb5425bb 100644 --- a/Mage.Sets/src/mage/cards/a/ApexOfPower.java +++ b/Mage.Sets/src/mage/cards/a/ApexOfPower.java @@ -110,7 +110,7 @@ class ApexOfPowerCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && objectId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java b/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java index 12a962afb6f..0a0d05fd249 100644 --- a/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java +++ b/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java @@ -89,7 +89,7 @@ class ConspyEffect extends ContinuousEffectImpl { } // in Library (e.g. for Mystical Teachings) for (Card card : controller.getLibrary().getCards(game)) { - if (card.getOwnerId().equals(controller.getId()) && card.isCreature() && !card.hasSubtype(subType, game)) { + if (card.isOwnedBy(controller.getId()) && card.isCreature() && !card.hasSubtype(subType, game)) { game.getState().getCreateCardAttribute(card, game).getSubtype().add(subType); } } @@ -106,7 +106,7 @@ class ConspyEffect extends ContinuousEffectImpl { for (Iterator iterator = game.getStack().iterator(); iterator.hasNext();) { StackObject stackObject = iterator.next(); if (stackObject instanceof Spell - && stackObject.getControllerId().equals(source.getControllerId()) + && stackObject.isControlledBy(source.getControllerId()) && stackObject.isCreature() && !stackObject.hasSubtype(subType, game)) { Card card = ((Spell) stackObject).getCard(); diff --git a/Mage.Sets/src/mage/cards/a/ArchonOfRedemption.java b/Mage.Sets/src/mage/cards/a/ArchonOfRedemption.java index 1386b5e8b2f..4107f3f9901 100644 --- a/Mage.Sets/src/mage/cards/a/ArchonOfRedemption.java +++ b/Mage.Sets/src/mage/cards/a/ArchonOfRedemption.java @@ -66,7 +66,7 @@ class ArchonOfRedemptionTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent.getControllerId().equals(getControllerId()) + if (permanent.isControlledBy(getControllerId()) && permanent.isCreature() && (permanent.getId().equals(getSourceId()) || (permanent.getAbilities().contains(FlyingAbility.getInstance())))) { diff --git a/Mage.Sets/src/mage/cards/a/ArchonOfValorsReach.java b/Mage.Sets/src/mage/cards/a/ArchonOfValorsReach.java index f8166c4b1e2..ffc743472c6 100644 --- a/Mage.Sets/src/mage/cards/a/ArchonOfValorsReach.java +++ b/Mage.Sets/src/mage/cards/a/ArchonOfValorsReach.java @@ -133,7 +133,7 @@ class ArchonOfValorsReachChoice extends ChoiceImpl { return CardType.INSTANT; case "Sorcery": return CardType.SORCERY; - case "Planewswalker": + case "Planeswalker": return CardType.PLANESWALKER; default: return null; diff --git a/Mage.Sets/src/mage/cards/a/ArtifactPossession.java b/Mage.Sets/src/mage/cards/a/ArtifactPossession.java index 8725c3e1042..5cd51f52b09 100644 --- a/Mage.Sets/src/mage/cards/a/ArtifactPossession.java +++ b/Mage.Sets/src/mage/cards/a/ArtifactPossession.java @@ -74,7 +74,7 @@ class AbilityActivatedTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent aura = game.getPermanent(this.getSourceId()); - return aura != null && aura.getAttachedTo() != null && aura.getAttachedTo().equals(event.getSourceId()); + return aura != null && aura.isAttachedTo(event.getSourceId()); } diff --git a/Mage.Sets/src/mage/cards/a/AsLuckWouldHaveIt.java b/Mage.Sets/src/mage/cards/a/AsLuckWouldHaveIt.java index 83adf2f33fc..d24d1a4de07 100644 --- a/Mage.Sets/src/mage/cards/a/AsLuckWouldHaveIt.java +++ b/Mage.Sets/src/mage/cards/a/AsLuckWouldHaveIt.java @@ -68,7 +68,7 @@ class AsLuckWouldHaveItTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (this.getControllerId().equals(event.getPlayerId()) && event.getFlag()) { + if (this.isControlledBy(event.getPlayerId()) && event.getFlag()) { for (Effect effect : this.getEffects()) { effect.setValue("rolled", event.getAmount()); } diff --git a/Mage.Sets/src/mage/cards/a/AshenGhoul.java b/Mage.Sets/src/mage/cards/a/AshenGhoul.java index 7b8b0d3f81e..b5ed0e24d78 100644 --- a/Mage.Sets/src/mage/cards/a/AshenGhoul.java +++ b/Mage.Sets/src/mage/cards/a/AshenGhoul.java @@ -61,8 +61,8 @@ enum AshenGhoulCondition implements Condition { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (!game.getStep().getType().equals(PhaseStep.UPKEEP) - || !game.getActivePlayerId().equals(source.getControllerId())) { + if (game.getStep().getType() != PhaseStep.UPKEEP + || !game.isActivePlayer(source.getControllerId())) { return false; } if (controller != null) { diff --git a/Mage.Sets/src/mage/cards/a/AsmiraHolyAvenger.java b/Mage.Sets/src/mage/cards/a/AsmiraHolyAvenger.java index 8f8ac3242bf..60cb57bd4f0 100644 --- a/Mage.Sets/src/mage/cards/a/AsmiraHolyAvenger.java +++ b/Mage.Sets/src/mage/cards/a/AsmiraHolyAvenger.java @@ -78,7 +78,7 @@ class AsmiraHolyAvengerWatcher extends Watcher { public void watch(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).isDiesEvent()) { MageObject card = game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (card != null && ((Card) card).getOwnerId().equals(this.controllerId) && card.isCreature()) { + if (card != null && ((Card) card).isOwnedBy(this.controllerId) && card.isCreature()) { creaturesCount++; } } diff --git a/Mage.Sets/src/mage/cards/a/AssaultSuit.java b/Mage.Sets/src/mage/cards/a/AssaultSuit.java index 34afdccb516..ac21d9ab6b4 100644 --- a/Mage.Sets/src/mage/cards/a/AssaultSuit.java +++ b/Mage.Sets/src/mage/cards/a/AssaultSuit.java @@ -95,8 +95,8 @@ public final class AssaultSuit extends CardImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.SACRIFICE_PERMANENT) { Permanent equipment = game.getPermanent(source.getSourceId()); - if (equipment != null && equipment.getAttachedTo() != null) { - return equipment.getAttachedTo().equals(event.getTargetId()); + if (equipment != null) { + return equipment.isAttachedTo(event.getTargetId()); } } return false; diff --git a/Mage.Sets/src/mage/cards/a/AvariceAmulet.java b/Mage.Sets/src/mage/cards/a/AvariceAmulet.java index cf772fe3ff1..70aec2e44e9 100644 --- a/Mage.Sets/src/mage/cards/a/AvariceAmulet.java +++ b/Mage.Sets/src/mage/cards/a/AvariceAmulet.java @@ -45,7 +45,7 @@ public final class AvariceAmulet extends CardImpl { ability.addEffect(effect); this.addAbility(ability); - // When equipped creature dies, target opponent gains control of Avarice Amulet. + // Whenever equipped creature dies, target opponent gains control of Avarice Amulet. ability = new DiesAttachedTriggeredAbility(new AvariceAmuletChangeControlEffect(), "equipped creature", false); ability.addTarget(new TargetOpponent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/a/AzorTheLawbringer.java b/Mage.Sets/src/mage/cards/a/AzorTheLawbringer.java index d879c1e609c..0933ac1fa1d 100644 --- a/Mage.Sets/src/mage/cards/a/AzorTheLawbringer.java +++ b/Mage.Sets/src/mage/cards/a/AzorTheLawbringer.java @@ -123,7 +123,7 @@ class AzorTheLawbringerCantCastEffect extends ContinuousRuleModifyingEffectImpl @Override public boolean applies(GameEvent event, Ability source, Game game) { UUID opponentId = getTargetPointer().getFirst(game, source); - if (game.getActivePlayerId().equals(opponentId)) { + if (game.isActivePlayer(opponentId)) { if (playersNextTurn == 0) { playersNextTurn = game.getTurnNum(); } diff --git a/Mage.Sets/src/mage/cards/a/AzoriusPloy.java b/Mage.Sets/src/mage/cards/a/AzoriusPloy.java new file mode 100644 index 00000000000..c7e1c996d58 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AzoriusPloy.java @@ -0,0 +1,57 @@ +package mage.cards.a; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.AbilityImpl; +import mage.abilities.SpellAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.PreventCombatDamageBySourceEffect; +import mage.abilities.effects.common.PreventDamageByTargetEffect; +import mage.abilities.effects.common.PreventDamageToTargetEffect; +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.filter.common.FilterCreaturePermanent; +import mage.target.Target; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.SecondTargetPointer; + +/** + * + * @author noahg + */ +public final class AzoriusPloy extends CardImpl { + + public AzoriusPloy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}{W}{U}"); + + + // Prevent all combat damage target creature would deal this turn. + Effect effect = new PreventDamageByTargetEffect( Duration.EndOfTurn, true); + effect.setText("Prevent all combat damage target creature would deal this turn."); + this.getSpellAbility().addEffect(effect); + Target target = new TargetCreaturePermanent(new FilterCreaturePermanent("first creature")); + this.getSpellAbility().addTarget(target); + + // Prevent all combat damage that would be dealt to target creature this turn. + Effect effect2 = new PreventDamageToTargetEffect(Duration.EndOfTurn, true); + effect2.setText("

Prevent all combat damage that would be dealt to target creature this turn."); + effect2.setTargetPointer(SecondTargetPointer.getInstance()); + this.getSpellAbility().addEffect(effect2); + target = new TargetCreaturePermanent(new FilterCreaturePermanent("second creature (can be the same as the first)")); + this.getSpellAbility().addTarget(target); + + } + + public AzoriusPloy(final AzoriusPloy card) { + super(card); + } + + @Override + public AzoriusPloy copy() { + return new AzoriusPloy(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/BalduvianFallen.java b/Mage.Sets/src/mage/cards/b/BalduvianFallen.java new file mode 100644 index 00000000000..6191b9cf44a --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BalduvianFallen.java @@ -0,0 +1,89 @@ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ManaEvent; + +/** + * + * @author noahg + */ +public final class BalduvianFallen extends CardImpl { + + public BalduvianFallen(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.ZOMBIE); + this.power = new MageInt(3); + this.toughness = new MageInt(5); + + // Cumulative upkeep {1} + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}"))); + + // Whenever Balduvian Fallen's cumulative upkeep is paid, it gets +1/+0 until end of turn for each {B} or {R} spent this way. + this.addAbility(new BalduvianFallenAbility()); + } + + public BalduvianFallen(final BalduvianFallen card) { + super(card); + } + + @Override + public BalduvianFallen copy() { + return new BalduvianFallen(this); + } +} + +class BalduvianFallenAbility extends TriggeredAbilityImpl { + + public BalduvianFallenAbility() { + super(Zone.BATTLEFIELD, null, false); + } + + public BalduvianFallenAbility(final BalduvianFallenAbility ability) { + super(ability); + } + + @Override + public BalduvianFallenAbility copy() { + return new BalduvianFallenAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.PAID_CUMULATIVE_UPKEEP; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + this.getEffects().clear(); + if(event.getSourceId() != null && event.getSourceId().equals(this.getSourceId()) && event instanceof ManaEvent) { + ManaEvent manaEvent = (ManaEvent) event; + int total = manaEvent.getMana().getBlack() + manaEvent.getMana().getRed(); + if (total > 0) { + this.getEffects().add(new BoostSourceEffect(total, 0, Duration.EndOfTurn)); + } + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever {this}'s cumulative upkeep is paid, it gets +1/+0 until end of turn for each {B} or {R} spent this way"; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java b/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java index a927300c895..635027c5ad3 100644 --- a/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java +++ b/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java @@ -80,7 +80,7 @@ class BattlefieldThaumaturgeSpellsCostReductionEffect extends CostModificationEf @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if ((abilityToModify instanceof SpellAbility) - && abilityToModify.getControllerId().equals(source.getControllerId())) { + && abilityToModify.isControlledBy(source.getControllerId())) { Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); return spell != null && StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY.match(spell, game); } diff --git a/Mage.Sets/src/mage/cards/b/BattlegraceAngel.java b/Mage.Sets/src/mage/cards/b/BattlegraceAngel.java index 10b675c1e76..62e5d7ea988 100644 --- a/Mage.Sets/src/mage/cards/b/BattlegraceAngel.java +++ b/Mage.Sets/src/mage/cards/b/BattlegraceAngel.java @@ -77,7 +77,7 @@ class BattlegraceAngelAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getActivePlayerId().equals(this.controllerId) ) { + if (game.isActivePlayer(this.controllerId) ) { if (game.getCombat().attacksAlone()) { for (Effect effect: this.getEffects()) { effect.setTargetPointer(new FixedTarget(game.getCombat().getAttackers().get(0))); diff --git a/Mage.Sets/src/mage/cards/b/BidentOfThassa.java b/Mage.Sets/src/mage/cards/b/BidentOfThassa.java index c6b52126a08..6161b610116 100644 --- a/Mage.Sets/src/mage/cards/b/BidentOfThassa.java +++ b/Mage.Sets/src/mage/cards/b/BidentOfThassa.java @@ -74,7 +74,7 @@ class BidentOfThassaTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (((DamagedPlayerEvent) event).isCombatDamage()) { Permanent creature = game.getPermanent(event.getSourceId()); - if (creature != null && creature.getControllerId().equals(controllerId)) { + if (creature != null && creature.isControlledBy(controllerId)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/b/Bioshift.java b/Mage.Sets/src/mage/cards/b/Bioshift.java index cccdcd17130..2876e55ca5c 100644 --- a/Mage.Sets/src/mage/cards/b/Bioshift.java +++ b/Mage.Sets/src/mage/cards/b/Bioshift.java @@ -82,7 +82,7 @@ class MoveCounterFromTargetToTargetEffect extends OneShotEffect { if (source.getTargets().size() > 1) { toPermanent = game.getPermanent(source.getTargets().get(1).getFirstTarget()); } - if (fromPermanent == null || toPermanent == null || !fromPermanent.getControllerId().equals(toPermanent.getControllerId())) { + if (fromPermanent == null || toPermanent == null || !fromPermanent.isControlledBy(toPermanent.getControllerId())) { return false; } int amountCounters = fromPermanent.getCounters(game).getCount(CounterType.P1P1); @@ -114,7 +114,7 @@ class SameControllerPredicate implements ObjectSourcePlayerPredicate it = permanent.getAbilities().iterator(); it.hasNext();) { - Ability ability = it.next(); - if (!ability.getAbilityType().equals(AbilityType.MANA)) { - it.remove(); - } - } + permanent.getAbilities().removeIf(ability -> ability.getAbilityType() != AbilityType.MANA); break; } } diff --git a/Mage.Sets/src/mage/cards/b/BloodsporeThrinax.java b/Mage.Sets/src/mage/cards/b/BloodsporeThrinax.java index dbd1fb37eca..86cea40752e 100644 --- a/Mage.Sets/src/mage/cards/b/BloodsporeThrinax.java +++ b/Mage.Sets/src/mage/cards/b/BloodsporeThrinax.java @@ -66,7 +66,7 @@ class BloodsporeThrinaxEntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); - return creature != null && creature.getControllerId().equals(source.getControllerId()) + return creature != null && creature.isControlledBy(source.getControllerId()) && creature.isCreature() && !event.getTargetId().equals(source.getSourceId()); } diff --git a/Mage.Sets/src/mage/cards/b/BloodstoneGoblin.java b/Mage.Sets/src/mage/cards/b/BloodstoneGoblin.java index 62cf4e3da35..d446113a6cf 100644 --- a/Mage.Sets/src/mage/cards/b/BloodstoneGoblin.java +++ b/Mage.Sets/src/mage/cards/b/BloodstoneGoblin.java @@ -71,7 +71,7 @@ class BloodstoneGoblinTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Spell spell = game.getStack().getSpell(event.getTargetId()); - if (spell != null && spell.getControllerId().equals(controllerId)) { + if (spell != null && spell.isControlledBy(controllerId)) { for (Ability ability : spell.getAbilities()) { if (ability instanceof KickerAbility && ((KickerAbility) ability).getKickedCounter(game, spell.getSpellAbility()) > 0) { return true; diff --git a/Mage.Sets/src/mage/cards/b/BoneyardScourge.java b/Mage.Sets/src/mage/cards/b/BoneyardScourge.java index 7c409d64fc1..4b61d293488 100644 --- a/Mage.Sets/src/mage/cards/b/BoneyardScourge.java +++ b/Mage.Sets/src/mage/cards/b/BoneyardScourge.java @@ -92,7 +92,7 @@ class DiesWhileInGraveyardTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; for (Zone z : Zone.values()) { - if (game.getShortLivingLKI(sourceId, z) && !z.equals(Zone.GRAVEYARD)) { + if (game.getShortLivingLKI(sourceId, z) && z != Zone.GRAVEYARD) { return false; } } diff --git a/Mage.Sets/src/mage/cards/b/Bossk.java b/Mage.Sets/src/mage/cards/b/Bossk.java index 302bea02de9..f8742c1cac7 100644 --- a/Mage.Sets/src/mage/cards/b/Bossk.java +++ b/Mage.Sets/src/mage/cards/b/Bossk.java @@ -81,7 +81,7 @@ class BosskTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.isLand() && permanent.getControllerId().equals(this.getControllerId())) { + if (permanent != null && permanent.isLand() && permanent.isControlledBy(this.getControllerId())) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/b/BottledCloister.java b/Mage.Sets/src/mage/cards/b/BottledCloister.java index 40fe3da5154..8036cdc8f54 100644 --- a/Mage.Sets/src/mage/cards/b/BottledCloister.java +++ b/Mage.Sets/src/mage/cards/b/BottledCloister.java @@ -111,7 +111,7 @@ class BottledCloisterReturnEffect extends OneShotEffect { ExileZone exileZone = game.getExile().getExileZone(exileId); if (exileZone != null) { for (Card card: exileZone.getCards(game)) { - if (card.getOwnerId().equals(controller.getId())) { + if (card.isOwnedBy(controller.getId())) { numberOfCards++; card.moveToZone(Zone.HAND, source.getSourceId(), game, true); card.setFaceDown(false, game); diff --git a/Mage.Sets/src/mage/cards/b/BoundDetermined.java b/Mage.Sets/src/mage/cards/b/BoundDetermined.java index 728e21e9db0..cfb16ba5176 100644 --- a/Mage.Sets/src/mage/cards/b/BoundDetermined.java +++ b/Mage.Sets/src/mage/cards/b/BoundDetermined.java @@ -141,6 +141,6 @@ class DeterminedEffect extends ContinuousRuleModifyingEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Spell spell = game.getStack().getSpell(event.getTargetId()); - return spell != null && !spell.getSourceId().equals(source.getSourceId()) && spell.getControllerId().equals(source.getControllerId()); + return spell != null && !spell.getSourceId().equals(source.getSourceId()) && spell.isControlledBy(source.getControllerId()); } } diff --git a/Mage.Sets/src/mage/cards/b/BowerPassage.java b/Mage.Sets/src/mage/cards/b/BowerPassage.java index 9b4194823b8..2051063fd98 100644 --- a/Mage.Sets/src/mage/cards/b/BowerPassage.java +++ b/Mage.Sets/src/mage/cards/b/BowerPassage.java @@ -60,7 +60,7 @@ class BowerPassageEffect extends RestrictionEffect { @Override public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { - if (attacker != null && attacker.getControllerId().equals(source.getControllerId()) && blocker.getAbilities().contains(FlyingAbility.getInstance())) { + if (attacker != null && attacker.isControlledBy(source.getControllerId()) && blocker.getAbilities().contains(FlyingAbility.getInstance())) { return false; } return true; diff --git a/Mage.Sets/src/mage/cards/b/BramblewoodParagon.java b/Mage.Sets/src/mage/cards/b/BramblewoodParagon.java index b2445b48113..00a2692cc53 100644 --- a/Mage.Sets/src/mage/cards/b/BramblewoodParagon.java +++ b/Mage.Sets/src/mage/cards/b/BramblewoodParagon.java @@ -79,7 +79,7 @@ class BramblewoodParagonReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); - return creature != null && creature.getControllerId().equals(source.getControllerId()) + return creature != null && creature.isControlledBy(source.getControllerId()) && creature.isCreature() && creature.hasSubtype(SubType.WARRIOR, game) && !event.getTargetId().equals(source.getSourceId()); diff --git a/Mage.Sets/src/mage/cards/b/BreathOfFury.java b/Mage.Sets/src/mage/cards/b/BreathOfFury.java index 2e8fb766f0e..f493139fadf 100644 --- a/Mage.Sets/src/mage/cards/b/BreathOfFury.java +++ b/Mage.Sets/src/mage/cards/b/BreathOfFury.java @@ -80,7 +80,7 @@ class BreathOfFuryAbility extends TriggeredAbilityImpl { Permanent enchantment = game.getPermanent(getSourceId()); if (damageEvent.isCombatDamage() && enchantment != null - && enchantment.getAttachedTo().equals(event.getSourceId())) { + && enchantment.isAttachedTo(event.getSourceId())) { Permanent creature = game.getPermanent(enchantment.getAttachedTo()); if (creature != null) { for (Effect effect : getEffects()) { diff --git a/Mage.Sets/src/mage/cards/b/BredForTheHunt.java b/Mage.Sets/src/mage/cards/b/BredForTheHunt.java index 13dca000ce4..2c5f15e810a 100644 --- a/Mage.Sets/src/mage/cards/b/BredForTheHunt.java +++ b/Mage.Sets/src/mage/cards/b/BredForTheHunt.java @@ -62,7 +62,7 @@ class BredForTheHuntTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (((DamagedEvent) event).isCombatDamage()) { Permanent creature = game.getPermanent(event.getSourceId()); - if (creature != null && creature.getControllerId().equals(getControllerId()) && creature.getCounters(game).getCount(CounterType.P1P1) > 0) { + if (creature != null && creature.isControlledBy(getControllerId()) && creature.getCounters(game).getCount(CounterType.P1P1) > 0) { return true; } } diff --git a/Mage.Sets/src/mage/cards/b/BrineShaman.java b/Mage.Sets/src/mage/cards/b/BrineShaman.java index 3b43cbe04dc..2a2d0398ca0 100644 --- a/Mage.Sets/src/mage/cards/b/BrineShaman.java +++ b/Mage.Sets/src/mage/cards/b/BrineShaman.java @@ -18,6 +18,8 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterSpell; import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT; + +import mage.filter.StaticFilters; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.target.TargetSpell; @@ -30,7 +32,7 @@ import mage.target.common.TargetCreaturePermanent; */ public final class BrineShaman extends CardImpl { - private static final FilterSpell filter = new FilterSpell("noncreature spell"); + private static final FilterSpell filter = new FilterSpell("creature spell"); static { filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); @@ -54,7 +56,7 @@ public final class BrineShaman extends CardImpl { ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(), new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); ability.addCost(new ManaCostsImpl("{1}{U}{U}")); - ability.addTarget(new TargetSpell(filter)); + ability.addTarget(new TargetSpell(StaticFilters.FILTER_SPELL_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BroodingSaurian.java b/Mage.Sets/src/mage/cards/b/BroodingSaurian.java index 0a2383c781d..135bbcff7c9 100644 --- a/Mage.Sets/src/mage/cards/b/BroodingSaurian.java +++ b/Mage.Sets/src/mage/cards/b/BroodingSaurian.java @@ -88,7 +88,7 @@ class BroodingSaurianControlEffect extends ContinuousEffectImpl { for (Iterator it = affectedObjectList.iterator(); it.hasNext();) { Permanent creature = it.next().getPermanent(game); if (creature != null) { - if (!creature.getControllerId().equals(creature.getOwnerId())) { + if (!creature.isControlledBy(creature.getOwnerId())) { creature.changeControllerId(creature.getOwnerId(), game); } } else { diff --git a/Mage.Sets/src/mage/cards/b/BrutalHordechief.java b/Mage.Sets/src/mage/cards/b/BrutalHordechief.java index eb3cc16faf9..e3b37d68008 100644 --- a/Mage.Sets/src/mage/cards/b/BrutalHordechief.java +++ b/Mage.Sets/src/mage/cards/b/BrutalHordechief.java @@ -113,7 +113,7 @@ class BrutalHordechiefTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent source = game.getPermanent(event.getSourceId()); - if (source != null && source.getControllerId().equals(controllerId)) { + if (source != null && source.isControlledBy(controllerId)) { UUID defendingPlayerId = game.getCombat().getDefendingPlayerId(event.getSourceId(), game); this.getEffects().get(0).setTargetPointer(new FixedTarget(defendingPlayerId)); return true; diff --git a/Mage.Sets/src/mage/cards/b/BuildersBane.java b/Mage.Sets/src/mage/cards/b/BuildersBane.java index 6b90776cfa4..094a17f47e8 100644 --- a/Mage.Sets/src/mage/cards/b/BuildersBane.java +++ b/Mage.Sets/src/mage/cards/b/BuildersBane.java @@ -77,7 +77,7 @@ class BuildersBaneEffect extends OneShotEffect { if (permanent.destroy(source.getSourceId(), game, false)) { game.applyEffects(); if (permanent.getZoneChangeCounter(game) + 1 == game.getState().getZoneChangeCounter(permanent.getId()) - && !game.getState().getZone(permanent.getId()).equals(Zone.GRAVEYARD)) { + && game.getState().getZone(permanent.getId()) != Zone.GRAVEYARD) { // A replacement effect has moved the card to another zone as grvayard continue; } diff --git a/Mage.Sets/src/mage/cards/b/BurnAway.java b/Mage.Sets/src/mage/cards/b/BurnAway.java index 69db42a5ddf..54e6e9344d0 100644 --- a/Mage.Sets/src/mage/cards/b/BurnAway.java +++ b/Mage.Sets/src/mage/cards/b/BurnAway.java @@ -62,7 +62,7 @@ class BurnAwayDelayedTriggeredAbility extends DelayedTriggeredAbility { public boolean checkTrigger(GameEvent event, Game game) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.isDiesEvent() && zEvent.getTarget() != null && zEvent.getTargetId().equals(getTargets().getFirstTarget())) { - this.getTargets().clear(); // else spell fizzels because target creature died + this.getTargets().clear(); // else spell fizzles because target creature died Target target = new TargetPlayer(); target.add(zEvent.getTarget().getControllerId(), game); this.addTarget(target); diff --git a/Mage.Sets/src/mage/cards/b/BurntheImpure.java b/Mage.Sets/src/mage/cards/b/BurnTheImpure.java similarity index 69% rename from Mage.Sets/src/mage/cards/b/BurntheImpure.java rename to Mage.Sets/src/mage/cards/b/BurnTheImpure.java index 5d6e6bd3213..9c57bb8b0db 100644 --- a/Mage.Sets/src/mage/cards/b/BurntheImpure.java +++ b/Mage.Sets/src/mage/cards/b/BurnTheImpure.java @@ -18,40 +18,41 @@ import mage.target.common.TargetCreaturePermanent; * * @author ayratn */ -public final class BurntheImpure extends CardImpl { +public final class BurnTheImpure extends CardImpl { - public BurntheImpure(UUID ownerId, CardSetInfo setInfo) { + public BurnTheImpure(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}"); + // Burn the Impure deals 3 damage to target creature. If that creature has infect, Burn the Impure deals 3 damage to that creature’s controller. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addEffect(new BurntheImpureEffect()); + this.getSpellAbility().addEffect(new BurnTheImpureEffect()); } - public BurntheImpure(final BurntheImpure card) { + public BurnTheImpure(final BurnTheImpure card) { super(card); } @Override - public BurntheImpure copy() { - return new BurntheImpure(this); + public BurnTheImpure copy() { + return new BurnTheImpure(this); } } -class BurntheImpureEffect extends OneShotEffect { +class BurnTheImpureEffect extends OneShotEffect { - public BurntheImpureEffect() { + public BurnTheImpureEffect() { super(Outcome.Damage); staticText = "{this} deals 3 damage to target creature. If that creature has infect, {this} deals 3 damage to that creature's controller."; } - public BurntheImpureEffect(final BurntheImpureEffect effect) { + public BurnTheImpureEffect(final BurnTheImpureEffect effect) { super(effect); } @Override - public BurntheImpureEffect copy() { - return new BurntheImpureEffect(this); + public BurnTheImpureEffect copy() { + return new BurnTheImpureEffect(this); } @Override diff --git a/Mage.Sets/src/mage/cards/c/CabalCoffers.java b/Mage.Sets/src/mage/cards/c/CabalCoffers.java index 72b167b5e4b..15afb42b599 100644 --- a/Mage.Sets/src/mage/cards/c/CabalCoffers.java +++ b/Mage.Sets/src/mage/cards/c/CabalCoffers.java @@ -1,4 +1,3 @@ - package mage.cards.c; import java.util.UUID; @@ -28,9 +27,9 @@ public final class CabalCoffers extends CardImpl { } public CabalCoffers(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - // {2}, {tap}: Add {B} for each Swamp you control. + // {2}, {T}: Add {B} for each Swamp you control. Ability ability = new DynamicManaAbility(Mana.BlackMana(1), new PermanentsOnBattlefieldCount(filter), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/c/CallerOfTheClaw.java b/Mage.Sets/src/mage/cards/c/CallerOfTheClaw.java index b386732ee92..e5607074fe6 100644 --- a/Mage.Sets/src/mage/cards/c/CallerOfTheClaw.java +++ b/Mage.Sets/src/mage/cards/c/CallerOfTheClaw.java @@ -82,7 +82,7 @@ class CallerOfTheClawWatcher extends Watcher { public void watch(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).isDiesEvent()) { Permanent card = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (card != null && card.getOwnerId().equals(this.controllerId) && card.isCreature() && !(card instanceof PermanentToken)) { + if (card != null && card.isOwnedBy(this.controllerId) && card.isCreature() && !(card instanceof PermanentToken)) { creaturesCount++; } } diff --git a/Mage.Sets/src/mage/cards/c/CampaignOfVengeance.java b/Mage.Sets/src/mage/cards/c/CampaignOfVengeance.java index 9db40745045..074e519a836 100644 --- a/Mage.Sets/src/mage/cards/c/CampaignOfVengeance.java +++ b/Mage.Sets/src/mage/cards/c/CampaignOfVengeance.java @@ -61,7 +61,7 @@ class CampaignOfVengeanceTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent source = game.getPermanent(event.getSourceId()); - if (source != null && source.getControllerId().equals(controllerId)) { + if (source != null && source.isControlledBy(controllerId)) { UUID defendingPlayerId = game.getCombat().getDefendingPlayerId(event.getSourceId(), game); this.getEffects().get(0).setTargetPointer(new FixedTarget(defendingPlayerId)); return true; diff --git a/Mage.Sets/src/mage/cards/c/CastThroughTime.java b/Mage.Sets/src/mage/cards/c/CastThroughTime.java index 92a51e71af4..143688a4200 100644 --- a/Mage.Sets/src/mage/cards/c/CastThroughTime.java +++ b/Mage.Sets/src/mage/cards/c/CastThroughTime.java @@ -77,7 +77,7 @@ class GainReboundEffect extends ContinuousEffectImpl { } for (Iterator iterator = game.getStack().iterator(); iterator.hasNext();) { StackObject stackObject = iterator.next(); - if (stackObject instanceof Spell && stackObject.getControllerId().equals(source.getControllerId())) { + if (stackObject instanceof Spell && stackObject.isControlledBy(source.getControllerId())) { Spell spell = (Spell) stackObject; Card card = spell.getCard(); if (card != null) { diff --git a/Mage.Sets/src/mage/cards/c/CatalystStone.java b/Mage.Sets/src/mage/cards/c/CatalystStone.java index bdcf7f251ef..0837d009974 100644 --- a/Mage.Sets/src/mage/cards/c/CatalystStone.java +++ b/Mage.Sets/src/mage/cards/c/CatalystStone.java @@ -89,7 +89,7 @@ class CatalystStoneCostReductionEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { - if (abilityToModify.getControllerId().equals(source.getControllerId())) { + if (abilityToModify.isControlledBy(source.getControllerId())) { return SpellAbilityCastMode.FLASHBACK.equals(((SpellAbility) abilityToModify).getSpellAbilityCastMode()); } } diff --git a/Mage.Sets/src/mage/cards/c/CelestialDawn.java b/Mage.Sets/src/mage/cards/c/CelestialDawn.java index 26e74879d8a..787eaf39cc2 100644 --- a/Mage.Sets/src/mage/cards/c/CelestialDawn.java +++ b/Mage.Sets/src/mage/cards/c/CelestialDawn.java @@ -122,13 +122,13 @@ class CelestialDawnToWhiteEffect extends ContinuousEffectImpl { } // Stack for (MageObject object : game.getStack()) { - if (object instanceof Spell && ((Spell) object).getControllerId().equals(controller.getId())) { + if (object instanceof Spell && ((Spell) object).isControlledBy(controller.getId())) { setColor(object.getColor(game), game); } } // Exile for (Card card : game.getExile().getAllCards(game)) { - if (card.getOwnerId().equals(controller.getId())) { + if (card.isOwnedBy(controller.getId())) { setColor(card.getColor(game), game); } } diff --git a/Mage.Sets/src/mage/cards/c/ChainsOfMephistopheles.java b/Mage.Sets/src/mage/cards/c/ChainsOfMephistopheles.java index 664d9387ab5..04f12fe4cf8 100644 --- a/Mage.Sets/src/mage/cards/c/ChainsOfMephistopheles.java +++ b/Mage.Sets/src/mage/cards/c/ChainsOfMephistopheles.java @@ -85,7 +85,7 @@ class ChainsOfMephistophelesReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (game.getActivePlayerId().equals(event.getPlayerId()) && game.getPhase().getStep().getType() == PhaseStep.DRAW) { + if (game.isActivePlayer(event.getPlayerId()) && game.getPhase().getStep().getType() == PhaseStep.DRAW) { CardsDrawnDuringDrawStepWatcher watcher = (CardsDrawnDuringDrawStepWatcher) game.getState().getWatchers().get(CardsDrawnDuringDrawStepWatcher.class.getSimpleName()); if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) > 0) { return true; diff --git a/Mage.Sets/src/mage/cards/c/ChampionOfLambholt.java b/Mage.Sets/src/mage/cards/c/ChampionOfLambholt.java index 3422e28fc32..de10a0845e0 100644 --- a/Mage.Sets/src/mage/cards/c/ChampionOfLambholt.java +++ b/Mage.Sets/src/mage/cards/c/ChampionOfLambholt.java @@ -79,7 +79,7 @@ class ChampionOfLambholtEffect extends RestrictionEffect { @Override public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (sourcePermanent != null && attacker.getControllerId().equals(sourcePermanent.getControllerId())) { + if (sourcePermanent != null && attacker.isControlledBy(sourcePermanent.getControllerId())) { return blocker.getPower().getValue() >= sourcePermanent.getPower().getValue(); } return true; diff --git a/Mage.Sets/src/mage/cards/c/ChanceEncounter.java b/Mage.Sets/src/mage/cards/c/ChanceEncounter.java index 6bacd9ab59d..84d4fbbac84 100644 --- a/Mage.Sets/src/mage/cards/c/ChanceEncounter.java +++ b/Mage.Sets/src/mage/cards/c/ChanceEncounter.java @@ -68,7 +68,7 @@ class ChanceEncounterTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - return this.getControllerId().equals(event.getPlayerId()) && event.getFlag(); + return this.isControlledBy(event.getPlayerId()) && event.getFlag(); } @Override diff --git a/Mage.Sets/src/mage/cards/c/ChancellorOfTheTangle.java b/Mage.Sets/src/mage/cards/c/ChancellorOfTheTangle.java index d7a2f94c461..3b61a924634 100644 --- a/Mage.Sets/src/mage/cards/c/ChancellorOfTheTangle.java +++ b/Mage.Sets/src/mage/cards/c/ChancellorOfTheTangle.java @@ -67,7 +67,7 @@ class ChancellorOfTheTangleDelayedTriggeredAbility extends DelayedTriggeredAbili @Override public boolean checkTrigger(GameEvent event, Game game) { - return game.getActivePlayerId().equals(controllerId); + return game.isActivePlayer(controllerId); } @Override public ChancellorOfTheTangleDelayedTriggeredAbility copy() { diff --git a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java index e2975f6b7d3..4e5b7fe082d 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java +++ b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java @@ -115,7 +115,7 @@ class ChandraPyromasterTarget extends TargetPermanent { } UUID firstTarget = player.getId(); Permanent permanent = game.getPermanent(id); - if (firstTarget != null && permanent != null && permanent.getControllerId().equals(firstTarget)) { + if (firstTarget != null && permanent != null && permanent.isControlledBy(firstTarget)) { return super.canTarget(id, source, game); } return false; @@ -142,7 +142,7 @@ class ChandraPyromasterTarget extends TargetPermanent { if (player != null) { for (UUID targetId : availablePossibleTargets) { Permanent permanent = game.getPermanent(targetId); - if (permanent != null && permanent.getControllerId().equals(player.getId())) { + if (permanent != null && permanent.isControlledBy(player.getId())) { possibleTargets.add(targetId); } } diff --git a/Mage.Sets/src/mage/cards/c/ChannelHarm.java b/Mage.Sets/src/mage/cards/c/ChannelHarm.java index 4d063d06442..ecd7da14f4f 100644 --- a/Mage.Sets/src/mage/cards/c/ChannelHarm.java +++ b/Mage.Sets/src/mage/cards/c/ChannelHarm.java @@ -82,14 +82,14 @@ class ChannelHarmEffect extends PreventionEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (super.applies(event, source, game)) { Permanent targetPermanent = game.getPermanent(event.getTargetId()); - if ((targetPermanent != null && targetPermanent.getControllerId().equals(source.getControllerId())) + if ((targetPermanent != null && targetPermanent.isControlledBy(source.getControllerId())) || event.getTargetId().equals(source.getControllerId())) { MageObject damageSource = game.getObject(event.getSourceId()); if (damageSource instanceof Controllable) { - return !((Controllable) damageSource).getControllerId().equals(source.getControllerId()); + return !((Controllable) damageSource).isControlledBy(source.getControllerId()); } else if (damageSource instanceof Card) { - return !((Card) damageSource).getOwnerId().equals(source.getControllerId()); + return !((Card) damageSource).isOwnedBy(source.getControllerId()); } } } diff --git a/Mage.Sets/src/mage/cards/c/ChaosWand.java b/Mage.Sets/src/mage/cards/c/ChaosWand.java index 1a13b28d8e3..f5f790060aa 100644 --- a/Mage.Sets/src/mage/cards/c/ChaosWand.java +++ b/Mage.Sets/src/mage/cards/c/ChaosWand.java @@ -82,14 +82,16 @@ class ChaosWandEffect extends OneShotEffect { break; } opponent.moveCards(card, Zone.EXILED, source, game); + controller.revealCards(source, new CardsImpl(card), game); if (card.isInstant() || card.isSorcery()) { if (!controller.chooseUse(outcome, "Cast " + card.getName() + " without paying its mana cost?", source, game) || !controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { cardsToShuffle.add(card); } break; + } else { + cardsToShuffle.add(card); } - cardsToShuffle.add(card); } return opponent.putCardsOnBottomOfLibrary(cardsToShuffle, game, source, false); } diff --git a/Mage.Sets/src/mage/cards/c/ChickenALaKing.java b/Mage.Sets/src/mage/cards/c/ChickenALaKing.java index cfa4f6c851a..54fc631a3b3 100644 --- a/Mage.Sets/src/mage/cards/c/ChickenALaKing.java +++ b/Mage.Sets/src/mage/cards/c/ChickenALaKing.java @@ -89,7 +89,7 @@ class ChickenALaKingTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (this.getControllerId().equals(event.getPlayerId()) && event.getFlag()) { + if (this.isControlledBy(event.getPlayerId()) && event.getFlag()) { // event.getData holds the num of sides of the die to roll String data = event.getData(); if (data != null) { diff --git a/Mage.Sets/src/mage/cards/c/ChitteringDoom.java b/Mage.Sets/src/mage/cards/c/ChitteringDoom.java index b6b626805db..5b50ecae6f7 100644 --- a/Mage.Sets/src/mage/cards/c/ChitteringDoom.java +++ b/Mage.Sets/src/mage/cards/c/ChitteringDoom.java @@ -57,7 +57,7 @@ class ChitteringDoomTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (this.getControllerId().equals(event.getPlayerId()) && event.getFlag()) { + if (this.isControlledBy(event.getPlayerId()) && event.getFlag()) { if (event.getAmount() >= 4) { return true; } diff --git a/Mage.Sets/src/mage/cards/c/ChronicFlooding.java b/Mage.Sets/src/mage/cards/c/ChronicFlooding.java index e20d623828f..62f452388d3 100644 --- a/Mage.Sets/src/mage/cards/c/ChronicFlooding.java +++ b/Mage.Sets/src/mage/cards/c/ChronicFlooding.java @@ -72,10 +72,9 @@ class ChronicFloodingAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent source = game.getPermanent(this.sourceId); - if (source != null && source.getAttachedTo().equals(event.getTargetId())) { + if (source != null && source.isAttachedTo(event.getTargetId())) { Permanent attached = game.getPermanent(source.getAttachedTo()); if (attached != null) { - for (Effect e : getEffects()) { e.setTargetPointer(new FixedTarget(attached.getControllerId())); } diff --git a/Mage.Sets/src/mage/cards/c/CinderCloud.java b/Mage.Sets/src/mage/cards/c/CinderCloud.java index 077dc5a04ef..24d02c18e8a 100644 --- a/Mage.Sets/src/mage/cards/c/CinderCloud.java +++ b/Mage.Sets/src/mage/cards/c/CinderCloud.java @@ -61,7 +61,7 @@ class CinderCloudEffect extends OneShotEffect { if (permanent != null && permanent.destroy(source.getSourceId(), game, false) && permanent.getColor(game).equals(ObjectColor.WHITE)) { game.applyEffects(); if (permanent.getZoneChangeCounter(game) + 1 == game.getState().getZoneChangeCounter(permanent.getId()) - && !game.getState().getZone(permanent.getId()).equals(Zone.GRAVEYARD)) { + && game.getState().getZone(permanent.getId()) != Zone.GRAVEYARD) { // A replacement effect has moved the card to another zone as grvayard return true; } diff --git a/Mage.Sets/src/mage/cards/c/CircleOfFlame.java b/Mage.Sets/src/mage/cards/c/CircleOfFlame.java index 028dd37cb2e..dc1c26cd8d2 100644 --- a/Mage.Sets/src/mage/cards/c/CircleOfFlame.java +++ b/Mage.Sets/src/mage/cards/c/CircleOfFlame.java @@ -77,7 +77,7 @@ class CircleOfFlameTriggeredAbility extends TriggeredAbilityImpl { Permanent permanent = game.getPermanent(event.getTargetId()); youOrYourPlaneswalker = permanent != null && permanent.isPlaneswalker() - && permanent.getControllerId().equals(this.getControllerId()); + && permanent.isControlledBy(this.getControllerId()); } if (youOrYourPlaneswalker) { for (Effect effect : this.getEffects()) { diff --git a/Mage.Sets/src/mage/cards/c/CityOfSolitude.java b/Mage.Sets/src/mage/cards/c/CityOfSolitude.java index 40becef9f80..01291a62521 100644 --- a/Mage.Sets/src/mage/cards/c/CityOfSolitude.java +++ b/Mage.Sets/src/mage/cards/c/CityOfSolitude.java @@ -67,7 +67,7 @@ class CityOfSolitudeEffect extends ContinuousRuleModifyingEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return !game.getActivePlayerId().equals(event.getPlayerId()); + return !game.isActivePlayer(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/c/CityOfTraitors.java b/Mage.Sets/src/mage/cards/c/CityOfTraitors.java index d5108787ed4..aa507b2a60d 100644 --- a/Mage.Sets/src/mage/cards/c/CityOfTraitors.java +++ b/Mage.Sets/src/mage/cards/c/CityOfTraitors.java @@ -62,7 +62,7 @@ class CityOfTraitorsTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent land = game.getPermanent(event.getTargetId()); return land.isLand() - && land.getControllerId().equals(this.controllerId) + && land.isControlledBy(this.controllerId) && !Objects.equals(event.getTargetId(), this.getSourceId()); } diff --git a/Mage.Sets/src/mage/cards/c/CleansingMeditation.java b/Mage.Sets/src/mage/cards/c/CleansingMeditation.java index d00337ab710..03bcd502104 100644 --- a/Mage.Sets/src/mage/cards/c/CleansingMeditation.java +++ b/Mage.Sets/src/mage/cards/c/CleansingMeditation.java @@ -74,7 +74,7 @@ class CleansingMeditationEffect extends OneShotEffect { for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_ENCHANTMENT_PERMANENT, source.getControllerId(), source.getSourceId(), game)) { if (permanent != null && permanent.destroy(source.getSourceId(), game, false)) { - if (threshold && controller != null && permanent.getOwnerId().equals(controller.getId())) { + if (threshold && controller != null && permanent.isOwnedBy(controller.getId())) { cardsToBattlefield.add(permanent); } } diff --git a/Mage.Sets/src/mage/cards/c/CloudCover.java b/Mage.Sets/src/mage/cards/c/CloudCover.java index 1793102559d..7367585c444 100644 --- a/Mage.Sets/src/mage/cards/c/CloudCover.java +++ b/Mage.Sets/src/mage/cards/c/CloudCover.java @@ -63,7 +63,7 @@ class CloudCoverAbility extends TriggeredAbilityImpl { Permanent permanent = game.getPermanent(event.getTargetId()); Player controller = game.getPlayer(this.getControllerId()); if (permanent != null - && permanent.getControllerId().equals(getControllerId()) + && permanent.isControlledBy(getControllerId()) && !permanent.getId().equals(this.getSourceId()) && controller != null && controller.hasOpponent(event.getPlayerId(), game)) { diff --git a/Mage.Sets/src/mage/cards/c/CloudKey.java b/Mage.Sets/src/mage/cards/c/CloudKey.java index 7da1f97dfc8..5a9bd8158e1 100644 --- a/Mage.Sets/src/mage/cards/c/CloudKey.java +++ b/Mage.Sets/src/mage/cards/c/CloudKey.java @@ -119,7 +119,7 @@ class CloudKeyCostModificationEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { - if (abilityToModify instanceof SpellAbility && abilityToModify.getControllerId().equals(source.getControllerId())) { + if (abilityToModify instanceof SpellAbility && abilityToModify.isControlledBy(source.getControllerId())) { Spell spell = game.getStack().getSpell(abilityToModify.getSourceId()); if (spell != null && spell.getCardType().toString().contains((String) game.getState().getValue(source.getSourceId().toString() + "_CloudKey"))) { return true; diff --git a/Mage.Sets/src/mage/cards/c/CoastalPiracy.java b/Mage.Sets/src/mage/cards/c/CoastalPiracy.java index dab61d18513..f3a94fc0a6b 100644 --- a/Mage.Sets/src/mage/cards/c/CoastalPiracy.java +++ b/Mage.Sets/src/mage/cards/c/CoastalPiracy.java @@ -63,7 +63,7 @@ class CoastalPiracyTriggeredAbility extends TriggeredAbilityImpl { if (((DamagedPlayerEvent) event).isCombatDamage() && game.getOpponents(this.controllerId).contains(((DamagedPlayerEvent) event).getPlayerId())) { Permanent creature = game.getPermanent(event.getSourceId()); - if (creature != null && creature.getControllerId().equals(controllerId)) { + if (creature != null && creature.isControlledBy(controllerId)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/c/Comeuppance.java b/Mage.Sets/src/mage/cards/c/Comeuppance.java index 6abcda8ce10..8d03fa51c8b 100644 --- a/Mage.Sets/src/mage/cards/c/Comeuppance.java +++ b/Mage.Sets/src/mage/cards/c/Comeuppance.java @@ -71,7 +71,7 @@ class ComeuppanceEffect extends PreventionEffectImpl { MageObject damageDealingObject = game.getObject(event.getSourceId()); UUID objectControllerId = null; if (damageDealingObject instanceof Permanent) { - if (((Permanent) damageDealingObject).isCreature()) { + if (damageDealingObject.isCreature()) { ((Permanent) damageDealingObject).damage(preventionData.getPreventedDamage(), source.getSourceId(), game, false, true); } else { objectControllerId = ((Permanent) damageDealingObject).getControllerId(); @@ -102,7 +102,7 @@ class ComeuppanceEffect extends PreventionEffectImpl { } else { Permanent targetPermanent = game.getPermanent(event.getTargetId()); if (targetPermanent != null && - targetPermanent.getControllerId().equals(source.getControllerId()) && + targetPermanent.isControlledBy(source.getControllerId()) && targetPermanent.isPlaneswalker()) { catched = true; } @@ -110,11 +110,11 @@ class ComeuppanceEffect extends PreventionEffectImpl { if (catched) { MageObject damageSource = game.getObject(event.getSourceId()); if (damageSource instanceof StackObject) { - return !((StackObject) damageSource).getControllerId().equals(source.getControllerId()); + return !((StackObject) damageSource).isControlledBy(source.getControllerId()); } else if (damageSource instanceof Permanent) { - return !((Permanent) damageSource).getControllerId().equals(source.getControllerId()); + return !((Permanent) damageSource).isControlledBy(source.getControllerId()); } else if (damageSource instanceof Card) { - return !((Card) damageSource).getOwnerId().equals(source.getControllerId()); + return !((Card) damageSource).isOwnedBy(source.getControllerId()); } Logger.getLogger(Comeuppance.class).error("Comeuppance: could not define source objects controller - " + (damageSource != null ? damageSource.getName(): "null")); } diff --git a/Mage.Sets/src/mage/cards/c/CommuneWithLava.java b/Mage.Sets/src/mage/cards/c/CommuneWithLava.java index da68914daf3..e38056a591d 100644 --- a/Mage.Sets/src/mage/cards/c/CommuneWithLava.java +++ b/Mage.Sets/src/mage/cards/c/CommuneWithLava.java @@ -105,7 +105,7 @@ class CommuneWithLavaMayPlayEffect extends AsThoughEffectImpl { @Override public boolean isInactive(Ability source, Game game) { if (castOnTurn != game.getTurnNum() && game.getPhase().getStep().getType() == PhaseStep.END_TURN) { - if (game.getActivePlayerId().equals(source.getControllerId())) { + if (game.isActivePlayer(source.getControllerId())) { return true; } } @@ -119,7 +119,7 @@ class CommuneWithLavaMayPlayEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && getTargetPointer().getTargets(game, source).contains(sourceId); } diff --git a/Mage.Sets/src/mage/cards/c/ConcussiveBolt.java b/Mage.Sets/src/mage/cards/c/ConcussiveBolt.java index 8cd274c678b..b8f39e589a3 100644 --- a/Mage.Sets/src/mage/cards/c/ConcussiveBolt.java +++ b/Mage.Sets/src/mage/cards/c/ConcussiveBolt.java @@ -89,7 +89,7 @@ class ConcussiveBoltRestrictionEffect extends RestrictionEffect { if (player == null) { return false; } - if (metalcraft && permanent.getControllerId().equals(player.getId())) { + if (metalcraft && permanent.isControlledBy(player.getId())) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/c/ConjurersBan.java b/Mage.Sets/src/mage/cards/c/ConjurersBan.java new file mode 100644 index 00000000000..f7624da9e81 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ConjurersBan.java @@ -0,0 +1,85 @@ +package mage.cards.c; + +import java.util.UUID; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.ChooseACardNameEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author noahg + */ +public final class ConjurersBan extends CardImpl { + + public ConjurersBan(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}{B}"); + + + // Choose a card name. Until your next turn, spells with the chosen name can’t be cast and lands with the chosen name can’t be played. + this.getSpellAbility().addEffect(new ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.ALL)); + this.getSpellAbility().addEffect(new ConjurersBanEffect()); + + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + } + + public ConjurersBan(final ConjurersBan card) { + super(card); + } + + @Override + public ConjurersBan copy() { + return new ConjurersBan(this); + } +} + +class ConjurersBanEffect extends ContinuousRuleModifyingEffectImpl { + + public ConjurersBanEffect() { + super(Duration.UntilYourNextTurn, Outcome.Detriment, true, false); + this.staticText = "spells with the chosen name can't be cast and lands with the chosen name can't be played"; + } + + public ConjurersBanEffect(final ConjurersBanEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public ConjurersBanEffect copy() { + return new ConjurersBanEffect(this); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getType() == GameEvent.EventType.CAST_SPELL || event.getType() == GameEvent.EventType.PLAY_LAND) { + MageObject object = game.getObject(event.getSourceId()); + return object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY)); + } + return false; + } + + @Override + public String getInfoMessage(Ability source, GameEvent event, Game game) { + String namedCard = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + String playerName = game.getPlayer(source.getControllerId()).getName(); + if (namedCard == null || playerName == null || source.getSourceObject(game) == null){ + return super.getInfoMessage(source, event, game); + } + return "Until "+playerName+"'s next turn, spells named "+namedCard+" can't be cast and lands named "+namedCard+" can't be played ("+source.getSourceObject(game).getIdName()+")."; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/ConquerorsFlail.java b/Mage.Sets/src/mage/cards/c/ConquerorsFlail.java index 3a350535550..477cd898b81 100644 --- a/Mage.Sets/src/mage/cards/c/ConquerorsFlail.java +++ b/Mage.Sets/src/mage/cards/c/ConquerorsFlail.java @@ -149,7 +149,7 @@ class ConquerorsFlailEffect extends ContinuousRuleModifyingEffectImpl { } } - if (isAttached && game.getActivePlayerId().equals(source.getControllerId()) + if (isAttached && game.isActivePlayer(source.getControllerId()) && game.getPlayer(source.getControllerId()).hasOpponent(event.getPlayerId(), game)) { return true; } diff --git a/Mage.Sets/src/mage/cards/c/Conspiracy.java b/Mage.Sets/src/mage/cards/c/Conspiracy.java index c70361593e8..1b305eff23b 100644 --- a/Mage.Sets/src/mage/cards/c/Conspiracy.java +++ b/Mage.Sets/src/mage/cards/c/Conspiracy.java @@ -85,13 +85,13 @@ class ConspiracyEffect extends ContinuousEffectImpl { } // in Exile for (Card card : game.getState().getExile().getAllCards(game)) { - if (card.getOwnerId().equals(controller.getId()) && card.isCreature()) { + if (card.isOwnedBy(controller.getId()) && card.isCreature()) { setCreatureSubtype(card, subType, game); } } // in Library (e.g. for Mystical Teachings) for (Card card : controller.getLibrary().getCards(game)) { - if (card.getOwnerId().equals(controller.getId()) && card.isCreature()) { + if (card.isOwnedBy(controller.getId()) && card.isCreature()) { setCreatureSubtype(card, subType, game); } } @@ -108,7 +108,7 @@ class ConspiracyEffect extends ContinuousEffectImpl { for (Iterator iterator = game.getStack().iterator(); iterator.hasNext();) { StackObject stackObject = iterator.next(); if (stackObject instanceof Spell - && stackObject.getControllerId().equals(source.getControllerId()) + && stackObject.isControlledBy(source.getControllerId()) && stackObject.isCreature()) { Card card = ((Spell) stackObject).getCard(); setCreatureSubtype(card, subType, game); diff --git a/Mage.Sets/src/mage/cards/c/CorpsejackMenace.java b/Mage.Sets/src/mage/cards/c/CorpsejackMenace.java index bb3ea2454fe..cb0f555675a 100644 --- a/Mage.Sets/src/mage/cards/c/CorpsejackMenace.java +++ b/Mage.Sets/src/mage/cards/c/CorpsejackMenace.java @@ -83,7 +83,7 @@ class CorpsejackMenaceReplacementEffect extends ReplacementEffectImpl { if (permanent == null) { permanent = game.getPermanentEntering(event.getTargetId()); } - if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) + if (permanent != null && permanent.isControlledBy(source.getControllerId()) && permanent.isCreature()) { return true; } diff --git a/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java b/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java index dda0916a501..ac19501f19b 100644 --- a/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java +++ b/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java @@ -175,8 +175,8 @@ class CorrosiveOozeCombatWatcher extends Watcher { } if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { - if (((ZoneChangeEvent) event).getFromZone().equals(Zone.BATTLEFIELD)) { - if (game.getTurn() != null && TurnPhase.COMBAT.equals(game.getTurn().getPhaseType())) { + if (((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { + if (game.getTurn() != null && TurnPhase.COMBAT == game.getTurn().getPhaseType()) { // Check if a previous blocked or blocked by creatures is leaving the battlefield for (Map.Entry> entry : oozeBlocksOrBlocked.entrySet()) { for (MageObjectReference mor : entry.getValue()) { diff --git a/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java b/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java index 7349f4100e4..b9b2f943eb3 100644 --- a/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java +++ b/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java @@ -120,7 +120,7 @@ class CouncilOfTheAbsoluteCostReductionEffect extends CostModificationEffectImpl @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if ((abilityToModify instanceof SpellAbility) - && abilityToModify.getControllerId().equals(source.getControllerId())) { + && abilityToModify.isControlledBy(source.getControllerId())) { Card card = game.getCard(abilityToModify.getSourceId()); return card.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY)); } diff --git a/Mage.Sets/src/mage/cards/c/CouncilsJudgment.java b/Mage.Sets/src/mage/cards/c/CouncilsJudgment.java index beda5d4bf05..340c01444bf 100644 --- a/Mage.Sets/src/mage/cards/c/CouncilsJudgment.java +++ b/Mage.Sets/src/mage/cards/c/CouncilsJudgment.java @@ -1,4 +1,3 @@ - package mage.cards.c; import java.util.HashMap; @@ -28,7 +27,7 @@ import mage.target.common.TargetNonlandPermanent; public final class CouncilsJudgment extends CardImpl { public CouncilsJudgment(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{W}{W}"); // Will of the council - Starting with you, each player votes for a nonland permanent you don't control. Exile each permanent with the most votes or tied for most votes. this.getSpellAbility().addEffect(new CouncilsJudgmentEffect()); @@ -89,7 +88,7 @@ class CouncilsJudgmentEffect extends OneShotEffect { } chosenCards.put(permanent, 1); } - game.informPlayers(player.getLogName() + " has chosen: " + permanent.getName()); + game.informPlayers(player.getLogName() + " has chosen: " + permanent.getLogName()); } } } diff --git a/Mage.Sets/src/mage/cards/c/Counterflux.java b/Mage.Sets/src/mage/cards/c/Counterflux.java index e27c4599afd..4f3703148bc 100644 --- a/Mage.Sets/src/mage/cards/c/Counterflux.java +++ b/Mage.Sets/src/mage/cards/c/Counterflux.java @@ -84,7 +84,7 @@ class CounterfluxEffect extends OneShotEffect { List spellsToCounter = new LinkedList<>(); for (StackObject stackObject : game.getStack()) { - if (stackObject instanceof Spell && !stackObject.getControllerId().equals(source.getControllerId())) { + if (stackObject instanceof Spell && !stackObject.isControlledBy(source.getControllerId())) { spellsToCounter.add((Spell) stackObject); } } diff --git a/Mage.Sets/src/mage/cards/c/CoverOfWinter.java b/Mage.Sets/src/mage/cards/c/CoverOfWinter.java new file mode 100644 index 00000000000..5497f041bb2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CoverOfWinter.java @@ -0,0 +1,102 @@ +package mage.cards.c; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.PreventionEffectData; +import mage.abilities.effects.PreventionEffectImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.Duration; +import mage.constants.SuperType; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author noahg + */ +public final class CoverOfWinter extends CardImpl { + + public CoverOfWinter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); + + this.addSuperType(SuperType.SNOW); + + // Cumulative upkeep {S} + this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{S}"))); + + // If a creature would deal combat damage to you and/or one or more creatures you control, prevent X of that damage, where X is the number of age counters on Cover of Winter. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CoverOfWinterEffect())); + + // {S}: Put an age counter on Cover of Winter. + this.addAbility(new SimpleActivatedAbility(new AddCountersSourceEffect(CounterType.AGE.createInstance()), new ManaCostsImpl("{S}"))); + } + + public CoverOfWinter(final CoverOfWinter card) { + super(card); + } + + @Override + public CoverOfWinter copy() { + return new CoverOfWinter(this); + } +} + +class CoverOfWinterEffect extends PreventionEffectImpl { + + public CoverOfWinterEffect() { + super(Duration.WhileOnBattlefield, -1, true); + this.staticText = "If a creature would deal combat damage to you and/or one or more creatures you control, prevent X of that damage, where X is the number of age counters on {this}"; + } + + public CoverOfWinterEffect(CoverOfWinterEffect effect) { + super(effect); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGE_PLAYER || event.getType() == GameEvent.EventType.DAMAGE_CREATURE; + } + + @Override + protected PreventionEffectData preventDamageAction(GameEvent event, Ability source, Game game) { + Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game); + if (sourcePermanent != null) { + return game.preventDamage(event, source, game, sourcePermanent.getCounters(game).getCount(CounterType.AGE)); + } else { + this.discard(); + return game.preventDamage(event, source, game, 0); + } + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getType() == GameEvent.EventType.DAMAGE_PLAYER + && event.getTargetId().equals(source.getControllerId())) { + return super.applies(event, source, game); + } + + if (event.getType() == GameEvent.EventType.DAMAGE_CREATURE) { + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { + return super.applies(event, source, game); + } + } + return false; + } + + @Override + public CoverOfWinterEffect copy() { + return new CoverOfWinterEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CowedByWisdom.java b/Mage.Sets/src/mage/cards/c/CowedByWisdom.java index 5561417e05e..7559402bc1b 100644 --- a/Mage.Sets/src/mage/cards/c/CowedByWisdom.java +++ b/Mage.Sets/src/mage/cards/c/CowedByWisdom.java @@ -80,7 +80,7 @@ class CowedByWisdomayCostToAttackBlockEffect extends PayCostToAttackBlockEffectI @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent enchantment = game.getPermanent(source.getSourceId()); - return enchantment != null && enchantment.getAttachedTo().equals(event.getSourceId()); + return enchantment != null && enchantment.isAttachedTo(event.getSourceId()); } @Override diff --git a/Mage.Sets/src/mage/cards/c/CrawlingSensation.java b/Mage.Sets/src/mage/cards/c/CrawlingSensation.java index 312d646ab53..f3c27887710 100644 --- a/Mage.Sets/src/mage/cards/c/CrawlingSensation.java +++ b/Mage.Sets/src/mage/cards/c/CrawlingSensation.java @@ -72,7 +72,7 @@ class CrawlingSensationTriggeredAbility extends TriggeredAbilityImpl { Set cardType = card.getCardType(); if (cardOwnerId != null - && card.getOwnerId().equals(getControllerId()) + && card.isOwnedBy(getControllerId()) && cardType != null && card.isLand()) { game.getState().setValue("usedOnTurn" + getControllerId() + getOriginalId(), game.getTurnNum()); diff --git a/Mage.Sets/src/mage/cards/c/CruelReality.java b/Mage.Sets/src/mage/cards/c/CruelReality.java index 40417f03cb6..ed9a9e29046 100644 --- a/Mage.Sets/src/mage/cards/c/CruelReality.java +++ b/Mage.Sets/src/mage/cards/c/CruelReality.java @@ -85,7 +85,7 @@ class CruelRealityTriggeredAbiilty extends TriggeredAbilityImpl { && enchantment.getAttachedTo() != null) { Player cursedPlayer = game.getPlayer(enchantment.getAttachedTo()); if (cursedPlayer != null - && game.getActivePlayerId().equals(cursedPlayer.getId())) { + && game.isActivePlayer(cursedPlayer.getId())) { this.getEffects().get(0).setTargetPointer(new FixedTarget(cursedPlayer.getId())); return true; } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java b/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java index 8363d4848df..7fe65e93557 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfBloodletting.java @@ -1,7 +1,6 @@ package mage.cards.c; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; @@ -16,14 +15,15 @@ import mage.game.permanent.Permanent; import mage.target.TargetPlayer; import mage.util.CardUtil; +import java.util.UUID; + /** - * * @author BetaSteward */ public final class CurseOfBloodletting extends CardImpl { public CurseOfBloodletting(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}{R}"); this.subtype.add(SubType.AURA, SubType.CURSE); @@ -71,10 +71,9 @@ class CurseOfBloodlettingEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent enchantment = game.getPermanent(source.getSourceId()); - if (enchantment != null && - enchantment.getAttachedTo() != null && - event.getTargetId().equals(enchantment.getAttachedTo())) { - return true; + if (enchantment != null && + enchantment.isAttachedTo(event.getTargetId())) { + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfEchoes.java b/Mage.Sets/src/mage/cards/c/CurseOfEchoes.java index aa3e6b8d77e..fc85728ff25 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfEchoes.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfEchoes.java @@ -90,7 +90,7 @@ class CurseOfEchoesCopyTriggeredAbility extends TriggeredAbilityImpl { Permanent enchantment = game.getPermanent(sourceId); if (enchantment != null && enchantment.getAttachedTo() != null) { Player player = game.getPlayer(enchantment.getAttachedTo()); - if (player != null && spell.getControllerId().equals(player.getId())) { + if (player != null && spell.isControlledBy(player.getId())) { this.getEffects().get(0).setTargetPointer(new FixedTarget(spell.getId())); return true; } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfOblivion.java b/Mage.Sets/src/mage/cards/c/CurseOfOblivion.java index e31da408eca..a12ec39a260 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfOblivion.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfOblivion.java @@ -79,7 +79,7 @@ class CurseOfOblivionAbility extends TriggeredAbilityImpl { Permanent enchantment = game.getPermanent(this.sourceId); if (enchantment != null && enchantment.getAttachedTo() != null) { Player player = game.getPlayer(enchantment.getAttachedTo()); - if (player != null && game.getActivePlayerId().equals(player.getId())) { + if (player != null && game.isActivePlayer(player.getId())) { this.getEffects().get(0).setTargetPointer(new FixedTarget(player.getId())); return true; } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfOpulence.java b/Mage.Sets/src/mage/cards/c/CurseOfOpulence.java index 6156af8739a..c6c93590741 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfOpulence.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfOpulence.java @@ -78,7 +78,7 @@ class CurseOfOpulenceEffect extends OneShotEffect { if (enchantment != null) { Player enchantedPlayer = game.getPlayer(enchantment.getAttachedTo()); if (enchantedPlayer != null) { - Set players = new HashSet(); + Set players = new HashSet<>(); for (UUID attacker : game.getCombat().getAttackers()) { UUID defender = game.getCombat().getDefenderId(attacker); if (defender.equals(enchantedPlayer.getId()) diff --git a/Mage.Sets/src/mage/cards/c/CurseOfPredation.java b/Mage.Sets/src/mage/cards/c/CurseOfPredation.java index be79d9fec45..a130d376858 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfPredation.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfPredation.java @@ -84,8 +84,7 @@ class CurseOfPredationTriggeredAbility extends TriggeredAbilityImpl { if (defender != null) { Permanent enchantment = game.getPermanent(this.getSourceId()); if (enchantment != null - && enchantment.getAttachedTo() != null - && enchantment.getAttachedTo().equals(defender.getId())) { + && enchantment.isAttachedTo(defender.getId())) { for (Effect effect: this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getSourceId())); } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfTheBloodyTome.java b/Mage.Sets/src/mage/cards/c/CurseOfTheBloodyTome.java index dc12e4ebdc8..18040ebb79d 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfTheBloodyTome.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfTheBloodyTome.java @@ -79,7 +79,7 @@ class CurseOfTheBloodyTomeAbility extends TriggeredAbilityImpl { Permanent enchantment = game.getPermanent(this.sourceId); if (enchantment != null && enchantment.getAttachedTo() != null) { Player player = game.getPlayer(enchantment.getAttachedTo()); - if (player != null && game.getActivePlayerId().equals(player.getId())) { + if (player != null && game.isActivePlayer(player.getId())) { this.getEffects().get(0).setTargetPointer(new FixedTarget(player.getId())); return true; } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfTheForsaken.java b/Mage.Sets/src/mage/cards/c/CurseOfTheForsaken.java index 2759845d264..f240a0e5d6f 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfTheForsaken.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfTheForsaken.java @@ -83,8 +83,7 @@ class CurseOfTheForsakenTriggeredAbility extends TriggeredAbilityImpl { if (defender != null) { Permanent enchantment = game.getPermanent(this.getSourceId()); if (enchantment != null - && enchantment.getAttachedTo() != null - && enchantment.getAttachedTo().equals(defender.getId())) { + && enchantment.isAttachedTo(defender.getId())) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getPlayerId())); } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfTheNightlyHunt.java b/Mage.Sets/src/mage/cards/c/CurseOfTheNightlyHunt.java index 473f8d72df9..72aa6094a55 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfTheNightlyHunt.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfTheNightlyHunt.java @@ -67,7 +67,7 @@ class CurseOfTheNightlyHuntEffect extends RequirementEffect { public boolean applies(Permanent permanent, Ability source, Game game) { Permanent enchantment = game.getPermanent(source.getSourceId()); if (enchantment != null && enchantment.getAttachedTo() != null) { - if (permanent.getControllerId().equals(enchantment.getAttachedTo())) { + if (permanent.isControlledBy(enchantment.getAttachedTo())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfThePiercedHeart.java b/Mage.Sets/src/mage/cards/c/CurseOfThePiercedHeart.java index bfd840ef5a2..9f713dcde14 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfThePiercedHeart.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfThePiercedHeart.java @@ -81,7 +81,7 @@ class CurseOfThePiercedHeartAbility extends TriggeredAbilityImpl { Permanent enchantment = game.getPermanent(this.sourceId); if (enchantment != null && enchantment.getAttachedTo() != null) { Player player = game.getPlayer(enchantment.getAttachedTo()); - if (player != null && game.getActivePlayerId().equals(player.getId())) { + if (player != null && game.isActivePlayer(player.getId())) { this.getEffects().get(0).setTargetPointer(new FixedTarget(player.getId())); return true; } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfTheSwine.java b/Mage.Sets/src/mage/cards/c/CurseOfTheSwine.java index 43dbcdb9670..cc40d560843 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfTheSwine.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfTheSwine.java @@ -36,7 +36,7 @@ public final class CurseOfTheSwine extends CardImpl { @Override public void adjustTargets(Ability ability, Game game) { - if (ability instanceof SpellAbility && ability.getAbilityType().equals(AbilityType.SPELL)) { + if (ability instanceof SpellAbility && ability.getAbilityType() == AbilityType.SPELL) { ability.getTargets().clear(); ability.addTarget(new TargetCreaturePermanent(ability.getManaCostsToPay().getX())); } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfThirst.java b/Mage.Sets/src/mage/cards/c/CurseOfThirst.java index a0f2087a3e1..97c1c9c1eac 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfThirst.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfThirst.java @@ -81,7 +81,7 @@ class CurseOfThirstAbility extends TriggeredAbilityImpl { Permanent enchantment = game.getPermanent(this.sourceId); if (enchantment != null && enchantment.getAttachedTo() != null) { Player player = game.getPlayer(enchantment.getAttachedTo()); - if (player != null && game.getActivePlayerId().equals(player.getId())) { + if (player != null && game.isActivePlayer(player.getId())) { this.getEffects().get(0).setTargetPointer(new FixedTarget(player.getId())); return true; } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfVengeance.java b/Mage.Sets/src/mage/cards/c/CurseOfVengeance.java index 0be3bf905dc..3fb01a3559e 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfVengeance.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfVengeance.java @@ -84,8 +84,7 @@ class CurseOfVengeanceTriggeredAbility extends TriggeredAbilityImpl { Spell spell = game.getStack().getSpell(event.getSourceId()); if (enchantment != null && spell != null - && enchantment.getAttachedTo() != null - && enchantment.getAttachedTo().equals(spell.getControllerId())) { + && enchantment.isAttachedTo(spell.getControllerId())) { this.getEffects().get(0).setTargetPointer(new FixedTarget(getSourceId())); return true; } @@ -126,7 +125,7 @@ class CurseOfVengeancePlayerLosesTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent sourceObject = game.getPermanentOrLKIBattlefield(this.getSourceId()); - return sourceObject != null && sourceObject.getAttachedTo().equals(event.getPlayerId()); + return sourceObject != null && sourceObject.isAttachedTo(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/c/CustodiLich.java b/Mage.Sets/src/mage/cards/c/CustodiLich.java index 1d8e2c41143..0fc1625b39c 100644 --- a/Mage.Sets/src/mage/cards/c/CustodiLich.java +++ b/Mage.Sets/src/mage/cards/c/CustodiLich.java @@ -70,7 +70,7 @@ class BecomesMonarchSourceControllerTriggeredAbility extends TriggeredAbilityImp @Override public boolean checkTrigger(GameEvent event, Game game) { - return getControllerId().equals(event.getPlayerId()); + return isControlledBy(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/d/DarigaazReincarnated.java b/Mage.Sets/src/mage/cards/d/DarigaazReincarnated.java index e1def85a885..e4623e5e5a2 100644 --- a/Mage.Sets/src/mage/cards/d/DarigaazReincarnated.java +++ b/Mage.Sets/src/mage/cards/d/DarigaazReincarnated.java @@ -161,7 +161,7 @@ class DarigaazReincarnatedReturnEffect extends OneShotEffect { return false; } MageObject sourceObject = source.getSourceObjectIfItStillExists(game); - if (sourceObject != null && sourceObject instanceof Card) { + if (sourceObject instanceof Card) { Card card = (Card) sourceObject; new RemoveCounterSourceEffect(CounterType.EGG.createInstance()).apply(game, source); if (card.getCounters(game).getCount(CounterType.EGG) == 0) { diff --git a/Mage.Sets/src/mage/cards/d/DarkDwellerOracle.java b/Mage.Sets/src/mage/cards/d/DarkDwellerOracle.java index fe999c3dc9c..bef6334009f 100644 --- a/Mage.Sets/src/mage/cards/d/DarkDwellerOracle.java +++ b/Mage.Sets/src/mage/cards/d/DarkDwellerOracle.java @@ -121,7 +121,7 @@ class DarkDwellerOracleCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && objectId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/d/DauntingDefender.java b/Mage.Sets/src/mage/cards/d/DauntingDefender.java index 69e9b5d0f46..bc1b8020875 100644 --- a/Mage.Sets/src/mage/cards/d/DauntingDefender.java +++ b/Mage.Sets/src/mage/cards/d/DauntingDefender.java @@ -65,7 +65,7 @@ class DauntingDefenderEffect extends PreventionEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.DAMAGE_CREATURE) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) && permanent.hasSubtype(SubType.CLERIC, game)) { + if (permanent != null && permanent.isControlledBy(source.getControllerId()) && permanent.hasSubtype(SubType.CLERIC, game)) { return super.applies(event, source, game); } } diff --git a/Mage.Sets/src/mage/cards/d/DawnsReflection.java b/Mage.Sets/src/mage/cards/d/DawnsReflection.java index 95c1d28040a..85b962c8727 100644 --- a/Mage.Sets/src/mage/cards/d/DawnsReflection.java +++ b/Mage.Sets/src/mage/cards/d/DawnsReflection.java @@ -76,7 +76,7 @@ class DawnsReflectionTriggeredAbility extends TriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent enchantment = game.getPermanent(this.getSourceId()); - return enchantment != null && event.getSourceId().equals(enchantment.getAttachedTo()); + return enchantment != null && enchantment.isAttachedTo(event.getSourceId()); } @Override diff --git a/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java b/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java index fa8c284a894..0f13053b5a6 100644 --- a/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java +++ b/Mage.Sets/src/mage/cards/d/DaxosOfMeletis.java @@ -144,7 +144,7 @@ class DaxosOfMeletisCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - if (sourceId.equals(cardId) && source.getControllerId().equals(affectedControllerId)) { + if (sourceId.equals(cardId) && source.isControlledBy(affectedControllerId)) { ExileZone exileZone = game.getState().getExile().getExileZone(exileId); return exileZone != null && exileZone.contains(cardId); } @@ -175,7 +175,7 @@ class DaxosOfMeletisSpendAnyManaEffect extends AsThoughEffectImpl implements AsT @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) && (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)) diff --git a/Mage.Sets/src/mage/cards/d/DearlyDeparted.java b/Mage.Sets/src/mage/cards/d/DearlyDeparted.java index af910d5c795..6083900b5c3 100644 --- a/Mage.Sets/src/mage/cards/d/DearlyDeparted.java +++ b/Mage.Sets/src/mage/cards/d/DearlyDeparted.java @@ -64,7 +64,7 @@ class DearlyDepartedEntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) && permanent.hasSubtype(SubType.HUMAN, game)) { + if (permanent != null && permanent.isControlledBy(source.getControllerId()) && permanent.hasSubtype(SubType.HUMAN, game)) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/d/DeathsPresence.java b/Mage.Sets/src/mage/cards/d/DeathsPresence.java index 00aac1bb567..0d69324a1cf 100644 --- a/Mage.Sets/src/mage/cards/d/DeathsPresence.java +++ b/Mage.Sets/src/mage/cards/d/DeathsPresence.java @@ -66,7 +66,7 @@ class DeathsPresenceTriggeredAbility extends TriggeredAbilityImpl { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent != null && permanent.getControllerId().equals(this.getControllerId()) && permanent.isCreature()) { + if (permanent != null && permanent.isControlledBy(this.getControllerId()) && permanent.isCreature()) { this.getTargets().clear(); this.addTarget(new TargetControlledCreaturePermanent()); this.getEffects().clear(); diff --git a/Mage.Sets/src/mage/cards/d/DeepfathomSkulker.java b/Mage.Sets/src/mage/cards/d/DeepfathomSkulker.java index 490a04b2b8a..d251e952760 100644 --- a/Mage.Sets/src/mage/cards/d/DeepfathomSkulker.java +++ b/Mage.Sets/src/mage/cards/d/DeepfathomSkulker.java @@ -80,7 +80,7 @@ class DeepfathomSkulkerTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (((DamagedPlayerEvent) event).isCombatDamage()) { Permanent creature = game.getPermanent(event.getSourceId()); - if (creature != null && creature.getControllerId().equals(controllerId)) { + if (creature != null && creature.isControlledBy(controllerId)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DefenseGrid.java b/Mage.Sets/src/mage/cards/d/DefenseGrid.java index 9699d07b17a..e4aaa65939f 100644 --- a/Mage.Sets/src/mage/cards/d/DefenseGrid.java +++ b/Mage.Sets/src/mage/cards/d/DefenseGrid.java @@ -57,7 +57,7 @@ class DefenseGridCostModificationEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { - if (!abilityToModify.getControllerId().equals(game.getActivePlayerId())) { + if (!abilityToModify.isControlledBy(game.getActivePlayerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DefiantGreatmaw.java b/Mage.Sets/src/mage/cards/d/DefiantGreatmaw.java index 300c5788e3f..b71d27ff4f1 100644 --- a/Mage.Sets/src/mage/cards/d/DefiantGreatmaw.java +++ b/Mage.Sets/src/mage/cards/d/DefiantGreatmaw.java @@ -80,7 +80,7 @@ class DefiantGreatmawTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - boolean weAreDoingIt = getControllerId().equals(game.getControllerId(event.getSourceId())); + boolean weAreDoingIt = isControlledBy(game.getControllerId(event.getSourceId())); boolean isM1M1Counters = event.getData().equals(CounterType.M1M1.getName()); if (weAreDoingIt && isM1M1Counters && event.getTargetId().equals(this.getSourceId())) { return true; diff --git a/Mage.Sets/src/mage/cards/d/Delirium.java b/Mage.Sets/src/mage/cards/d/Delirium.java new file mode 100644 index 00000000000..3a04e3523ae --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/Delirium.java @@ -0,0 +1,87 @@ +package mage.cards.d; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.common.CastOnlyIfConditionIsTrueAbility; +import mage.abilities.condition.common.OnOpponentsTurnCondition; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.*; +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.ControllerIsActivePlayerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author noahg + */ +public final class Delirium extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new ControllerIsActivePlayerPredicate()); + } + + public Delirium(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}{R}"); + + + // Cast this spell only during an opponent’s turn. + this.addAbility(new CastOnlyIfConditionIsTrueAbility(OnOpponentsTurnCondition.instance, "Cast this spell only during an opponent’s turn.")); + // Tap target creature that player controls. That creature deals damage equal to its power to the player. Prevent all combat damage that would be dealt to and dealt by the creature this turn. + this.getSpellAbility().addEffect(new TapTargetEffect().setText("target creature that player controls")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + this.getSpellAbility().addEffect(new DeliriumEffect()); + this.getSpellAbility().addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, true).setText("Prevent all combat damage that would be dealt to")); + this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true).setText("and dealt by the creature this turn.")); + } + + public Delirium(final Delirium card) { + super(card); + } + + @Override + public Delirium copy() { + return new Delirium(this); + } +} + +class DeliriumEffect extends OneShotEffect { + + public DeliriumEffect() { + super(Outcome.Damage); + this.staticText = "that creature deals damage equal to its power to the player"; + } + + public DeliriumEffect(DeliriumEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent creature = game.getPermanent(source.getFirstTarget()); + if (creature != null) { + int amount = creature.getPower().getValue(); + Player controller = game.getPlayer(creature.getControllerId()); + if (controller != null) { + controller.damage(amount, creature.getId(), game, false, true); + return true; + } + } + return false; + } + + @Override + public DeliriumEffect copy() { + return new DeliriumEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DereviEmpyrialTactician.java b/Mage.Sets/src/mage/cards/d/DereviEmpyrialTactician.java index 29dd3bf675e..851eff1ffbb 100644 --- a/Mage.Sets/src/mage/cards/d/DereviEmpyrialTactician.java +++ b/Mage.Sets/src/mage/cards/d/DereviEmpyrialTactician.java @@ -87,7 +87,7 @@ class DereviEmpyrialTacticianTriggeredAbility extends TriggeredAbilityImpl { if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER) { if (((DamagedPlayerEvent) event).isCombatDamage()) { Permanent creature = game.getPermanent(event.getSourceId()); - if (creature != null && creature.getControllerId().equals(controllerId)) { + if (creature != null && creature.isControlledBy(controllerId)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DesecratedTomb.java b/Mage.Sets/src/mage/cards/d/DesecratedTomb.java index 8112550b0fc..b597b3e36d2 100644 --- a/Mage.Sets/src/mage/cards/d/DesecratedTomb.java +++ b/Mage.Sets/src/mage/cards/d/DesecratedTomb.java @@ -65,7 +65,7 @@ class DesecratedTombTriggeredAbility extends TriggeredAbilityImpl { Set cardType = card.getCardType(); if (cardOwnerId != null - && card.getOwnerId().equals(getControllerId()) + && card.isOwnedBy(getControllerId()) && cardType != null && card.isCreature()) { return true; diff --git a/Mage.Sets/src/mage/cards/d/Dichotomancy.java b/Mage.Sets/src/mage/cards/d/Dichotomancy.java new file mode 100644 index 00000000000..c788c4dc8f3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/Dichotomancy.java @@ -0,0 +1,98 @@ +package mage.cards.d; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.SuspendAbility; +import mage.cards.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreatureCard; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetOpponent; + +/** + * + * @author noahg + */ +public final class Dichotomancy extends CardImpl { + + public Dichotomancy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{7}{U}{U}"); + + + // For each tapped nonland permanent target opponent controls, search that player’s library for a card with the same name as that permanent and put it onto the battlefield under your control. Then that player shuffles their library. + this.getSpellAbility().addEffect(new DichotomancyEffect()); + this.getSpellAbility().addTarget(new TargetOpponent()); + + // Suspend 3-{1}{U}{U} + this.addAbility(new SuspendAbility(3, new ManaCostsImpl("{1}{U}{U}"), this)); + } + + public Dichotomancy(final Dichotomancy card) { + super(card); + } + + @Override + public Dichotomancy copy() { + return new Dichotomancy(this); + } +} + +class DichotomancyEffect extends OneShotEffect { + + private static final FilterNonlandPermanent filter = new FilterNonlandPermanent(); + + static { + filter.add(new TappedPredicate()); + } + + public DichotomancyEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "For each tapped nonland permanent target opponent controls, search that player’s library for a card with the same name as that permanent and put it onto the battlefield under your control. Then that player shuffles their library"; + } + + public DichotomancyEffect(DichotomancyEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source)); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && opponent != null) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, opponent.getId(), game)) { + String name = permanent.getName(); + FilterCard filterCard = new FilterCard("card named \""+name+'"'); + filterCard.add(new NamePredicate(name)); + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filterCard); + if (controller.searchLibrary(target, game, opponent.getId())) { + controller.moveCards(opponent.getLibrary().getCard(target.getFirstTarget(), game), Zone.BATTLEFIELD, source, game); + } + } + opponent.shuffleLibrary(source, game); + return true; + } + return false; + } + + @Override + public DichotomancyEffect copy() { + return new DichotomancyEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java b/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java index 20130a2c615..72fe39f0cae 100644 --- a/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java +++ b/Mage.Sets/src/mage/cards/d/DireFleetDaredevil.java @@ -147,7 +147,7 @@ class DireFleetDaredevilPlayEffect extends AsThoughEffectImpl { UUID targetId = getTargetPointer().getFirst(game, source); if (targetId != null) { return targetId.equals(objectId) - && source.getControllerId().equals(affectedControllerId); + && source.isControlledBy(affectedControllerId); } else { // the target card has changed zone meanwhile, so the effect is no longer needed discard(); @@ -179,7 +179,7 @@ class DireFleetDaredevilSpendAnyManaEffect extends AsThoughEffectImpl implements @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) && game.getState().getZone(objectId) == Zone.STACK; @@ -210,7 +210,7 @@ class DireFleetDaredevilReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - UUID eventObject = ((ZoneChangeEvent) event).getTargetId(); + UUID eventObject = event.getTargetId(); StackObject stackObject = game.getStack().getStackObject(eventObject); if (stackObject != null) { if (stackObject instanceof Spell) { diff --git a/Mage.Sets/src/mage/cards/d/DiregrafCaptain.java b/Mage.Sets/src/mage/cards/d/DiregrafCaptain.java index 4f47406d21e..4d77c40513b 100644 --- a/Mage.Sets/src/mage/cards/d/DiregrafCaptain.java +++ b/Mage.Sets/src/mage/cards/d/DiregrafCaptain.java @@ -88,7 +88,7 @@ class DiregrafCaptainTriggeredAbility extends TriggeredAbilityImpl { ZoneChangeEvent zEvent = (ZoneChangeEvent)event; if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { Permanent p = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (p != null && p.getControllerId().equals(this.controllerId) && filter.match(p, game)) { + if (p != null && p.isControlledBy(this.controllerId) && filter.match(p, game)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DisplayOfDominance.java b/Mage.Sets/src/mage/cards/d/DisplayOfDominance.java index 407864aae39..f80123275b0 100644 --- a/Mage.Sets/src/mage/cards/d/DisplayOfDominance.java +++ b/Mage.Sets/src/mage/cards/d/DisplayOfDominance.java @@ -99,7 +99,7 @@ class DisplayOfDominanceEffect extends ContinuousRuleModifyingEffectImpl { mageObject instanceof Spell && (mageObject.getColor(game).isBlack() || mageObject.getColor(game).isBlue())) { Permanent permanent = game.getPermanent(event.getTargetId()); - return permanent != null && permanent.getControllerId().equals(ability.getControllerId()); + return permanent != null && permanent.isControlledBy(ability.getControllerId()); } return false; } diff --git a/Mage.Sets/src/mage/cards/d/DivineDeflection.java b/Mage.Sets/src/mage/cards/d/DivineDeflection.java index b0ffb232d98..9044094c555 100644 --- a/Mage.Sets/src/mage/cards/d/DivineDeflection.java +++ b/Mage.Sets/src/mage/cards/d/DivineDeflection.java @@ -118,12 +118,12 @@ class DivineDeflectionPreventDamageTargetEffect extends PreventionEffectImpl { // check permanent first Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null) { - if (permanent.getControllerId().equals(source.getControllerId())) { + if (permanent.isControlledBy(source.getControllerId())) { return true; } } // check player - if (source.getControllerId().equals(event.getTargetId())) { + if (source.isControlledBy(event.getTargetId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DjeruWithEyesOpen.java b/Mage.Sets/src/mage/cards/d/DjeruWithEyesOpen.java index 1e5e879503b..f29593b7e25 100644 --- a/Mage.Sets/src/mage/cards/d/DjeruWithEyesOpen.java +++ b/Mage.Sets/src/mage/cards/d/DjeruWithEyesOpen.java @@ -87,7 +87,7 @@ class DjeruWithEyesOpenPreventEffect extends PreventionEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { + if (permanent != null && permanent.isControlledBy(source.getControllerId())) { return super.applies(event, source, game); } } diff --git a/Mage.Sets/src/mage/cards/d/DjinnIlluminatus.java b/Mage.Sets/src/mage/cards/d/DjinnIlluminatus.java index e33b08f37e0..bba34f74968 100644 --- a/Mage.Sets/src/mage/cards/d/DjinnIlluminatus.java +++ b/Mage.Sets/src/mage/cards/d/DjinnIlluminatus.java @@ -81,8 +81,8 @@ class DjinnIlluminatusGainReplicateEffect extends ContinuousEffectImpl { // only spells cast, so no copies of spells if ((stackObject instanceof Spell) && !stackObject.isCopy() - && stackObject.getControllerId().equals(source.getControllerId()) - && djinn.getControllerId().equals(source.getControllerId()) // verify that the controller of the djinn cast that spell + && stackObject.isControlledBy(source.getControllerId()) + && djinn.isControlledBy(source.getControllerId()) // verify that the controller of the djinn cast that spell && !stackObject.getManaCost().isEmpty()) { //handle cases like Ancestral Vision Spell spell = (Spell) stackObject; if (filter.match(stackObject, game)) { diff --git a/Mage.Sets/src/mage/cards/d/DoorOfDestinies.java b/Mage.Sets/src/mage/cards/d/DoorOfDestinies.java index 8edb4b467d0..5f196a12056 100644 --- a/Mage.Sets/src/mage/cards/d/DoorOfDestinies.java +++ b/Mage.Sets/src/mage/cards/d/DoorOfDestinies.java @@ -75,7 +75,7 @@ class AddCounterAbility extends TriggeredAbilityImpl { if (subType != null) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null - && spell.getControllerId().equals(getControllerId()) + && spell.isControlledBy(getControllerId()) && spell.hasSubtype(subType, game)) { return true; } diff --git a/Mage.Sets/src/mage/cards/d/DosanTheFallingLeaf.java b/Mage.Sets/src/mage/cards/d/DosanTheFallingLeaf.java index ab35abb5230..b8e535ff8e8 100644 --- a/Mage.Sets/src/mage/cards/d/DosanTheFallingLeaf.java +++ b/Mage.Sets/src/mage/cards/d/DosanTheFallingLeaf.java @@ -54,7 +54,7 @@ class DosanTheFallingLeafEffect extends ContinuousRuleModifyingEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return event.getType() == GameEvent.EventType.CAST_SPELL && !game.getActivePlayerId().equals(event.getPlayerId()); + return event.getType() == GameEvent.EventType.CAST_SPELL && !game.isActivePlayer(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/d/DoublingSeason.java b/Mage.Sets/src/mage/cards/d/DoublingSeason.java index 587342dffac..fab6ae021d2 100644 --- a/Mage.Sets/src/mage/cards/d/DoublingSeason.java +++ b/Mage.Sets/src/mage/cards/d/DoublingSeason.java @@ -79,7 +79,7 @@ class DoublingSeasonCounterEffect extends ReplacementEffectImpl { && permanent.isLand()); // a played land is not an effect } return permanent != null - && permanent.getControllerId().equals(source.getControllerId()) + && permanent.isControlledBy(source.getControllerId()) && !landPlayed; // example: gemstone mine being played as a land drop } diff --git a/Mage.Sets/src/mage/cards/d/DrafnasRestoration.java b/Mage.Sets/src/mage/cards/d/DrafnasRestoration.java index 0fcaa1f512f..83b5bb36b0c 100644 --- a/Mage.Sets/src/mage/cards/d/DrafnasRestoration.java +++ b/Mage.Sets/src/mage/cards/d/DrafnasRestoration.java @@ -63,7 +63,7 @@ class DrafnasRestorationTarget extends TargetCardInGraveyard { public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { Set possibleTargets = new HashSet<>(); MageObject object = game.getObject(sourceId); - if (object != null && object instanceof StackObject) { + if (object instanceof StackObject) { Player targetPlayer = game.getPlayer(((StackObject) object).getStackAbility().getFirstTarget()); if (targetPlayer != null) { for (Card card : targetPlayer.getGraveyard().getCards(filter, sourceId, sourceControllerId, game)) { diff --git a/Mage.Sets/src/mage/cards/d/DragonlordDromoka.java b/Mage.Sets/src/mage/cards/d/DragonlordDromoka.java index a33d28d65b6..c24d6985bce 100644 --- a/Mage.Sets/src/mage/cards/d/DragonlordDromoka.java +++ b/Mage.Sets/src/mage/cards/d/DragonlordDromoka.java @@ -78,7 +78,7 @@ class DragonlordDromokaEffect extends ContinuousRuleModifyingEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (game.getActivePlayerId().equals(source.getControllerId()) && + if (game.isActivePlayer(source.getControllerId()) && game.getPlayer(source.getControllerId()).hasOpponent(event.getPlayerId(), game)) { return true; } diff --git a/Mage.Sets/src/mage/cards/d/DragonlordsPrerogative.java b/Mage.Sets/src/mage/cards/d/DragonlordsPrerogative.java index f0b975accbe..6ce626db3fa 100644 --- a/Mage.Sets/src/mage/cards/d/DragonlordsPrerogative.java +++ b/Mage.Sets/src/mage/cards/d/DragonlordsPrerogative.java @@ -91,7 +91,7 @@ class DragonlordsPrerogativeCondition implements Condition { if (spell != null && spell.getSpellAbility() != null) { for(Cost cost: spell.getSpellAbility().getCosts()) { if (cost instanceof RevealTargetFromHandCost) { - applies = !((RevealTargetFromHandCost)cost).getTargets().isEmpty(); + applies = !cost.getTargets().isEmpty(); break; } } diff --git a/Mage.Sets/src/mage/cards/d/DreamPillager.java b/Mage.Sets/src/mage/cards/d/DreamPillager.java index 39b74f41392..ad7ca79d2e7 100644 --- a/Mage.Sets/src/mage/cards/d/DreamPillager.java +++ b/Mage.Sets/src/mage/cards/d/DreamPillager.java @@ -153,7 +153,7 @@ class DreamPillagerCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && objectId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/d/DungeonGeists.java b/Mage.Sets/src/mage/cards/d/DungeonGeists.java index c6b2fa5afbf..ca1adb97464 100644 --- a/Mage.Sets/src/mage/cards/d/DungeonGeists.java +++ b/Mage.Sets/src/mage/cards/d/DungeonGeists.java @@ -89,7 +89,7 @@ class DungeonGeistsEffect extends ContinuousRuleModifyingEffectImpl { // the battlefield triggered ability the source dies (or will be exiled), then the ZONE_CHANGE or LOST_CONTROL // event will happen before this effect is applied ever) MageObject sourceObject = source.getSourceObjectIfItStillExists(game); - if (!(sourceObject instanceof Permanent) || !((Permanent) sourceObject).getControllerId().equals(source.getControllerId())) { + if (!(sourceObject instanceof Permanent) || !((Permanent) sourceObject).isControlledBy(source.getControllerId())) { discard(); return false; } @@ -109,7 +109,7 @@ class DungeonGeistsEffect extends ContinuousRuleModifyingEffectImpl { if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getTargetId().equals(targetPointer.getFirst(game, source))) { Permanent targetCreature = game.getPermanent(targetPointer.getFirst(game, source)); if (targetCreature != null) { - return targetCreature.getControllerId().equals(game.getActivePlayerId()); + return targetCreature.isControlledBy(game.getActivePlayerId()); } else { discard(); return false; diff --git a/Mage.Sets/src/mage/cards/d/DwarvenSoldier.java b/Mage.Sets/src/mage/cards/d/DwarvenSoldier.java index 73f29e88af0..b15c4d3a726 100644 --- a/Mage.Sets/src/mage/cards/d/DwarvenSoldier.java +++ b/Mage.Sets/src/mage/cards/d/DwarvenSoldier.java @@ -1,9 +1,8 @@ package mage.cards.d; -import java.util.UUID; import mage.MageInt; -import mage.abilities.common.BlocksOrBecomesBlockedTriggeredAbility; +import mage.abilities.common.BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -12,6 +11,8 @@ import mage.constants.Duration; import mage.constants.SubType; import mage.filter.common.FilterCreaturePermanent; +import java.util.UUID; + /** * * @author MarcoMarin @@ -26,7 +27,7 @@ public final class DwarvenSoldier extends CardImpl { this.toughness = new MageInt(1); // Whenever Dwarven Soldier blocks or becomes blocked by one or more Orcs, Dwarven Soldier gets +0/+2 until end of turn. - this.addAbility(new BlocksOrBecomesBlockedTriggeredAbility(new BoostSourceEffect(0, 2, Duration.EndOfTurn), new FilterCreaturePermanent(SubType.ORC, "Orc creature"), false)); + this.addAbility(new BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(new BoostSourceEffect(0, 2, Duration.EndOfTurn), new FilterCreaturePermanent(SubType.ORC, "Orcs"), false)); } public DwarvenSoldier(final DwarvenSoldier card) { diff --git a/Mage.Sets/src/mage/cards/e/EdificeOfAuthority.java b/Mage.Sets/src/mage/cards/e/EdificeOfAuthority.java index 27b95e5d19b..9ee96ef7838 100644 --- a/Mage.Sets/src/mage/cards/e/EdificeOfAuthority.java +++ b/Mage.Sets/src/mage/cards/e/EdificeOfAuthority.java @@ -117,7 +117,7 @@ class EdificeOfAuthorityRestrictionEffect extends RestrictionEffect { public boolean isInactive(Ability source, Game game) { if (game.getPhase().getStep().getType() == PhaseStep.UNTAP && game.getStep().getStepPart() == Step.StepPart.PRE) { - if (game.getActivePlayerId().equals(source.getControllerId()) + if (game.isActivePlayer(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) { for (UUID targetId : this.getTargetPointer().getTargets(game, source)) { Permanent permanent = game.getPermanent(targetId); diff --git a/Mage.Sets/src/mage/cards/e/ElderwoodScion.java b/Mage.Sets/src/mage/cards/e/ElderwoodScion.java index e099cab1e4b..778ffb55e52 100644 --- a/Mage.Sets/src/mage/cards/e/ElderwoodScion.java +++ b/Mage.Sets/src/mage/cards/e/ElderwoodScion.java @@ -73,7 +73,7 @@ class ElderwoodScionCostReductionEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { - if (abilityToModify.getControllerId().equals(source.getControllerId())) { + if (abilityToModify.isControlledBy(source.getControllerId())) { for (UUID modeId : abilityToModify.getModes().getSelectedModes()) { Mode mode = abilityToModify.getModes().get(modeId); for (Target target : mode.getTargets()) { diff --git a/Mage.Sets/src/mage/cards/e/Electropotence.java b/Mage.Sets/src/mage/cards/e/Electropotence.java index f556ab2bf34..ebaa86d2cfc 100644 --- a/Mage.Sets/src/mage/cards/e/Electropotence.java +++ b/Mage.Sets/src/mage/cards/e/Electropotence.java @@ -64,7 +64,7 @@ class ElectropotenceTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.isCreature() - && permanent.getControllerId().equals(this.controllerId)) { + && permanent.isControlledBy(this.controllerId)) { this.getEffects().get(0).setValue("damageSource", event.getTargetId()); return true; } diff --git a/Mage.Sets/src/mage/cards/e/ElkinBottle.java b/Mage.Sets/src/mage/cards/e/ElkinBottle.java index 972c8ca29f5..5ace27859f0 100644 --- a/Mage.Sets/src/mage/cards/e/ElkinBottle.java +++ b/Mage.Sets/src/mage/cards/e/ElkinBottle.java @@ -97,7 +97,7 @@ class ElkinBottleCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean isInactive(Ability source, Game game) { if (game.getPhase().getStep().getType() == PhaseStep.UPKEEP) { - if (!sameStep && game.getActivePlayerId().equals(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) { + if (!sameStep && game.isActivePlayer(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) { return true; } } else { @@ -113,7 +113,7 @@ class ElkinBottleCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && sourceId.equals(getTargetPointer().getFirst(game, source)); } diff --git a/Mage.Sets/src/mage/cards/e/EmbermawHellion.java b/Mage.Sets/src/mage/cards/e/EmbermawHellion.java index 42ae1cdbcb6..9bc75994f26 100644 --- a/Mage.Sets/src/mage/cards/e/EmbermawHellion.java +++ b/Mage.Sets/src/mage/cards/e/EmbermawHellion.java @@ -74,7 +74,7 @@ class EmbermawHellionEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if(source.getControllerId().equals(game.getControllerId(event.getSourceId()))) { + if(source.isControlledBy(game.getControllerId(event.getSourceId()))) { MageObject sourceObject; Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); if(sourcePermanent == null) { diff --git a/Mage.Sets/src/mage/cards/e/EncirclingFissure.java b/Mage.Sets/src/mage/cards/e/EncirclingFissure.java index a022c29835b..ca9f6b61ebc 100644 --- a/Mage.Sets/src/mage/cards/e/EncirclingFissure.java +++ b/Mage.Sets/src/mage/cards/e/EncirclingFissure.java @@ -66,7 +66,7 @@ class EncirclingFissurePreventEffect extends PreventionEffectImpl { Permanent permanent = game.getPermanent(damageEvent.getSourceId()); if (permanent != null && permanent.isCreature() - && permanent.getControllerId().equals(getTargetPointer().getFirst(game, source))) { + && permanent.isControlledBy(getTargetPointer().getFirst(game, source))) { return true; } } diff --git a/Mage.Sets/src/mage/cards/e/EnduringScalelord.java b/Mage.Sets/src/mage/cards/e/EnduringScalelord.java index f315c98fec3..663f0f9cfe3 100644 --- a/Mage.Sets/src/mage/cards/e/EnduringScalelord.java +++ b/Mage.Sets/src/mage/cards/e/EnduringScalelord.java @@ -76,7 +76,7 @@ class EnduringScalelordTriggeredAbility extends TriggeredAbilityImpl { return (permanent != null && !event.getTargetId().equals(this.getSourceId()) && permanent.isCreature() - && permanent.getControllerId().equals(this.getControllerId())); + && permanent.isControlledBy(this.getControllerId())); } return false; } diff --git a/Mage.Sets/src/mage/cards/e/EnigmaSphinx.java b/Mage.Sets/src/mage/cards/e/EnigmaSphinx.java index 7b988de1da3..ddeb27ac4e3 100644 --- a/Mage.Sets/src/mage/cards/e/EnigmaSphinx.java +++ b/Mage.Sets/src/mage/cards/e/EnigmaSphinx.java @@ -90,7 +90,7 @@ class EnigmaSphinxTriggeredAbility extends TriggeredAbilityImpl { && permanent.getId().equals(this.getSourceId()) && // 5/1/2009 If you control an Enigma Sphinx that's owned by another player, it's put into that player's // graveyard from the battlefield, so Enigma Sphinx's middle ability won't trigger. - permanent.getOwnerId().equals(permanent.getControllerId())) { + permanent.isOwnedBy(permanent.getControllerId())) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/e/EnterTheInfinite.java b/Mage.Sets/src/mage/cards/e/EnterTheInfinite.java index 536676ee668..5b725d6d0ae 100644 --- a/Mage.Sets/src/mage/cards/e/EnterTheInfinite.java +++ b/Mage.Sets/src/mage/cards/e/EnterTheInfinite.java @@ -123,7 +123,7 @@ class MaximumHandSizeEffect extends MaximumHandSizeControllerEffect { @Override public boolean isInactive(Ability source, Game game) { if (game.getPhase().getStep().getType() == PhaseStep.UNTAP && game.getStep().getStepPart() == Step.StepPart.PRE) { - if (game.getActivePlayerId().equals(source.getControllerId())) { + if (game.isActivePlayer(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/e/EssenceOfTheWild.java b/Mage.Sets/src/mage/cards/e/EssenceOfTheWild.java index 7dd16294548..2d1a030d4d1 100644 --- a/Mage.Sets/src/mage/cards/e/EssenceOfTheWild.java +++ b/Mage.Sets/src/mage/cards/e/EssenceOfTheWild.java @@ -66,7 +66,7 @@ class EssenceOfTheWildEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent perm = ((EntersTheBattlefieldEvent) event).getTarget(); - return perm != null && perm.isCreature() && perm.getControllerId().equals(source.getControllerId()); + return perm != null && perm.isCreature() && perm.isControlledBy(source.getControllerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/e/EternalScourge.java b/Mage.Sets/src/mage/cards/e/EternalScourge.java index 4dc83fce265..b226e01a859 100644 --- a/Mage.Sets/src/mage/cards/e/EternalScourge.java +++ b/Mage.Sets/src/mage/cards/e/EternalScourge.java @@ -71,7 +71,7 @@ class EternalScourgePlayEffect extends AsThoughEffectImpl { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { if (sourceId.equals(source.getSourceId())) { Card card = game.getCard(source.getSourceId()); - if (card != null && card.getOwnerId().equals(affectedControllerId) && game.getState().getZone(source.getSourceId()) == Zone.EXILED) { + if (card != null && card.isOwnedBy(affectedControllerId) && game.getState().getZone(source.getSourceId()) == Zone.EXILED) { return true; } } diff --git a/Mage.Sets/src/mage/cards/e/EunuchsIntrigues.java b/Mage.Sets/src/mage/cards/e/EunuchsIntrigues.java index f4ca2c87794..1daf99900dc 100644 --- a/Mage.Sets/src/mage/cards/e/EunuchsIntrigues.java +++ b/Mage.Sets/src/mage/cards/e/EunuchsIntrigues.java @@ -103,7 +103,7 @@ class EunuchsIntriguesRestrictionEffect extends RestrictionEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { - if (permanent.getControllerId().equals(source.getFirstTarget())) { + if (permanent.isControlledBy(source.getFirstTarget())) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/f/FaithsFetters.java b/Mage.Sets/src/mage/cards/f/FaithsFetters.java index d5fd0ecc6e3..42327c282a5 100644 --- a/Mage.Sets/src/mage/cards/f/FaithsFetters.java +++ b/Mage.Sets/src/mage/cards/f/FaithsFetters.java @@ -86,7 +86,7 @@ class FaithsFettersEffect extends ContinuousRuleModifyingEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent enchantment = game.getPermanent(source.getSourceId()); - if (enchantment != null && enchantment.getAttachedTo().equals(event.getSourceId())) { + if (enchantment != null && enchantment.isAttachedTo(event.getSourceId())) { Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); if (ability.isPresent() && ability.get().getAbilityType() != AbilityType.MANA) { return true; diff --git a/Mage.Sets/src/mage/cards/f/FaithsReward.java b/Mage.Sets/src/mage/cards/f/FaithsReward.java index 1c34dec0802..cf449635657 100644 --- a/Mage.Sets/src/mage/cards/f/FaithsReward.java +++ b/Mage.Sets/src/mage/cards/f/FaithsReward.java @@ -61,7 +61,7 @@ class FaithsRewardEffect extends OneShotEffect { if (watcher != null) { for (UUID id : watcher.cards) { Card c = game.getCard(id); - if (c != null && c.getOwnerId().equals(source.getControllerId()) && game.getState().getZone(id) == Zone.GRAVEYARD) { + if (c != null && c.isOwnedBy(source.getControllerId()) && game.getState().getZone(id) == Zone.GRAVEYARD) { c.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false); } } diff --git a/Mage.Sets/src/mage/cards/f/FalkenrathGorger.java b/Mage.Sets/src/mage/cards/f/FalkenrathGorger.java index b6274936b81..5a9aac019f7 100644 --- a/Mage.Sets/src/mage/cards/f/FalkenrathGorger.java +++ b/Mage.Sets/src/mage/cards/f/FalkenrathGorger.java @@ -99,7 +99,7 @@ class FalkenrathGorgerEffect extends ContinuousEffectImpl { // Exile for (Card card : game.getExile().getAllCards(game)) { if (filter.match(card, source.getSourceId(), controller.getId(), game)) { - if (card.getOwnerId().equals(controller.getId())) { + if (card.isOwnedBy(controller.getId())) { addMadnessToCard(game, card, usedMadnessAbilities); } } diff --git a/Mage.Sets/src/mage/cards/f/FavorableDestiny.java b/Mage.Sets/src/mage/cards/f/FavorableDestiny.java index 3f585e83d94..d5a237d635b 100644 --- a/Mage.Sets/src/mage/cards/f/FavorableDestiny.java +++ b/Mage.Sets/src/mage/cards/f/FavorableDestiny.java @@ -90,7 +90,7 @@ class FavorableDestinyCondition implements Condition { Player controller = game.getPlayer(creature.getControllerId()); if (controller != null) { for (Permanent perm : game.getBattlefield().getActivePermanents(controller.getId(), game)) { - if (perm.getControllerId().equals(controller.getId()) + if (perm.isControlledBy(controller.getId()) && perm.isCreature() && !perm.equals(creature)) { return true; diff --git a/Mage.Sets/src/mage/cards/f/FellShepherd.java b/Mage.Sets/src/mage/cards/f/FellShepherd.java index e8197945ca2..626237217f5 100644 --- a/Mage.Sets/src/mage/cards/f/FellShepherd.java +++ b/Mage.Sets/src/mage/cards/f/FellShepherd.java @@ -87,7 +87,7 @@ class FellShepherdWatcher extends Watcher { public void watch(GameEvent event, Game game) { if (event.getType() == EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).isDiesEvent()) { MageObject card = game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (card != null && ((Card) card).getOwnerId().equals(this.controllerId) && card.isCreature()) { + if (card != null && ((Card) card).isOwnedBy(this.controllerId) && card.isCreature()) { creatureIds.add(card.getId()); } } diff --git a/Mage.Sets/src/mage/cards/f/FertileImagination.java b/Mage.Sets/src/mage/cards/f/FertileImagination.java new file mode 100644 index 00000000000..f25b42bef30 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FertileImagination.java @@ -0,0 +1,125 @@ +package mage.cards.f; + +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.game.permanent.token.SaprolingToken; +import mage.players.Player; +import mage.target.common.TargetOpponent; + +/** + * + * @author noahg + */ +public final class FertileImagination extends CardImpl { + + public FertileImagination(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}{G}"); + + + // Choose a card type. Target opponent reveals their hand. Create two 1/1 green Saproling creature tokens for each card of the chosen type revealed this way. + this.getSpellAbility().addEffect(new FertileImaginationEffect()); + this.getSpellAbility().addTarget(new TargetOpponent()); + } + + public FertileImagination(final FertileImagination card) { + super(card); + } + + @Override + public FertileImagination copy() { + return new FertileImagination(this); + } +} + +class FertileImaginationEffect 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 FertileImaginationEffect() { + super(Outcome.Benefit); + staticText = "Choose a card type. Target opponent reveals their hand. Create two 1/1 green Saproling creature tokens for each card of the chosen type revealed this way"; + } + + public FertileImaginationEffect(final FertileImaginationEffect effect) { + super(effect); + } + + @Override + public FertileImaginationEffect copy() { + return new FertileImaginationEffect(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); + if (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(); + SaprolingToken saprolingToken = new SaprolingToken(); + opponent.revealCards(sourceObject.getIdName(), hand, game); + Set cards = hand.getCards(game); + int tokensToMake = 0; + for (Card card : cards) { + if (card != null && card.getCardType().contains(type)) { + tokensToMake += 2; + } + } + game.informPlayers(sourceObject.getLogName() + " creates " + (tokensToMake == 0 ? "no" : "" + tokensToMake) + " 1/1 green Saproling creature tokens."); + saprolingToken.putOntoBattlefield(tokensToMake, game, source.getId(), source.getControllerId()); + return true; + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/f/FiendslayerPaladin.java b/Mage.Sets/src/mage/cards/f/FiendslayerPaladin.java index d1687d6fef9..3749823252d 100644 --- a/Mage.Sets/src/mage/cards/f/FiendslayerPaladin.java +++ b/Mage.Sets/src/mage/cards/f/FiendslayerPaladin.java @@ -97,7 +97,7 @@ class FiendslayerPaladinEffect extends ContinuousRuleModifyingEffectImpl { StackObject stackObject = (StackObject) game.getStack().getStackObject(event.getSourceId()); if (targetCard != null && stackObject != null && targetCard.getId().equals(source.getSourceId())) { if (stackObject.getColor(game).isBlack() || stackObject.getColor(game).isRed()) { - if (!stackObject.getControllerId().equals(source.getControllerId()) + if (!stackObject.isControlledBy(source.getControllerId()) && stackObject.isInstant() || stackObject.isSorcery()) { return true; diff --git a/Mage.Sets/src/mage/cards/f/FinestHour.java b/Mage.Sets/src/mage/cards/f/FinestHour.java index 87b8adea5ed..2163788f4bc 100644 --- a/Mage.Sets/src/mage/cards/f/FinestHour.java +++ b/Mage.Sets/src/mage/cards/f/FinestHour.java @@ -74,7 +74,7 @@ class FinestHourAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getActivePlayerId().equals(this.controllerId)) { + if (game.isActivePlayer(this.controllerId)) { if (game.getCombat().attacksAlone()) { for (Effect effect: this.getEffects()) { effect.setTargetPointer(new FixedTarget(game.getCombat().getAttackers().get(0))); diff --git a/Mage.Sets/src/mage/cards/f/FireServant.java b/Mage.Sets/src/mage/cards/f/FireServant.java index 432634db048..5cd9c2c04a9 100644 --- a/Mage.Sets/src/mage/cards/f/FireServant.java +++ b/Mage.Sets/src/mage/cards/f/FireServant.java @@ -74,7 +74,7 @@ class FireServantEffect extends ReplacementEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { StackObject spell = game.getStack().getStackObject(event.getSourceId()); return spell != null && - spell.getControllerId().equals(source.getControllerId()) && + spell.isControlledBy(source.getControllerId()) && spell.getColor(game).isRed() && (spell.isInstant() || spell.isSorcery()); } diff --git a/Mage.Sets/src/mage/cards/f/FlamebladeAngel.java b/Mage.Sets/src/mage/cards/f/FlamebladeAngel.java index 4558dfcf55e..ef69d3eaddf 100644 --- a/Mage.Sets/src/mage/cards/f/FlamebladeAngel.java +++ b/Mage.Sets/src/mage/cards/f/FlamebladeAngel.java @@ -78,7 +78,7 @@ class FlamebladeAngelTriggeredAbility extends TriggeredAbilityImpl { result = true; } else { Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); - if (permanent != null && getControllerId().equals(permanent.getControllerId())) { + if (permanent != null && isControlledBy(permanent.getControllerId())) { result = true; } } diff --git a/Mage.Sets/src/mage/cards/f/FlamesOfRemembrance.java b/Mage.Sets/src/mage/cards/f/FlamesOfRemembrance.java index 01d71f30101..8c80d6be9c2 100644 --- a/Mage.Sets/src/mage/cards/f/FlamesOfRemembrance.java +++ b/Mage.Sets/src/mage/cards/f/FlamesOfRemembrance.java @@ -111,6 +111,6 @@ class FlamesOfRemembranceMayPlayExiledEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) && this.getTargetPointer().getTargets(game, source).contains(objectId); + return source.isControlledBy(affectedControllerId) && this.getTargetPointer().getTargets(game, source).contains(objectId); } } diff --git a/Mage.Sets/src/mage/cards/f/FlashFoliage.java b/Mage.Sets/src/mage/cards/f/FlashFoliage.java new file mode 100644 index 00000000000..2460dffc863 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FlashFoliage.java @@ -0,0 +1,101 @@ +package mage.cards.f; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.condition.common.AfterBlockersAreDeclaredCondition; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TurnPhase; +import mage.game.Game; +import mage.game.combat.CombatGroup; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.SaprolingToken; +import mage.game.permanent.token.Token; +import mage.players.Player; +import mage.target.common.FilterCreatureAttackingYou; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author noahg + */ +public final class FlashFoliage extends CardImpl { + + public FlashFoliage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); + + + // Cast Flash Foliage only during combat after blockers are declared. + this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(TurnPhase.COMBAT, AfterBlockersAreDeclaredCondition.instance)); + + // Create a 1/1 green Saproling creature token that’s blocking target creature attacking you. + this.getSpellAbility().addEffect(new FlashFoliageEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreatureAttackingYou())); + + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + } + + public FlashFoliage(final FlashFoliage card) { + super(card); + } + + @Override + public FlashFoliage copy() { + return new FlashFoliage(this); + } +} + +class FlashFoliageEffect extends OneShotEffect { + + public FlashFoliageEffect() { + super(Outcome.Benefit); + this.staticText = "create a 1/1 green Saproling creature token that’s blocking target creature attacking you"; + } + + public FlashFoliageEffect(final FlashFoliageEffect effect) { + super(effect); + } + + @Override + public FlashFoliageEffect copy() { + return new FlashFoliageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + + if (controller != null) { + Token token = new SaprolingToken(); + token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId()); + Permanent attackingCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (attackingCreature != null && game.getState().getCombat() != null) { + // Possible ruling (see Aetherplasm) + // The token you created is blocking the attacking creature, + // even if the block couldn't legally be declared (for example, if that creature + // enters the battlefield tapped, or it can't block, or the attacking creature + // has protection from it) + CombatGroup combatGroup = game.getState().getCombat().findGroup(attackingCreature.getId()); + if (combatGroup != null) { + for (UUID tokenId : token.getLastAddedTokenIds()) { + Permanent saprolingToken = game.getPermanent(tokenId); + if (saprolingToken != null) { + combatGroup.addBlocker(tokenId, source.getControllerId(), game); + game.getCombat().addBlockingGroup(tokenId, attackingCreature.getId(), controller.getId(), game); + } + } + combatGroup.pickBlockerOrder(attackingCreature.getControllerId(), game); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/f/FlayerOfTheHatebound.java b/Mage.Sets/src/mage/cards/f/FlayerOfTheHatebound.java index 768c7fb74c9..b51a555a73a 100644 --- a/Mage.Sets/src/mage/cards/f/FlayerOfTheHatebound.java +++ b/Mage.Sets/src/mage/cards/f/FlayerOfTheHatebound.java @@ -72,7 +72,7 @@ class FlayerTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (((EntersTheBattlefieldEvent) event).getFromZone() == Zone.GRAVEYARD - && permanent.getOwnerId().equals(controllerId) + && permanent.isOwnedBy(controllerId) && permanent.isCreature()) { Effect effect = this.getEffects().get(0); effect.setValue("damageSource", event.getTargetId()); diff --git a/Mage.Sets/src/mage/cards/f/Flickerform.java b/Mage.Sets/src/mage/cards/f/Flickerform.java index 042640a62dc..550ae27ce61 100644 --- a/Mage.Sets/src/mage/cards/f/Flickerform.java +++ b/Mage.Sets/src/mage/cards/f/Flickerform.java @@ -182,7 +182,7 @@ class FlickerformReturnEffect extends OneShotEffect { if (!toBattlefieldAttached.isEmpty()) { controller.moveCards(toBattlefieldAttached, Zone.BATTLEFIELD, source, game); for (Card card : toBattlefieldAttached) { - if (game.getState().getZone(card.getId()).equals(Zone.BATTLEFIELD)) { + if (game.getState().getZone(card.getId()) == Zone.BATTLEFIELD) { newPermanent.addAttachment(card.getId(), game); } } diff --git a/Mage.Sets/src/mage/cards/f/Fluctuator.java b/Mage.Sets/src/mage/cards/f/Fluctuator.java index db73ce83db4..7554bb482b8 100644 --- a/Mage.Sets/src/mage/cards/f/Fluctuator.java +++ b/Mage.Sets/src/mage/cards/f/Fluctuator.java @@ -43,7 +43,7 @@ public final class Fluctuator extends CardImpl { class FluctuatorEffect extends CostModificationEffectImpl { - private static final String effectText = "Cycling abilities you activate cost you up to {2} less to activate"; + private static final String effectText = "Cycling abilities you activate cost up to {2} less to activate"; public FluctuatorEffect() { super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST); @@ -56,7 +56,7 @@ class FluctuatorEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { - return abilityToModify.getControllerId().equals(source.getControllerId()) + return abilityToModify.isControlledBy(source.getControllerId()) && (abilityToModify instanceof CyclingAbility); } diff --git a/Mage.Sets/src/mage/cards/f/FoeRazerRegent.java b/Mage.Sets/src/mage/cards/f/FoeRazerRegent.java index 08619da0bd7..b66dd9c48a5 100644 --- a/Mage.Sets/src/mage/cards/f/FoeRazerRegent.java +++ b/Mage.Sets/src/mage/cards/f/FoeRazerRegent.java @@ -91,7 +91,7 @@ class FoeRazerRegentTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (permanent != null && permanent.getControllerId().equals(getControllerId())) { + if (permanent != null && permanent.isControlledBy(getControllerId())) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(permanent, game)); } diff --git a/Mage.Sets/src/mage/cards/f/ForbiddenCrypt.java b/Mage.Sets/src/mage/cards/f/ForbiddenCrypt.java index 97f42256d0c..06678f2232e 100644 --- a/Mage.Sets/src/mage/cards/f/ForbiddenCrypt.java +++ b/Mage.Sets/src/mage/cards/f/ForbiddenCrypt.java @@ -149,7 +149,7 @@ class ForbiddenCryptPutIntoYourGraveyardReplacementEffect extends ReplacementEff public boolean applies(GameEvent event, Ability source, Game game) { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD) { Card card = game.getCard(event.getTargetId()); - if (card != null && card.getOwnerId().equals(source.getControllerId())) { + if (card != null && card.isOwnedBy(source.getControllerId())) { Permanent permanent = ((ZoneChangeEvent) event).getTarget(); if (permanent == null || !(permanent instanceof PermanentToken)) { return true; diff --git a/Mage.Sets/src/mage/cards/f/FracturedLoyalty.java b/Mage.Sets/src/mage/cards/f/FracturedLoyalty.java index 27e81fe492a..260c148e634 100644 --- a/Mage.Sets/src/mage/cards/f/FracturedLoyalty.java +++ b/Mage.Sets/src/mage/cards/f/FracturedLoyalty.java @@ -71,7 +71,7 @@ public final class FracturedLoyalty extends CardImpl { if (enchantedCreature != null) { Player controller = game.getPlayer(enchantedCreature.getControllerId()); if (enchantment.getAttachedTo() != null) { - if (controller != null && !enchantedCreature.getControllerId().equals(this.getTargetPointer().getFirst(game, source))) { + if (controller != null && !enchantedCreature.isControlledBy(this.getTargetPointer().getFirst(game, source))) { ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, this.getTargetPointer().getFirst(game, source)); effect.setTargetPointer(new FixedTarget(enchantment.getAttachedTo())); game.addEffect(effect, source); diff --git a/Mage.Sets/src/mage/cards/g/GabrielAngelfire.java b/Mage.Sets/src/mage/cards/g/GabrielAngelfire.java index 83a1c2357b4..a820735811a 100644 --- a/Mage.Sets/src/mage/cards/g/GabrielAngelfire.java +++ b/Mage.Sets/src/mage/cards/g/GabrielAngelfire.java @@ -77,7 +77,7 @@ class GabrielAngelfireGainAbilityEffect extends GainAbilitySourceEffect { @Override public boolean isInactive(Ability source, Game game) { if (game.getPhase().getStep().getType() == PhaseStep.UPKEEP) { - if (!sameStep && game.getActivePlayerId().equals(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) { + if (!sameStep && game.isActivePlayer(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) { return true; } } else { diff --git a/Mage.Sets/src/mage/cards/g/GarnaTheBloodflame.java b/Mage.Sets/src/mage/cards/g/GarnaTheBloodflame.java index fac88ce9315..74585b1ffe8 100644 --- a/Mage.Sets/src/mage/cards/g/GarnaTheBloodflame.java +++ b/Mage.Sets/src/mage/cards/g/GarnaTheBloodflame.java @@ -85,7 +85,7 @@ class GarnaTheBloodflameEffect extends OneShotEffect { Set toHand = new HashSet<>(); for (UUID cardId : watcher.getCardsPutToGraveyardThisTurn()) { Card card = game.getCard(cardId); - if (card != null && card.getOwnerId().equals(source.getControllerId()) && game.getState().getZone(cardId) == Zone.GRAVEYARD) { + if (card != null && card.isOwnedBy(source.getControllerId()) && game.getState().getZone(cardId) == Zone.GRAVEYARD) { toHand.add(card); } } @@ -119,7 +119,7 @@ class GarnaTheBloodflameWatcher extends Watcher { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).getToZone().equals(Zone.GRAVEYARD)) { + if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD) { Card card = game.getCard(event.getTargetId()); if (card != null && card.isCreature()) { cards.add(event.getTargetId()); diff --git a/Mage.Sets/src/mage/cards/g/GauntletOfPower.java b/Mage.Sets/src/mage/cards/g/GauntletOfPower.java index 62d0bb6eae7..9d14044b086 100644 --- a/Mage.Sets/src/mage/cards/g/GauntletOfPower.java +++ b/Mage.Sets/src/mage/cards/g/GauntletOfPower.java @@ -1,4 +1,3 @@ - package mage.cards.g; import java.util.UUID; @@ -164,7 +163,8 @@ class TapForManaAllTriggeredAbility extends TriggeredManaAbility { @Override public String getRule() { - return "Whenever " + filter.getMessage() + " for mana, " + super.getRule(); + return "Whenever a basic land is tapped for mana of the chosen color, " + + "its controller adds an additional one mana of that color."; } } @@ -172,7 +172,7 @@ class GauntletOfPowerEffectEffect2 extends ManaEffect { public GauntletOfPowerEffectEffect2() { super(); - staticText = "its controller adds one mana of that color"; + staticText = "its controller adds one additional mana of that color"; } public GauntletOfPowerEffectEffect2(final GauntletOfPowerEffectEffect2 effect) { diff --git a/Mage.Sets/src/mage/cards/g/GenerousPatron.java b/Mage.Sets/src/mage/cards/g/GenerousPatron.java index 87cefacb22e..ccbfaa40354 100644 --- a/Mage.Sets/src/mage/cards/g/GenerousPatron.java +++ b/Mage.Sets/src/mage/cards/g/GenerousPatron.java @@ -62,7 +62,7 @@ class GenerousPatronTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (!getControllerId().equals(game.getControllerId(event.getSourceId()))) { + if (!isControlledBy(game.getControllerId(event.getSourceId()))) { return false; } Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); @@ -71,7 +71,7 @@ class GenerousPatronTriggeredAbility extends TriggeredAbilityImpl { } return permanent != null && permanent.isCreature() - && !permanent.getControllerId().equals(getControllerId()); + && !permanent.isControlledBy(getControllerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/g/GiantAlbatross.java b/Mage.Sets/src/mage/cards/g/GiantAlbatross.java new file mode 100644 index 00000000000..d2c05f3e8cd --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GiantAlbatross.java @@ -0,0 +1,101 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +import java.util.List; +import java.util.UUID; + +/** + * + * @author noahg + */ +public final class GiantAlbatross extends CardImpl { + + public GiantAlbatross(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.BIRD); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Giant Albatross dies, you may pay {1}{U}. If you do, for each creature that dealt damage to Giant Albatross this turn, destroy that creature unless its controller pays 2 life. A creature destroyed this way can't be regenerated. + Ability ability = new DiesTriggeredAbility(new DoIfCostPaid(new GiantAlbatrossEffect(), new ManaCostsImpl("{1}{U}"))); + this.addAbility(ability); + } + + public GiantAlbatross(final GiantAlbatross card) { + super(card); + } + + @Override + public GiantAlbatross copy() { + return new GiantAlbatross(this); + } +} + +class GiantAlbatrossEffect extends OneShotEffect { + + public GiantAlbatrossEffect() { + super(Outcome.Detriment); + this.staticText = "for each creature that dealt damage to {this} this turn, destroy that creature unless its controller pays 2 life. A creature destroyed this way can’t be regenerated"; + } + + public GiantAlbatrossEffect(final GiantAlbatrossEffect effect) { + super(effect); + } + + @Override + public GiantAlbatrossEffect copy() { + return new GiantAlbatrossEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (sourcePermanent != null) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + List creatures = game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game); + + Cost cost = new PayLifeCost(2); + for (Permanent creature : creatures) { + if (sourcePermanent.getDealtDamageByThisTurn().contains(new MageObjectReference(creature.getId(), game))) { + final StringBuilder sb = new StringBuilder("Pay 2 life? (Otherwise ").append(creature.getName()).append(" will be destroyed)"); + if (cost.canPay(source, creature.getControllerId(), creature.getControllerId(), game) && player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { + cost.pay(source, game, creature.getControllerId(), creature.getControllerId(), true, null); + } + if (!cost.isPaid()) { + creature.destroy(source.getSourceId(), game, true); + } + } + } + } + } + } + + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GiantOyster.java b/Mage.Sets/src/mage/cards/g/GiantOyster.java new file mode 100644 index 00000000000..05617d00dca --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GiantOyster.java @@ -0,0 +1,164 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SkipUntapOptionalAbility; +import mage.abilities.common.delayed.AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DontUntapAsLongAsSourceTappedEffect; +import mage.abilities.effects.common.RemoveDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.effects.common.counter.RemoveAllCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * + * @author noahg + */ +public final class GiantOyster extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("tapped creature"); + + static { + filter.add(new TappedPredicate()); + } + + public GiantOyster(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); + + this.subtype.add(SubType.OYSTER); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // You may choose not to untap Giant Oyster during your untap step. + this.addAbility(new SkipUntapOptionalAbility()); + + // {tap}: For as long as Giant Oyster remains tapped, target tapped creature doesn't untap during its controller's untap step, and at the beginning of each of your draw steps, put a -1/-1 counter on that creature. When Giant Oyster leaves the battlefield or becomes untapped, remove all -1/-1 counters from the creature. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GiantOysterDontUntapAsLongAsSourceTappedEffect(), new TapSourceCost()); + ability.addEffect(new GiantOysterCreateDelayedTriggerEffects()); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public GiantOyster(final GiantOyster card) { + super(card); + } + + @Override + public GiantOyster copy() { + return new GiantOyster(this); + } +} + +class GiantOysterDontUntapAsLongAsSourceTappedEffect extends DontUntapAsLongAsSourceTappedEffect { + + public GiantOysterDontUntapAsLongAsSourceTappedEffect() { + super(); + staticText = "For as long as {source} remains tapped, target tapped creature doesn't untap during its controller's untap step"; + } + + public GiantOysterDontUntapAsLongAsSourceTappedEffect(final GiantOysterDontUntapAsLongAsSourceTappedEffect effect) { + super(effect); + } + + @Override + public GiantOysterDontUntapAsLongAsSourceTappedEffect copy() { + return new GiantOysterDontUntapAsLongAsSourceTappedEffect(this); + } +} + +class GiantOysterCreateDelayedTriggerEffects extends OneShotEffect { + + public GiantOysterCreateDelayedTriggerEffects() { + super(Outcome.Detriment); + this.staticText = "at the beginning of each of your draw steps, put a -1/-1 counter on that creature. When {this} leaves the battlefield or becomes untapped, remove all -1/-1 counters from the creature."; + } + + public GiantOysterCreateDelayedTriggerEffects(final GiantOysterCreateDelayedTriggerEffects effect) { + super(effect); + } + + @Override + public GiantOysterCreateDelayedTriggerEffects copy() { + return new GiantOysterCreateDelayedTriggerEffects(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent oyster = game.getPermanent(source.getSourceId()); + Permanent tappedCreature = game.getPermanent(source.getFirstTarget()); + if (oyster != null && tappedCreature != null) { + Effect addCountersEffect = new AddCountersTargetEffect(CounterType.M1M1.createInstance(1)); + addCountersEffect.setTargetPointer(getTargetPointer().getFixedTarget(game, source)); + DelayedTriggeredAbility drawStepAbility = new AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility(addCountersEffect, Duration.Custom, false); + drawStepAbility.setSourceObject(oyster, game); + drawStepAbility.setControllerId(source.getControllerId()); + UUID drawStepAbilityUUID = game.addDelayedTriggeredAbility(drawStepAbility, source); + + DelayedTriggeredAbility leaveUntapDelayedTriggeredAbility = new GiantOysterLeaveUntapDelayedTriggeredAbility(drawStepAbilityUUID); + leaveUntapDelayedTriggeredAbility.getEffects().get(0).setTargetPointer(new FixedTarget(tappedCreature, game)); + game.addDelayedTriggeredAbility(leaveUntapDelayedTriggeredAbility, source); + return true; + } + } + return false; + } +} + +class GiantOysterLeaveUntapDelayedTriggeredAbility extends DelayedTriggeredAbility { + + public GiantOysterLeaveUntapDelayedTriggeredAbility(UUID abilityToCancel) { + super(new RemoveAllCountersTargetEffect(CounterType.M1M1), Duration.EndOfGame, true, false); + this.addEffect(new RemoveDelayedTriggeredAbilityEffect(abilityToCancel)); + } + + public GiantOysterLeaveUntapDelayedTriggeredAbility(GiantOysterLeaveUntapDelayedTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType().equals(GameEvent.EventType.UNTAPPED) || event.getType().equals(GameEvent.EventType.ZONE_CHANGE); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType().equals(GameEvent.EventType.UNTAPPED) && event.getTargetId() != null + && event.getTargetId().equals(getSourceId())) { + System.out.println("Untapped"); + return true; + } + return event.getType().equals(GameEvent.EventType.ZONE_CHANGE) && event.getTargetId() != null + && event.getTargetId().equals(getSourceId()) && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD; + } + + @Override + public GiantOysterLeaveUntapDelayedTriggeredAbility copy() { + return new GiantOysterLeaveUntapDelayedTriggeredAbility(this); + } + + @Override + public String getRule() { + return "When {this} leaves the battlefield or becomes untapped, remove all -1/-1 counters from the creature."; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GideonBattleForged.java b/Mage.Sets/src/mage/cards/g/GideonBattleForged.java index 9971f9973de..95072064241 100644 --- a/Mage.Sets/src/mage/cards/g/GideonBattleForged.java +++ b/Mage.Sets/src/mage/cards/g/GideonBattleForged.java @@ -138,7 +138,7 @@ class GideonBattleForgedAttacksIfAbleTargetEffect extends RequirementEffect { if (targetPermanent == null) { return true; } - if (nextTurnTargetController == 0 && startingTurn != game.getTurnNum() && game.getActivePlayerId().equals(targetPermanent.getControllerId())) { + if (nextTurnTargetController == 0 && startingTurn != game.getTurnNum() && game.isActivePlayer(targetPermanent.getControllerId())) { nextTurnTargetController = game.getTurnNum(); } return game.getPhase().getType() == TurnPhase.END && nextTurnTargetController > 0 && game.getTurnNum() > nextTurnTargetController; @@ -157,7 +157,7 @@ class GideonBattleForgedAttacksIfAbleTargetEffect extends RequirementEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { if (permanent.getId().equals(getTargetPointer().getFirst(game, source))) { - if (game.getActivePlayerId().equals(permanent.getControllerId())) { + if (game.isActivePlayer(permanent.getControllerId())) { Permanent planeswalker = game.getPermanent(source.getSourceId()); if (planeswalker != null) { return true; diff --git a/Mage.Sets/src/mage/cards/g/GideonJura.java b/Mage.Sets/src/mage/cards/g/GideonJura.java index 1e1c44adabc..d4890e31143 100644 --- a/Mage.Sets/src/mage/cards/g/GideonJura.java +++ b/Mage.Sets/src/mage/cards/g/GideonJura.java @@ -122,14 +122,14 @@ class GideonJuraEffect extends RequirementEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { - return permanent.getControllerId().equals(source.getFirstTarget()); + return permanent.isControlledBy(source.getFirstTarget()); } @Override public boolean isInactive(Ability source, Game game) { return (startingTurn != game.getTurnNum() && (game.getPhase().getType() == TurnPhase.END - && game.getActivePlayerId().equals(source.getFirstTarget()))) + && game.isActivePlayer(source.getFirstTarget()))) || // 6/15/2010: If a creature controlled by the affected player can't attack Gideon Jura (because he's no longer on the battlefield, for example), that player may have it attack you, another one of your planeswalkers, or nothing at all. creatingPermanent.getPermanent(game) == null; } diff --git a/Mage.Sets/src/mage/cards/g/GideonsIntervention.java b/Mage.Sets/src/mage/cards/g/GideonsIntervention.java index 1c6d51538f1..91e539b291e 100644 --- a/Mage.Sets/src/mage/cards/g/GideonsIntervention.java +++ b/Mage.Sets/src/mage/cards/g/GideonsIntervention.java @@ -139,7 +139,7 @@ class GideonsInterventionPreventAllDamageEffect extends PreventionEffectImpl { || event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER))) { if (object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY)) && (event.getTargetId().equals(source.getControllerId()) - || targetPerm != null && targetPerm.getControllerId().equals(source.getControllerId()))) { + || targetPerm != null && targetPerm.isControlledBy(source.getControllerId()))) { return super.applies(event, source, game); } } diff --git a/Mage.Sets/src/mage/cards/g/GiftofGrowth.java b/Mage.Sets/src/mage/cards/g/GiftOfGrowth.java similarity index 84% rename from Mage.Sets/src/mage/cards/g/GiftofGrowth.java rename to Mage.Sets/src/mage/cards/g/GiftOfGrowth.java index 0dedf15bd09..2e599b32362 100644 --- a/Mage.Sets/src/mage/cards/g/GiftofGrowth.java +++ b/Mage.Sets/src/mage/cards/g/GiftOfGrowth.java @@ -4,7 +4,6 @@ package mage.cards.g; import mage.abilities.condition.LockedInCondition; import mage.abilities.condition.common.KickedCondition; import mage.abilities.decorator.ConditionalContinuousEffect; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.keyword.KickerAbility; @@ -20,9 +19,9 @@ import java.util.UUID; * * @author rscoates */ -public final class GiftofGrowth extends CardImpl { +public final class GiftOfGrowth extends CardImpl { - public GiftofGrowth(UUID ownerId, CardSetInfo setInfo) { + public GiftOfGrowth(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}"); // Kicker {2} @@ -36,12 +35,12 @@ public final class GiftofGrowth extends CardImpl { "It gets +2/+2 until end of turn. If this spell was kicked, that creature gets +4/+4 until end of turn instead.")); } - public GiftofGrowth(final GiftofGrowth card) { + public GiftOfGrowth(final GiftOfGrowth card) { super(card); } @Override - public GiftofGrowth copy() { - return new GiftofGrowth(this); + public GiftOfGrowth copy() { + return new GiftOfGrowth(this); } } diff --git a/Mage.Sets/src/mage/cards/g/GisaAndGeralf.java b/Mage.Sets/src/mage/cards/g/GisaAndGeralf.java index c88f1150fe2..66e7d23cbd8 100644 --- a/Mage.Sets/src/mage/cards/g/GisaAndGeralf.java +++ b/Mage.Sets/src/mage/cards/g/GisaAndGeralf.java @@ -81,7 +81,7 @@ class GisaAndGeralfContinuousEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - if (!game.getActivePlayerId().equals(player.getId())) { + if (!game.isActivePlayer(player.getId())) { return false; } for (Card card : player.getGraveyard().getCards(filter, game)) { diff --git a/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java b/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java index 29578aca461..79dd93dfd96 100644 --- a/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java +++ b/Mage.Sets/src/mage/cards/g/GiselaBladeOfGoldnight.java @@ -106,7 +106,7 @@ class GiselaBladeOfGoldnightDoubleDamageEffect extends ReplacementEffectImpl { case DAMAGE_PLANESWALKER: Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null) { - if (permanent.getControllerId().equals(source.getControllerId())) { + if (permanent.isControlledBy(source.getControllerId())) { preventDamage(event, source, permanent.getId(), game); } else if (game.getOpponents(source.getControllerId()).contains(permanent.getControllerId())) { event.setAmount(CardUtil.addWithOverflowCheck(event.getAmount(), event.getAmount())); diff --git a/Mage.Sets/src/mage/cards/g/GladehartCavalry.java b/Mage.Sets/src/mage/cards/g/GladehartCavalry.java index 08a97e5be10..df612eb6e01 100644 --- a/Mage.Sets/src/mage/cards/g/GladehartCavalry.java +++ b/Mage.Sets/src/mage/cards/g/GladehartCavalry.java @@ -74,7 +74,7 @@ class GladehartCavalryTriggeredAbility extends TriggeredAbilityImpl { && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); if (permanent != null - && permanent.getControllerId().equals(this.getControllerId()) + && permanent.isControlledBy(this.getControllerId()) && permanent.isCreature() && permanent.getCounters(game).getCount(CounterType.P1P1) > 0) { return true; diff --git a/Mage.Sets/src/mage/cards/g/Gleancrawler.java b/Mage.Sets/src/mage/cards/g/Gleancrawler.java index 648dc92902e..9b183e132c5 100644 --- a/Mage.Sets/src/mage/cards/g/Gleancrawler.java +++ b/Mage.Sets/src/mage/cards/g/Gleancrawler.java @@ -82,7 +82,7 @@ class GleancrawlerEffect extends OneShotEffect { if (game.getState().getZoneChangeCounter(mor.getSourceId()) == mor.getZoneChangeCounter()) { Card card = game.getCard(mor.getSourceId()); if (card != null && card.isCreature() - && card.getOwnerId().equals(source.getControllerId())) { + && card.isOwnedBy(source.getControllerId())) { cardsToHand.add(card); } } diff --git a/Mage.Sets/src/mage/cards/g/GoblinRockSled.java b/Mage.Sets/src/mage/cards/g/GoblinRockSled.java index 15bc0cb8b6f..fa2d9fd3782 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinRockSled.java +++ b/Mage.Sets/src/mage/cards/g/GoblinRockSled.java @@ -95,7 +95,7 @@ class DontUntapIfAttackedLastTurnSourceEffect extends ContinuousRuleModifyingEff if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getTargetId().equals(source.getSourceId())) { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null && permanent.getControllerId().equals(game.getActivePlayerId())) { + if (permanent != null && permanent.isControlledBy(game.getActivePlayerId())) { AttackedLastTurnWatcher watcher = (AttackedLastTurnWatcher) game.getState().getWatchers().get(AttackedLastTurnWatcher.class.getSimpleName()); if (watcher != null) { Set attackingCreatures = watcher.getAttackedLastTurnCreatures(permanent.getControllerId()); diff --git a/Mage.Sets/src/mage/cards/g/GoblinWarCry.java b/Mage.Sets/src/mage/cards/g/GoblinWarCry.java index f1e4518365b..d4479c84759 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinWarCry.java +++ b/Mage.Sets/src/mage/cards/g/GoblinWarCry.java @@ -103,7 +103,7 @@ class GoblinWarCryRestrictionEffect extends RestrictionEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { - if (permanent.getControllerId().equals(source.getFirstTarget())) { + if (permanent.isControlledBy(source.getFirstTarget())) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/g/GoblinWelder.java b/Mage.Sets/src/mage/cards/g/GoblinWelder.java index a5eaa4a6b79..8df331165b3 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinWelder.java +++ b/Mage.Sets/src/mage/cards/g/GoblinWelder.java @@ -75,7 +75,7 @@ public final class GoblinWelder extends CardImpl { && artifact.isArtifact() && card.isArtifact() && currentZone == Zone.GRAVEYARD - && card.getOwnerId().equals(artifact.getControllerId())) { + && card.isOwnedBy(artifact.getControllerId())) { boolean sacrifice = artifact.sacrifice(source.getSourceId(), game); boolean putOnBF = owner.moveCards(card, Zone.BATTLEFIELD, source, game); if (sacrifice || putOnBF) { diff --git a/Mage.Sets/src/mage/cards/g/GrandAbolisher.java b/Mage.Sets/src/mage/cards/g/GrandAbolisher.java index 2f557aaace5..e9c05daf965 100644 --- a/Mage.Sets/src/mage/cards/g/GrandAbolisher.java +++ b/Mage.Sets/src/mage/cards/g/GrandAbolisher.java @@ -85,7 +85,7 @@ class GrandAbolisherEffect extends ContinuousRuleModifyingEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (game.getActivePlayerId().equals(source.getControllerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { + if (game.isActivePlayer(source.getControllerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { switch(event.getType()) { case CAST_SPELL: return true; diff --git a/Mage.Sets/src/mage/cards/g/GrandWarlordRadha.java b/Mage.Sets/src/mage/cards/g/GrandWarlordRadha.java index 0a426b135cd..508844bc913 100644 --- a/Mage.Sets/src/mage/cards/g/GrandWarlordRadha.java +++ b/Mage.Sets/src/mage/cards/g/GrandWarlordRadha.java @@ -120,7 +120,7 @@ class GrandWarlordRadhaTriggeredAbility extends TriggeredAbilityImpl { Permanent creature = game.getPermanent(attacker); if (creature != null && creature.getControllerId() != null - && creature.getControllerId().equals(this.getControllerId())) { + && creature.isControlledBy(this.getControllerId())) { return true; } } @@ -157,7 +157,7 @@ class GrandWarlordRadhaEffect extends OneShotEffect { if (watcher != null) { int attackingCreatures = 0; for (MageObjectReference attacker : watcher.getAttackedThisTurnCreatures()) { - if (attacker.getPermanentOrLKIBattlefield(game).getControllerId().equals(controller.getId())) { + if (attacker.getPermanentOrLKIBattlefield(game).isControlledBy(controller.getId())) { attackingCreatures++; } } diff --git a/Mage.Sets/src/mage/cards/g/GratuitousViolence.java b/Mage.Sets/src/mage/cards/g/GratuitousViolence.java index 216a6ac5920..b345c48d223 100644 --- a/Mage.Sets/src/mage/cards/g/GratuitousViolence.java +++ b/Mage.Sets/src/mage/cards/g/GratuitousViolence.java @@ -72,7 +72,7 @@ class GratuitousViolenceReplacementEffect extends ReplacementEffectImpl { Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); return permanent != null && permanent.isCreature() - && permanent.getControllerId().equals(source.getControllerId()); + && permanent.isControlledBy(source.getControllerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/g/GraveBetrayal.java b/Mage.Sets/src/mage/cards/g/GraveBetrayal.java index 3fdc4bd5e8f..888925283e9 100644 --- a/Mage.Sets/src/mage/cards/g/GraveBetrayal.java +++ b/Mage.Sets/src/mage/cards/g/GraveBetrayal.java @@ -75,7 +75,7 @@ class GraveBetrayalTriggeredAbility extends TriggeredAbilityImpl { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent != null && !permanent.getControllerId().equals(this.getControllerId()) && permanent.isCreature()) { + if (permanent != null && !permanent.isControlledBy(this.getControllerId()) && permanent.isCreature()) { Card card = (Card) game.getObject(permanent.getId()); if (card != null) { Effect effect = new GraveBetrayalEffect(); diff --git a/Mage.Sets/src/mage/cards/g/GravePact.java b/Mage.Sets/src/mage/cards/g/GravePact.java index 8898367c9ba..c2dd2f4ee53 100644 --- a/Mage.Sets/src/mage/cards/g/GravePact.java +++ b/Mage.Sets/src/mage/cards/g/GravePact.java @@ -69,7 +69,7 @@ class GravePactTriggeredAbility extends TriggeredAbilityImpl { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent.getControllerId().equals(this.getControllerId()) && permanent.isCreature()) { + if (permanent.isControlledBy(this.getControllerId()) && permanent.isCreature()) { return true; } } diff --git a/Mage.Sets/src/mage/cards/g/Gravecrawler.java b/Mage.Sets/src/mage/cards/g/Gravecrawler.java index dd5154a31f9..6c119740d8c 100644 --- a/Mage.Sets/src/mage/cards/g/Gravecrawler.java +++ b/Mage.Sets/src/mage/cards/g/Gravecrawler.java @@ -75,7 +75,7 @@ class GravecrawlerPlayEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - if (sourceId.equals(source.getSourceId()) && source.getControllerId().equals(affectedControllerId)) { + if (sourceId.equals(source.getSourceId()) && source.isControlledBy(affectedControllerId)) { Card card = game.getCard(source.getSourceId()); if (card != null && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { if (game.getBattlefield().countAll(filter, source.getControllerId(), game) > 0) { diff --git a/Mage.Sets/src/mage/cards/g/GreatbowDoyen.java b/Mage.Sets/src/mage/cards/g/GreatbowDoyen.java index d5906391550..0323b7d343a 100644 --- a/Mage.Sets/src/mage/cards/g/GreatbowDoyen.java +++ b/Mage.Sets/src/mage/cards/g/GreatbowDoyen.java @@ -86,7 +86,7 @@ class GreatbowDoyenTriggeredAbility extends TriggeredAbilityImpl { if (creature != null && damagedCreature != null && creature.isCreature() && creature.hasSubtype(SubType.ARCHER, game) - && creature.getControllerId().equals(controllerId)) { + && creature.isControlledBy(controllerId)) { this.getEffects().get(0).setValue("damageAmount", event.getAmount()); this.getEffects().get(0).setValue("controller", damagedCreature.getControllerId()); this.getEffects().get(0).setValue("source", event.getSourceId()); diff --git a/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java b/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java index 674ef59bdd7..f4167607445 100644 --- a/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java +++ b/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java @@ -101,7 +101,7 @@ class GrenzoHavocRaiserTriggeredAbility extends TriggeredAbilityImpl { Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); if (damagedPlayer != null && permanent != null && ((DamagedEvent) event).isCombatDamage() - && getControllerId().equals(permanent.getControllerId())) { + && isControlledBy(permanent.getControllerId())) { FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + damagedPlayer.getLogName() + " controls"); filter.add(new ControllerIdPredicate(damagedPlayer.getId())); this.getTargets().clear(); @@ -198,7 +198,7 @@ class GrenzoHavocRaiserCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - if (sourceId.equals(cardId) && source.getControllerId().equals(affectedControllerId)) { + if (sourceId.equals(cardId) && source.isControlledBy(affectedControllerId)) { ExileZone exileZone = game.getState().getExile().getExileZone(exileId); return exileZone != null && exileZone.contains(cardId); } @@ -229,7 +229,7 @@ class GrenzoHavocRaiserSpendAnyManaEffect extends AsThoughEffectImpl implements @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) && (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)) diff --git a/Mage.Sets/src/mage/cards/g/GrinningTotem.java b/Mage.Sets/src/mage/cards/g/GrinningTotem.java index 37016ec834e..b2fa96eebfe 100644 --- a/Mage.Sets/src/mage/cards/g/GrinningTotem.java +++ b/Mage.Sets/src/mage/cards/g/GrinningTotem.java @@ -124,7 +124,7 @@ class GrinningTotemMayPlayEffect extends AsThoughEffectImpl { @Override public boolean isInactive(Ability source, Game game) { if (game.getPhase().getStep().getType() == PhaseStep.UPKEEP) { - if (!sameStep && game.getActivePlayerId().equals(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) { + if (!sameStep && game.isActivePlayer(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) { return true; } } else { @@ -140,7 +140,7 @@ class GrinningTotemMayPlayEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && sourceId.equals(getTargetPointer().getFirst(game, source)); } @@ -178,7 +178,7 @@ class GrinningTotemDelayedTriggeredAbility extends DelayedTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - return game.getActivePlayerId().equals(this.getControllerId()); + return game.isActivePlayer(this.getControllerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/g/GroundPounder.java b/Mage.Sets/src/mage/cards/g/GroundPounder.java index db43efdee49..dcfcf17eb30 100644 --- a/Mage.Sets/src/mage/cards/g/GroundPounder.java +++ b/Mage.Sets/src/mage/cards/g/GroundPounder.java @@ -106,7 +106,7 @@ class GroundPounderTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (this.getControllerId().equals(event.getPlayerId()) && event.getFlag()) { + if (this.isControlledBy(event.getPlayerId()) && event.getFlag()) { if (event.getAmount() >= 5) { return true; } diff --git a/Mage.Sets/src/mage/cards/g/GruulRagebeast.java b/Mage.Sets/src/mage/cards/g/GruulRagebeast.java index f5da5a8ed24..7ac876b7ce1 100644 --- a/Mage.Sets/src/mage/cards/g/GruulRagebeast.java +++ b/Mage.Sets/src/mage/cards/g/GruulRagebeast.java @@ -83,7 +83,7 @@ class GruulRagebeastTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { UUID targetId = event.getTargetId(); Permanent permanent = game.getPermanent(targetId); - if (permanent.getControllerId().equals(this.controllerId) + if (permanent.isControlledBy(this.controllerId) && permanent.isCreature() && (targetId.equals(this.getSourceId()) || !targetId.equals(this.getSourceId()))) { diff --git a/Mage.Sets/src/mage/cards/g/GuardianOfTazeem.java b/Mage.Sets/src/mage/cards/g/GuardianOfTazeem.java index 2a8076d6693..a550fb2d671 100644 --- a/Mage.Sets/src/mage/cards/g/GuardianOfTazeem.java +++ b/Mage.Sets/src/mage/cards/g/GuardianOfTazeem.java @@ -85,7 +85,7 @@ class GuardianOfTazeemTriggeredAbility extends TriggeredAbilityImpl { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.isLand() - && permanent.getControllerId().equals(getControllerId())) { + && permanent.isControlledBy(getControllerId())) { for (Effect effect : getEffects()) { if (effect instanceof GuardianOfTazeemEffect) { effect.setTargetPointer(new FixedTarget(permanent, game)); diff --git a/Mage.Sets/src/mage/cards/g/Guile.java b/Mage.Sets/src/mage/cards/g/Guile.java index b30d1e541bc..c641c4df146 100644 --- a/Mage.Sets/src/mage/cards/g/Guile.java +++ b/Mage.Sets/src/mage/cards/g/Guile.java @@ -107,6 +107,6 @@ class GuileReplacementEffect extends ReplacementEffectImpl { StackObject counteringObject = game.getStack().getStackObject(event.getSourceId()); return counteredSpell != null && counteringObject != null - && counteringObject.getControllerId().equals(source.getControllerId()); + && counteringObject.isControlledBy(source.getControllerId()); } } diff --git a/Mage.Sets/src/mage/cards/g/GutterGrime.java b/Mage.Sets/src/mage/cards/g/GutterGrime.java index 19985966deb..28fa9508b39 100644 --- a/Mage.Sets/src/mage/cards/g/GutterGrime.java +++ b/Mage.Sets/src/mage/cards/g/GutterGrime.java @@ -73,7 +73,7 @@ class GutterGrimeTriggeredAbility extends TriggeredAbilityImpl { Permanent permanent = (Permanent) card; ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD - && permanent.getControllerId().equals(this.controllerId) + && permanent.isControlledBy(this.controllerId) && (targetId.equals(this.getSourceId()) || (permanent.isCreature() && !(permanent instanceof PermanentToken)))) { diff --git a/Mage.Sets/src/mage/cards/h/HaakonStromgaldScourge.java b/Mage.Sets/src/mage/cards/h/HaakonStromgaldScourge.java index bcf84ab249e..edba324a79d 100644 --- a/Mage.Sets/src/mage/cards/h/HaakonStromgaldScourge.java +++ b/Mage.Sets/src/mage/cards/h/HaakonStromgaldScourge.java @@ -156,7 +156,7 @@ class HaakonPlayKnightsFromGraveyardEffect extends AsThoughEffectImpl { Card knightToCast = game.getCard(objectId); if (knightToCast != null && knightToCast.hasSubtype(SubType.KNIGHT, game) - && knightToCast.getOwnerId().equals(source.getControllerId()) + && knightToCast.isOwnedBy(source.getControllerId()) && game.getState().getZone(objectId) == Zone.GRAVEYARD) { return true; } diff --git a/Mage.Sets/src/mage/cards/h/HakimLoreweaver.java b/Mage.Sets/src/mage/cards/h/HakimLoreweaver.java index 4b17ac32df6..ef9f925de72 100644 --- a/Mage.Sets/src/mage/cards/h/HakimLoreweaver.java +++ b/Mage.Sets/src/mage/cards/h/HakimLoreweaver.java @@ -145,7 +145,7 @@ class HakimLoreweaverCondition implements Condition { } } return PhaseStep.UPKEEP == game.getStep().getType() - && game.getActivePlayerId().equals(source.getControllerId()); + && game.isActivePlayer(source.getControllerId()); } return false; } diff --git a/Mage.Sets/src/mage/cards/h/HallarTheFirefletcher.java b/Mage.Sets/src/mage/cards/h/HallarTheFirefletcher.java index 7ca188563c3..8eb11c779ac 100644 --- a/Mage.Sets/src/mage/cards/h/HallarTheFirefletcher.java +++ b/Mage.Sets/src/mage/cards/h/HallarTheFirefletcher.java @@ -81,7 +81,7 @@ class HallarTheFirefletcherTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Spell spell = game.getStack().getSpell(event.getTargetId()); - if (spell != null && spell.getControllerId().equals(controllerId)) { + if (spell != null && spell.isControlledBy(controllerId)) { for (Ability ability : spell.getAbilities()) { if (ability instanceof KickerAbility && ((KickerAbility) ability).getKickedCounter(game, spell.getSpellAbility()) > 0) { return true; diff --git a/Mage.Sets/src/mage/cards/h/HardenedBerserker.java b/Mage.Sets/src/mage/cards/h/HardenedBerserker.java index 80804e74ae8..5793f80ee18 100644 --- a/Mage.Sets/src/mage/cards/h/HardenedBerserker.java +++ b/Mage.Sets/src/mage/cards/h/HardenedBerserker.java @@ -84,7 +84,7 @@ class HardenedBerserkerSpellsCostReductionEffect extends CostModificationEffectI } } if (abilityToModify instanceof SpellAbility) { - return abilityToModify.getControllerId().equals(source.getControllerId()); + return abilityToModify.isControlledBy(source.getControllerId()); } return false; } diff --git a/Mage.Sets/src/mage/cards/h/HardenedScales.java b/Mage.Sets/src/mage/cards/h/HardenedScales.java index 6e72fb04dc8..ce764544f94 100644 --- a/Mage.Sets/src/mage/cards/h/HardenedScales.java +++ b/Mage.Sets/src/mage/cards/h/HardenedScales.java @@ -73,7 +73,7 @@ class HardenedScalesEffect extends ReplacementEffectImpl { if (permanent == null) { permanent = game.getPermanentEntering(event.getTargetId()); } - if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) + if (permanent != null && permanent.isControlledBy(source.getControllerId()) && permanent.isCreature()) { return true; } diff --git a/Mage.Sets/src/mage/cards/h/HarmsWay.java b/Mage.Sets/src/mage/cards/h/HarmsWay.java index 3f0c5a544ea..a6df836e323 100644 --- a/Mage.Sets/src/mage/cards/h/HarmsWay.java +++ b/Mage.Sets/src/mage/cards/h/HarmsWay.java @@ -86,7 +86,7 @@ class HarmsWayPreventDamageTargetEffect extends RedirectionEffect { // check permanent first Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null) { - if (permanent.getControllerId().equals(source.getControllerId())) { + if (permanent.isControlledBy(source.getControllerId())) { // it's your permanent return true; } diff --git a/Mage.Sets/src/mage/cards/h/HavengulLich.java b/Mage.Sets/src/mage/cards/h/HavengulLich.java index b48b5bb0b65..8c1c4a4896e 100644 --- a/Mage.Sets/src/mage/cards/h/HavengulLich.java +++ b/Mage.Sets/src/mage/cards/h/HavengulLich.java @@ -91,7 +91,7 @@ class HavengulLichPlayEffect extends AsThoughEffectImpl { UUID targetId = getTargetPointer().getFirst(game, source); if (targetId != null) { return targetId.equals(objectId) - && source.getControllerId().equals(affectedControllerId) + && source.isControlledBy(affectedControllerId) && Zone.GRAVEYARD == game.getState().getZone(objectId); } else { // the target card has changed zone meanwhile, so the effect is no longer needed diff --git a/Mage.Sets/src/mage/cards/h/HeartWolf.java b/Mage.Sets/src/mage/cards/h/HeartWolf.java new file mode 100644 index 00000000000..7409660149e --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HeartWolf.java @@ -0,0 +1,106 @@ +package mage.cards.h; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.IsPhaseCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.ExileGraveyardAllTargetPlayerEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.constants.*; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.turn.Phase; +import mage.target.Target; +import mage.target.TargetPlayer; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author noahg + */ +public final class HeartWolf extends CardImpl { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new SubtypePredicate(SubType.DWARF)); + } + + public HeartWolf(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.WOLF); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // {tap}: Target Dwarf creature gets +2/+0 and gains first strike until end of turn. When that creature leaves the battlefield this turn, sacrifice Heart Wolf. Activate this ability only during combat. + Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(2, 0, Duration.EndOfTurn) + .setText("Target Dwarf creature gets +2/+0"), new TapSourceCost(), new IsPhaseCondition(TurnPhase.COMBAT)); + ability.addEffect(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), + Duration.EndOfTurn).setText("and gains first strike until end of turn")); + ability.addTarget(new TargetCreaturePermanent(filter)); + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new HeartWolfDelayedTriggeredAbility(), true)); + this.addAbility(ability); + } + + public HeartWolf(final HeartWolf card) { + super(card); + } + + @Override + public HeartWolf copy() { + return new HeartWolf(this); + } +} + +class HeartWolfDelayedTriggeredAbility extends DelayedTriggeredAbility { + + public HeartWolfDelayedTriggeredAbility() { + super(new SacrificeSourceEffect(), Duration.EndOfTurn, false); + } + + public HeartWolfDelayedTriggeredAbility(HeartWolfDelayedTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getTarget() != null && zEvent.getTargetId().equals(getTargets().getFirstTarget())) { + this.getTargets().clear(); // else spell fizzles because target creature died + return true; + } + return false; + } + + @Override + public HeartWolfDelayedTriggeredAbility copy() { + return new HeartWolfDelayedTriggeredAbility(this); + } + + @Override + public String getRule() { + return "When that creature leaves the battlefield this turn, sacrifice {this}."; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/h/HeartwoodDryad.java b/Mage.Sets/src/mage/cards/h/HeartwoodDryad.java index 3fe01db33eb..88c2bc0c894 100644 --- a/Mage.Sets/src/mage/cards/h/HeartwoodDryad.java +++ b/Mage.Sets/src/mage/cards/h/HeartwoodDryad.java @@ -6,6 +6,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.common.CanBlockAsThoughtItHadShadowEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AsThoughEffectType; @@ -29,7 +30,7 @@ public final class HeartwoodDryad extends CardImpl { this.toughness = new MageInt(1); // Heartwood Dryad can block creatures with shadow as though Heartwood Dryad had shadow. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockAsThoughtIthadShadowEffect(Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockAsThoughtItHadShadowEffect(Duration.WhileOnBattlefield))); } public HeartwoodDryad(final HeartwoodDryad card) { @@ -40,32 +41,4 @@ public final class HeartwoodDryad extends CardImpl { public HeartwoodDryad copy() { return new HeartwoodDryad(this); } -} - -class CanBlockAsThoughtIthadShadowEffect extends AsThoughEffectImpl { - - public CanBlockAsThoughtIthadShadowEffect(Duration duration) { - super(AsThoughEffectType.BLOCK_SHADOW, duration, Outcome.Benefit); - staticText = "{this} can block creatures with shadow as though {this} had shadow"; - } - - public CanBlockAsThoughtIthadShadowEffect(final CanBlockAsThoughtIthadShadowEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public CanBlockAsThoughtIthadShadowEffect copy() { - return new CanBlockAsThoughtIthadShadowEffect(this); - } - - @Override - public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - return sourceId.equals(source.getSourceId()); - } - } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/h/HeatStroke.java b/Mage.Sets/src/mage/cards/h/HeatStroke.java index e2b04db1869..130b465e313 100644 --- a/Mage.Sets/src/mage/cards/h/HeatStroke.java +++ b/Mage.Sets/src/mage/cards/h/HeatStroke.java @@ -1,35 +1,46 @@ package mage.cards.h; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.UUID; + +import mage.MageObjectReference; +import mage.abilities.Ability; import mage.abilities.common.EndOfCombatTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Outcome; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.BlockedPredicate; import mage.filter.predicate.permanent.BlockingPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.watchers.common.BlockedThisTurnWatcher; +import mage.watchers.common.WasBlockedThisTurnWatcher; /** * @author dustinroepsch */ public final class HeatStroke extends CardImpl { - private static final FilterPermanent filter = new FilterCreaturePermanent(); - - static { - filter.add(Predicates.or(new BlockedPredicate(), new BlockingPredicate())); - } - public HeatStroke(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); // At end of combat, destroy each creature that blocked or was blocked this turn. - this.addAbility(new EndOfCombatTriggeredAbility(new DestroyAllEffect(filter) - .setText("destroy each creature that blocked or was blocked this turn"), false)); + Ability ability = new EndOfCombatTriggeredAbility(new HeatStrokeEffect(), false); + ability.addWatcher(new BlockedThisTurnWatcher()); + ability.addWatcher(new WasBlockedThisTurnWatcher()); + this.addAbility(ability); } public HeatStroke(final HeatStroke card) { @@ -41,3 +52,45 @@ public final class HeatStroke extends CardImpl { return new HeatStroke(this); } } + +class HeatStrokeEffect extends OneShotEffect { + + public HeatStrokeEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "destroy each creature that blocked or was blocked this turn"; + } + + public HeatStrokeEffect(HeatStrokeEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + BlockedThisTurnWatcher blockedWatcher = (BlockedThisTurnWatcher) game.getState().getWatchers().get(BlockedThisTurnWatcher.class.getSimpleName()); + WasBlockedThisTurnWatcher wasBlockedThisTurnWatcher = (WasBlockedThisTurnWatcher) game.getState().getWatchers().get(WasBlockedThisTurnWatcher.class.getSimpleName()); + Set inROI = new HashSet<>(game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)); + boolean toRet = false; + Set toDestroy = new HashSet<>(); + + if (blockedWatcher != null){ + toDestroy.addAll(blockedWatcher.getBlockedThisTurnCreatures()); + } + if (wasBlockedThisTurnWatcher != null){ + toDestroy.addAll(wasBlockedThisTurnWatcher.getWasBlockedThisTurnCreatures()); + } + + for (MageObjectReference mor : toDestroy) { + Permanent permanent = mor.getPermanent(game); + if (permanent != null && permanent.isCreature() && inROI.contains(permanent)){ + permanent.destroy(source.getSourceId(), game, false); + toRet = true; + } + } + return toRet; + } + + @Override + public HeatStrokeEffect copy() { + return new HeatStrokeEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/h/HedronFieldPurists.java b/Mage.Sets/src/mage/cards/h/HedronFieldPurists.java index 602fc6d9b77..21d86be5120 100644 --- a/Mage.Sets/src/mage/cards/h/HedronFieldPurists.java +++ b/Mage.Sets/src/mage/cards/h/HedronFieldPurists.java @@ -90,7 +90,7 @@ class HedronFieldPuristsEffect extends PreventionEffectImpl { if (event.getType() == GameEvent.EventType.DAMAGE_CREATURE) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { + if (permanent != null && permanent.isControlledBy(source.getControllerId())) { return super.applies(event, source, game); } } diff --git a/Mage.Sets/src/mage/cards/h/Hellfire.java b/Mage.Sets/src/mage/cards/h/Hellfire.java index 3d7076eda0d..b12ebf4b684 100644 --- a/Mage.Sets/src/mage/cards/h/Hellfire.java +++ b/Mage.Sets/src/mage/cards/h/Hellfire.java @@ -66,7 +66,7 @@ class HellfireEffect extends OneShotEffect { filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); for (Permanent creature : game.getState().getBattlefield().getActivePermanents(filter, controller.getId(), game)) { if (creature.destroy(source.getSourceId(), game, false) - && game.getState().getZone(creature.getId()).equals(Zone.GRAVEYARD)) { // If a commander is replaced to command zone, the creature does not die) { + && game.getState().getZone(creature.getId()) == Zone.GRAVEYARD) { // If a commander is replaced to command zone, the creature does not die) { destroyedCreature++; } } diff --git a/Mage.Sets/src/mage/cards/h/Hellrider.java b/Mage.Sets/src/mage/cards/h/Hellrider.java index 0de939add9a..91ebfa5e2d7 100644 --- a/Mage.Sets/src/mage/cards/h/Hellrider.java +++ b/Mage.Sets/src/mage/cards/h/Hellrider.java @@ -68,7 +68,7 @@ class HellriderTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent source = game.getPermanent(event.getSourceId()); - if (source != null && source.getControllerId().equals(controllerId)) { + if (source != null && source.isControlledBy(controllerId)) { UUID defendingPlayerId = game.getCombat().getDefenderId(event.getSourceId()); this.getEffects().get(0).setTargetPointer(new FixedTarget(defendingPlayerId)); return true; diff --git a/Mage.Sets/src/mage/cards/h/HeraldOfFaith.java b/Mage.Sets/src/mage/cards/h/HeraldOfFaith.java index a8912a006f8..02b4255b59e 100644 --- a/Mage.Sets/src/mage/cards/h/HeraldOfFaith.java +++ b/Mage.Sets/src/mage/cards/h/HeraldOfFaith.java @@ -4,11 +4,11 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.effects.common.GainLifeEffect; -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; /** * @@ -27,7 +27,7 @@ public final class HeraldOfFaith extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Herald of Faith attacks, you gain 2 life. - this.addAbility(new AttacksTriggeredAbility(new GainLifeEffect(1), false)); + this.addAbility(new AttacksTriggeredAbility(new GainLifeEffect(2), false)); } public HeraldOfFaith(final HeraldOfFaith card) { diff --git a/Mage.Sets/src/mage/cards/h/HeraldOfWar.java b/Mage.Sets/src/mage/cards/h/HeraldOfWar.java index c8e55bf6ba4..4ab890792c6 100644 --- a/Mage.Sets/src/mage/cards/h/HeraldOfWar.java +++ b/Mage.Sets/src/mage/cards/h/HeraldOfWar.java @@ -79,7 +79,7 @@ class HeraldOfWarCostReductionEffect extends CostModificationEffectImpl { public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { Card sourceCard = game.getCard(abilityToModify.getSourceId()); - if (sourceCard != null && abilityToModify.getControllerId().equals(source.getControllerId()) && (sourceCard.hasSubtype(SubType.ANGEL, game) || sourceCard.hasSubtype(SubType.HUMAN, game))) { + if (sourceCard != null && abilityToModify.isControlledBy(source.getControllerId()) && (sourceCard.hasSubtype(SubType.ANGEL, game) || sourceCard.hasSubtype(SubType.HUMAN, game))) { return true; } } diff --git a/Mage.Sets/src/mage/cards/h/HintOfInsanity.java b/Mage.Sets/src/mage/cards/h/HintOfInsanity.java index 922837d71c3..745149db0bb 100644 --- a/Mage.Sets/src/mage/cards/h/HintOfInsanity.java +++ b/Mage.Sets/src/mage/cards/h/HintOfInsanity.java @@ -46,7 +46,7 @@ class HintOfInsanityEffect extends OneShotEffect { public HintOfInsanityEffect() { super(Outcome.Discard); - this.staticText = "Target player reveals his or her hand. That player discards all nonland cards with the same name as another card in his or her hand"; + this.staticText = "Target player reveals their hand. That player discards all nonland cards with the same name as another card in their hand"; } public HintOfInsanityEffect(final HintOfInsanityEffect effect) { diff --git a/Mage.Sets/src/mage/cards/h/HomewardPath.java b/Mage.Sets/src/mage/cards/h/HomewardPath.java index d4c99489ec9..f6773fe9638 100644 --- a/Mage.Sets/src/mage/cards/h/HomewardPath.java +++ b/Mage.Sets/src/mage/cards/h/HomewardPath.java @@ -89,7 +89,7 @@ class HomewardPathControlEffect extends ContinuousEffectImpl { for (Iterator it = affectedObjectList.iterator(); it.hasNext();) { Permanent creature = it.next().getPermanent(game); if (creature != null) { - if (!creature.getControllerId().equals(creature.getOwnerId())) { + if (!creature.isControlledBy(creature.getOwnerId())) { creature.changeControllerId(creature.getOwnerId(), game); } } else { diff --git a/Mage.Sets/src/mage/cards/h/Hostility.java b/Mage.Sets/src/mage/cards/h/Hostility.java index 723b368c98f..a9cfc57da29 100644 --- a/Mage.Sets/src/mage/cards/h/Hostility.java +++ b/Mage.Sets/src/mage/cards/h/Hostility.java @@ -86,7 +86,7 @@ class HostilityEffect extends PreventionEffectImpl { if (super.applies(event, source, game)) { if (game.getOpponents(source.getControllerId()).contains(event.getTargetId())) { Spell spell = game.getStack().getSpell(event.getSourceId()); - if (spell != null && spell.getControllerId().equals(source.getControllerId())) { + if (spell != null && spell.isControlledBy(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/i/IcefallRegent.java b/Mage.Sets/src/mage/cards/i/IcefallRegent.java index 0280b8b847b..8e21b7bf10d 100644 --- a/Mage.Sets/src/mage/cards/i/IcefallRegent.java +++ b/Mage.Sets/src/mage/cards/i/IcefallRegent.java @@ -111,7 +111,7 @@ class IcefallRegentEffect extends ContinuousRuleModifyingEffectImpl { // the battlefield triggered ability the source dies (or will be exiled), then the ZONE_CHANGE or LOST_CONTROL // event will happen before this effect is applied ever) Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (sourcePermanent == null || !sourcePermanent.getControllerId().equals(source.getControllerId())) { + if (sourcePermanent == null || !sourcePermanent.isControlledBy(source.getControllerId())) { discard(); return false; } @@ -132,7 +132,7 @@ class IcefallRegentEffect extends ContinuousRuleModifyingEffectImpl { if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) { if (event.getTargetId().equals(targetPointer.getFirst(game, source))) { Permanent targetCreature = game.getPermanent(targetPointer.getFirst(game, source)); - return targetCreature != null && game.getActivePlayerId().equals(targetCreature.getControllerId()); + return targetCreature != null && game.isActivePlayer(targetCreature.getControllerId()); } } diff --git a/Mage.Sets/src/mage/cards/i/IkraShidiqiTheUsurper.java b/Mage.Sets/src/mage/cards/i/IkraShidiqiTheUsurper.java index 1b76006a71e..2a44a903b35 100644 --- a/Mage.Sets/src/mage/cards/i/IkraShidiqiTheUsurper.java +++ b/Mage.Sets/src/mage/cards/i/IkraShidiqiTheUsurper.java @@ -79,7 +79,7 @@ class IkraShidiqiTheUsurperTriggeredAbility extends TriggeredAbilityImpl { DamagedEvent damageEvent = (DamagedEvent) event; if (damageEvent.isCombatDamage()) { Permanent permanent = game.getPermanent(event.getSourceId()); - if (permanent != null && permanent.isCreature() && permanent.getControllerId().equals(this.getControllerId())) { + if (permanent != null && permanent.isCreature() && permanent.isControlledBy(this.getControllerId())) { this.getEffects().clear(); this.getEffects().add(new GainLifeEffect(permanent.getToughness().getValue())); return true; diff --git a/Mage.Sets/src/mage/cards/i/IllusionistsBracers.java b/Mage.Sets/src/mage/cards/i/IllusionistsBracers.java index 8e73dee5b4b..389d705645c 100644 --- a/Mage.Sets/src/mage/cards/i/IllusionistsBracers.java +++ b/Mage.Sets/src/mage/cards/i/IllusionistsBracers.java @@ -72,7 +72,7 @@ class AbilityActivatedTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent equipment = game.getPermanent(this.getSourceId()); - if (equipment != null && equipment.getAttachedTo() != null && equipment.getAttachedTo().equals(event.getSourceId())) { + if (equipment != null && equipment.isAttachedTo(event.getSourceId())) { StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(event.getSourceId()); if (!(stackAbility.getStackAbility() instanceof ActivatedManaAbilityImpl)) { Effect effect = this.getEffects().get(0); diff --git a/Mage.Sets/src/mage/cards/i/IllusionistsGambit.java b/Mage.Sets/src/mage/cards/i/IllusionistsGambit.java index e381280918a..b624891e7a2 100644 --- a/Mage.Sets/src/mage/cards/i/IllusionistsGambit.java +++ b/Mage.Sets/src/mage/cards/i/IllusionistsGambit.java @@ -180,7 +180,7 @@ class IllusionistsGambitRestrictionEffect extends RestrictionEffect { } // planeswalker Permanent permanent = game.getPermanent(defenderId); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) + if (permanent != null && permanent.isControlledBy(source.getControllerId()) && permanent.isPlaneswalker()) { return false; } diff --git a/Mage.Sets/src/mage/cards/i/Immerwolf.java b/Mage.Sets/src/mage/cards/i/Immerwolf.java index ea7c0b63dd2..ebc726beb07 100644 --- a/Mage.Sets/src/mage/cards/i/Immerwolf.java +++ b/Mage.Sets/src/mage/cards/i/Immerwolf.java @@ -90,7 +90,7 @@ class ImmerwolfEffect extends ContinuousRuleModifyingEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); return permanent != null && - permanent.getControllerId().equals(source.getControllerId()) && + permanent.isControlledBy(source.getControllerId()) && filter.match(permanent, game) ; } } diff --git a/Mage.Sets/src/mage/cards/i/IncreasingVengeance.java b/Mage.Sets/src/mage/cards/i/IncreasingVengeance.java index b9966b8a7e9..33d22626e0d 100644 --- a/Mage.Sets/src/mage/cards/i/IncreasingVengeance.java +++ b/Mage.Sets/src/mage/cards/i/IncreasingVengeance.java @@ -75,14 +75,14 @@ class IncreasingVengeanceEffect extends OneShotEffect { Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); if (spell != null) { StackObject stackObjectCopy = spell.createCopyOnStack(game, source, source.getControllerId(), true); - if (stackObjectCopy != null && stackObjectCopy instanceof Spell) { + if (stackObjectCopy instanceof Spell) { game.informPlayers(new StringBuilder(controller.getLogName()).append(((Spell) stackObjectCopy).getActivatedMessage(game)).toString()); } Spell sourceSpell = (Spell) game.getStack().getStackObject(source.getSourceId()); if (sourceSpell != null) { if (sourceSpell.getFromZone() == Zone.GRAVEYARD) { stackObjectCopy = spell.createCopyOnStack(game, source, source.getControllerId(), true); - if (stackObjectCopy != null && stackObjectCopy instanceof Spell) { + if (stackObjectCopy instanceof Spell) { game.informPlayers(new StringBuilder(controller.getLogName()).append(((Spell) stackObjectCopy).getActivatedMessage(game)).toString()); } } diff --git a/Mage.Sets/src/mage/cards/i/InfectiousCurse.java b/Mage.Sets/src/mage/cards/i/InfectiousCurse.java index c1a5a54fdcc..555dc866bd6 100644 --- a/Mage.Sets/src/mage/cards/i/InfectiousCurse.java +++ b/Mage.Sets/src/mage/cards/i/InfectiousCurse.java @@ -87,7 +87,7 @@ class InfectiousCurseAbility extends TriggeredAbilityImpl { Permanent enchantment = game.getPermanent(this.sourceId); if (enchantment != null && enchantment.getAttachedTo() != null) { Player player = game.getPlayer(enchantment.getAttachedTo()); - if (player != null && game.getActivePlayerId().equals(player.getId())) { + if (player != null && game.isActivePlayer(player.getId())) { this.getEffects().get(0).setTargetPointer(new FixedTarget(player.getId())); return true; } @@ -122,7 +122,7 @@ class InfectiousCurseCostReductionEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { - if (source.getControllerId().equals(abilityToModify.getControllerId())) { + if (source.isControlledBy(abilityToModify.getControllerId())) { for (UUID modeId : abilityToModify.getModes().getSelectedModes()) { Mode mode = abilityToModify.getModes().get(modeId); for (Target target : mode.getTargets()) { diff --git a/Mage.Sets/src/mage/cards/i/InfiniteReflection.java b/Mage.Sets/src/mage/cards/i/InfiniteReflection.java index 597a9f36eac..50643266bae 100644 --- a/Mage.Sets/src/mage/cards/i/InfiniteReflection.java +++ b/Mage.Sets/src/mage/cards/i/InfiniteReflection.java @@ -117,7 +117,7 @@ class InfiniteReflectionEntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); - return permanent != null && permanent.getControllerId().equals(source.getControllerId()) + return permanent != null && permanent.isControlledBy(source.getControllerId()) && permanent.isCreature() && !(permanent instanceof PermanentToken); } diff --git a/Mage.Sets/src/mage/cards/i/InstillEnergy.java b/Mage.Sets/src/mage/cards/i/InstillEnergy.java index f884141e318..a1c89de4009 100644 --- a/Mage.Sets/src/mage/cards/i/InstillEnergy.java +++ b/Mage.Sets/src/mage/cards/i/InstillEnergy.java @@ -80,6 +80,6 @@ class CanAttackAsThoughItHadHasteEnchantedEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { Permanent enchantment = game.getPermanent(source.getSourceId()); - return enchantment != null && enchantment.getAttachedTo() != null && enchantment.getAttachedTo().equals(objectId); + return enchantment != null && enchantment.isAttachedTo(objectId); } } diff --git a/Mage.Sets/src/mage/cards/i/IreShaman.java b/Mage.Sets/src/mage/cards/i/IreShaman.java index cc7055ab6f7..8d0cbda7bca 100644 --- a/Mage.Sets/src/mage/cards/i/IreShaman.java +++ b/Mage.Sets/src/mage/cards/i/IreShaman.java @@ -115,7 +115,7 @@ class IreShamanCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && objectId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/i/IsarethTheAwakener.java b/Mage.Sets/src/mage/cards/i/IsarethTheAwakener.java index ceec1d0a5b5..62cf6c7eff7 100644 --- a/Mage.Sets/src/mage/cards/i/IsarethTheAwakener.java +++ b/Mage.Sets/src/mage/cards/i/IsarethTheAwakener.java @@ -105,7 +105,7 @@ class IsarethTheAwakenerCreateReflexiveTriggerEffect extends OneShotEffect { class IsarethTheAwakenerReflexiveTriggeredAbility extends DelayedTriggeredAbility { public IsarethTheAwakenerReflexiveTriggeredAbility() { - super(new IsarethTheAwakenerEffect(), Duration.OneUse, false); + super(new IsarethTheAwakenerEffect(), Duration.OneUse, true); this.addEffect(new IsarethTheAwakenerReplacementEffect()); } diff --git a/Mage.Sets/src/mage/cards/i/IslandSanctuary.java b/Mage.Sets/src/mage/cards/i/IslandSanctuary.java index 6cec4f2d425..aabf94d6899 100644 --- a/Mage.Sets/src/mage/cards/i/IslandSanctuary.java +++ b/Mage.Sets/src/mage/cards/i/IslandSanctuary.java @@ -81,7 +81,7 @@ class IslandSanctuaryEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return source.getControllerId().equals(event.getPlayerId()) && game.getTurn().getStepType() == PhaseStep.DRAW; + return source.isControlledBy(event.getPlayerId()) && game.getTurn().getStepType() == PhaseStep.DRAW; } @Override diff --git a/Mage.Sets/src/mage/cards/i/IvoryGargoyle.java b/Mage.Sets/src/mage/cards/i/IvoryGargoyle.java new file mode 100644 index 00000000000..0cd6c5e37d4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IvoryGargoyle.java @@ -0,0 +1,54 @@ +package mage.cards.i; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.ExileSourceEffect; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect; +import mage.abilities.effects.common.SkipNextDrawStepControllerEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author noahg + */ +public final class IvoryGargoyle extends CardImpl { + + public IvoryGargoyle(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); + + this.subtype.add(SubType.GARGOYLE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Ivory Gargoyle dies, return it to the battlefield under its owner's control at the beginning of the next end step and you skip your next draw step. + Ability ability = new DiesTriggeredAbility(new CreateDelayedTriggeredAbilityEffect( + new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnSourceFromGraveyardToBattlefieldEffect()))); + ability.addEffect(new SkipNextDrawStepControllerEffect()); + this.addAbility(ability); + + // {4}{W}: Exile Ivory Gargoyle. + this.addAbility(new SimpleActivatedAbility(new ExileSourceEffect(), new ManaCostsImpl("{4}{W}"))); + } + + public IvoryGargoyle(final IvoryGargoyle card) { + super(card); + } + + @Override + public IvoryGargoyle copy() { + return new IvoryGargoyle(this); + } +} diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 639950af6b6..efd444476fe 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -134,7 +134,7 @@ class JaceArchitectOfThoughtDelayedTriggeredAbility extends DelayedTriggeredAbil @Override public boolean isInactive(Game game) { - return game.getActivePlayerId().equals(getControllerId()) && game.getTurnNum() != startingTurn; + return game.isActivePlayer(getControllerId()) && game.getTurnNum() != startingTurn; } @Override @@ -242,7 +242,7 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); - if (source.getControllerId().equals(player.getId())) { + if (source.isControlledBy(player.getId())) { playerName = "your"; } TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); diff --git a/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java b/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java index 160baea0769..e5b52f876da 100644 --- a/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java +++ b/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java @@ -112,7 +112,7 @@ class JaceCunningCastawayDamageTriggeredAbility extends DelayedTriggeredAbility if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER) { if (((DamagedPlayerEvent) event).isCombatDamage()) { Permanent creature = game.getPermanent(event.getSourceId()); - if (creature != null && creature.getControllerId().equals(controllerId) + if (creature != null && creature.isControlledBy(controllerId) && !damagedPlayerIds.contains(event.getTargetId())) { damagedPlayerIds.add(event.getTargetId()); return true; diff --git a/Mage.Sets/src/mage/cards/j/JaceTheLivingGuildpact.java b/Mage.Sets/src/mage/cards/j/JaceTheLivingGuildpact.java index d2a30b37c56..bf09d707176 100644 --- a/Mage.Sets/src/mage/cards/j/JaceTheLivingGuildpact.java +++ b/Mage.Sets/src/mage/cards/j/JaceTheLivingGuildpact.java @@ -1,4 +1,3 @@ - package mage.cards.j; import java.util.UUID; @@ -55,6 +54,7 @@ public final class JaceTheLivingGuildpact extends CardImpl { // -8: Each player shuffles their hand and graveyard into their library. You draw seven cards. ability = new LoyaltyAbility(new ShuffleHandGraveyardAllEffect(), -8); ability.addEffect(new DrawCardSourceControllerEffect(7).setText("You draw seven cards")); + this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/j/JarOfEyeballs.java b/Mage.Sets/src/mage/cards/j/JarOfEyeballs.java index f8076da878f..5ea98a196fc 100644 --- a/Mage.Sets/src/mage/cards/j/JarOfEyeballs.java +++ b/Mage.Sets/src/mage/cards/j/JarOfEyeballs.java @@ -83,7 +83,7 @@ class JarOfEyeballsTriggeredAbility extends TriggeredAbilityImpl { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent.getControllerId().equals(this.getControllerId()) && permanent.isCreature()) { + if (permanent.isControlledBy(this.getControllerId()) && permanent.isCreature()) { return true; } } diff --git a/Mage.Sets/src/mage/cards/j/Jokulmorder.java b/Mage.Sets/src/mage/cards/j/Jokulmorder.java index 5ce19758477..dfe4138831a 100644 --- a/Mage.Sets/src/mage/cards/j/Jokulmorder.java +++ b/Mage.Sets/src/mage/cards/j/Jokulmorder.java @@ -86,7 +86,7 @@ class JokulmorderTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent land = game.getPermanent(event.getTargetId()); return land.hasSubtype(SubType.ISLAND, game) - && land.getControllerId().equals(this.controllerId); + && land.isControlledBy(this.controllerId); } @Override diff --git a/Mage.Sets/src/mage/cards/j/JourneyToEternity.java b/Mage.Sets/src/mage/cards/j/JourneyToEternity.java index 1aebd7b437a..365534cf3a5 100644 --- a/Mage.Sets/src/mage/cards/j/JourneyToEternity.java +++ b/Mage.Sets/src/mage/cards/j/JourneyToEternity.java @@ -86,7 +86,7 @@ class JourneyToEternityReturnTransformedSourceEffect extends OneShotEffect { if (card != null && controller != null) { Zone zone = game.getState().getZone(card.getId()); // cards needs to be in public non battlefield zone - if (zone.equals(Zone.BATTLEFIELD) || !zone.isPublicZone()) { + if (zone == Zone.BATTLEFIELD || !zone.isPublicZone()) { return true; } game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); diff --git a/Mage.Sets/src/mage/cards/j/JovensFerrets.java b/Mage.Sets/src/mage/cards/j/JovensFerrets.java new file mode 100644 index 00000000000..a4df82c443c --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JovensFerrets.java @@ -0,0 +1,111 @@ +package mage.cards.j; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.EndOfCombatTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; +import mage.abilities.effects.common.TapAllEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.watchers.common.BlockedAttackerWatcher; + +/** + * + * @author noahg + */ +public final class JovensFerrets extends CardImpl { + + public JovensFerrets(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); + + this.subtype.add(SubType.FERRET); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Whenever Joven's Ferrets attacks, it gets +0/+2 until end of turn. + Effect boostSourceEffect = new BoostSourceEffect(0, 2, Duration.EndOfTurn); + boostSourceEffect.setText("it gets +0/+2 until end of turn"); + this.addAbility(new AttacksTriggeredAbility(boostSourceEffect, false)); + + // At end of combat, tap all creatures that blocked Joven's Ferrets this turn. They don't untap during their controller's next untap step. + Ability eocAbility = new EndOfCombatTriggeredAbility(new JovensFerretsEffect(), false); + eocAbility.addWatcher(new BlockedAttackerWatcher()); + this.addAbility(eocAbility); + } + + public JovensFerrets(final JovensFerrets card) { + super(card); + } + + @Override + public JovensFerrets copy() { + return new JovensFerrets(this); + } +} + +class JovensFerretsEffect extends OneShotEffect { + + public JovensFerretsEffect() { + super(Outcome.Benefit); + } + + public JovensFerretsEffect(final JovensFerretsEffect effect) { + super(effect); + } + + @Override + public JovensFerretsEffect copy() { + return new JovensFerretsEffect(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) { + BlockedAttackerWatcher watcher = (BlockedAttackerWatcher) game.getState().getWatchers().get(BlockedAttackerWatcher.class.getSimpleName()); + if (watcher != null) { + List toTap = new ArrayList<>(); + for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) { + if (!creature.getId().equals(source.getSourceId())) { + if (watcher.creatureHasBlockedAttacker(sourcePermanent, creature, game)) { + toTap.add(creature); + } + } + } + for (Permanent creature : toTap) { + creature.tap(game); + DontUntapInControllersNextUntapStepTargetEffect effect = new DontUntapInControllersNextUntapStepTargetEffect(); + effect.setTargetPointer(new FixedTarget(creature.getId())); + game.addEffect(effect, source); + } + return true; + } + } + return false; + } + + @Override + public String getText(Mode mode) { + return "tap all creatures that blocked {this} this turn. They don't untap during their controller's next untap step."; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/j/Juxtapose.java b/Mage.Sets/src/mage/cards/j/Juxtapose.java index 2adf2dfa6b3..ecc67002684 100644 --- a/Mage.Sets/src/mage/cards/j/Juxtapose.java +++ b/Mage.Sets/src/mage/cards/j/Juxtapose.java @@ -97,7 +97,7 @@ class JuxtaposeEffect extends ContinuousEffectImpl { if (permanent1 != null && permanent2 != null) { // exchange works only for two different controllers - if (permanent1.getControllerId().equals(permanent2.getControllerId())) { + if (permanent1.isControlledBy(permanent2.getControllerId())) { // discard effect if controller of both permanents is the same discard(); return; diff --git a/Mage.Sets/src/mage/cards/k/KaerveksPurge.java b/Mage.Sets/src/mage/cards/k/KaerveksPurge.java index 6028d89f010..591f109a1b3 100644 --- a/Mage.Sets/src/mage/cards/k/KaerveksPurge.java +++ b/Mage.Sets/src/mage/cards/k/KaerveksPurge.java @@ -76,7 +76,7 @@ class KaerveksPurgeEffect extends OneShotEffect { if (targetCreature != null && targetCreature.destroy(source.getSourceId(), game, false)) { game.applyEffects(); if (targetCreature.getZoneChangeCounter(game) + 1 == game.getState().getZoneChangeCounter(targetCreature.getId()) - && !game.getState().getZone(targetCreature.getId()).equals(Zone.GRAVEYARD)) { + && game.getState().getZone(targetCreature.getId()) != Zone.GRAVEYARD) { // A replacement effect has moved the card to another zone as graveyard return true; } diff --git a/Mage.Sets/src/mage/cards/k/KalitasBloodchiefOfGhet.java b/Mage.Sets/src/mage/cards/k/KalitasBloodchiefOfGhet.java index 551627d15c4..6f54f2debcb 100644 --- a/Mage.Sets/src/mage/cards/k/KalitasBloodchiefOfGhet.java +++ b/Mage.Sets/src/mage/cards/k/KalitasBloodchiefOfGhet.java @@ -74,7 +74,7 @@ class KalitasDestroyEffect extends OneShotEffect { Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (permanent != null && permanent.destroy(source.getSourceId(), game, false)) { // if not destroyed it returns false if (permanent.getZoneChangeCounter(game) + 1 == game.getState().getZoneChangeCounter(permanent.getId()) - && !game.getState().getZone(permanent.getId()).equals(Zone.GRAVEYARD)) { + && game.getState().getZone(permanent.getId()) != Zone.GRAVEYARD) { // A replacement effect has moved the card to another zone as grvayard return true; } diff --git a/Mage.Sets/src/mage/cards/k/KaradorGhostChieftain.java b/Mage.Sets/src/mage/cards/k/KaradorGhostChieftain.java index 35b7d59bc52..aba7458be3e 100644 --- a/Mage.Sets/src/mage/cards/k/KaradorGhostChieftain.java +++ b/Mage.Sets/src/mage/cards/k/KaradorGhostChieftain.java @@ -111,7 +111,7 @@ class KaradorGhostChieftainContinuousEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - if (game.getActivePlayerId() == null || !game.getActivePlayerId().equals(player.getId())) { + if (game.getActivePlayerId() == null || !game.isActivePlayer(player.getId())) { return false; } for (Card card : player.getGraveyard().getCards(new FilterCreatureCard(), game)) { diff --git a/Mage.Sets/src/mage/cards/k/KarnLiberated.java b/Mage.Sets/src/mage/cards/k/KarnLiberated.java index 5a4629551fc..dc7a656eab9 100644 --- a/Mage.Sets/src/mage/cards/k/KarnLiberated.java +++ b/Mage.Sets/src/mage/cards/k/KarnLiberated.java @@ -111,7 +111,7 @@ class KarnLiberatedEffect extends OneShotEffect { player.getHand().clear(); player.getLibrary().clear(); for (Card card : game.getCards()) { - if (card.getOwnerId().equals(player.getId()) && !card.isCopy() // no copies + if (card.isOwnedBy(player.getId()) && !card.isCopy() // no copies && !player.getSideboard().contains(card.getId()) && !cards.contains(card)) { // not the exiled cards if (player.getCommandersIds().contains(card.getId())) { diff --git a/Mage.Sets/src/mage/cards/k/KarnScionOfUrza.java b/Mage.Sets/src/mage/cards/k/KarnScionOfUrza.java index e9589ae4605..7fc485e7150 100644 --- a/Mage.Sets/src/mage/cards/k/KarnScionOfUrza.java +++ b/Mage.Sets/src/mage/cards/k/KarnScionOfUrza.java @@ -170,7 +170,7 @@ class KarnMinus1Effect extends OneShotEffect { Cards filteredCards = new CardsImpl(); for (Card exileCard : exile) { - if (exileCard.getOwnerId().equals(source.getControllerId()) && filter.match(exileCard, game)) { + if (exileCard.isOwnedBy(source.getControllerId()) && filter.match(exileCard, game)) { filteredCards.add(exileCard); } } diff --git a/Mage.Sets/src/mage/cards/k/KaronaFalseGod.java b/Mage.Sets/src/mage/cards/k/KaronaFalseGod.java index 636f40c80c2..b338d4cf51b 100644 --- a/Mage.Sets/src/mage/cards/k/KaronaFalseGod.java +++ b/Mage.Sets/src/mage/cards/k/KaronaFalseGod.java @@ -86,8 +86,8 @@ class KaronaFalseGodUntapGetControlEffect extends OneShotEffect { // remove old control effects of the same player for (ContinuousEffect effect : game.getState().getContinuousEffects().getLayeredEffects(game)) { if (effect instanceof GainControlTargetEffect) { - UUID checkId = (UUID) ((GainControlTargetEffect) effect).getValue("KaronaFalseGodSourceId"); - UUID controllerId = (UUID) ((GainControlTargetEffect) effect).getValue("KaronaFalseGodControllerId"); + UUID checkId = (UUID) effect.getValue("KaronaFalseGodSourceId"); + UUID controllerId = (UUID) effect.getValue("KaronaFalseGodControllerId"); if (source.getSourceId().equals(checkId) && newController.getId().equals(controllerId)) { effect.discard(); } diff --git a/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java b/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java index f4ee2af344e..eda2fdad620 100644 --- a/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java +++ b/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java @@ -103,7 +103,7 @@ class KarplusanMinotaurFlipWinTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - return this.getControllerId().equals(event.getPlayerId()) && event.getFlag(); + return this.isControlledBy(event.getPlayerId()) && event.getFlag(); } @Override @@ -134,7 +134,7 @@ class KarplusanMinotaurFlipLoseTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - return this.getControllerId().equals(event.getPlayerId()) && !event.getFlag(); + return this.isControlledBy(event.getPlayerId()) && !event.getFlag(); } @Override diff --git a/Mage.Sets/src/mage/cards/k/KazarovSengirPureblood.java b/Mage.Sets/src/mage/cards/k/KazarovSengirPureblood.java index b56ea5a3b06..53a780e8b81 100644 --- a/Mage.Sets/src/mage/cards/k/KazarovSengirPureblood.java +++ b/Mage.Sets/src/mage/cards/k/KazarovSengirPureblood.java @@ -87,7 +87,7 @@ class KazarovSengirPurebloodTriggeredAbility extends TriggeredAbilityImpl { if (permanent == null) { return false; } - if (permanent.getControllerId().equals(this.getControllerId())) { + if (permanent.isControlledBy(this.getControllerId())) { return false; } return true; diff --git a/Mage.Sets/src/mage/cards/k/KeeperOfTheBeasts.java b/Mage.Sets/src/mage/cards/k/KeeperOfTheBeasts.java new file mode 100644 index 00000000000..cc4ccc8fcdd --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KeeperOfTheBeasts.java @@ -0,0 +1,111 @@ +package mage.cards.k; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +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.CreateTokenEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterOpponent; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.token.BeastToken2; +import mage.game.permanent.token.BeastToken4; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetOpponent; + +/** + * + * @author noahg + */ +public final class KeeperOfTheBeasts extends CardImpl { + + public KeeperOfTheBeasts(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{G}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // {G}, {tap}: Choose target opponent who controlled more creatures than you did as you activated this ability. Put a 2/2 green Beast creature token onto the battlefield. + Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new BeastToken4()).setText("Choose target opponent who controlled more creatures than you did as you activated this ability. Put a 2/2 green Beast creature token onto the battlefield."), + new ManaCostsImpl("{G}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new KeeperOfTheBeastsTarget()); + this.addAbility(ability); + } + + public KeeperOfTheBeasts(final KeeperOfTheBeasts card) { + super(card); + } + + @Override + public KeeperOfTheBeasts copy() { + return new KeeperOfTheBeasts(this); + } +} + +class KeeperOfTheBeastsTarget extends TargetPlayer { + + public KeeperOfTheBeastsTarget() { + super(1, 1, false, new FilterOpponent("opponent that controls more creatures than you")); + } + + public KeeperOfTheBeastsTarget(final KeeperOfTheBeastsTarget target) { + super(target); + } + + @Override + public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { + Set availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game); + Set possibleTargets = new HashSet<>(); + int creaturesController = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, sourceControllerId, game); + + for (UUID targetId : availablePossibleTargets) { + if (game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, targetId, game) > creaturesController) { + possibleTargets.add(targetId); + } + } + return possibleTargets; + } + + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + int count = 0; + MageObject targetSource = game.getObject(sourceId); + Player controller = game.getPlayer(sourceControllerId); + if (controller != null) { + for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) { + Player player = game.getPlayer(playerId); + if (player != null + && game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, sourceControllerId, game) + < game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game) + && !player.hasLeft() + && filter.match(player, sourceId, sourceControllerId, game) + && player.canBeTargetedBy(targetSource, sourceControllerId, game)) { + count++; + if (count >= this.minNumberOfTargets) { + return true; + } + } + } + } + return false; + } + + @Override + public KeeperOfTheBeastsTarget copy() { + return new KeeperOfTheBeastsTarget(this); + } +} + diff --git a/Mage.Sets/src/mage/cards/k/KeeperOfTheDead.java b/Mage.Sets/src/mage/cards/k/KeeperOfTheDead.java index eadc6f82a77..3508e2839f3 100644 --- a/Mage.Sets/src/mage/cards/k/KeeperOfTheDead.java +++ b/Mage.Sets/src/mage/cards/k/KeeperOfTheDead.java @@ -128,7 +128,7 @@ class KeeperOfTheDeadCreatureTarget extends TargetPermanent { public boolean canTarget(UUID id, Ability source, Game game) { UUID firstTarget = source.getFirstTarget(); Permanent permanent = game.getPermanent(id); - if (firstTarget != null && permanent != null && permanent.getControllerId().equals(firstTarget)) { + if (firstTarget != null && permanent != null && permanent.isControlledBy(firstTarget)) { return super.canTarget(id, source, game); } return false; @@ -153,7 +153,7 @@ class KeeperOfTheDeadCreatureTarget extends TargetPermanent { UUID playerId = ((StackObject) object).getStackAbility().getFirstTarget(); for (UUID targetId : availablePossibleTargets) { Permanent permanent = game.getPermanent(targetId); - if (permanent != null && nonblackCreaturefilter.match(permanent, game) && permanent.getControllerId().equals(playerId)) { + if (permanent != null && nonblackCreaturefilter.match(permanent, game) && permanent.isControlledBy(playerId)) { possibleTargets.add(targetId); } } diff --git a/Mage.Sets/src/mage/cards/k/KeranosGodOfStorms.java b/Mage.Sets/src/mage/cards/k/KeranosGodOfStorms.java index 2713e4282d8..3590d941232 100644 --- a/Mage.Sets/src/mage/cards/k/KeranosGodOfStorms.java +++ b/Mage.Sets/src/mage/cards/k/KeranosGodOfStorms.java @@ -92,7 +92,7 @@ class KeranosGodOfStormsTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getPlayerId().equals(this.getControllerId())) { - if (game.getActivePlayerId().equals(this.getControllerId())) { + if (game.isActivePlayer(this.getControllerId())) { CardsAmountDrawnThisTurnWatcher watcher = (CardsAmountDrawnThisTurnWatcher) game.getState().getWatchers().get(CardsAmountDrawnThisTurnWatcher.class.getSimpleName()); if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) != 1) { diff --git a/Mage.Sets/src/mage/cards/k/KessDissidentMage.java b/Mage.Sets/src/mage/cards/k/KessDissidentMage.java index 8eb49369f9c..bc3cc94473f 100644 --- a/Mage.Sets/src/mage/cards/k/KessDissidentMage.java +++ b/Mage.Sets/src/mage/cards/k/KessDissidentMage.java @@ -97,7 +97,7 @@ class KessDissidentMageContinuousEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - if (!game.getActivePlayerId().equals(player.getId())) { + if (!game.isActivePlayer(player.getId())) { return false; } for (Card card : player.getGraveyard().getCards(filter, game)) { @@ -138,7 +138,7 @@ class KessDissidentMageCastFromGraveyardEffect extends AsThoughEffectImpl { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { if (objectId.equals(getTargetPointer().getFirst(game, source))) { if (affectedControllerId.equals(source.getControllerId())) { - if (game.getActivePlayerId().equals(source.getControllerId())) { + if (game.isActivePlayer(source.getControllerId())) { KessDissidentMageWatcher watcher = (KessDissidentMageWatcher) game.getState().getWatchers().get(KessDissidentMageWatcher.class.getSimpleName(), source.getSourceId()); if (!(source instanceof FlashbackAbility)) { return !watcher.isAbilityUsed(); diff --git a/Mage.Sets/src/mage/cards/k/KnacksawClique.java b/Mage.Sets/src/mage/cards/k/KnacksawClique.java index 9de1b132b83..1b3b4882150 100644 --- a/Mage.Sets/src/mage/cards/k/KnacksawClique.java +++ b/Mage.Sets/src/mage/cards/k/KnacksawClique.java @@ -122,7 +122,7 @@ class KnacksawCliqueCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && sourceId.equals(getTargetPointer().getFirst(game, source)); } diff --git a/Mage.Sets/src/mage/cards/k/KnightsOfTheBlackRose.java b/Mage.Sets/src/mage/cards/k/KnightsOfTheBlackRose.java index 1faaa0d25d7..482ed9506d0 100644 --- a/Mage.Sets/src/mage/cards/k/KnightsOfTheBlackRose.java +++ b/Mage.Sets/src/mage/cards/k/KnightsOfTheBlackRose.java @@ -86,7 +86,7 @@ class BecomesMonarchTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkInterveningIfClause(Game game) { MonarchAtTurnStartWatcher watcher = (MonarchAtTurnStartWatcher) game.getState().getWatchers().get(MonarchAtTurnStartWatcher.class.getSimpleName()); - return watcher != null && getControllerId().equals(watcher.getMonarchIdAtTurnStart()); + return watcher != null && isControlledBy(watcher.getMonarchIdAtTurnStart()); } @Override diff --git a/Mage.Sets/src/mage/cards/k/KopalaWardenOfWaves.java b/Mage.Sets/src/mage/cards/k/KopalaWardenOfWaves.java index 5f8dc1b4414..738f2ffc63c 100644 --- a/Mage.Sets/src/mage/cards/k/KopalaWardenOfWaves.java +++ b/Mage.Sets/src/mage/cards/k/KopalaWardenOfWaves.java @@ -93,7 +93,7 @@ class KopalaWardenOfWavesCostReductionEffect extends CostModificationEffectImpl Permanent creature = game.getPermanent(targetUUID); if (creature != null && filter.match(creature, game) - && creature.getControllerId().equals(source.getControllerId())) { + && creature.isControlledBy(source.getControllerId())) { return true; } } @@ -144,7 +144,7 @@ class KopalaWardenOfWavesCostReductionEffect2 extends CostModificationEffectImpl Permanent creature = game.getPermanent(targetUUID); if (creature != null && filter.match(creature, game) - && creature.getControllerId().equals(source.getControllerId())) { + && creature.isControlledBy(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/k/KrarksOtherThumb.java b/Mage.Sets/src/mage/cards/k/KrarksOtherThumb.java index 1575db39a59..6001ec55995 100644 --- a/Mage.Sets/src/mage/cards/k/KrarksOtherThumb.java +++ b/Mage.Sets/src/mage/cards/k/KrarksOtherThumb.java @@ -82,7 +82,7 @@ class KrarksOtherThumbEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/k/KrarksThumb.java b/Mage.Sets/src/mage/cards/k/KrarksThumb.java index 20a705b886a..3acb3bde5aa 100644 --- a/Mage.Sets/src/mage/cards/k/KrarksThumb.java +++ b/Mage.Sets/src/mage/cards/k/KrarksThumb.java @@ -74,7 +74,7 @@ class KrarksThumbEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/k/KumanosBlessing.java b/Mage.Sets/src/mage/cards/k/KumanosBlessing.java index c6873c3cf90..c745c6fd9c6 100644 --- a/Mage.Sets/src/mage/cards/k/KumanosBlessing.java +++ b/Mage.Sets/src/mage/cards/k/KumanosBlessing.java @@ -1,9 +1,6 @@ package mage.cards.k; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -24,15 +21,18 @@ import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; import mage.watchers.Watcher; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class KumanosBlessing extends CardImpl { public KumanosBlessing(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); this.subtype.add(SubType.AURA); // Flash @@ -77,7 +77,7 @@ class KumanosBlessingEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = ((ZoneChangeEvent)event).getTarget(); + Permanent permanent = ((ZoneChangeEvent) event).getTarget(); Player controller = game.getPlayer(source.getControllerId()); if (controller != null && permanent != null) { return controller.moveCardToExileWithInfo(permanent, null, null, source.getSourceId(), game, Zone.BATTLEFIELD, true); @@ -89,10 +89,10 @@ class KumanosBlessingEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ZONE_CHANGE; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - ZoneChangeEvent zce = (ZoneChangeEvent) event; + ZoneChangeEvent zce = (ZoneChangeEvent) event; if (zce.isDiesEvent()) { DamagedByEnchantedWatcher watcher = (DamagedByEnchantedWatcher) game.getState().getWatchers().get(DamagedByEnchantedWatcher.class.getSimpleName(), source.getSourceId()); if (watcher != null) { @@ -126,16 +126,15 @@ class DamagedByEnchantedWatcher extends Watcher { public void watch(GameEvent event, Game game) { if (event.getType() == EventType.DAMAGED_CREATURE) { Permanent enchantment = game.getPermanent(this.getSourceId()); - if (enchantment != null && enchantment.getAttachedTo() != null) { - if (enchantment.getAttachedTo().equals(event.getSourceId())) { - MageObjectReference mor = new MageObjectReference(event.getTargetId(), game); - damagedCreatures.add(mor); + if (enchantment != null && enchantment.isAttachedTo(event.getSourceId())) { + MageObjectReference mor = new MageObjectReference(event.getTargetId(), game); + damagedCreatures.add(mor); - } } } } + @Override public void reset() { super.reset(); diff --git a/Mage.Sets/src/mage/cards/l/Larceny.java b/Mage.Sets/src/mage/cards/l/Larceny.java index 19279f5e722..297dd135e86 100644 --- a/Mage.Sets/src/mage/cards/l/Larceny.java +++ b/Mage.Sets/src/mage/cards/l/Larceny.java @@ -64,7 +64,7 @@ class LarcenyTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (((DamagedPlayerEvent) event).isCombatDamage()) { Permanent creature = game.getPermanent(event.getSourceId()); - if (creature != null && creature.getControllerId().equals(controllerId)) { + if (creature != null && creature.isControlledBy(controllerId)) { for(Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getPlayerId())); diff --git a/Mage.Sets/src/mage/cards/l/LashknifeBarrier.java b/Mage.Sets/src/mage/cards/l/LashknifeBarrier.java index 77a2b57084f..994ea460f78 100644 --- a/Mage.Sets/src/mage/cards/l/LashknifeBarrier.java +++ b/Mage.Sets/src/mage/cards/l/LashknifeBarrier.java @@ -79,7 +79,7 @@ class LashknifeBarrierEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent creature = game.getPermanent(event.getTargetId()); - return creature.getControllerId().equals(source.getControllerId()); + return creature.isControlledBy(source.getControllerId()); } } diff --git a/Mage.Sets/src/mage/cards/l/LeovoldEmissaryOfTrest.java b/Mage.Sets/src/mage/cards/l/LeovoldEmissaryOfTrest.java index cce548fd280..270e0500530 100644 --- a/Mage.Sets/src/mage/cards/l/LeovoldEmissaryOfTrest.java +++ b/Mage.Sets/src/mage/cards/l/LeovoldEmissaryOfTrest.java @@ -109,7 +109,7 @@ class LeovoldEmissaryOfTrestTriggeredAbility extends TriggeredAbilityImpl { return true; // Player was targeted } Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); - if (permanent != null && this.getControllerId().equals(permanent.getControllerId())) { + if (permanent != null && this.isControlledBy(permanent.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/l/LightOfSanction.java b/Mage.Sets/src/mage/cards/l/LightOfSanction.java index c9528142999..a0976975685 100644 --- a/Mage.Sets/src/mage/cards/l/LightOfSanction.java +++ b/Mage.Sets/src/mage/cards/l/LightOfSanction.java @@ -56,13 +56,13 @@ class LightOfSanctionEffect extends PreventionEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.DAMAGE_CREATURE) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { + if (permanent != null && permanent.isControlledBy(source.getControllerId())) { MageObject damageSource = game.getObject(event.getSourceId()); if (damageSource instanceof Controllable) { - return ((Controllable) damageSource).getControllerId().equals(source.getControllerId()); + return ((Controllable) damageSource).isControlledBy(source.getControllerId()); } else if (damageSource instanceof Card) { - return ((Card) damageSource).getOwnerId().equals(source.getControllerId()); + return ((Card) damageSource).isOwnedBy(source.getControllerId()); } } } diff --git a/Mage.Sets/src/mage/cards/l/LilianaUntouchedByDeath.java b/Mage.Sets/src/mage/cards/l/LilianaUntouchedByDeath.java index 5d8bb40b5a5..6d569e10128 100644 --- a/Mage.Sets/src/mage/cards/l/LilianaUntouchedByDeath.java +++ b/Mage.Sets/src/mage/cards/l/LilianaUntouchedByDeath.java @@ -135,7 +135,7 @@ class LilianaUntouchedByDeathGraveyardEffect extends AsThoughEffectImpl { Card card = game.getCard(objectId); if (card != null && card.hasSubtype(SubType.ZOMBIE, game) - && card.getOwnerId().equals(source.getControllerId()) + && card.isOwnedBy(source.getControllerId()) && game.getState().getZone(objectId) == Zone.GRAVEYARD) { return true; } diff --git a/Mage.Sets/src/mage/cards/l/LilianasContract.java b/Mage.Sets/src/mage/cards/l/LilianasContract.java index b98459a50ac..68ca8092406 100644 --- a/Mage.Sets/src/mage/cards/l/LilianasContract.java +++ b/Mage.Sets/src/mage/cards/l/LilianasContract.java @@ -70,7 +70,7 @@ enum LilianasContractCondition implements Condition { Set demonNames = new HashSet(); for (Permanent permanent : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { if (permanent == null - || !permanent.getControllerId().equals(source.getControllerId()) + || !permanent.isControlledBy(source.getControllerId()) || !permanent.hasSubtype(SubType.DEMON, game)) { continue; } diff --git a/Mage.Sets/src/mage/cards/l/LionsEyeDiamond.java b/Mage.Sets/src/mage/cards/l/LionsEyeDiamond.java index d90cc470085..69983349c42 100644 --- a/Mage.Sets/src/mage/cards/l/LionsEyeDiamond.java +++ b/Mage.Sets/src/mage/cards/l/LionsEyeDiamond.java @@ -42,8 +42,8 @@ public final class LionsEyeDiamond extends CardImpl { class LionsEyeDiamondAbility extends ActivatedManaAbilityImpl { public LionsEyeDiamondAbility() { - super(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(3), new SacrificeSourceCost()); - this.addCost(new DiscardHandCost()); + super(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(3), new DiscardHandCost()); + this.addCost(new SacrificeSourceCost()); this.netMana.add(new Mana(0, 0, 0, 0, 0, 0, 3, 0)); } diff --git a/Mage.Sets/src/mage/cards/l/LoamingShaman.java b/Mage.Sets/src/mage/cards/l/LoamingShaman.java index d31cd699bf0..e9ed578b3f1 100644 --- a/Mage.Sets/src/mage/cards/l/LoamingShaman.java +++ b/Mage.Sets/src/mage/cards/l/LoamingShaman.java @@ -99,10 +99,10 @@ class LoamingShamanTargetCardsInGraveyard extends TargetCardInGraveyard { if (firstTarget != null) { Card card = game.getCard(firstTarget); if (card == null || targetCard == null - || !card.getOwnerId().equals(targetCard.getOwnerId())) { + || !card.isOwnedBy(targetCard.getOwnerId())) { return false; } - } else if (targetCard == null || !targetCard.getOwnerId().equals(targetPlayerId)) { + } else if (targetCard == null || !targetCard.isOwnedBy(targetPlayerId)) { return false; } return super.canTarget(id, source, game); diff --git a/Mage.Sets/src/mage/cards/l/LocketOfYesterdays.java b/Mage.Sets/src/mage/cards/l/LocketOfYesterdays.java index 8c649f6fcff..e987b48df8b 100644 --- a/Mage.Sets/src/mage/cards/l/LocketOfYesterdays.java +++ b/Mage.Sets/src/mage/cards/l/LocketOfYesterdays.java @@ -70,7 +70,7 @@ class LocketOfYesterdaysCostReductionEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { - if (abilityToModify.getControllerId().equals(source.getControllerId()) + if (abilityToModify.isControlledBy(source.getControllerId()) && (abilityToModify instanceof SpellAbility)) { return true; } diff --git a/Mage.Sets/src/mage/cards/l/LuminatePrimordial.java b/Mage.Sets/src/mage/cards/l/LuminatePrimordial.java index d5df07c0b8a..ce678715e65 100644 --- a/Mage.Sets/src/mage/cards/l/LuminatePrimordial.java +++ b/Mage.Sets/src/mage/cards/l/LuminatePrimordial.java @@ -88,7 +88,7 @@ class LuminatePrimordialEffect extends OneShotEffect { for (Target target: source.getTargets()) { if (target instanceof TargetCreaturePermanent) { Permanent targetCreature = game.getPermanent(target.getFirstTarget()); - if (targetCreature != null && !targetCreature.getControllerId().equals(source.getControllerId())) { + if (targetCreature != null && !targetCreature.isControlledBy(source.getControllerId())) { int amountLife = targetCreature.getPower().getValue(); Player controller = game.getPlayer(targetCreature.getControllerId()); targetCreature.moveToExile(null, null, source.getSourceId(), game); diff --git a/Mage.Sets/src/mage/cards/m/MaelstromNexus.java b/Mage.Sets/src/mage/cards/m/MaelstromNexus.java index 73ed90b41ea..c88f8d523ce 100644 --- a/Mage.Sets/src/mage/cards/m/MaelstromNexus.java +++ b/Mage.Sets/src/mage/cards/m/MaelstromNexus.java @@ -67,7 +67,7 @@ class MaelstromNexusGainCascadeFirstSpellEffect extends ContinuousEffectImpl { if (controller != null) { for (StackObject stackObject : game.getStack()) { // only spells cast, so no copies of spells - if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.getControllerId().equals(source.getControllerId())) { + if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.isControlledBy(source.getControllerId())) { Spell spell = (Spell) stackObject; FirstSpellCastThisTurnWatcher watcher = (FirstSpellCastThisTurnWatcher) game.getState().getWatchers().get(FirstSpellCastThisTurnWatcher.class.getSimpleName()); if (watcher != null && spell.getId().equals(watcher.getIdOfFirstCastSpell(source.getControllerId()))) { diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheWill.java b/Mage.Sets/src/mage/cards/m/MagusOfTheWill.java index 604ffe0b417..e56c7ef98e5 100644 --- a/Mage.Sets/src/mage/cards/m/MagusOfTheWill.java +++ b/Mage.Sets/src/mage/cards/m/MagusOfTheWill.java @@ -137,9 +137,9 @@ class MagusOfTheWillReplacementEffect extends ReplacementEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD) { Card card = game.getCard(event.getTargetId()); - if (card != null && card.getOwnerId().equals(source.getControllerId())) { + if (card != null && card.isOwnedBy(source.getControllerId())) { Permanent permanent = ((ZoneChangeEvent) event).getTarget(); - if (permanent == null || !(permanent instanceof PermanentToken)) { + if (!(permanent instanceof PermanentToken)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/m/MaliciousAffliction.java b/Mage.Sets/src/mage/cards/m/MaliciousAffliction.java index 2c177e369c8..7df96dfdce9 100644 --- a/Mage.Sets/src/mage/cards/m/MaliciousAffliction.java +++ b/Mage.Sets/src/mage/cards/m/MaliciousAffliction.java @@ -81,7 +81,7 @@ class CopySourceSpellEffect extends OneShotEffect { Spell spell = game.getStack().getSpell(source.getSourceId()); if (spell != null) { StackObject stackObjectCopy = spell.createCopyOnStack(game, source, source.getControllerId(), true); - if (stackObjectCopy != null && stackObjectCopy instanceof Spell) { + if (stackObjectCopy instanceof Spell) { String activateMessage = ((Spell) stackObjectCopy).getActivatedMessage(game); if (activateMessage.startsWith(" casts ")) { activateMessage = activateMessage.substring(6); diff --git a/Mage.Sets/src/mage/cards/m/Manaplasm.java b/Mage.Sets/src/mage/cards/m/Manaplasm.java index d3fab12d96a..26e23737080 100644 --- a/Mage.Sets/src/mage/cards/m/Manaplasm.java +++ b/Mage.Sets/src/mage/cards/m/Manaplasm.java @@ -67,7 +67,7 @@ class ManaplasmAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Spell spell = game.getStack().getSpell(event.getTargetId()); - if (spell != null && spell.getControllerId().equals(controllerId)) { + if (spell != null && spell.isControlledBy(controllerId)) { this.getEffects().remove(0); int x = spell.getConvertedManaCost(); this.addEffect(new BoostSourceEffect(x,x, Duration.EndOfTurn)); diff --git a/Mage.Sets/src/mage/cards/m/MangarasTome.java b/Mage.Sets/src/mage/cards/m/MangarasTome.java index 0d92198f566..c46179ffc40 100644 --- a/Mage.Sets/src/mage/cards/m/MangarasTome.java +++ b/Mage.Sets/src/mage/cards/m/MangarasTome.java @@ -123,6 +123,6 @@ class MangarasTomeReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } } diff --git a/Mage.Sets/src/mage/cards/m/MarangRiverProwler.java b/Mage.Sets/src/mage/cards/m/MarangRiverProwler.java index 1e7591a456a..e03922c936d 100644 --- a/Mage.Sets/src/mage/cards/m/MarangRiverProwler.java +++ b/Mage.Sets/src/mage/cards/m/MarangRiverProwler.java @@ -89,7 +89,7 @@ class MarangRiverProwlerCastEffect extends AsThoughEffectImpl { if (sourceId.equals(source.getSourceId())) { Card card = game.getCard(source.getSourceId()); if (card != null - && card.getOwnerId().equals(affectedControllerId) + && card.isOwnedBy(affectedControllerId) && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD && game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) { return true; diff --git a/Mage.Sets/src/mage/cards/m/MarchOfTheDroids.java b/Mage.Sets/src/mage/cards/m/MarchOfTheDroids.java index 6a07b61fa9f..5e31a472b5b 100644 --- a/Mage.Sets/src/mage/cards/m/MarchOfTheDroids.java +++ b/Mage.Sets/src/mage/cards/m/MarchOfTheDroids.java @@ -69,7 +69,7 @@ class MarchOfTheDroidsEffect extends OneShotEffect { if (controller != null) { Cards cardsToReturn = new CardsImpl(); for (Card card : controller.getGraveyard().getCards(game)) { - if (card.getOwnerId().equals(controller.getId()) && card.getCounters(game).getCount(CounterType.REPAIR) > 0) { + if (card.isOwnedBy(controller.getId()) && card.getCounters(game).getCount(CounterType.REPAIR) > 0) { int number = card.getCounters(game).getCount(CounterType.REPAIR); if (number > 0) { cardsToReturn.add(card); diff --git a/Mage.Sets/src/mage/cards/m/MarchesaTheBlackRose.java b/Mage.Sets/src/mage/cards/m/MarchesaTheBlackRose.java index 6617f13762c..1dc83d372b5 100644 --- a/Mage.Sets/src/mage/cards/m/MarchesaTheBlackRose.java +++ b/Mage.Sets/src/mage/cards/m/MarchesaTheBlackRose.java @@ -89,7 +89,7 @@ class MarchesaTheBlackRoseTriggeredAbility extends TriggeredAbilityImpl { && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { Permanent permanent = ((ZoneChangeEvent) event).getTarget(); if (permanent != null - && permanent.getControllerId().equals(this.getControllerId()) + && permanent.isControlledBy(this.getControllerId()) && permanent.isCreature() && permanent.getCounters(game).getCount(CounterType.P1P1) > 0) { for (Effect effect : this.getEffects()) { diff --git a/Mage.Sets/src/mage/cards/m/MarketFestival.java b/Mage.Sets/src/mage/cards/m/MarketFestival.java index f6421137288..b6431fa7651 100644 --- a/Mage.Sets/src/mage/cards/m/MarketFestival.java +++ b/Mage.Sets/src/mage/cards/m/MarketFestival.java @@ -78,7 +78,7 @@ class MarketFestivalTriggeredAbility extends TriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent enchantment = game.getPermanent(this.getSourceId()); - return enchantment != null && event.getSourceId().equals(enchantment.getAttachedTo()); + return enchantment != null && enchantment.isAttachedTo(event.getSourceId()); } @Override diff --git a/Mage.Sets/src/mage/cards/m/MartyrsBond.java b/Mage.Sets/src/mage/cards/m/MartyrsBond.java index cebfff601bd..930d3670c18 100644 --- a/Mage.Sets/src/mage/cards/m/MartyrsBond.java +++ b/Mage.Sets/src/mage/cards/m/MartyrsBond.java @@ -74,7 +74,7 @@ class MartyrsBondTriggeredAbility extends TriggeredAbilityImpl { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent.getControllerId().equals(this.getControllerId()) && !permanent.isLand()) { + if (permanent.isControlledBy(this.getControllerId()) && !permanent.isLand()) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(permanent.getId())); } diff --git a/Mage.Sets/src/mage/cards/m/MasakoTheHumorless.java b/Mage.Sets/src/mage/cards/m/MasakoTheHumorless.java index e4ef412e4c2..1ab1ddf3505 100644 --- a/Mage.Sets/src/mage/cards/m/MasakoTheHumorless.java +++ b/Mage.Sets/src/mage/cards/m/MasakoTheHumorless.java @@ -68,7 +68,7 @@ class BlockTappedEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { Permanent permanent = game.getPermanent(sourceId); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { + if (permanent != null && permanent.isControlledBy(source.getControllerId())) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/m/MasterBiomancer.java b/Mage.Sets/src/mage/cards/m/MasterBiomancer.java index 7b1ca8c4a8a..79f1c605383 100644 --- a/Mage.Sets/src/mage/cards/m/MasterBiomancer.java +++ b/Mage.Sets/src/mage/cards/m/MasterBiomancer.java @@ -66,7 +66,7 @@ class MasterBiomancerEntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); - return creature != null && creature.getControllerId().equals(source.getControllerId()) + return creature != null && creature.isControlledBy(source.getControllerId()) && creature.isCreature() && !event.getTargetId().equals(source.getSourceId()); } diff --git a/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java b/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java index d85d9d55468..a0b101ebcb4 100644 --- a/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java +++ b/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java @@ -83,7 +83,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) && creature.getControllerId().equals(controllerId)) { + if (creature != null && filter.match(creature, game) && creature.isControlledBy(controllerId)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/m/MelekIzzetParagon.java b/Mage.Sets/src/mage/cards/m/MelekIzzetParagon.java index a407ae32946..8d6dd6cd670 100644 --- a/Mage.Sets/src/mage/cards/m/MelekIzzetParagon.java +++ b/Mage.Sets/src/mage/cards/m/MelekIzzetParagon.java @@ -93,7 +93,7 @@ class MelekIzzetParagonTriggeredAbility extends TriggeredAbilityImpl { if (event.getZone() == Zone.LIBRARY) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null - && spell.getOwnerId().equals(super.getControllerId()) + && spell.isOwnedBy(super.getControllerId()) && (spell.isInstant() || spell.isSorcery())) { for (Effect effect : this.getEffects()) { diff --git a/Mage.Sets/src/mage/cards/m/MeliraSylvokOutcast.java b/Mage.Sets/src/mage/cards/m/MeliraSylvokOutcast.java index d83881a5f5e..d3d868a2e25 100644 --- a/Mage.Sets/src/mage/cards/m/MeliraSylvokOutcast.java +++ b/Mage.Sets/src/mage/cards/m/MeliraSylvokOutcast.java @@ -121,7 +121,7 @@ class MeliraSylvokOutcastEffect2 extends ReplacementEffectImpl { if (perm == null) { perm = game.getPermanentEntering(event.getTargetId()); } - if (perm != null && perm.isCreature() && perm.getControllerId().equals(source.getControllerId())) { + if (perm != null && perm.isCreature() && perm.isControlledBy(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/m/MemoryCrystal.java b/Mage.Sets/src/mage/cards/m/MemoryCrystal.java index 961c67224f3..2da9818be48 100644 --- a/Mage.Sets/src/mage/cards/m/MemoryCrystal.java +++ b/Mage.Sets/src/mage/cards/m/MemoryCrystal.java @@ -74,7 +74,7 @@ class MemoryCrystalSpellsCostReductionEffect extends CostModificationEffectImpl @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { - if (abilityToModify.getControllerId().equals(source.getControllerId())) { + if (abilityToModify.isControlledBy(source.getControllerId())) { Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); if (spell != null) { if (BuybackCondition.instance.apply(game, abilityToModify)) { diff --git a/Mage.Sets/src/mage/cards/m/MetallicMimic.java b/Mage.Sets/src/mage/cards/m/MetallicMimic.java index 28105b9f4d6..8788555ab1a 100644 --- a/Mage.Sets/src/mage/cards/m/MetallicMimic.java +++ b/Mage.Sets/src/mage/cards/m/MetallicMimic.java @@ -75,7 +75,7 @@ class MetallicMimicReplacementEffect extends ReplacementEffectImpl { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Permanent enteringCreature = ((EntersTheBattlefieldEvent) event).getTarget(); if (enteringCreature != null && sourcePermanent != null - && enteringCreature.getControllerId().equals(source.getControllerId()) + && enteringCreature.isControlledBy(source.getControllerId()) && enteringCreature.isCreature() && !event.getTargetId().equals(source.getSourceId())) { SubType subType = ChooseCreatureTypeEffect.getChoosenCreatureType(source.getSourceId(), game); diff --git a/Mage.Sets/src/mage/cards/m/MetamorphicAlteration.java b/Mage.Sets/src/mage/cards/m/MetamorphicAlteration.java new file mode 100644 index 00000000000..8b09566c295 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MetamorphicAlteration.java @@ -0,0 +1,153 @@ +package mage.cards.m; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * + * @author noahg + */ +public final class MetamorphicAlteration extends CardImpl { + + public MetamorphicAlteration(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); + + // As Metamorphic Alteration enters the battlefield, choose a creature. + this.addAbility(new AsEntersBattlefieldAbility(new ChooseACreature())); + + // Enchanted creature is a copy of the chosen creature. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MetamorphicAlterationEffect())); + } + + public MetamorphicAlteration(final MetamorphicAlteration card) { + super(card); + } + + @Override + public MetamorphicAlteration copy() { + return new MetamorphicAlteration(this); + } +} + +class ChooseACreature extends OneShotEffect { + + public static String INFO_KEY = "CHOSEN_CREATURE"; + + public ChooseACreature() { + super(Outcome.Copy); + staticText = "choose a creature"; + } + + public ChooseACreature(final ChooseACreature effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getPermanentEntering(source.getSourceId()); + if (sourceObject == null) { + sourceObject = game.getObject(source.getSourceId()); + } + if (controller != null && sourceObject != null) { + Target target = new TargetCreaturePermanent(); + target.setNotTarget(true); + if (target.canChoose(source.getSourceId(), controller.getId(), game)) { + controller.choose(Outcome.Copy, target, source.getSourceId(), game); + Permanent chosenPermanent = game.getPermanent(target.getFirstTarget()); + game.getState().setValue(source.getSourceId().toString() + INFO_KEY, chosenPermanent.copy()); + } + } + return false; + } + + @Override + public ChooseACreature copy() { + return new ChooseACreature(this); + } +} + +class MetamorphicAlterationEffect extends ContinuousEffectImpl { + + public MetamorphicAlterationEffect() { + super(Duration.WhileOnBattlefield, Layer.CopyEffects_1, SubLayer.NA, Outcome.Copy); + this.staticText = "Enchanted creature is a copy of the chosen creature."; + } + + public MetamorphicAlterationEffect(MetamorphicAlterationEffect effect) { + super(effect); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + //TODO this is stupid and there's got to be a better way, but it works and people probably want to practice full M19 before Prerelease. + Permanent enchantment = game.getPermanent(source.getSourceId()); + Permanent copied = (Permanent) game.getState().getValue(source.getSourceId().toString() + ChooseACreature.INFO_KEY); + if (enchantment != null && copied != null) { + Permanent permanent = game.getPermanent(enchantment.getAttachedTo()); + if (permanent != null && layer == Layer.CopyEffects_1) { + permanent.setName(copied.getName()); + permanent.getManaCost().clear(); + permanent.getManaCost().addAll(copied.getManaCost()); + permanent.setExpansionSetCode(copied.getExpansionSetCode()); + permanent.getSuperType().clear(); + for (SuperType t : copied.getSuperType()) { + permanent.addSuperType(t); + } + permanent.getCardType().clear(); + for (CardType t : copied.getCardType()) { + permanent.addCardType(t); + } + permanent.getSubtype(game).retainAll(SubType.getLandTypes(false)); + for (SubType t : copied.getSubtype(game)) { + permanent.getSubtype(game).add(t); + } + permanent.getColor(game).setColor(copied.getColor(game)); + permanent.removeAllAbilities(source.getSourceId(), game); + for (Ability ability : copied.getAbilities()) { + permanent.addAbility(ability, source.getSourceId(), game); + } + permanent.getPower().setValue(copied.getPower().getValue()); + permanent.getToughness().setValue(copied.getToughness().getValue()); + return true; + } + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public MetamorphicAlterationEffect copy() { + return new MetamorphicAlterationEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/MidnightOil.java b/Mage.Sets/src/mage/cards/m/MidnightOil.java index 3dd316efc81..954d3408969 100644 --- a/Mage.Sets/src/mage/cards/m/MidnightOil.java +++ b/Mage.Sets/src/mage/cards/m/MidnightOil.java @@ -87,10 +87,8 @@ class MidnightOilTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (getControllerId().equals(event.getPlayerId())) { - return true; - } - return false; + return isControlledBy(event.getPlayerId()); + } @Override diff --git a/Mage.Sets/src/mage/cards/m/MightMakesRight.java b/Mage.Sets/src/mage/cards/m/MightMakesRight.java index 43ffe00f406..3054b42de96 100644 --- a/Mage.Sets/src/mage/cards/m/MightMakesRight.java +++ b/Mage.Sets/src/mage/cards/m/MightMakesRight.java @@ -82,7 +82,7 @@ enum ControlsEachCreatureWithGreatestPowerCondition implements Condition { result = true; } if (power == maxPower) { - result &= permanent.getControllerId().equals(source.getControllerId()); + result &= permanent.isControlledBy(source.getControllerId()); } } return result; diff --git a/Mage.Sets/src/mage/cards/m/MindbladeRender.java b/Mage.Sets/src/mage/cards/m/MindbladeRender.java index ab7e20d8796..f17a4d593cb 100644 --- a/Mage.Sets/src/mage/cards/m/MindbladeRender.java +++ b/Mage.Sets/src/mage/cards/m/MindbladeRender.java @@ -1,4 +1,3 @@ - package mage.cards.m; import java.util.UUID; @@ -12,6 +11,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.DamagedPlayerEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -48,13 +48,13 @@ class MindbladeRenderTriggeredAbility extends TriggeredAbilityImpl { private boolean usedForCombatDamageStep; - MindbladeRenderTriggeredAbility() { + public MindbladeRenderTriggeredAbility() { super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1)); this.addEffect(new LoseLifeSourceControllerEffect(1)); this.usedForCombatDamageStep = false; } - MindbladeRenderTriggeredAbility(final MindbladeRenderTriggeredAbility effect) { + public MindbladeRenderTriggeredAbility(final MindbladeRenderTriggeredAbility effect) { super(effect); this.usedForCombatDamageStep = effect.usedForCombatDamageStep; } @@ -71,6 +71,13 @@ class MindbladeRenderTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST) { + usedForCombatDamageStep = false; + return false; + } + if (event.getType() != GameEvent.EventType.DAMAGED_PLAYER) { + return false; + } Player controller = game.getPlayer(getControllerId()); if (controller == null) { return false; @@ -79,17 +86,13 @@ class MindbladeRenderTriggeredAbility extends TriggeredAbilityImpl { if (damager == null) { return false; } - if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER - && event.getFlag() + if (((DamagedPlayerEvent) event).isCombatDamage() && controller.hasOpponent(event.getTargetId(), game) && damager.hasSubtype(SubType.WARRIOR, game) && !usedForCombatDamageStep) { usedForCombatDamageStep = true; return true; } - if (event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST) { - usedForCombatDamageStep = false; - } return false; } diff --git a/Mage.Sets/src/mage/cards/m/Mindswipe.java b/Mage.Sets/src/mage/cards/m/Mindswipe.java index cda1df94a9f..fbfa217fd31 100644 --- a/Mage.Sets/src/mage/cards/m/Mindswipe.java +++ b/Mage.Sets/src/mage/cards/m/Mindswipe.java @@ -70,7 +70,7 @@ class MindswipeEffect extends OneShotEffect { if (object == null) { object = game.getLastKnownInformation(getTargetPointer().getFirst(game, source), Zone.STACK); } - if (object != null && object instanceof Spell) { + if (object instanceof Spell) { Spell spell = (Spell) object; Player spellController = game.getPlayer(spell.getControllerId()); if (spellController != null) { diff --git a/Mage.Sets/src/mage/cards/m/MineMineMine.java b/Mage.Sets/src/mage/cards/m/MineMineMine.java index 51f7444aaa2..b5c54f0dad2 100644 --- a/Mage.Sets/src/mage/cards/m/MineMineMine.java +++ b/Mage.Sets/src/mage/cards/m/MineMineMine.java @@ -63,7 +63,7 @@ class MineMineMineDrawEffect extends OneShotEffect { MineMineMineDrawEffect() { super(Outcome.DrawCard); - this.staticText = "each player puts his or her library into his or her hand"; + this.staticText = "each player puts their library into their hand"; } MineMineMineDrawEffect(final MineMineMineDrawEffect effect) { diff --git a/Mage.Sets/src/mage/cards/m/Mirari.java b/Mage.Sets/src/mage/cards/m/Mirari.java index bdace8ebf8e..0c0b0fe580f 100644 --- a/Mage.Sets/src/mage/cards/m/Mirari.java +++ b/Mage.Sets/src/mage/cards/m/Mirari.java @@ -92,7 +92,7 @@ class MirariTriggeredAbility extends TriggeredAbilityImpl { private boolean isControlledInstantOrSorcery(Spell spell) { return spell != null - && (spell.getControllerId().equals(this.getControllerId())) + && (spell.isControlledBy(this.getControllerId())) && (spell.isInstant() || spell.isSorcery()); } diff --git a/Mage.Sets/src/mage/cards/m/MirrorMatch.java b/Mage.Sets/src/mage/cards/m/MirrorMatch.java index f3bfc7ae932..895f00a1caa 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorMatch.java +++ b/Mage.Sets/src/mage/cards/m/MirrorMatch.java @@ -70,7 +70,7 @@ class MirrorMatchEffect extends OneShotEffect { for (UUID attackerId : game.getCombat().getAttackers()) { Permanent attacker = game.getPermanent(attackerId); if (attacker != null - && source.getControllerId().equals(game.getCombat().getDefendingPlayerId(attackerId, game))) { + && source.isControlledBy(game.getCombat().getDefendingPlayerId(attackerId, game))) { CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false); effect.setTargetPointer(new FixedTarget(attacker, game)); effect.apply(game, source); diff --git a/Mage.Sets/src/mage/cards/m/MirrorOfFate.java b/Mage.Sets/src/mage/cards/m/MirrorOfFate.java index f66350bffed..bc8bd0e12fd 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorOfFate.java +++ b/Mage.Sets/src/mage/cards/m/MirrorOfFate.java @@ -134,7 +134,7 @@ class MirrorOfFateTarget extends TargetCardInExile { @Override public boolean canTarget(UUID id, Ability source, Game game) { Card card = game.getCard(id); - if (card != null && card.getOwnerId().equals(source.getControllerId()) + if (card != null && card.isOwnedBy(source.getControllerId()) && game.getState().getZone(card.getId()) == Zone.EXILED) { for (ExileZone exile : game.getExile().getExileZones()) { if (exile != null && exile.contains(id)) { diff --git a/Mage.Sets/src/mage/cards/m/MirrorwingDragon.java b/Mage.Sets/src/mage/cards/m/MirrorwingDragon.java index d91e782b5b3..73e4af0c51d 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorwingDragon.java +++ b/Mage.Sets/src/mage/cards/m/MirrorwingDragon.java @@ -153,7 +153,7 @@ class MirrorwingDragonCopySpellEffect extends CopySpellForEachItCouldTargetEffec @Override protected boolean okUUIDToCopyFor(UUID potentialTarget, Game game, Ability source, Spell spell) { Permanent permanent = game.getPermanent(potentialTarget); - if (permanent == null || !permanent.getControllerId().equals(spell.getControllerId())) { + if (permanent == null || !permanent.isControlledBy(spell.getControllerId())) { return false; } return true; diff --git a/Mage.Sets/src/mage/cards/m/MisthollowGriffin.java b/Mage.Sets/src/mage/cards/m/MisthollowGriffin.java index cc59223b768..decac80309c 100644 --- a/Mage.Sets/src/mage/cards/m/MisthollowGriffin.java +++ b/Mage.Sets/src/mage/cards/m/MisthollowGriffin.java @@ -72,7 +72,7 @@ class MisthollowGriffinPlayEffect extends AsThoughEffectImpl { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { if (sourceId.equals(source.getSourceId())) { Card card = game.getCard(source.getSourceId()); - if (card != null && card.getOwnerId().equals(affectedControllerId) + if (card != null && card.isOwnedBy(affectedControllerId) && game.getState().getZone(source.getSourceId()) == Zone.EXILED) { return true; } diff --git a/Mage.Sets/src/mage/cards/m/MizzixOfTheIzmagnus.java b/Mage.Sets/src/mage/cards/m/MizzixOfTheIzmagnus.java index c5de6457ea4..4a598ae096b 100644 --- a/Mage.Sets/src/mage/cards/m/MizzixOfTheIzmagnus.java +++ b/Mage.Sets/src/mage/cards/m/MizzixOfTheIzmagnus.java @@ -107,7 +107,7 @@ class MizzixOfTheIzmagnusCostReductionEffect extends CostModificationEffectImpl @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { - if (abilityToModify instanceof SpellAbility && abilityToModify.getControllerId().equals(source.getControllerId())) { + if (abilityToModify instanceof SpellAbility && abilityToModify.isControlledBy(source.getControllerId())) { Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); if (spell != null) { return StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY.match(spell, source.getSourceId(), source.getControllerId(), game); diff --git a/Mage.Sets/src/mage/cards/m/MoggInfestation.java b/Mage.Sets/src/mage/cards/m/MoggInfestation.java index be7b4dc9a4c..e0a05836ef8 100644 --- a/Mage.Sets/src/mage/cards/m/MoggInfestation.java +++ b/Mage.Sets/src/mage/cards/m/MoggInfestation.java @@ -65,7 +65,7 @@ class MoggInfestationEffect extends OneShotEffect { if (controller != null && getTargetPointer().getFirst(game, source) != null) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, getTargetPointer().getFirst(game, source), game)) { if (permanent.destroy(source.getSourceId(), game, false)) { - if (game.getState().getZone(permanent.getId()).equals(Zone.GRAVEYARD)) { // If a commander is replaced to command zone, the creature does not die + if (game.getState().getZone(permanent.getId()) == Zone.GRAVEYARD) { // If a commander is replaced to command zone, the creature does not die Effect effect = new CreateTokenTargetEffect(new GoblinToken(), 2); effect.setTargetPointer(getTargetPointer()); effect.apply(game, source); diff --git a/Mage.Sets/src/mage/cards/m/MoltenFirebird.java b/Mage.Sets/src/mage/cards/m/MoltenFirebird.java new file mode 100644 index 00000000000..81001ce6abc --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MoltenFirebird.java @@ -0,0 +1,52 @@ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.*; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author noahg + */ +public final class MoltenFirebird extends CardImpl { + + public MoltenFirebird(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); + + this.subtype.add(SubType.PHOENIX); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Molten Firebird dies, return it to the battlefield under its owner’s control at the beginning of the next end step and you skip your next draw step. + Ability ability = new DiesTriggeredAbility(new CreateDelayedTriggeredAbilityEffect( + new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnSourceFromGraveyardToBattlefieldEffect()))); + ability.addEffect(new SkipNextDrawStepControllerEffect()); + this.addAbility(ability); + + // {4}{R}: Exile Molten Firebird. + this.addAbility(new SimpleActivatedAbility(new ExileSourceEffect(), new ManaCostsImpl("{4}{R}"))); + } + + public MoltenFirebird(final MoltenFirebird card) { + super(card); + } + + @Override + public MoltenFirebird copy() { + return new MoltenFirebird(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MonasterySiege.java b/Mage.Sets/src/mage/cards/m/MonasterySiege.java index 7b329972201..162abdd40c7 100644 --- a/Mage.Sets/src/mage/cards/m/MonasterySiege.java +++ b/Mage.Sets/src/mage/cards/m/MonasterySiege.java @@ -86,7 +86,7 @@ class MonasterySiegeCostIncreaseEffect extends CostModificationEffectImpl { return true; } Permanent permanent = game.getPermanent(targetUUID); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { + if (permanent != null && permanent.isControlledBy(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/m/MuldrothaTheGravetide.java b/Mage.Sets/src/mage/cards/m/MuldrothaTheGravetide.java index bc84efc939c..f80bf2ab4d4 100644 --- a/Mage.Sets/src/mage/cards/m/MuldrothaTheGravetide.java +++ b/Mage.Sets/src/mage/cards/m/MuldrothaTheGravetide.java @@ -84,8 +84,8 @@ class MuldrothaTheGravetideCastFromGraveyardEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (source.getControllerId().equals(affectedControllerId) - && source.getControllerId().equals(game.getOwnerId(objectId)) // only from your graveyard + if (source.isControlledBy(affectedControllerId) + && source.isControlledBy(game.getOwnerId(objectId)) // only from your graveyard && affectedControllerId.equals(game.getActivePlayerId()) // only during your turns (e.g. prevent flash creatures) && Zone.GRAVEYARD.equals(game.getState().getZone(objectId))) { MuldrothaTheGravetideWatcher watcher = (MuldrothaTheGravetideWatcher) game.getState().getWatchers().get(MuldrothaTheGravetideWatcher.class.getSimpleName()); @@ -139,13 +139,13 @@ class MuldrothaTheGravetideWatcher extends Watcher { if (event.getType() == GameEvent.EventType.PLAY_LAND) { fromZone = game.getState().getZone(event.getTargetId()); // Remember the Zone the land came from } - if (event.getType() == GameEvent.EventType.LAND_PLAYED && fromZone.equals(Zone.GRAVEYARD)) { + if (event.getType() == GameEvent.EventType.LAND_PLAYED && fromZone == Zone.GRAVEYARD) { addPermanentTypes(event, game.getPermanentOrLKIBattlefield(event.getTargetId()), game); } if (event.getType() == GameEvent.EventType.SPELL_CAST) { Spell spell = (Spell) game.getObject(event.getTargetId()); - if (spell.getFromZone().equals(Zone.GRAVEYARD)) { + if (spell.getFromZone() == Zone.GRAVEYARD) { addPermanentTypes(event, spell, game); } } diff --git a/Mage.Sets/src/mage/cards/m/MuseVessel.java b/Mage.Sets/src/mage/cards/m/MuseVessel.java new file mode 100644 index 00000000000..8744823ebc6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MuseVessel.java @@ -0,0 +1,185 @@ +package mage.cards.m; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; +import mage.constants.*; +import mage.filter.FilterCard; +import mage.game.ExileZone; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInExile; +import mage.target.common.TargetCardInHand; +import mage.util.CardUtil; + +/** + * + * @author noahg + */ +public final class MuseVessel extends CardImpl { + + public MuseVessel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + + + // {3}, {tap}: Target player exiles a card from their hand. Activate this ability only any time you could cast a sorcery. + ActivateAsSorceryActivatedAbility tapAbility = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new MuseVesselExileEffect(), new TapSourceCost()); + tapAbility.addCost(new ManaCostsImpl("{3}")); + tapAbility.addTarget(new TargetPlayer()); + this.addAbility(tapAbility); + + // {1}: Choose a card exiled with Muse Vessel. You may play that card this turn. + SimpleActivatedAbility playAbility = new SimpleActivatedAbility(new MuseVesselMayPlayExiledEffect(), new ManaCostsImpl("{1}")); + playAbility.addTarget(new TargetCardInMuseVesselExile()); + this.addAbility(playAbility); + } + + public MuseVessel(final MuseVessel card) { + super(card); + } + + @Override + public MuseVessel copy() { + return new MuseVessel(this); + } +} + +class MuseVesselExileEffect extends OneShotEffect { + + public MuseVesselExileEffect() { + super(Outcome.Exile); + staticText = "target player exiles a card from their hand"; + } + + public MuseVesselExileEffect(final MuseVesselExileEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + MageObject sourceObject = source.getSourceObject(game); + if (sourceObject == null) { + return false; + } + if (player == null) { + return false; + } + TargetCardInHand target = new TargetCardInHand(); + if (target.canChoose(source.getSourceId(), player.getId(), game) + && target.chooseTarget(Outcome.Exile, player.getId(), source, game)) { + UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); + return player.moveCardsToExile(new CardsImpl(target.getTargets()).getCards(game), source, game, true, exileId, sourceObject.getIdName()); + } + return false; + } + + @Override + public MuseVesselExileEffect copy() { + return new MuseVesselExileEffect(this); + } + +} + +class MuseVesselMayPlayExiledEffect extends AsThoughEffectImpl { + + public MuseVesselMayPlayExiledEffect() { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); + this.staticText = "Choose a card exiled with {this}. You may play that card this turn"; + } + + public MuseVesselMayPlayExiledEffect(final MuseVesselMayPlayExiledEffect effect) { + super(effect); + } + + @Override + public MuseVesselMayPlayExiledEffect copy() { + return new MuseVesselMayPlayExiledEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + return affectedControllerId.equals(source.getControllerId()) + && getTargetPointer().getTargets(game, source).contains(objectId); + } + +} + +class TargetCardInMuseVesselExile extends TargetCardInExile { + + public TargetCardInMuseVesselExile() { + super(1, 1, new FilterCard("card exiled with Muse Vessel"), null); + } + + public TargetCardInMuseVesselExile(final TargetCardInMuseVesselExile target) { + super(target); + } + + @Override + public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { + Set possibleTargets = new HashSet<>(); + Card sourceCard = game.getCard(sourceId); + if (sourceCard != null) { + UUID exileId = CardUtil.getCardExileZoneId(game, sourceId); + ExileZone exile = game.getExile().getExileZone(exileId); + if (exile != null && !exile.isEmpty()) { + possibleTargets.addAll(exile); + } + } + return possibleTargets; + } + + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + Card sourceCard = game.getCard(sourceId); + if (sourceCard != null) { + UUID exileId = CardUtil.getCardExileZoneId(game, sourceId); + ExileZone exile = game.getExile().getExileZone(exileId); + if (exile != null && !exile.isEmpty()) { + return true; + } + } + return false; + } + + @Override + public boolean canTarget(UUID id, Ability source, Game game) { + Card card = game.getCard(id); + if (card != null && game.getState().getZone(card.getId()) == Zone.EXILED) { + ExileZone exile = null; + Card sourceCard = game.getCard(source.getSourceId()); + if (sourceCard != null) { + UUID exileId = CardUtil.getCardExileZoneId(game, source); + exile = game.getExile().getExileZone(exileId); + } + if (exile != null && exile.contains(id)) { + return filter.match(card, source.getControllerId(), game); + } + } + return false; + } + + @Override + public TargetCardInMuseVesselExile copy() { + return new TargetCardInMuseVesselExile(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/MycoidShepherd.java b/Mage.Sets/src/mage/cards/m/MycoidShepherd.java index 2e00d71e7ec..ae18362969c 100644 --- a/Mage.Sets/src/mage/cards/m/MycoidShepherd.java +++ b/Mage.Sets/src/mage/cards/m/MycoidShepherd.java @@ -75,7 +75,7 @@ class MycoidShepherdTriggeredAbility extends TriggeredAbilityImpl { } if (super.getSourceId().equals(event.getTargetId()) || permanent.getPower().getValue() > 4 - && permanent.getControllerId().equals(controllerId)) { + && permanent.isControlledBy(controllerId)) { Zone after = game.getState().getZone(event.getTargetId()); return after != null && Zone.GRAVEYARD.match(after); } diff --git a/Mage.Sets/src/mage/cards/n/NabanDeanOfIteration.java b/Mage.Sets/src/mage/cards/n/NabanDeanOfIteration.java index 3a7b63ae636..be2690ceb58 100644 --- a/Mage.Sets/src/mage/cards/n/NabanDeanOfIteration.java +++ b/Mage.Sets/src/mage/cards/n/NabanDeanOfIteration.java @@ -74,7 +74,7 @@ class NabanDeanOfIterationEffect extends ReplacementEffectImpl { if (event instanceof NumberOfTriggersEvent) { NumberOfTriggersEvent numberOfTriggersEvent = (NumberOfTriggersEvent) event; // Only triggers of the controller of Naban - if (source.getControllerId().equals(event.getPlayerId())) { + if (source.isControlledBy(event.getPlayerId())) { GameEvent sourceEvent = numberOfTriggersEvent.getSourceEvent(); // Only EtB triggers if (sourceEvent != null diff --git a/Mage.Sets/src/mage/cards/n/NaturesWill.java b/Mage.Sets/src/mage/cards/n/NaturesWill.java index 2aec1b05d60..f96bc4b0065 100644 --- a/Mage.Sets/src/mage/cards/n/NaturesWill.java +++ b/Mage.Sets/src/mage/cards/n/NaturesWill.java @@ -63,7 +63,7 @@ class NaturesWillEffect extends OneShotEffect { for (Permanent land : lands) { if (damagedPlayers.contains(land.getControllerId())) { land.tap(game); - } else if (land.getControllerId().equals(source.getControllerId())) { + } else if (land.isControlledBy(source.getControllerId())) { land.untap(game); } } diff --git a/Mage.Sets/src/mage/cards/n/NecromancersMagemark.java b/Mage.Sets/src/mage/cards/n/NecromancersMagemark.java index 7ec8e35d058..168c633cb71 100644 --- a/Mage.Sets/src/mage/cards/n/NecromancersMagemark.java +++ b/Mage.Sets/src/mage/cards/n/NecromancersMagemark.java @@ -113,7 +113,7 @@ class NecromancersMagemarkEffect extends ReplacementEffectImpl { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { Permanent permanent = ((ZoneChangeEvent) event).getTarget(); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { + if (permanent != null && permanent.isControlledBy(source.getControllerId())) { for (UUID attachmentId : permanent.getAttachments()) { Permanent attachment = game.getPermanentOrLKIBattlefield(attachmentId); if (attachment != null && attachment.hasSubtype(SubType.AURA, game)) { diff --git a/Mage.Sets/src/mage/cards/n/NecropolisRegent.java b/Mage.Sets/src/mage/cards/n/NecropolisRegent.java index d7a628de3d4..5e53ec1011b 100644 --- a/Mage.Sets/src/mage/cards/n/NecropolisRegent.java +++ b/Mage.Sets/src/mage/cards/n/NecropolisRegent.java @@ -76,7 +76,7 @@ class NecropolisRegentTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (((DamagedPlayerEvent) event).isCombatDamage()) { Permanent creature = game.getPermanent(event.getSourceId()); - if (creature != null && creature.getControllerId().equals(controllerId)) { + if (creature != null && creature.isControlledBy(controllerId)) { this.getEffects().clear(); Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(event.getAmount())); effect.setTargetPointer(new FixedTarget(creature.getId())); diff --git a/Mage.Sets/src/mage/cards/n/Necropotence.java b/Mage.Sets/src/mage/cards/n/Necropotence.java index 8a7372a4b2b..3c1cc4bf289 100644 --- a/Mage.Sets/src/mage/cards/n/Necropotence.java +++ b/Mage.Sets/src/mage/cards/n/Necropotence.java @@ -79,7 +79,7 @@ class NecropotenceTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (getControllerId().equals(event.getPlayerId())) { + if (isControlledBy(event.getPlayerId())) { this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getTargetId())); return true; } diff --git a/Mage.Sets/src/mage/cards/n/NestOfScarabs.java b/Mage.Sets/src/mage/cards/n/NestOfScarabs.java index c5d031e6373..2086264318a 100644 --- a/Mage.Sets/src/mage/cards/n/NestOfScarabs.java +++ b/Mage.Sets/src/mage/cards/n/NestOfScarabs.java @@ -56,7 +56,7 @@ class NestOfScarabsTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - boolean weAreDoingIt = getControllerId().equals(game.getControllerId(event.getSourceId())); + boolean weAreDoingIt = isControlledBy(game.getControllerId(event.getSourceId())); boolean isM1M1Counters = event.getData().equals(CounterType.M1M1.getName()); if (weAreDoingIt && isM1M1Counters && event.getAmount() > 0) { Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); diff --git a/Mage.Sets/src/mage/cards/n/NetherTraitor.java b/Mage.Sets/src/mage/cards/n/NetherTraitor.java index e790731580e..269030fc48e 100644 --- a/Mage.Sets/src/mage/cards/n/NetherTraitor.java +++ b/Mage.Sets/src/mage/cards/n/NetherTraitor.java @@ -75,13 +75,13 @@ class NetherTraitorTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; for (Zone z : Zone.values()) { - if (game.getShortLivingLKI(sourceId, z) && !z.equals(Zone.GRAVEYARD)) { + if (game.getShortLivingLKI(sourceId, z) && z != Zone.GRAVEYARD) { return false; } } if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { if (zEvent.getTarget() != null && - zEvent.getTarget().getOwnerId().equals(this.getControllerId()) && + zEvent.getTarget().isOwnedBy(this.getControllerId()) && zEvent.getTarget().isCreature()&& !zEvent.getTarget().getId().equals(this.getSourceId())) { return true; diff --git a/Mage.Sets/src/mage/cards/n/NettlingCurse.java b/Mage.Sets/src/mage/cards/n/NettlingCurse.java new file mode 100644 index 00000000000..18456d6a31b --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NettlingCurse.java @@ -0,0 +1,54 @@ +package mage.cards.n; + +import java.util.UUID; + +import mage.abilities.common.AttacksOrBlocksEnchantedTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.LoseLifeControllerAttachedEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.effects.common.combat.AttacksIfAbleAttachedEffect; +import mage.constants.*; +import mage.target.TargetPlayer; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.effects.common.AttachEffect; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; + +/** + * + * @author noahg + */ +public final class NettlingCurse extends CardImpl { + + public NettlingCurse(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); + + 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); + + // Whenever enchanted creature attacks or blocks, its controller loses 3 life. + this.addAbility(new AttacksOrBlocksEnchantedTriggeredAbility(Zone.BATTLEFIELD, new LoseLifeControllerAttachedEffect(3))); + + // {1}{R}: Enchanted creature attacks this turn if able. + this.addAbility(new SimpleActivatedAbility(new AttacksIfAbleAttachedEffect(Duration.EndOfTurn, AttachmentType.AURA).setText("Enchanted creature attacks this turn if able."), new ManaCostsImpl("{1}{R}"))); + } + + public NettlingCurse(final NettlingCurse card) { + super(card); + } + + @Override + public NettlingCurse copy() { + return new NettlingCurse(this); + } +} diff --git a/Mage.Sets/src/mage/cards/n/Nightcreep.java b/Mage.Sets/src/mage/cards/n/Nightcreep.java new file mode 100644 index 00000000000..13e51cd7b0a --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/Nightcreep.java @@ -0,0 +1,100 @@ +package mage.cards.n; + +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.effects.common.continuous.BecomesBasicLandTargetEffect; +import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTargets; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * + * @author noahg + */ +public final class Nightcreep extends CardImpl { + + public Nightcreep(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}{B}"); + + + // Until end of turn, all creatures become black and all lands become Swamps. + this.getSpellAbility().addEffect(new NightcreepCreatureEffect()); + this.getSpellAbility().addEffect(new NightcreepLandEffect()); + } + + public Nightcreep(final Nightcreep card) { + super(card); + } + + @Override + public Nightcreep copy() { + return new Nightcreep(this); + } +} + +class NightcreepLandEffect extends BecomesBasicLandTargetEffect { + + public NightcreepLandEffect() { + super(Duration.EndOfTurn, SubType.SWAMP); + this.staticText = ""; + } + + public NightcreepLandEffect(NightcreepLandEffect effect) { + super(effect); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + List targets = new ArrayList<>(game.getBattlefield().getActivePermanents(StaticFilters.FILTER_LAND, source.getControllerId(), source.getSourceId(), game)); + this.setTargetPointer(new FixedTargets(targets, game)); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + return super.apply(layer, sublayer, source, game); + } + + @Override + public NightcreepLandEffect copy() { + return new NightcreepLandEffect(this); + } +} + +class NightcreepCreatureEffect extends BecomesColorTargetEffect { + + public NightcreepCreatureEffect() { + super(ObjectColor.BLACK, Duration.EndOfTurn); + this.staticText = "Until end of turn, all creatures become black and all lands become Swamps"; + } + + public NightcreepCreatureEffect(NightcreepCreatureEffect effect) { + super(effect); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + List targets = new ArrayList<>(game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)); + this.setTargetPointer(new FixedTargets(targets, game)); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + return super.apply(layer, sublayer, source, game); + } + + @Override + public NightcreepCreatureEffect copy() { + return new NightcreepCreatureEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/n/NimDeathmantle.java b/Mage.Sets/src/mage/cards/n/NimDeathmantle.java index 6ccaafd97b1..895ef5405cf 100644 --- a/Mage.Sets/src/mage/cards/n/NimDeathmantle.java +++ b/Mage.Sets/src/mage/cards/n/NimDeathmantle.java @@ -91,7 +91,7 @@ class NimDeathmantleTriggeredAbility extends TriggeredAbilityImpl { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; Permanent permanent = zEvent.getTarget(); if (permanent != null - && permanent.getOwnerId().equals(this.controllerId) + && permanent.isOwnedBy(this.controllerId) && zEvent.getToZone() == Zone.GRAVEYARD && zEvent.getFromZone() == Zone.BATTLEFIELD && !(permanent instanceof PermanentToken) diff --git a/Mage.Sets/src/mage/cards/n/NivixAerieOfTheFiremind.java b/Mage.Sets/src/mage/cards/n/NivixAerieOfTheFiremind.java index 38aa79dcba5..f9bbf4d741e 100644 --- a/Mage.Sets/src/mage/cards/n/NivixAerieOfTheFiremind.java +++ b/Mage.Sets/src/mage/cards/n/NivixAerieOfTheFiremind.java @@ -112,7 +112,7 @@ class NivixAerieOfTheFiremindCanCastEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && objectId.equals(this.getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/n/NoRestForTheWicked.java b/Mage.Sets/src/mage/cards/n/NoRestForTheWicked.java index dcf415c54ec..063f4958cbd 100644 --- a/Mage.Sets/src/mage/cards/n/NoRestForTheWicked.java +++ b/Mage.Sets/src/mage/cards/n/NoRestForTheWicked.java @@ -67,7 +67,7 @@ class NoRestForTheWickedEffect extends OneShotEffect { if (c != null) { if (game.getState().getZone(cardId) == Zone.GRAVEYARD && c.isCreature() - && c.getOwnerId().equals(source.getControllerId())) { + && c.isOwnedBy(source.getControllerId())) { cardsToHand.add(c); } } diff --git a/Mage.Sets/src/mage/cards/n/NoblePurpose.java b/Mage.Sets/src/mage/cards/n/NoblePurpose.java index e2df397cd8d..6fce1fb36ff 100644 --- a/Mage.Sets/src/mage/cards/n/NoblePurpose.java +++ b/Mage.Sets/src/mage/cards/n/NoblePurpose.java @@ -66,7 +66,7 @@ class NoblePurposeTriggeredAbility extends TriggeredAbilityImpl { if (damageEvent.isCombatDamage()) { Permanent permanent = game.getPermanent(event.getSourceId()); if (permanent != null && permanent.isCreature() - && permanent.getControllerId().equals(this.getControllerId())) { + && permanent.isControlledBy(this.getControllerId())) { this.getEffects().clear(); this.getEffects().add(new GainLifeEffect(damageEvent.getAmount())); return true; diff --git a/Mage.Sets/src/mage/cards/n/NotOfThisWorld.java b/Mage.Sets/src/mage/cards/n/NotOfThisWorld.java index 5c0ab9a662f..740bd42953c 100644 --- a/Mage.Sets/src/mage/cards/n/NotOfThisWorld.java +++ b/Mage.Sets/src/mage/cards/n/NotOfThisWorld.java @@ -94,7 +94,7 @@ class TargetStackObjectTargetingControlledPermanent extends TargetObject { for (Target target : objectTargets) { for (UUID targetId : target.getTargets()) { Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); - if (targetedPermanent != null && targetedPermanent.getControllerId().equals(sourceControllerId)) { + if (targetedPermanent != null && targetedPermanent.isControlledBy(sourceControllerId)) { return true; } } @@ -121,7 +121,7 @@ class TargetStackObjectTargetingControlledPermanent extends TargetObject { for (Target target : objectTargets) { for (UUID targetId : target.getTargets()) { Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); - if (targetedPermanent != null && targetedPermanent.getControllerId().equals(sourceControllerId)) { + if (targetedPermanent != null && targetedPermanent.isControlledBy(sourceControllerId)) { possibleTargets.add(stackObject.getId()); } } diff --git a/Mage.Sets/src/mage/cards/n/NotionThief.java b/Mage.Sets/src/mage/cards/n/NotionThief.java index 1d790f30eb7..9ff6a3977a7 100644 --- a/Mage.Sets/src/mage/cards/n/NotionThief.java +++ b/Mage.Sets/src/mage/cards/n/NotionThief.java @@ -89,7 +89,7 @@ class NotionThiefReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - if (game.getActivePlayerId().equals(event.getPlayerId()) && game.getStep().getType() == PhaseStep.DRAW) { + if (game.isActivePlayer(event.getPlayerId()) && game.getStep().getType() == PhaseStep.DRAW) { CardsDrawnDuringDrawStepWatcher watcher = (CardsDrawnDuringDrawStepWatcher) game.getState().getWatchers().get(CardsDrawnDuringDrawStepWatcher.class.getSimpleName()); if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) > 0) { return true; diff --git a/Mage.Sets/src/mage/cards/n/NoviceKnight.java b/Mage.Sets/src/mage/cards/n/NoviceKnight.java index c7fb1e98855..1a40f02fc3f 100644 --- a/Mage.Sets/src/mage/cards/n/NoviceKnight.java +++ b/Mage.Sets/src/mage/cards/n/NoviceKnight.java @@ -2,19 +2,20 @@ package mage.cards.n; import java.util.UUID; import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.OrCondition; -import mage.abilities.condition.common.EnchantedSourceCondition; -import mage.abilities.condition.common.EquippedSourceCondition; -import mage.abilities.decorator.ConditionalContinuousEffect; -import mage.abilities.effects.common.combat.CanAttackAsThoughItDidntHaveDefenderSourceEffect; +import mage.abilities.effects.AsThoughEffectImpl; import mage.constants.SubType; import mage.abilities.keyword.DefenderAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AsThoughEffectType; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; /** * @@ -35,18 +36,7 @@ public final class NoviceKnight extends CardImpl { // As long as Novice Knight is enchanted or equipped, it can attack as though it didn't have defender. this.addAbility(new SimpleStaticAbility( - Zone.BATTLEFIELD, - new ConditionalContinuousEffect( - new CanAttackAsThoughItDidntHaveDefenderSourceEffect( - Duration.WhileOnBattlefield - ), - new OrCondition( - EquippedSourceCondition.instance, - new EnchantedSourceCondition() - ), - "As long as {this} is enchanted or equipped, " - + "it can attack as though it didn't have defender." - ) + Zone.BATTLEFIELD, new NoviceKnightEffect() )); } @@ -59,3 +49,45 @@ public final class NoviceKnight extends CardImpl { return new NoviceKnight(this); } } + +class NoviceKnightEffect extends AsThoughEffectImpl { + + public NoviceKnightEffect() { + super(AsThoughEffectType.ATTACK, Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "As long as {this} is enchanted or equipped, " + + "it can attack as though it didn't have defender."; + } + + public NoviceKnightEffect(final NoviceKnightEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public NoviceKnightEffect copy() { + return new NoviceKnightEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (!objectId.equals(source.getSourceId())) { + return false; + } + Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId()); + if (permanent != null) { + for (UUID uuid : permanent.getAttachments()) { + Permanent attached = game.getBattlefield().getPermanent(uuid); + if (attached != null + && (attached.hasSubtype(SubType.EQUIPMENT, game) + || attached.hasSubtype(SubType.AURA, game))) { + return true; + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/n/NykthosShrineToNyx.java b/Mage.Sets/src/mage/cards/n/NykthosShrineToNyx.java index 67453e05318..6b08d876413 100644 --- a/Mage.Sets/src/mage/cards/n/NykthosShrineToNyx.java +++ b/Mage.Sets/src/mage/cards/n/NykthosShrineToNyx.java @@ -66,11 +66,11 @@ class NykthosShrineToNyxManaAbility extends ActivatedManaAbilityImpl { @Override public List getNetMana(Game game) { - netMana.clear(); + ArrayList netManaCopy = new ArrayList<>(); if (game != null) { - netMana.addAll(((ManaEffect) this.getEffects().get(0)).getNetMana(game, this)); + netManaCopy.addAll(((ManaEffect) this.getEffects().get(0)).getNetMana(game, this)); } - return netMana; + return netManaCopy; } } diff --git a/Mage.Sets/src/mage/cards/o/OathOfGideon.java b/Mage.Sets/src/mage/cards/o/OathOfGideon.java index dbc04025c0d..255862c77ed 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfGideon.java +++ b/Mage.Sets/src/mage/cards/o/OathOfGideon.java @@ -63,7 +63,7 @@ class OathOfGideonReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); - return creature != null && creature.getControllerId().equals(source.getControllerId()) + return creature != null && creature.isControlledBy(source.getControllerId()) && creature.isPlaneswalker() && !event.getTargetId().equals(source.getSourceId()); } diff --git a/Mage.Sets/src/mage/cards/o/OathOfNissa.java b/Mage.Sets/src/mage/cards/o/OathOfNissa.java index ce7ead3c278..514e75cb565 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfNissa.java +++ b/Mage.Sets/src/mage/cards/o/OathOfNissa.java @@ -128,7 +128,7 @@ class OathOfNissaSpendAnyManaEffect extends AsThoughEffectImpl implements AsThou @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (source.getControllerId().equals(affectedControllerId)) { + if (source.isControlledBy(affectedControllerId)) { MageObject mageObject = game.getObject(objectId); if (mageObject != null) { if (mageObject.isPlaneswalker()) { diff --git a/Mage.Sets/src/mage/cards/o/OathswornVampire.java b/Mage.Sets/src/mage/cards/o/OathswornVampire.java index a1caad56ea6..8fc5b428128 100644 --- a/Mage.Sets/src/mage/cards/o/OathswornVampire.java +++ b/Mage.Sets/src/mage/cards/o/OathswornVampire.java @@ -80,7 +80,7 @@ class OathswornVampirePlayEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - if (sourceId.equals(source.getSourceId()) && source.getControllerId().equals(affectedControllerId)) { + if (sourceId.equals(source.getSourceId()) && source.isControlledBy(affectedControllerId)) { Card card = game.getCard(source.getSourceId()); if (card != null && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { return condition.apply(game, source); diff --git a/Mage.Sets/src/mage/cards/o/OnceMoreWithFeeling.java b/Mage.Sets/src/mage/cards/o/OnceMoreWithFeeling.java index 467c6d2724d..a5e986680f4 100644 --- a/Mage.Sets/src/mage/cards/o/OnceMoreWithFeeling.java +++ b/Mage.Sets/src/mage/cards/o/OnceMoreWithFeeling.java @@ -55,7 +55,7 @@ class OnceMoreWithFeelingEffect extends OneShotEffect { public OnceMoreWithFeelingEffect() { super(Outcome.Detriment); - staticText = "Exile all permanents and all cards from all graveyards. Each player shuffles his or her hand into his or her library"; + staticText = "Exile all permanents and all cards from all graveyards. Each player shuffles their hand into their library"; } public OnceMoreWithFeelingEffect(final OnceMoreWithFeelingEffect effect) { diff --git a/Mage.Sets/src/mage/cards/o/OonasBlackguard.java b/Mage.Sets/src/mage/cards/o/OonasBlackguard.java index 452995f26ab..f4e3abb70a1 100644 --- a/Mage.Sets/src/mage/cards/o/OonasBlackguard.java +++ b/Mage.Sets/src/mage/cards/o/OonasBlackguard.java @@ -74,7 +74,7 @@ class OonasBlackguardReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); - if (creature != null && creature.getControllerId().equals(source.getControllerId()) + if (creature != null && creature.isControlledBy(source.getControllerId()) && creature.isCreature() && creature.hasSubtype(SubType.ROGUE, game) && !event.getTargetId().equals(source.getSourceId())) { @@ -127,7 +127,7 @@ class OonasBlackguardTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (((DamagedPlayerEvent) event).isCombatDamage()) { Permanent creature = game.getPermanent(event.getSourceId()); - if (creature != null && creature.getControllerId().equals(getControllerId()) && creature.getCounters(game).getCount(CounterType.P1P1) > 0) { + if (creature != null && creature.isControlledBy(getControllerId()) && creature.getCounters(game).getCount(CounterType.P1P1) > 0) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getPlayerId())); } diff --git a/Mage.Sets/src/mage/cards/o/OracleEnVec.java b/Mage.Sets/src/mage/cards/o/OracleEnVec.java index 4770125d3fc..118fd61524d 100644 --- a/Mage.Sets/src/mage/cards/o/OracleEnVec.java +++ b/Mage.Sets/src/mage/cards/o/OracleEnVec.java @@ -139,7 +139,7 @@ class OracleEnVecMustAttackRequirementEffect extends RequirementEffect { public boolean isInactive(Ability source, Game game) { return startingTurn != game.getTurnNum() && (game.getPhase().getType() == TurnPhase.END - && game.getActivePlayerId().equals(this.getTargetPointer().getFirst(game, source))); + && game.isActivePlayer(this.getTargetPointer().getFirst(game, source))); } @Override @@ -177,7 +177,7 @@ class OracleEnVecCantAttackRestrictionEffect extends RestrictionEffect { public boolean isInactive(Ability source, Game game) { return startingTurn != game.getTurnNum() && (game.getPhase().getType() == TurnPhase.END - && game.getActivePlayerId().equals(this.getTargetPointer().getFirst(game, source))); + && game.isActivePlayer(this.getTargetPointer().getFirst(game, source))); } @Override @@ -207,7 +207,7 @@ class OracleEnVecDelayedTriggeredAbility extends DelayedTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - return startingTurn != game.getTurnNum() && game.getActivePlayerId().equals(event.getPlayerId()); + return startingTurn != game.getTurnNum() && game.isActivePlayer(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/o/OranRiefHydra.java b/Mage.Sets/src/mage/cards/o/OranRiefHydra.java index ff793ae4f9e..fab442f4267 100644 --- a/Mage.Sets/src/mage/cards/o/OranRiefHydra.java +++ b/Mage.Sets/src/mage/cards/o/OranRiefHydra.java @@ -78,7 +78,7 @@ class OranRiefHydraTriggeredAbility extends TriggeredAbilityImpl { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.isLand() - && permanent.getControllerId().equals(getControllerId())) { + && permanent.isControlledBy(getControllerId())) { Permanent sourcePermanent = game.getPermanent(getSourceId()); if (sourcePermanent != null) { for (Effect effect : getEffects()) { diff --git a/Mage.Sets/src/mage/cards/o/OrderOfSuccession.java b/Mage.Sets/src/mage/cards/o/OrderOfSuccession.java index e88e00e95c3..eb366f17fe2 100644 --- a/Mage.Sets/src/mage/cards/o/OrderOfSuccession.java +++ b/Mage.Sets/src/mage/cards/o/OrderOfSuccession.java @@ -70,7 +70,7 @@ class OrderOfSuccessionEffect extends OneShotEffect { if (controller != null) { Map playerCreature = new HashMap<>(2); Choice choice = new ChoiceLeftOrRight(); - if (controller.choose(Outcome.Neutral, choice, game)) { + if (!controller.choose(Outcome.Neutral, choice, game)) { return false; } boolean left = choice.getChoice().equals("Left"); diff --git a/Mage.Sets/src/mage/cards/o/OrnateKanzashi.java b/Mage.Sets/src/mage/cards/o/OrnateKanzashi.java index cde70b63df7..163714d47e0 100644 --- a/Mage.Sets/src/mage/cards/o/OrnateKanzashi.java +++ b/Mage.Sets/src/mage/cards/o/OrnateKanzashi.java @@ -113,7 +113,7 @@ class OrnateKanzashiCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && objectId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/o/OrzhovCharm.java b/Mage.Sets/src/mage/cards/o/OrzhovCharm.java index f15c6adda17..bf6486b1cb5 100644 --- a/Mage.Sets/src/mage/cards/o/OrzhovCharm.java +++ b/Mage.Sets/src/mage/cards/o/OrzhovCharm.java @@ -92,12 +92,12 @@ class OrzhovCharmReturnToHandEffect extends OneShotEffect { attachments.addAll(target.getAttachments()); for (UUID attachmentId : attachments) { Permanent attachment = game.getPermanent(attachmentId); - if (attachment != null && attachment.getControllerId().equals(source.getControllerId()) + if (attachment != null && attachment.isControlledBy(source.getControllerId()) && attachment.hasSubtype(SubType.AURA, game)) { attachment.moveToZone(Zone.HAND, source.getSourceId(), game, false); } } - if (target.getControllerId().equals(source.getControllerId())) { + if (target.isControlledBy(source.getControllerId())) { target.moveToZone(Zone.HAND, source.getSourceId(), game, false); } return true; diff --git a/Mage.Sets/src/mage/cards/o/OutpostSiege.java b/Mage.Sets/src/mage/cards/o/OutpostSiege.java index dc028a94dbf..2fabfdbc093 100644 --- a/Mage.Sets/src/mage/cards/o/OutpostSiege.java +++ b/Mage.Sets/src/mage/cards/o/OutpostSiege.java @@ -133,7 +133,7 @@ class CastFromNonHandZoneTargetEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { if (getTargetPointer().getTargets(game, source).contains(objectId) - && source.getControllerId().equals(affectedControllerId)) { + && source.isControlledBy(affectedControllerId)) { Card card = game.getCard(objectId); if (card != null) { return true; diff --git a/Mage.Sets/src/mage/cards/o/Overgrowth.java b/Mage.Sets/src/mage/cards/o/Overgrowth.java index 27718d28c09..39d17416692 100644 --- a/Mage.Sets/src/mage/cards/o/Overgrowth.java +++ b/Mage.Sets/src/mage/cards/o/Overgrowth.java @@ -77,7 +77,7 @@ class OvergrowthTriggeredAbility extends TriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent enchantment = game.getPermanent(this.getSourceId()); - if (enchantment != null && event.getSourceId().equals(enchantment.getAttachedTo())) { + if (enchantment != null && enchantment.isAttachedTo(event.getSourceId())) { Permanent enchanted = game.getPermanent(enchantment.getAttachedTo()); if (enchanted != null) { getEffects().get(0).setTargetPointer(new FixedTarget(enchanted.getControllerId())); diff --git a/Mage.Sets/src/mage/cards/p/PalisadeGiant.java b/Mage.Sets/src/mage/cards/p/PalisadeGiant.java index 5f3a83ca376..10a8ffde346 100644 --- a/Mage.Sets/src/mage/cards/p/PalisadeGiant.java +++ b/Mage.Sets/src/mage/cards/p/PalisadeGiant.java @@ -98,7 +98,7 @@ class PalisadeGiantReplacementEffect extends ReplacementEffectImpl { Permanent targetPermanent = game.getPermanent(event.getTargetId()); Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (targetPermanent != null && - targetPermanent.getControllerId().equals(source.getControllerId()) && + targetPermanent.isControlledBy(source.getControllerId()) && !targetPermanent.getName().equals(sourcePermanent.getName())) { // no redirection from or to other Palisade Giants return true; } diff --git a/Mage.Sets/src/mage/cards/p/PalladiaMorsTheRuiner.java b/Mage.Sets/src/mage/cards/p/PalladiaMorsTheRuiner.java index 57e06bac912..0ce811c3ee0 100644 --- a/Mage.Sets/src/mage/cards/p/PalladiaMorsTheRuiner.java +++ b/Mage.Sets/src/mage/cards/p/PalladiaMorsTheRuiner.java @@ -33,7 +33,7 @@ import mage.watchers.Watcher; public final class PalladiaMorsTheRuiner extends CardImpl { public PalladiaMorsTheRuiner(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{R}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}{W}"); this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.ELDER); @@ -79,7 +79,7 @@ enum PalladiaMorsTheRuinerCondition implements Condition { public boolean apply(Game game, Ability source) { Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId()); PalladiaMorsTheRuinerWatcher watcher = (PalladiaMorsTheRuinerWatcher) game.getState().getWatchers().get(PalladiaMorsTheRuinerWatcher.class.getSimpleName()); - return !watcher.getDamagers().contains(new MageObjectReference(permanent, game)); + return permanent != null && !watcher.getDamagers().contains(new MageObjectReference(permanent, game)); } @Override @@ -91,7 +91,7 @@ enum PalladiaMorsTheRuinerCondition implements Condition { class PalladiaMorsTheRuinerWatcher extends Watcher { - private Set damagers = new HashSet(); + private final Set damagers = new HashSet(); public PalladiaMorsTheRuinerWatcher() { super(PalladiaMorsTheRuinerWatcher.class.getSimpleName(), WatcherScope.GAME); diff --git a/Mage.Sets/src/mage/cards/p/Panharmonicon.java b/Mage.Sets/src/mage/cards/p/Panharmonicon.java index ea7bedb1874..35ee17e6e70 100644 --- a/Mage.Sets/src/mage/cards/p/Panharmonicon.java +++ b/Mage.Sets/src/mage/cards/p/Panharmonicon.java @@ -66,7 +66,7 @@ class PanharmoniconEffect extends ReplacementEffectImpl { if (event instanceof NumberOfTriggersEvent) { NumberOfTriggersEvent numberOfTriggersEvent = (NumberOfTriggersEvent) event; // Only triggers of the controller of Panharmonicon - if (source.getControllerId().equals(event.getPlayerId())) { + if (source.isControlledBy(event.getPlayerId())) { GameEvent sourceEvent = numberOfTriggersEvent.getSourceEvent(); // Only EtB triggers if (sourceEvent != null diff --git a/Mage.Sets/src/mage/cards/p/ParadoxHaze.java b/Mage.Sets/src/mage/cards/p/ParadoxHaze.java index 38b926a89fb..eb98a98e32b 100644 --- a/Mage.Sets/src/mage/cards/p/ParadoxHaze.java +++ b/Mage.Sets/src/mage/cards/p/ParadoxHaze.java @@ -79,7 +79,7 @@ class ParadoxHazeTriggeredAbility extends TriggeredAbilityImpl { Permanent permanent = game.getPermanent(getSourceId()); if (permanent != null) { Player player = game.getPlayer(permanent.getAttachedTo()); - if (player != null && game.getActivePlayerId().equals(player.getId())) { + if (player != null && game.isActivePlayer(player.getId())) { FirstTimeStepWatcher watcher = (FirstTimeStepWatcher) game.getState().getWatchers().get(EventType.UPKEEP_STEP_POST.toString() + FirstTimeStepWatcher.class.getSimpleName()); if (watcher != null && !watcher.conditionMet()) { this.getEffects().get(0).setTargetPointer(new FixedTarget(player.getId())); diff --git a/Mage.Sets/src/mage/cards/p/ParallelThoughts.java b/Mage.Sets/src/mage/cards/p/ParallelThoughts.java index cf23ec4d588..16858edec0a 100644 --- a/Mage.Sets/src/mage/cards/p/ParallelThoughts.java +++ b/Mage.Sets/src/mage/cards/p/ParallelThoughts.java @@ -150,6 +150,6 @@ class ParallelThoughtsReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } } diff --git a/Mage.Sets/src/mage/cards/p/PathOfMettle.java b/Mage.Sets/src/mage/cards/p/PathOfMettle.java index 274b6023e5b..10ec5e2d641 100644 --- a/Mage.Sets/src/mage/cards/p/PathOfMettle.java +++ b/Mage.Sets/src/mage/cards/p/PathOfMettle.java @@ -101,7 +101,7 @@ class PathOfMettleTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { int attackerCount = 0; if (game.getCombat() != null) { - if (getControllerId().equals(game.getCombat().getAttackingPlayerId())) { + if (isControlledBy(game.getCombat().getAttackingPlayerId())) { for (UUID attacker : game.getCombat().getAttackers()) { if (filter.match(game.getPermanent(attacker), game)) { attackerCount++; diff --git a/Mage.Sets/src/mage/cards/p/PawnOfUlamog.java b/Mage.Sets/src/mage/cards/p/PawnOfUlamog.java index e270d7f1d98..0ef7b2de1c2 100644 --- a/Mage.Sets/src/mage/cards/p/PawnOfUlamog.java +++ b/Mage.Sets/src/mage/cards/p/PawnOfUlamog.java @@ -74,7 +74,7 @@ class PawnOfUlamogTriggeredAbility extends TriggeredAbilityImpl { Permanent permanent = (Permanent) card; ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD - && permanent.getControllerId().equals(this.controllerId) + && permanent.isControlledBy(this.controllerId) && (targetId.equals(this.getSourceId()) || (permanent.isCreature() && !targetId.equals(this.getSourceId()) diff --git a/Mage.Sets/src/mage/cards/p/PedanticLearning.java b/Mage.Sets/src/mage/cards/p/PedanticLearning.java index a11782b0cc0..b72a54652c1 100644 --- a/Mage.Sets/src/mage/cards/p/PedanticLearning.java +++ b/Mage.Sets/src/mage/cards/p/PedanticLearning.java @@ -63,7 +63,7 @@ class PedanticLearningTriggeredAbility extends TriggeredAbilityImpl { UUID cardOwnerId = card.getOwnerId(); Set cardType = card.getCardType(); if (cardOwnerId != null - && card.getOwnerId().equals(getControllerId()) + && card.isOwnedBy(getControllerId()) && cardType != null && card.isLand()) { return true; diff --git a/Mage.Sets/src/mage/cards/p/PerimeterCaptain.java b/Mage.Sets/src/mage/cards/p/PerimeterCaptain.java index f46eaf61a67..5034a47c860 100644 --- a/Mage.Sets/src/mage/cards/p/PerimeterCaptain.java +++ b/Mage.Sets/src/mage/cards/p/PerimeterCaptain.java @@ -67,7 +67,7 @@ class PerimeterCaptainTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent creature = game.getPermanent(event.getSourceId()); if (creature != null) { - if (creature.getControllerId().equals(this.getControllerId()) && creature.getAbilities().contains(DefenderAbility.getInstance())) { + if (creature.isControlledBy(this.getControllerId()) && creature.getAbilities().contains(DefenderAbility.getInstance())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/p/PersonalSanctuary.java b/Mage.Sets/src/mage/cards/p/PersonalSanctuary.java index f6f62c3deb9..2a0cdb373b8 100644 --- a/Mage.Sets/src/mage/cards/p/PersonalSanctuary.java +++ b/Mage.Sets/src/mage/cards/p/PersonalSanctuary.java @@ -68,7 +68,7 @@ class PersonalSanctuaryEffect extends PreventionEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.DAMAGE_PLAYER) { - if (event.getTargetId().equals(source.getControllerId()) && game.getActivePlayerId().equals(source.getControllerId())) + if (event.getTargetId().equals(source.getControllerId()) && game.isActivePlayer(source.getControllerId())) return super.applies(event, source, game); } return false; diff --git a/Mage.Sets/src/mage/cards/p/Portcullis.java b/Mage.Sets/src/mage/cards/p/Portcullis.java index fecfdb308ce..c238942678d 100644 --- a/Mage.Sets/src/mage/cards/p/Portcullis.java +++ b/Mage.Sets/src/mage/cards/p/Portcullis.java @@ -1,4 +1,3 @@ - package mage.cards.p; import java.util.UUID; @@ -32,7 +31,7 @@ public final class Portcullis extends CardImpl { private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature"); public Portcullis(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); // Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature. String rule = "Whenever a creature enters the battlefield, if there are two or more other creatures on the battlefield, exile that creature"; @@ -90,14 +89,18 @@ class PortcullisExileEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); Permanent creature = game.getPermanent(targetPointer.getFirst(game, source)); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + permanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); + } if (permanent != null && creature != null) { Player controller = game.getPlayer(creature.getControllerId()); Zone currentZone = game.getState().getZone(creature.getId()); if (currentZone == Zone.BATTLEFIELD) { controller.moveCardsToExile(creature, source, game, true, CardUtil.getCardExileZoneId(game, source), permanent.getIdName()); + return true; } } return false; diff --git a/Mage.Sets/src/mage/cards/p/PrecipiceOfMortis.java b/Mage.Sets/src/mage/cards/p/PrecipiceOfMortis.java index f0989f29591..8ed229abe34 100644 --- a/Mage.Sets/src/mage/cards/p/PrecipiceOfMortis.java +++ b/Mage.Sets/src/mage/cards/p/PrecipiceOfMortis.java @@ -66,7 +66,7 @@ class PrecipiceOfMortisEffect extends ReplacementEffectImpl { if (event instanceof NumberOfTriggersEvent) { NumberOfTriggersEvent numberOfTriggersEvent = (NumberOfTriggersEvent) event; // Only triggers of the controller of Precipice of Mortis - if (source.getControllerId().equals(event.getPlayerId())) { + if (source.isControlledBy(event.getPlayerId())) { GameEvent sourceEvent = numberOfTriggersEvent.getSourceEvent(); // enters triggers if (sourceEvent.getType() == EventType.ENTERS_THE_BATTLEFIELD && sourceEvent instanceof EntersTheBattlefieldEvent) { diff --git a/Mage.Sets/src/mage/cards/p/PredatoryAdvantage.java b/Mage.Sets/src/mage/cards/p/PredatoryAdvantage.java index 551d5a692cc..fe202bc1e04 100644 --- a/Mage.Sets/src/mage/cards/p/PredatoryAdvantage.java +++ b/Mage.Sets/src/mage/cards/p/PredatoryAdvantage.java @@ -76,7 +76,7 @@ class CastCreatureWatcher extends Watcher { @Override public void watch(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.SPELL_CAST - && game.getActivePlayerId().equals(event.getPlayerId()) + && game.isActivePlayer(event.getPlayerId()) && game.getOpponents(controllerId).contains(event.getPlayerId())) { Spell spell = (Spell) game.getObject(event.getTargetId()); if (spell.isCreature()) { diff --git a/Mage.Sets/src/mage/cards/p/PredatoryFocus.java b/Mage.Sets/src/mage/cards/p/PredatoryFocus.java new file mode 100644 index 00000000000..807f5249596 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PredatoryFocus.java @@ -0,0 +1,81 @@ +package mage.cards.p; + +import java.util.UUID; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.AsThoughEffect; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AsThoughEffectType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author noahg + */ +public final class PredatoryFocus extends CardImpl { + + public PredatoryFocus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}{G}"); + + + // You may have creatures you control assign their combat damage this turn as though they weren't blocked. + this.getSpellAbility().addEffect(new PredatoryFocusEffect()); + } + + public PredatoryFocus(final PredatoryFocus card) { + super(card); + } + + @Override + public PredatoryFocus copy() { + return new PredatoryFocus(this); + } +} + +class PredatoryFocusEffect extends AsThoughEffectImpl { + + private boolean choseUse; + + public PredatoryFocusEffect() { + super(AsThoughEffectType.DAMAGE_NOT_BLOCKED, Duration.EndOfTurn, Outcome.Damage); + this.staticText = "You may have creatures you control assign their combat damage this turn as though they weren't blocked."; + } + + public PredatoryFocusEffect(PredatoryFocusEffect effect) { + super(effect); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + Player controller = game.getPlayer(source.getControllerId()); + String sourceName = source.getSourceObject(game).getLogName(); + choseUse = controller.chooseUse(Outcome.Damage, "Have creatures you control deal combat damage this turn" + + " as though they weren't blocked?", source, game); + game.informPlayers(choseUse ? controller.getName()+" chose to use "+sourceName+"'s effect" : + controller.getName()+" chose not to use "+sourceName+"'s effect."); + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + return choseUse && affectedControllerId.equals(source.getControllerId()); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public PredatoryFocusEffect copy() { + return new PredatoryFocusEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/PriceOfGlory.java b/Mage.Sets/src/mage/cards/p/PriceOfGlory.java index cfe602387f3..c34c287cd4f 100644 --- a/Mage.Sets/src/mage/cards/p/PriceOfGlory.java +++ b/Mage.Sets/src/mage/cards/p/PriceOfGlory.java @@ -69,7 +69,7 @@ class PriceOfGloryAbility extends TriggeredAbilityImpl { } if (permanent.isLand() && player.getInRange().contains(permanent.getControllerId()) - && !permanent.getControllerId().equals(game.getActivePlayerId())) { // intervening if clause + && !permanent.isControlledBy(game.getActivePlayerId())) { // intervening if clause getEffects().get(0).setTargetPointer(new FixedTarget(permanent.getId())); return true; } @@ -103,7 +103,7 @@ class PriceOfGloryEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Permanent land = game.getPermanentOrLKIBattlefield(this.targetPointer.getFirst(game, source)); - if (land != null && !land.getControllerId().equals(game.getActivePlayerId())) { // intervening if clause has to be checked again + if (land != null && !land.isControlledBy(game.getActivePlayerId())) { // intervening if clause has to be checked again land.destroy(source.getSourceId(), game, false); } return true; diff --git a/Mage.Sets/src/mage/cards/p/PrimitiveEtchings.java b/Mage.Sets/src/mage/cards/p/PrimitiveEtchings.java index addf6310f54..630ceaa9e1a 100644 --- a/Mage.Sets/src/mage/cards/p/PrimitiveEtchings.java +++ b/Mage.Sets/src/mage/cards/p/PrimitiveEtchings.java @@ -65,7 +65,7 @@ class PrimitiveEtchingsAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getPlayerId().equals(this.getControllerId())) { - if (game.getActivePlayerId().equals(this.getControllerId()) && this.lastTriggeredTurn != game.getTurnNum()) { + if (game.isActivePlayer(this.getControllerId()) && this.lastTriggeredTurn != game.getTurnNum()) { Card card = game.getCard(event.getTargetId()); Player controller = game.getPlayer(this.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(this.getSourceId()); diff --git a/Mage.Sets/src/mage/cards/p/PrizedAmalgam.java b/Mage.Sets/src/mage/cards/p/PrizedAmalgam.java index a6e0f5b39c9..77d939f26f8 100644 --- a/Mage.Sets/src/mage/cards/p/PrizedAmalgam.java +++ b/Mage.Sets/src/mage/cards/p/PrizedAmalgam.java @@ -88,7 +88,7 @@ class PrizedAmalgamTriggerdAbility extends EntersBattlefieldAllTriggeredAbility EntersTheBattlefieldEvent entersEvent = (EntersTheBattlefieldEvent) event; if (entersEvent.getFromZone() == Zone.GRAVEYARD) { result = true; - } else if (entersEvent.getFromZone() == Zone.STACK && entersEvent.getTarget().getControllerId().equals(getControllerId())) { + } else if (entersEvent.getFromZone() == Zone.STACK && entersEvent.getTarget().isControlledBy(getControllerId())) { CastFromGraveyardWatcher watcher = (CastFromGraveyardWatcher) game.getState().getWatchers().get(CastFromGraveyardWatcher.class.getSimpleName()); if (watcher != null) { int zcc = game.getState().getZoneChangeCounter(event.getSourceId()); diff --git a/Mage.Sets/src/mage/cards/p/ProperBurial.java b/Mage.Sets/src/mage/cards/p/ProperBurial.java index 1c178d59036..53b6feb9d28 100644 --- a/Mage.Sets/src/mage/cards/p/ProperBurial.java +++ b/Mage.Sets/src/mage/cards/p/ProperBurial.java @@ -63,7 +63,7 @@ class ProperBurialTriggeredAbility extends TriggeredAbilityImpl { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent.getControllerId().equals(this.getControllerId()) && permanent.isCreature()) { + if (permanent.isControlledBy(this.getControllerId()) && permanent.isCreature()) { this.getEffects().clear(); this.addEffect(new GainLifeEffect(permanent.getToughness().getValue())); return true; diff --git a/Mage.Sets/src/mage/cards/p/Prophecy.java b/Mage.Sets/src/mage/cards/p/Prophecy.java new file mode 100644 index 00000000000..e8c1e6260f5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/Prophecy.java @@ -0,0 +1,89 @@ +package mage.cards.p; + +import java.util.UUID; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.delayed.AtTheBeginOfNextUpkeepDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +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.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetOpponent; + +/** + * + * @author noahg + */ +public final class Prophecy extends CardImpl { + + public Prophecy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}"); + + + // Reveal the top card of target opponent's library. If it's a land, you gain 1 life. Then that player shuffles their library. + this.getSpellAbility().addEffect(new ProphecyEffect()); + this.getSpellAbility().addTarget(new TargetOpponent()); + + // Draw a card at the beginning of the next turn's upkeep. + this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(new DrawCardSourceControllerEffect(1)), false)); + } + + public Prophecy(final Prophecy card) { + super(card); + } + + @Override + public Prophecy copy() { + return new Prophecy(this); + } +} + +class ProphecyEffect extends OneShotEffect { + + public ProphecyEffect() { + super(Outcome.GainLife); + this.staticText = "Reveal the top card of target opponent's library. If it's a land, you gain 1 life. Then that player shuffles their library"; + } + + public ProphecyEffect(final ProphecyEffect effect) { + super(effect); + } + + @Override + public ProphecyEffect copy() { + return new ProphecyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player targetPlayer = game.getPlayer(source.getFirstTarget()); + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject == null || targetPlayer == null || controller == null) { + return false; + } + if (targetPlayer.getLibrary().hasCards()) { + CardsImpl cards = new CardsImpl(); + Card card = targetPlayer.getLibrary().getFromTop(game); + if (card == null) { + return false; + } + cards.add(card); + targetPlayer.revealCards(sourceObject.getIdName(), cards, game); + if (card.isLand()) { + controller.gainLife(1, game, source.getSourceId()); + } + targetPlayer.shuffleLibrary(source, game); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/p/PropheticFlamespeaker.java b/Mage.Sets/src/mage/cards/p/PropheticFlamespeaker.java index e4a257ed00e..2309a098cd9 100644 --- a/Mage.Sets/src/mage/cards/p/PropheticFlamespeaker.java +++ b/Mage.Sets/src/mage/cards/p/PropheticFlamespeaker.java @@ -113,7 +113,7 @@ class PropheticFlamespeakerCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && objectId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/p/PsychicBattle.java b/Mage.Sets/src/mage/cards/p/PsychicBattle.java index 65673a95833..f4f3eb91b9a 100644 --- a/Mage.Sets/src/mage/cards/p/PsychicBattle.java +++ b/Mage.Sets/src/mage/cards/p/PsychicBattle.java @@ -88,7 +88,7 @@ class PsychicBattleEffect extends OneShotEffect { public PsychicBattleEffect() { super(Outcome.Benefit); - this.staticText = "each player reveals the top card of his or her library. The player who reveals the card with the highest converted mana cost may change the target or targets. If two or more cards are tied for highest cost, the target or targets remain unchanged"; + this.staticText = "each player reveals the top card of their library. The player who reveals the card with the highest converted mana cost may change the target or targets. If two or more cards are tied for highest cost, the target or targets remain unchanged"; } public PsychicBattleEffect(final PsychicBattleEffect effect) { diff --git a/Mage.Sets/src/mage/cards/p/PureIntentions.java b/Mage.Sets/src/mage/cards/p/PureIntentions.java index 9ef3d452264..df8ff3752bb 100644 --- a/Mage.Sets/src/mage/cards/p/PureIntentions.java +++ b/Mage.Sets/src/mage/cards/p/PureIntentions.java @@ -71,7 +71,7 @@ class PureIntentionsAllTriggeredAbility extends DelayedTriggeredAbility { if (stackObject != null && game.getOpponents(this.getControllerId()).contains(stackObject.getControllerId())) { Card card = game.getCard(event.getTargetId()); - if (card != null && card.getOwnerId().equals(getControllerId())) { + if (card != null && card.isOwnedBy(getControllerId())) { for (Effect effect : getEffects()) { effect.setTargetPointer(new FixedTarget(event.getTargetId())); } diff --git a/Mage.Sets/src/mage/cards/p/Purgatory.java b/Mage.Sets/src/mage/cards/p/Purgatory.java index 15fdd00b4be..7fdb5917e89 100644 --- a/Mage.Sets/src/mage/cards/p/Purgatory.java +++ b/Mage.Sets/src/mage/cards/p/Purgatory.java @@ -94,7 +94,7 @@ class PurgatoryTriggeredAbility extends TriggeredAbilityImpl { && zEvent.getFromZone() == Zone.BATTLEFIELD && !(permanent instanceof PermanentToken) && permanent.isCreature() - && permanent.getOwnerId().equals(controller.getId())) { + && permanent.isOwnedBy(controller.getId())) { this.getEffects().get(0).setTargetPointer(new FixedTarget(permanent.getId())); return true; @@ -129,7 +129,7 @@ class PurgatoryExileEffect extends OneShotEffect { MageObject sourceObject = source.getSourceObject(game); Card card = game.getCard(this.getTargetPointer().getFirst(game, source)); if (sourceController != null && exileId != null && sourceObject != null && card != null) { - if (game.getState().getZone(card.getId()).equals(Zone.GRAVEYARD)) { + if (game.getState().getZone(card.getId()) == Zone.GRAVEYARD) { sourceController.moveCardsToExile(card, source, game, true, exileId, sourceObject.getIdName()); } return true; diff --git a/Mage.Sets/src/mage/cards/p/PyromancerAscension.java b/Mage.Sets/src/mage/cards/p/PyromancerAscension.java index 8cb391cd509..c4831f5dd24 100644 --- a/Mage.Sets/src/mage/cards/p/PyromancerAscension.java +++ b/Mage.Sets/src/mage/cards/p/PyromancerAscension.java @@ -88,7 +88,7 @@ class PyromancerAscensionQuestTriggeredAbility extends TriggeredAbilityImpl { private boolean isControlledInstantOrSorcery(Spell spell) { return spell != null && - (spell.getControllerId().equals(this.getControllerId())) && + (spell.isControlledBy(this.getControllerId())) && (spell.isInstant() || spell.isSorcery()); } @@ -135,7 +135,7 @@ class PyromancerAscensionCopyTriggeredAbility extends TriggeredAbilityImpl { private boolean isControlledInstantOrSorcery(Spell spell) { return spell != null && - (spell.getControllerId().equals(this.getControllerId())) && + (spell.isControlledBy(this.getControllerId())) && (spell.isInstant() || spell.isSorcery()); } diff --git a/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java b/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java index 77c12981a06..8c6055dc4bb 100644 --- a/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java +++ b/Mage.Sets/src/mage/cards/p/PyromancersGauntlet.java @@ -63,7 +63,7 @@ class PyromancersGauntletReplacementEffect extends ReplacementEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { MageObject object = game.getObject(event.getSourceId()); if (object != null && object instanceof Spell) { - if (((Spell) object).getControllerId().equals(source.getControllerId()) + if (((Spell) object).isControlledBy(source.getControllerId()) && (object.isInstant() || object.isSorcery())){ return true; diff --git a/Mage.Sets/src/mage/cards/p/PyromancersSwath.java b/Mage.Sets/src/mage/cards/p/PyromancersSwath.java index 79fac231a10..9bcae7d269b 100644 --- a/Mage.Sets/src/mage/cards/p/PyromancersSwath.java +++ b/Mage.Sets/src/mage/cards/p/PyromancersSwath.java @@ -67,7 +67,7 @@ class PyromancersSwathReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (source.getControllerId().equals(game.getControllerId(event.getSourceId()))) { + if (source.isControlledBy(game.getControllerId(event.getSourceId()))) { MageObject object = game.getObject(event.getSourceId()); return object != null && (object.isInstant() || object.isSorcery()); } diff --git a/Mage.Sets/src/mage/cards/q/QasaliAmbusher.java b/Mage.Sets/src/mage/cards/q/QasaliAmbusher.java index c4739d42e48..134df294229 100644 --- a/Mage.Sets/src/mage/cards/q/QasaliAmbusher.java +++ b/Mage.Sets/src/mage/cards/q/QasaliAmbusher.java @@ -81,7 +81,7 @@ class QasaliAmbusherAbility extends ActivatedAbilityImpl { if (!game.getBattlefield().getActivePermanents(filterPlains, this.getControllerId(), this.getSourceId(), game).isEmpty() && !game.getBattlefield().getActivePermanents(filterForest, this.getControllerId(), this.getSourceId(), game).isEmpty()) { for (CombatGroup group : game.getCombat().getGroups()) { - if (getControllerId().equals(group.getDefenderId())) { + if (isControlledBy(group.getDefenderId())) { return super.canActivate(playerId, game); } } diff --git a/Mage.Sets/src/mage/cards/q/QasaliSlingers.java b/Mage.Sets/src/mage/cards/q/QasaliSlingers.java index 7d9b09aac1a..a68dd907373 100644 --- a/Mage.Sets/src/mage/cards/q/QasaliSlingers.java +++ b/Mage.Sets/src/mage/cards/q/QasaliSlingers.java @@ -76,7 +76,7 @@ class QasaliSlingersTriggeredAbility extends TriggeredAbilityImpl { if (permanent.getId().equals(this.getSourceId())) { return true; } - if (permanent.hasSubtype(SubType.CAT, game) && permanent.getControllerId().equals(this.getControllerId())) { + if (permanent.hasSubtype(SubType.CAT, game) && permanent.isControlledBy(this.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java b/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java index ab997678880..abd0c7e33f3 100644 --- a/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java +++ b/Mage.Sets/src/mage/cards/q/QuestForPureFlame.java @@ -72,7 +72,7 @@ class QuestForPureFlameTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { if (game.getOpponents(getControllerId()).contains(event.getTargetId())) { - return getControllerId().equals(game.getControllerId(event.getSourceId())); + return isControlledBy(game.getControllerId(event.getSourceId())); } return false; } @@ -108,7 +108,7 @@ class QuestForPureFlameEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return source.getControllerId().equals(game.getControllerId(event.getSourceId())); + return source.isControlledBy(game.getControllerId(event.getSourceId())); } @Override diff --git a/Mage.Sets/src/mage/cards/q/Quicken.java b/Mage.Sets/src/mage/cards/q/Quicken.java index 07ff6c72b9a..e34973989e3 100644 --- a/Mage.Sets/src/mage/cards/q/Quicken.java +++ b/Mage.Sets/src/mage/cards/q/Quicken.java @@ -86,7 +86,7 @@ class QuickenAsThoughEffect extends AsThoughEffectImpl { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { if (quickenWatcher.isQuickenSpellActive(affectedControllerId, source.getSourceId(), zoneChangeCounter)) { Card card = game.getCard(sourceId); - if (card != null && card.isSorcery() && source.getControllerId().equals(affectedControllerId)) { + if (card != null && card.isSorcery() && source.isControlledBy(affectedControllerId)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/r/RafiqOfTheMany.java b/Mage.Sets/src/mage/cards/r/RafiqOfTheMany.java index c8384d9c944..904e443aa4a 100644 --- a/Mage.Sets/src/mage/cards/r/RafiqOfTheMany.java +++ b/Mage.Sets/src/mage/cards/r/RafiqOfTheMany.java @@ -77,7 +77,7 @@ class RafiqOfTheManyAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getActivePlayerId().equals(this.controllerId) ) { + if (game.isActivePlayer(this.controllerId) ) { if (game.getCombat().attacksAlone()) { for (Effect effect: this.getEffects()) { effect.setTargetPointer(new FixedTarget(game.getCombat().getAttackers().get(0))); diff --git a/Mage.Sets/src/mage/cards/r/RagingRiver.java b/Mage.Sets/src/mage/cards/r/RagingRiver.java index 6f065dd5131..1d5eba39f43 100644 --- a/Mage.Sets/src/mage/cards/r/RagingRiver.java +++ b/Mage.Sets/src/mage/cards/r/RagingRiver.java @@ -128,11 +128,11 @@ class RagingRiverEffect extends OneShotEffect { } else { List leftLog = left.stream() .filter(permanent -> permanent.getControllerId() != null) - .filter(permanent -> permanent.getControllerId().equals(defender.getId())) + .filter(permanent -> permanent.isControlledBy(defender.getId())) .collect(Collectors.toList()); List rightLog = right.stream() .filter(permanent -> permanent.getControllerId() != null) - .filter(permanent -> permanent.getControllerId().equals(defender.getId())) + .filter(permanent -> permanent.isControlledBy(defender.getId())) .collect(Collectors.toList()); diff --git a/Mage.Sets/src/mage/cards/r/RaidBombardment.java b/Mage.Sets/src/mage/cards/r/RaidBombardment.java index 74a95d90a3a..25f1a4d7a1d 100644 --- a/Mage.Sets/src/mage/cards/r/RaidBombardment.java +++ b/Mage.Sets/src/mage/cards/r/RaidBombardment.java @@ -59,7 +59,7 @@ class RaidBombardmentTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getActivePlayerId().equals(this.controllerId)) { + if (game.isActivePlayer(this.controllerId)) { Permanent attacker = game.getPermanent(event.getSourceId()); if (attacker != null) { if (attacker.getPower().getValue() <= 2) { diff --git a/Mage.Sets/src/mage/cards/r/RaidersSpoils.java b/Mage.Sets/src/mage/cards/r/RaidersSpoils.java index dc20f31e86d..ed92d70e999 100644 --- a/Mage.Sets/src/mage/cards/r/RaidersSpoils.java +++ b/Mage.Sets/src/mage/cards/r/RaidersSpoils.java @@ -70,7 +70,7 @@ class RaidersSpoilsTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; Permanent permanent = game.getPermanent(event.getSourceId()); - if (damageEvent.isCombatDamage() && permanent != null && permanent.hasSubtype(SubType.WARRIOR, game) && permanent.getControllerId().equals(controllerId)) { + if (damageEvent.isCombatDamage() && permanent != null && permanent.hasSubtype(SubType.WARRIOR, game) && permanent.isControlledBy(controllerId)) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/r/RainOfGore.java b/Mage.Sets/src/mage/cards/r/RainOfGore.java index e14e6fbfb37..9deeecbaf74 100644 --- a/Mage.Sets/src/mage/cards/r/RainOfGore.java +++ b/Mage.Sets/src/mage/cards/r/RainOfGore.java @@ -77,7 +77,7 @@ class RainOfGoreEffect extends ReplacementEffectImpl { if (!game.getStack().isEmpty()) { StackObject stackObject = game.getStack().getFirst(); if (stackObject != null) { - return stackObject.getControllerId().equals(event.getPlayerId()); + return stackObject.isControlledBy(event.getPlayerId()); } } return false; diff --git a/Mage.Sets/src/mage/cards/r/RakdosAugermage.java b/Mage.Sets/src/mage/cards/r/RakdosAugermage.java new file mode 100644 index 00000000000..422d4c32918 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RakdosAugermage.java @@ -0,0 +1,94 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.RevealHandSourceControllerEffect; +import mage.abilities.effects.common.RevealHandTargetEffect; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetOpponent; + +import java.util.UUID; + +/** + * + * @author noahg + */ +public final class RakdosAugermage extends CardImpl { + + public RakdosAugermage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{B}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // {tap}: Reveal your hand and discard a card of target opponent’s choice. Then that player reveals their hand and discards a card of your choice. Activate this ability only any time you could cast a sorcery. + ActivateAsSorceryActivatedAbility ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new RakdosAugermageEffect(), new TapSourceCost()); + ability.addEffect(new DiscardCardYouChooseTargetEffect()); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public RakdosAugermage(final RakdosAugermage card) { + super(card); + } + + @Override + public RakdosAugermage copy() { + return new RakdosAugermage(this); + } +} + +class RakdosAugermageEffect extends OneShotEffect { + + public RakdosAugermageEffect() { + super(Outcome.Discard); + staticText = "reveal your hand and discard a card of target opponent’s choice"; + } + + public RakdosAugermageEffect(final RakdosAugermageEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + Player controller = game.getPlayer(source.getControllerId()); + Card sourceCard = game.getCard(source.getSourceId()); + if (player != null && controller != null) { + Cards revealedCards = new CardsImpl(); + revealedCards.addAll(controller.getHand()); + player.revealCards((sourceCard != null ? sourceCard.getIdName() + " (" + sourceCard.getZoneChangeCounter(game) + ") (" : "Discard (")+controller.getName()+")", revealedCards, game); + TargetCard target = new TargetCard(Zone.HAND, new FilterCard()); + if (player.choose(Outcome.Benefit, revealedCards, target, game)) { + Card card = revealedCards.get(target.getFirstTarget(), game); + if (card != null) { + return player.discard(card, source, game); + } + } + } + return false; + } + + @Override + public RakdosAugermageEffect copy() { + return new RakdosAugermageEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/RakdosLordOfRiots.java b/Mage.Sets/src/mage/cards/r/RakdosLordOfRiots.java index 18074ed07df..31d5b44e3d4 100644 --- a/Mage.Sets/src/mage/cards/r/RakdosLordOfRiots.java +++ b/Mage.Sets/src/mage/cards/r/RakdosLordOfRiots.java @@ -120,7 +120,7 @@ class RakdosLordOfRiotsCostReductionEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { - if (abilityToModify.getControllerId().equals(source.getControllerId())) { + if (abilityToModify.isControlledBy(source.getControllerId())) { Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); if (spell != null) { return spell.isCreature(); diff --git a/Mage.Sets/src/mage/cards/r/RakdosRiteknife.java b/Mage.Sets/src/mage/cards/r/RakdosRiteknife.java new file mode 100644 index 00000000000..5af3ca5d8db --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RakdosRiteknife.java @@ -0,0 +1,103 @@ +package mage.cards.r; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.abilities.effects.common.SacrificeOpponentsEffect; +import mage.abilities.effects.common.SacrificeTargetEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.constants.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPlayer; +import mage.target.common.TargetControlledCreaturePermanent; + +import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT; + +/** + * + * @author noahg + */ +public final class RakdosRiteknife extends CardImpl { + + public RakdosRiteknife(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + this.subtype.add(SubType.EQUIPMENT); + + // Equipped creature gets +1/+0 for each blood counter on Rakdos Riteknife and has "{T}, Sacrifice a creature: Put a blood counter on Rakdos Riteknife." + SimpleStaticAbility staticAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(new CountersSourceCount(CounterType.BLOOD), new StaticValue(0)).setText("Equipped creature gets +1/+0 for each blood counter on {this}")); + SimpleActivatedAbility grantedAbility = new SimpleActivatedAbility(new RakdosRiteKnifeEffect(this.getId()), new TapSourceCost()); + grantedAbility.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + staticAbility.addEffect(new GainAbilityAttachedEffect(grantedAbility, AttachmentType.EQUIPMENT).setText("and has \"{T}, Sacrifice a creature: Put a blood counter on {this}.\"")); + this.addAbility(staticAbility); + + // {B}{R}, Sacrifice Rakdos Riteknife: Target player sacrifices a permanent for each blood counter on Rakdos Riteknife. + SimpleActivatedAbility activatedAbility = new SimpleActivatedAbility( + new SacrificeEffect(StaticFilters.FILTER_PERMANENT, new CountersSourceCount(CounterType.BLOOD), "Target player") + .setText("target player sacrifices a permanent for each blood counter on {this}"), new ManaCostsImpl("{R}{B}")); + activatedAbility.addCost(new SacrificeSourceCost()); + activatedAbility.addTarget(new TargetPlayer()); + this.addAbility(activatedAbility); + + // Equip {2} + this.addAbility(new EquipAbility(2)); + } + + public RakdosRiteknife(final RakdosRiteknife card) { + super(card); + } + + @Override + public RakdosRiteknife copy() { + return new RakdosRiteknife(this); + } +} + +class RakdosRiteKnifeEffect extends OneShotEffect { + + private UUID effectGivingEquipmentId; + + public RakdosRiteKnifeEffect(UUID effectGivingEquipmentId) { + super(Outcome.Benefit); + this.effectGivingEquipmentId = effectGivingEquipmentId; + staticText = "Put a blood counter on Rakdos Riteknife"; + } + + public RakdosRiteKnifeEffect(final RakdosRiteKnifeEffect effect) { + super(effect); + this.effectGivingEquipmentId = effect.effectGivingEquipmentId; + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent equipment = game.getPermanent(this.effectGivingEquipmentId); + if (equipment != null) { + equipment.addCounters(CounterType.BLOOD.createInstance(), source, game); + } + return true; + } + + @Override + public RakdosRiteKnifeEffect copy() { + return new RakdosRiteKnifeEffect(this); + } + + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/RakishHeir.java b/Mage.Sets/src/mage/cards/r/RakishHeir.java index 4234f39dc99..37de821632b 100644 --- a/Mage.Sets/src/mage/cards/r/RakishHeir.java +++ b/Mage.Sets/src/mage/cards/r/RakishHeir.java @@ -71,7 +71,7 @@ class RakishHeirTriggeredAbility extends TriggeredAbilityImpl { DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; Permanent permanent = game.getPermanent(event.getSourceId()); if (damageEvent.isCombatDamage() && permanent != null - && permanent.hasSubtype(SubType.VAMPIRE, game) && permanent.getControllerId().equals(controllerId)) { + && permanent.hasSubtype(SubType.VAMPIRE, game) && permanent.isControlledBy(controllerId)) { this.getEffects().clear(); AddCountersTargetEffect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); effect.setTargetPointer(new FixedTarget(permanent.getId())); diff --git a/Mage.Sets/src/mage/cards/r/RakshasaVizier.java b/Mage.Sets/src/mage/cards/r/RakshasaVizier.java index 6e306889927..955fc762581 100644 --- a/Mage.Sets/src/mage/cards/r/RakshasaVizier.java +++ b/Mage.Sets/src/mage/cards/r/RakshasaVizier.java @@ -67,7 +67,7 @@ class RakshasaVizierTriggeredAbility extends TriggeredAbilityImpl { if (zEvent.getFromZone() == Zone.GRAVEYARD && zEvent.getToZone() == Zone.EXILED) { Card card = game.getCard(event.getTargetId()); - if (card != null && card.getOwnerId().equals(getControllerId())) { + if (card != null && card.isOwnedBy(getControllerId())) { return true; } diff --git a/Mage.Sets/src/mage/cards/r/RavagerOfTheFells.java b/Mage.Sets/src/mage/cards/r/RavagerOfTheFells.java index 2feb9951b62..c64031eef9a 100644 --- a/Mage.Sets/src/mage/cards/r/RavagerOfTheFells.java +++ b/Mage.Sets/src/mage/cards/r/RavagerOfTheFells.java @@ -164,7 +164,7 @@ class RavagerOfTheFellsTarget extends TargetPermanent { } UUID firstTarget = player.getId(); Permanent permanent = game.getPermanent(id); - if (firstTarget != null && permanent != null && permanent.getControllerId().equals(firstTarget)) { + if (firstTarget != null && permanent != null && permanent.isControlledBy(firstTarget)) { return super.canTarget(id, source, game); } return false; @@ -191,7 +191,7 @@ class RavagerOfTheFellsTarget extends TargetPermanent { if (player != null) { for (UUID targetId : availablePossibleTargets) { Permanent permanent = game.getPermanent(targetId); - if (permanent != null && permanent.getControllerId().equals(player.getId())) { + if (permanent != null && permanent.isControlledBy(player.getId())) { possibleTargets.add(targetId); } } diff --git a/Mage.Sets/src/mage/cards/r/RayneAcademyChancellor.java b/Mage.Sets/src/mage/cards/r/RayneAcademyChancellor.java index 341f7f277d1..b20a2e3d949 100644 --- a/Mage.Sets/src/mage/cards/r/RayneAcademyChancellor.java +++ b/Mage.Sets/src/mage/cards/r/RayneAcademyChancellor.java @@ -77,7 +77,7 @@ class RayneAcademyChancellorTriggeredAbility extends TriggeredAbilityImpl { return true; } Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); - if (permanent != null && this.getControllerId().equals(permanent.getControllerId())) { + if (permanent != null && this.isControlledBy(permanent.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/r/RealitySmasher.java b/Mage.Sets/src/mage/cards/r/RealitySmasher.java index 8d559180e5e..706af59e41f 100644 --- a/Mage.Sets/src/mage/cards/r/RealitySmasher.java +++ b/Mage.Sets/src/mage/cards/r/RealitySmasher.java @@ -73,7 +73,7 @@ class RealitySmasherTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { StackObject spell = game.getStack().getStackObject(event.getSourceId()); - if (spell == null || !(spell instanceof Spell)) { + if (!(spell instanceof Spell)) { return false; } else { if (event.getTargetId().equals(this.getSourceId()) diff --git a/Mage.Sets/src/mage/cards/r/RefractionTrap.java b/Mage.Sets/src/mage/cards/r/RefractionTrap.java index a058cff52dc..84d3bc36722 100644 --- a/Mage.Sets/src/mage/cards/r/RefractionTrap.java +++ b/Mage.Sets/src/mage/cards/r/RefractionTrap.java @@ -158,7 +158,7 @@ class RefractionTrapPreventDamageEffect extends PreventionEffectImpl { // check permanent first Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null) { - if (permanent.getControllerId().equals(source.getControllerId())) { + if (permanent.isControlledBy(source.getControllerId())) { // it's your permanent return true; } diff --git a/Mage.Sets/src/mage/cards/r/RegalBehemoth.java b/Mage.Sets/src/mage/cards/r/RegalBehemoth.java index 2ef608b4954..07e8352ad17 100644 --- a/Mage.Sets/src/mage/cards/r/RegalBehemoth.java +++ b/Mage.Sets/src/mage/cards/r/RegalBehemoth.java @@ -80,7 +80,7 @@ class RegalBehemothTriggeredManaAbility extends TriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (getControllerId().equals(game.getMonarchId())) { + if (isControlledBy(game.getMonarchId())) { Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); if (permanent != null && filter.match(permanent, getSourceId(), getControllerId(), game)) { ManaEvent mEvent = (ManaEvent) event; diff --git a/Mage.Sets/src/mage/cards/r/RemoveEnchantments.java b/Mage.Sets/src/mage/cards/r/RemoveEnchantments.java index 9c6d6165cfa..6828490c7f7 100644 --- a/Mage.Sets/src/mage/cards/r/RemoveEnchantments.java +++ b/Mage.Sets/src/mage/cards/r/RemoveEnchantments.java @@ -86,7 +86,7 @@ class AttachedToOpponentControlledAttackingCreaturePredicate implements ObjectPl if (permanent != null) { if (permanent.isCreature()) { if (permanent.isAttacking()) { - if (!permanent.getControllerId().equals(input.getPlayerId()) && + if (!permanent.isControlledBy(input.getPlayerId()) && game.getPlayer(input.getPlayerId()).hasOpponent(permanent.getControllerId(), game)) { return true; } diff --git a/Mage.Sets/src/mage/cards/r/RenegadeDoppelganger.java b/Mage.Sets/src/mage/cards/r/RenegadeDoppelganger.java index f137b6278f6..a6c2585ab44 100644 --- a/Mage.Sets/src/mage/cards/r/RenegadeDoppelganger.java +++ b/Mage.Sets/src/mage/cards/r/RenegadeDoppelganger.java @@ -72,7 +72,7 @@ class RenegadeDoppelgangerTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (!event.getTargetId().equals(this.getSourceId())) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.isCreature() && permanent.getControllerId().equals(this.getControllerId())) { + if (permanent != null && permanent.isCreature() && permanent.isControlledBy(this.getControllerId())) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(permanent.getId())); } diff --git a/Mage.Sets/src/mage/cards/r/Reparations.java b/Mage.Sets/src/mage/cards/r/Reparations.java index 249f94a636f..e909ec6339f 100644 --- a/Mage.Sets/src/mage/cards/r/Reparations.java +++ b/Mage.Sets/src/mage/cards/r/Reparations.java @@ -74,7 +74,7 @@ class ReparationsTriggeredAbility extends TriggeredAbilityImpl { } if (targetPermanent != null && targetPermanent.isCreature() - && targetPermanent.getControllerId().equals(controllerId)) { + && targetPermanent.isControlledBy(controllerId)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/r/Retribution.java b/Mage.Sets/src/mage/cards/r/Retribution.java index f5167bcbed9..2c0a7214ad3 100644 --- a/Mage.Sets/src/mage/cards/r/Retribution.java +++ b/Mage.Sets/src/mage/cards/r/Retribution.java @@ -107,7 +107,7 @@ class TargetCreaturePermanentOpponentSameController extends TargetCreaturePerman Permanent targetPermanent = game.getPermanent(targetId); if (targetPermanent != null) { if (!firstTargetPermanent.getId().equals(targetPermanent.getId())) { - if (!firstTargetPermanent.getControllerId().equals(targetPermanent.getOwnerId())) { + if (!firstTargetPermanent.isControlledBy(targetPermanent.getOwnerId())) { return false; } } diff --git a/Mage.Sets/src/mage/cards/r/ReturnToDust.java b/Mage.Sets/src/mage/cards/r/ReturnToDust.java index 9cdef129d82..c57d35ac043 100644 --- a/Mage.Sets/src/mage/cards/r/ReturnToDust.java +++ b/Mage.Sets/src/mage/cards/r/ReturnToDust.java @@ -37,7 +37,7 @@ public final class ReturnToDust extends CardImpl { @Override public void adjustTargets(Ability ability, Game game) { if (ability instanceof SpellAbility) { - if (game.getActivePlayerId().equals(ability.getControllerId()) && game.isMainPhase()) { + if (game.isActivePlayer(ability.getControllerId()) && game.isMainPhase()) { ability.addTarget(new TargetPermanent(1, 2, StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT, false)); } else { diff --git a/Mage.Sets/src/mage/cards/r/Revitalize.java b/Mage.Sets/src/mage/cards/r/Revitalize.java index 241448f180b..f4464efc4af 100644 --- a/Mage.Sets/src/mage/cards/r/Revitalize.java +++ b/Mage.Sets/src/mage/cards/r/Revitalize.java @@ -1,4 +1,3 @@ - package mage.cards.r; import java.util.UUID; @@ -18,7 +17,7 @@ public final class Revitalize extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); // You gain 3 life. - this.getSpellAbility().addEffect(new GainLifeEffect(4)); + this.getSpellAbility().addEffect(new GainLifeEffect(3)); // Draw a card. this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); diff --git a/Mage.Sets/src/mage/cards/r/ReyhanLastOfTheAbzan.java b/Mage.Sets/src/mage/cards/r/ReyhanLastOfTheAbzan.java index a814fc7a9fa..3d95cc5195a 100644 --- a/Mage.Sets/src/mage/cards/r/ReyhanLastOfTheAbzan.java +++ b/Mage.Sets/src/mage/cards/r/ReyhanLastOfTheAbzan.java @@ -99,7 +99,7 @@ class ReyhanLastOfTheAbzanTriggeredAbility extends TriggeredAbilityImpl { // You control Player player = game.getPlayer(this.getControllerId()); - if (player == null || !permanent.getControllerId().equals(getControllerId())) { + if (player == null || !permanent.isControlledBy(getControllerId())) { return false; } diff --git a/Mage.Sets/src/mage/cards/r/RhysTheRedeemed.java b/Mage.Sets/src/mage/cards/r/RhysTheRedeemed.java index e87bf81a3f8..1a46092cb31 100644 --- a/Mage.Sets/src/mage/cards/r/RhysTheRedeemed.java +++ b/Mage.Sets/src/mage/cards/r/RhysTheRedeemed.java @@ -91,7 +91,7 @@ class RhysTheRedeemedEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) { - if (permanent.getControllerId().equals(source.getControllerId())) { + if (permanent.isControlledBy(source.getControllerId())) { CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); diff --git a/Mage.Sets/src/mage/cards/r/RingOfMaruf.java b/Mage.Sets/src/mage/cards/r/RingOfMaruf.java index a836a3a52c8..3b39d23e7d1 100644 --- a/Mage.Sets/src/mage/cards/r/RingOfMaruf.java +++ b/Mage.Sets/src/mage/cards/r/RingOfMaruf.java @@ -80,6 +80,6 @@ class RingOfMarufEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } } diff --git a/Mage.Sets/src/mage/cards/r/RisenExecutioner.java b/Mage.Sets/src/mage/cards/r/RisenExecutioner.java index df4278b14bd..40c1b4c7997 100644 --- a/Mage.Sets/src/mage/cards/r/RisenExecutioner.java +++ b/Mage.Sets/src/mage/cards/r/RisenExecutioner.java @@ -91,7 +91,7 @@ class RisenExecutionerCastEffect extends AsThoughEffectImpl { if (sourceId.equals(source.getSourceId())) { Card card = game.getCard(source.getSourceId()); if (card != null - && card.getOwnerId().equals(affectedControllerId) + && card.isOwnedBy(affectedControllerId) && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { return true; } diff --git a/Mage.Sets/src/mage/cards/r/RoninWarclub.java b/Mage.Sets/src/mage/cards/r/RoninWarclub.java index 8cf766bef6d..d3f6624f420 100644 --- a/Mage.Sets/src/mage/cards/r/RoninWarclub.java +++ b/Mage.Sets/src/mage/cards/r/RoninWarclub.java @@ -71,7 +71,7 @@ public final class RoninWarclub extends CardImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent.isCreature() - && (permanent.getControllerId().equals(this.controllerId))) { + && (permanent.isControlledBy(this.controllerId))) { if (!this.getTargets().isEmpty()) { // remove previous target diff --git a/Mage.Sets/src/mage/cards/r/RootSliver.java b/Mage.Sets/src/mage/cards/r/RootSliver.java index 57dc6af5e7a..69c57f6a76b 100644 --- a/Mage.Sets/src/mage/cards/r/RootSliver.java +++ b/Mage.Sets/src/mage/cards/r/RootSliver.java @@ -89,7 +89,7 @@ class RootSliverEffect extends ContinuousRuleModifyingEffectImpl { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null && spell.hasSubtype(SubType.SLIVER, game)) { MageObject sourceObject = game.getObject(event.getSourceId()); - if (sourceObject != null && sourceObject instanceof StackObject) { + if (sourceObject instanceof StackObject) { return true; } } diff --git a/Mage.Sets/src/mage/cards/r/RowanKenrith.java b/Mage.Sets/src/mage/cards/r/RowanKenrith.java index b32b883391f..a3a6678dfd4 100644 --- a/Mage.Sets/src/mage/cards/r/RowanKenrith.java +++ b/Mage.Sets/src/mage/cards/r/RowanKenrith.java @@ -107,14 +107,14 @@ class RowanKenrithAttackEffect extends RequirementEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { - return permanent.getControllerId().equals(source.getFirstTarget()); + return permanent.isControlledBy(source.getFirstTarget()); } @Override public boolean isInactive(Ability source, Game game) { return (startingTurn != game.getTurnNum() && (game.getPhase().getType() == TurnPhase.END - && game.getActivePlayerId().equals(source.getFirstTarget()))) + && game.isActivePlayer(source.getFirstTarget()))) || // 6/15/2010: If a creature controlled by the affected player can't attack Gideon Jura (because he's no longer on the battlefield, for example), that player may have it attack you, another one of your planeswalkers, or nothing at all. creatingPermanent.getPermanent(game) == null; } diff --git a/Mage.Sets/src/mage/cards/r/Rowen.java b/Mage.Sets/src/mage/cards/r/Rowen.java index de7dc8e4fbe..c44d050a386 100644 --- a/Mage.Sets/src/mage/cards/r/Rowen.java +++ b/Mage.Sets/src/mage/cards/r/Rowen.java @@ -65,7 +65,7 @@ class RowenAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getPlayerId().equals(this.getControllerId())) { - if (game.getActivePlayerId().equals(this.getControllerId()) && this.lastTriggeredTurn != game.getTurnNum()) { + if (game.isActivePlayer(this.getControllerId()) && this.lastTriggeredTurn != game.getTurnNum()) { Card card = game.getCard(event.getTargetId()); Player controller = game.getPlayer(this.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(this.getSourceId()); diff --git a/Mage.Sets/src/mage/cards/r/RumblingAftershocks.java b/Mage.Sets/src/mage/cards/r/RumblingAftershocks.java index 20245e932a4..74f8e3b0255 100644 --- a/Mage.Sets/src/mage/cards/r/RumblingAftershocks.java +++ b/Mage.Sets/src/mage/cards/r/RumblingAftershocks.java @@ -78,7 +78,7 @@ class RumblingAftershocksTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Spell spell = game.getStack().getSpell(event.getTargetId()); - if (spell != null && spell.getControllerId().equals(controllerId)) { + if (spell != null && spell.isControlledBy(controllerId)) { int damageAmount = 0; for (Ability ability: spell.getAbilities()) { if (ability instanceof KickerAbility) { diff --git a/Mage.Sets/src/mage/cards/r/RysorianBadger.java b/Mage.Sets/src/mage/cards/r/RysorianBadger.java new file mode 100644 index 00000000000..0b188d906f4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RysorianBadger.java @@ -0,0 +1,105 @@ +package mage.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksAndIsNotBlockedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.AssignNoCombatDamageSourceEffect; +import mage.cards.Card; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.permanent.DefendingPlayerOwnsCardPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInGraveyard; + +/** + * + * @author TheElk801 + */ +public final class RysorianBadger extends CardImpl { + + private static final FilterCreatureCard filter = new FilterCreatureCard("creature cards from defending player's graveyard"); + + static { + filter.add(new DefendingPlayerOwnsCardPredicate()); + } + + public RysorianBadger(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.BADGER); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Rysorian Badger attacks and isn't blocked, you may exile up to two target creature cards from defending player's graveyard. If you do, you gain 1 life for each card exiled this way and Rysorian Badger assigns no combat damage this turn. + Ability ability = new AttacksAndIsNotBlockedTriggeredAbility( + new RysorianBadgerEffect(), true + ); + ability.addTarget(new TargetCardInGraveyard(0, 2, filter)); + this.addAbility(ability); + } + + public RysorianBadger(final RysorianBadger card) { + super(card); + } + + @Override + public RysorianBadger copy() { + return new RysorianBadger(this); + } +} + +class RysorianBadgerEffect extends OneShotEffect { + + public RysorianBadgerEffect() { + super(Outcome.Benefit); + this.staticText = "you may exile up to two target creature cards " + + "from defending player's graveyard. If you do, " + + "you gain 1 life for each card exiled this way " + + "and {this} assigns no combat damage this turn."; + } + + public RysorianBadgerEffect(final RysorianBadgerEffect effect) { + super(effect); + } + + @Override + public RysorianBadgerEffect copy() { + return new RysorianBadgerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Cards cardsToExile = new CardsImpl(); + for (UUID cardId : this.getTargetPointer().getTargets(game, source)) { + Card card = game.getCard(cardId); + if (card != null) { + cardsToExile.add(card); + } + } + int cardsExiled = 0; + player.moveCardsToExile(cardsToExile.getCards(game), source, game, false, null, null); + for (Card card : cardsToExile.getCards(game)) { + if (game.getState().getZone(card.getId()) == Zone.EXILED) { + cardsExiled++; + } + } + player.gainLife(cardsExiled, game, source); + game.addEffect(new AssignNoCombatDamageSourceEffect(Duration.EndOfTurn), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SacredGround.java b/Mage.Sets/src/mage/cards/s/SacredGround.java index bfe3c54d2d0..93a2b21b08f 100644 --- a/Mage.Sets/src/mage/cards/s/SacredGround.java +++ b/Mage.Sets/src/mage/cards/s/SacredGround.java @@ -64,7 +64,7 @@ class SacredGroundTriggeredAbility extends TriggeredAbilityImpl { ZoneChangeEvent zce = (ZoneChangeEvent) event; if (Zone.BATTLEFIELD == zce.getFromZone() && Zone.GRAVEYARD == zce.getToZone()) { Permanent targetPermanent = zce.getTarget(); - if (targetPermanent.isLand() && targetPermanent.getControllerId().equals(getControllerId())) { + if (targetPermanent.isLand() && targetPermanent.isControlledBy(getControllerId())) { getEffects().get(0).setTargetPointer(new FixedTarget(targetPermanent.getId(), game.getState().getZoneChangeCounter(targetPermanent.getId()))); return true; } diff --git a/Mage.Sets/src/mage/cards/s/SaffiEriksdotter.java b/Mage.Sets/src/mage/cards/s/SaffiEriksdotter.java index cb54538d81e..da707f54caf 100644 --- a/Mage.Sets/src/mage/cards/s/SaffiEriksdotter.java +++ b/Mage.Sets/src/mage/cards/s/SaffiEriksdotter.java @@ -106,7 +106,7 @@ class SaffiEriksdotterDelayedTriggeredAbility extends DelayedTriggeredAbility { public boolean checkTrigger(GameEvent event, Game game) { if (((ZoneChangeEvent) event).isDiesEvent()) { if (fixedTarget.getFirst(game, this).equals(event.getTargetId())) { - if (this.getControllerId().equals(event.getPlayerId())) { + if (this.isControlledBy(event.getPlayerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/s/SageOfFables.java b/Mage.Sets/src/mage/cards/s/SageOfFables.java index 1b5b3119905..fb238129d5b 100644 --- a/Mage.Sets/src/mage/cards/s/SageOfFables.java +++ b/Mage.Sets/src/mage/cards/s/SageOfFables.java @@ -71,7 +71,7 @@ class SageOfFablesReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); - return creature != null && creature.getControllerId().equals(source.getControllerId()) + return creature != null && creature.isControlledBy(source.getControllerId()) && creature.isCreature() && creature.hasSubtype(SubType.WIZARD, game) && !event.getTargetId().equals(source.getSourceId()); diff --git a/Mage.Sets/src/mage/cards/s/SagesOfTheAnima.java b/Mage.Sets/src/mage/cards/s/SagesOfTheAnima.java index 05a8e44e5c6..397a44cedaa 100644 --- a/Mage.Sets/src/mage/cards/s/SagesOfTheAnima.java +++ b/Mage.Sets/src/mage/cards/s/SagesOfTheAnima.java @@ -1,4 +1,3 @@ - package mage.cards.s; import java.util.UUID; @@ -53,7 +52,10 @@ class SagesOfTheAnimaReplacementEffect extends ReplacementEffectImpl { public SagesOfTheAnimaReplacementEffect() { super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "If you would draw a card, instead reveal the top three cards of your library. Put all creature cards revealed this way into your hand and the rest on the bottom of your library in any order"; + staticText = "If you would draw a card, instead " + + "reveal the top three cards of your library. " + + "Put all creature cards revealed this way into your hand " + + "and the rest on the bottom of your library in any order"; } public SagesOfTheAnimaReplacementEffect(final SagesOfTheAnimaReplacementEffect effect) { @@ -77,7 +79,7 @@ class SagesOfTheAnimaReplacementEffect extends ReplacementEffectImpl { Cards revealedCards = new CardsImpl(player.getLibrary().getTopCards(game, 3)); player.revealCards(source, revealedCards, game); Cards creatures = new CardsImpl(revealedCards.getCards(StaticFilters.FILTER_CARD_CREATURE, game)); - player.moveCards(creatures, Zone.BATTLEFIELD, source, game); + player.moveCards(creatures, Zone.HAND, source, game); revealedCards.removeAll(creatures); player.putCardsOnBottomOfLibrary(revealedCards, game, source, true); return true; diff --git a/Mage.Sets/src/mage/cards/s/SakikoMotherOfSummer.java b/Mage.Sets/src/mage/cards/s/SakikoMotherOfSummer.java index 59a3944ea53..da0593a803b 100644 --- a/Mage.Sets/src/mage/cards/s/SakikoMotherOfSummer.java +++ b/Mage.Sets/src/mage/cards/s/SakikoMotherOfSummer.java @@ -74,7 +74,7 @@ class SakikoMotherOfSummerTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (((DamagedPlayerEvent) event).isCombatDamage()) { Permanent creature = game.getPermanent(event.getSourceId()); - if (creature != null && creature.getControllerId().equals(controllerId)) { + if (creature != null && creature.isControlledBy(controllerId)) { this.getEffects().clear(); Effect effect = new AddManaToManaPoolTargetControllerEffect(Mana.GreenMana(event.getAmount()), "that player", true); effect.setTargetPointer(new FixedTarget(creature.getControllerId())); diff --git a/Mage.Sets/src/mage/cards/s/SatyrFiredancer.java b/Mage.Sets/src/mage/cards/s/SatyrFiredancer.java index 52deb05c284..fafe9257058 100644 --- a/Mage.Sets/src/mage/cards/s/SatyrFiredancer.java +++ b/Mage.Sets/src/mage/cards/s/SatyrFiredancer.java @@ -95,7 +95,7 @@ class SatyrFiredancerTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (getControllerId().equals(game.getControllerId(event.getSourceId()))) { + if (isControlledBy(game.getControllerId(event.getSourceId()))) { MageObject damageSource = game.getObject(event.getSourceId()); if (damageSource != null) { if (game.getOpponents(getControllerId()).contains(event.getTargetId())) { diff --git a/Mage.Sets/src/mage/cards/s/SavageStomp.java b/Mage.Sets/src/mage/cards/s/SavageStomp.java index 95968629190..8a080176193 100644 --- a/Mage.Sets/src/mage/cards/s/SavageStomp.java +++ b/Mage.Sets/src/mage/cards/s/SavageStomp.java @@ -84,7 +84,7 @@ enum SavageStompCondition implements Condition { Iterator targets = sourceSpell.getStackAbility().getTargets().iterator(); while (targets.hasNext()) { Permanent permanent = game.getPermanentOrLKIBattlefield(targets.next().getFirstTarget()); - if (permanent != null && filter.match(permanent, game) && permanent.getControllerId().equals(source.getControllerId())) { + if (permanent != null && filter.match(permanent, game) && permanent.isControlledBy(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/s/SavageSummoning.java b/Mage.Sets/src/mage/cards/s/SavageSummoning.java index 28c873c4e84..2d19dea4fb8 100644 --- a/Mage.Sets/src/mage/cards/s/SavageSummoning.java +++ b/Mage.Sets/src/mage/cards/s/SavageSummoning.java @@ -103,9 +103,9 @@ class SavageSummoningAsThoughEffect extends AsThoughEffectImpl { if (commander.isCreature() && commander.getControllerId().equals(source.getControllerId())) { return true; } - } else if (mageObject != null && mageObject instanceof Card) { + } else if (mageObject instanceof Card) { Card card = (Card) mageObject; - if (card.isCreature() && card.getOwnerId().equals(source.getControllerId())) { + if (card.isCreature() && card.isOwnedBy(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/s/SavingGrace.java b/Mage.Sets/src/mage/cards/s/SavingGrace.java index 0ee8ad8d973..bf4a045014f 100644 --- a/Mage.Sets/src/mage/cards/s/SavingGrace.java +++ b/Mage.Sets/src/mage/cards/s/SavingGrace.java @@ -94,7 +94,7 @@ class SavingGraceReplacementEffect extends ReplacementEffectImpl { if (event.getType() == GameEvent.EventType.DAMAGE_CREATURE || event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER) { Permanent targetPermanent = game.getPermanent(event.getTargetId()); if (targetPermanent != null - && targetPermanent.getControllerId().equals(source.getControllerId())) { + && targetPermanent.isControlledBy(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/s/ScourgeOfNelToth.java b/Mage.Sets/src/mage/cards/s/ScourgeOfNelToth.java index e6a1cb64b54..4e09668db0b 100644 --- a/Mage.Sets/src/mage/cards/s/ScourgeOfNelToth.java +++ b/Mage.Sets/src/mage/cards/s/ScourgeOfNelToth.java @@ -76,7 +76,7 @@ class ScourgeOfNelTothPlayEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - if (sourceId.equals(source.getSourceId()) && source.getControllerId().equals(affectedControllerId)) { + if (sourceId.equals(source.getSourceId()) && source.isControlledBy(affectedControllerId)) { if (game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { Player player = game.getPlayer(affectedControllerId); if (player != null) { diff --git a/Mage.Sets/src/mage/cards/s/ScoutsWarning.java b/Mage.Sets/src/mage/cards/s/ScoutsWarning.java index c2a22fd2811..5ddb9e6c3a5 100644 --- a/Mage.Sets/src/mage/cards/s/ScoutsWarning.java +++ b/Mage.Sets/src/mage/cards/s/ScoutsWarning.java @@ -87,7 +87,7 @@ class ScoutsWarningAsThoughEffect extends AsThoughEffectImpl { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { if (watcher.isScoutsWarningSpellActive(source.getSourceId(), zoneChangeCounter)) { Card card = game.getCard(sourceId); - if (card != null && card.isCreature() && source.getControllerId().equals(affectedControllerId)) { + if (card != null && card.isCreature() && source.isControlledBy(affectedControllerId)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/s/ScrapTrawler.java b/Mage.Sets/src/mage/cards/s/ScrapTrawler.java index 60546eaa7aa..65de4ee26e5 100644 --- a/Mage.Sets/src/mage/cards/s/ScrapTrawler.java +++ b/Mage.Sets/src/mage/cards/s/ScrapTrawler.java @@ -78,7 +78,7 @@ class ScrapTrawlerTriggeredAbility extends TriggeredAbilityImpl { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { Permanent permanent = ((ZoneChangeEvent) event).getTarget(); - if (permanent.getControllerId().equals(this.getControllerId()) && permanent.isArtifact()) { + if (permanent.isControlledBy(this.getControllerId()) && permanent.isArtifact()) { FilterCard filter = new FilterArtifactCard("artifact card in your graveyard with converted mana cost less than " + permanent.getManaCost().convertedManaCost()); filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, permanent.getManaCost().convertedManaCost())); TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(filter); diff --git a/Mage.Sets/src/mage/cards/s/Scrapheap.java b/Mage.Sets/src/mage/cards/s/Scrapheap.java index c38b844d81c..b57e7f95e6f 100644 --- a/Mage.Sets/src/mage/cards/s/Scrapheap.java +++ b/Mage.Sets/src/mage/cards/s/Scrapheap.java @@ -64,7 +64,7 @@ class ScrapheapTriggeredAbility extends TriggeredAbilityImpl { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent != null && permanent.getOwnerId().equals(this.getControllerId())) { + if (permanent != null && permanent.isOwnedBy(this.getControllerId())) { if (StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT.match(permanent, sourceId, controllerId, game)) { return true; } diff --git a/Mage.Sets/src/mage/cards/s/SeaTroll.java b/Mage.Sets/src/mage/cards/s/SeaTroll.java new file mode 100644 index 00000000000..09a364ec860 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SeaTroll.java @@ -0,0 +1,118 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.abilities.condition.OrCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.effects.common.RegenerateSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.WatcherScope; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; +import mage.watchers.common.BlockedAttackerWatcher; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * + * @author noahg + */ +public final class SeaTroll extends CardImpl { + + public SeaTroll(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.TROLL); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // {U}: Regenerate Sea Troll. Activate this ability only if Sea Troll blocked or was blocked by a blue creature this turn. + Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{U}"), new SeaTrollCondition()); + ability.addWatcher(new SeaTrollWatcher()); + this.addAbility(ability); + } + + public SeaTroll(final SeaTroll card) { + super(card); + } + + @Override + public SeaTroll copy() { + return new SeaTroll(this); + } +} + +class SeaTrollWatcher extends Watcher { + + private final Set blockedOrBlockedByBlueThisTurnCreatures; + + public SeaTrollWatcher() { + super(SeaTrollWatcher.class.getSimpleName(), WatcherScope.GAME); + blockedOrBlockedByBlueThisTurnCreatures = new HashSet<>(); + } + + public SeaTrollWatcher(SeaTrollWatcher watcher) { + super(watcher); + this.blockedOrBlockedByBlueThisTurnCreatures = new HashSet<>(watcher.blockedOrBlockedByBlueThisTurnCreatures); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED) { + MageObjectReference blocker = new MageObjectReference(event.getSourceId(), game); + MageObjectReference attacker = new MageObjectReference(event.getTargetId(), game); + if (blocker.getPermanentOrLKIBattlefield(game).getColor(game).isBlue()){ + blockedOrBlockedByBlueThisTurnCreatures.add(attacker); + } + if (attacker.getPermanentOrLKIBattlefield(game).getColor(game).isBlue()){ + blockedOrBlockedByBlueThisTurnCreatures.add(blocker); + } + } + } + + @Override + public void reset() { + super.reset(); + blockedOrBlockedByBlueThisTurnCreatures.clear(); + } + + public boolean blockedOrBlockedByBlueCreatureThisTurn(MageObjectReference creature){ + return blockedOrBlockedByBlueThisTurnCreatures.contains(creature); + } + + @Override + public SeaTrollWatcher copy() { + return new SeaTrollWatcher(this); + } +} + +class SeaTrollCondition implements Condition { + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (sourcePermanent != null){ + SeaTrollWatcher watcher = (SeaTrollWatcher) game.getState().getWatchers().get(SeaTrollWatcher.class.getSimpleName()); + if (watcher != null) { + return watcher.blockedOrBlockedByBlueCreatureThisTurn(new MageObjectReference(sourcePermanent, game)); + } + } + return false; + } + + @Override + public String toString() { + return "{this} blocked or was blocked by a blue creature this turn"; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SealOfTheGuildpact.java b/Mage.Sets/src/mage/cards/s/SealOfTheGuildpact.java index 3cd5899623d..6bd3881998a 100644 --- a/Mage.Sets/src/mage/cards/s/SealOfTheGuildpact.java +++ b/Mage.Sets/src/mage/cards/s/SealOfTheGuildpact.java @@ -143,7 +143,7 @@ class SealOfTheGuildpactCostReductionEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { - return abilityToModify.getControllerId().equals(source.getControllerId()) + return abilityToModify.isControlledBy(source.getControllerId()) && abilityToModify instanceof SpellAbility; } diff --git a/Mage.Sets/src/mage/cards/s/SearingBlaze.java b/Mage.Sets/src/mage/cards/s/SearingBlaze.java index 0deaae3341f..cda4d3ce257 100644 --- a/Mage.Sets/src/mage/cards/s/SearingBlaze.java +++ b/Mage.Sets/src/mage/cards/s/SearingBlaze.java @@ -100,7 +100,7 @@ class SearingBlazeTarget extends TargetPermanent { } UUID firstTarget = player.getId(); Permanent permanent = game.getPermanent(id); - if (firstTarget != null && permanent != null && permanent.getControllerId().equals(firstTarget)) { + if (firstTarget != null && permanent != null && permanent.isControlledBy(firstTarget)) { return super.canTarget(id, source, game); } return false; @@ -117,7 +117,7 @@ class SearingBlazeTarget extends TargetPermanent { if (player != null) { for (UUID targetId : availablePossibleTargets) { Permanent permanent = game.getPermanent(targetId); - if (permanent != null && permanent.getControllerId().equals(player.getId())) { + if (permanent != null && permanent.isControlledBy(player.getId())) { possibleTargets.add(targetId); } } diff --git a/Mage.Sets/src/mage/cards/s/SelflessSquire.java b/Mage.Sets/src/mage/cards/s/SelflessSquire.java index adcd11469e6..eac10d15e67 100644 --- a/Mage.Sets/src/mage/cards/s/SelflessSquire.java +++ b/Mage.Sets/src/mage/cards/s/SelflessSquire.java @@ -74,7 +74,7 @@ class SelflessSquireTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (getControllerId().equals(event.getTargetId())) { + if (isControlledBy(event.getTargetId())) { getEffects().clear(); getEffects().add(new AddCountersSourceEffect(CounterType.P1P1.createInstance(event.getAmount()))); return true; diff --git a/Mage.Sets/src/mage/cards/s/SemblanceAnvil.java b/Mage.Sets/src/mage/cards/s/SemblanceAnvil.java index 1f39b373f4e..34372611f2f 100644 --- a/Mage.Sets/src/mage/cards/s/SemblanceAnvil.java +++ b/Mage.Sets/src/mage/cards/s/SemblanceAnvil.java @@ -109,7 +109,7 @@ class SemblanceAnvilCostReductionEffect extends CostModificationEffectImpl { public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { Card sourceCard = game.getCard(abilityToModify.getSourceId()); - if (sourceCard != null && sourceCard.getOwnerId().equals(source.getControllerId())) { + if (sourceCard != null && sourceCard.isOwnedBy(source.getControllerId())) { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { List imprinted = permanent.getImprinted(); diff --git a/Mage.Sets/src/mage/cards/s/SenTriplets.java b/Mage.Sets/src/mage/cards/s/SenTriplets.java index e0681a13080..e1d6ed588ba 100644 --- a/Mage.Sets/src/mage/cards/s/SenTriplets.java +++ b/Mage.Sets/src/mage/cards/s/SenTriplets.java @@ -147,7 +147,7 @@ class SenTripletsPlayFromOpponentsHandEffect extends AsThoughEffectImpl { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { Card card = game.getCard(objectId); return card != null && - card.getOwnerId().equals(getTargetPointer().getFirst(game, source)) && + card.isOwnedBy(getTargetPointer().getFirst(game, source)) && game.getState().getZone(objectId) == Zone.HAND && affectedControllerId.equals(source.getControllerId()); } diff --git a/Mage.Sets/src/mage/cards/s/SenatorLottDod.java b/Mage.Sets/src/mage/cards/s/SenatorLottDod.java index 903bb71b243..2c6f13cddcc 100644 --- a/Mage.Sets/src/mage/cards/s/SenatorLottDod.java +++ b/Mage.Sets/src/mage/cards/s/SenatorLottDod.java @@ -75,7 +75,7 @@ class SenatorLottDodSpellsTargetingCreatureCostReductionEffect extends CostModif for (Target target : mode.getTargets()) { for (UUID targetUUID : target.getTargets()) { Permanent permanent = game.getPermanent(targetUUID); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { + if (permanent != null && permanent.isControlledBy(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/s/SentinelTower.java b/Mage.Sets/src/mage/cards/s/SentinelTower.java index b9d645b05e0..9988c741ccc 100644 --- a/Mage.Sets/src/mage/cards/s/SentinelTower.java +++ b/Mage.Sets/src/mage/cards/s/SentinelTower.java @@ -61,7 +61,7 @@ class SentinelTowerTriggeredAbility extends SpellCastAllTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getActivePlayerId().equals(getControllerId()) + if (game.isActivePlayer(getControllerId()) && super.checkTrigger(event, game)) { SentinelTowerWatcher watcher = (SentinelTowerWatcher) game.getState().getWatchers().get(SentinelTowerWatcher.class.getSimpleName()); if (watcher == null) { diff --git a/Mage.Sets/src/mage/cards/s/SerraAvenger.java b/Mage.Sets/src/mage/cards/s/SerraAvenger.java index 065adc24a34..1ddb5e47d22 100644 --- a/Mage.Sets/src/mage/cards/s/SerraAvenger.java +++ b/Mage.Sets/src/mage/cards/s/SerraAvenger.java @@ -80,7 +80,7 @@ class CantCastSerraAvengerEffect extends ContinuousRuleModifyingEffectImpl { if (event.getType() == EventType.CAST_SPELL && event.getSourceId().equals(source.getSourceId())) { Player controller = game.getPlayer(source.getControllerId()); // it can be cast on other players turn 1 - 3 if some effect let allow you to do this - if (controller != null && controller.getTurns() <= 3 && game.getActivePlayerId().equals(source.getControllerId())) { + if (controller != null && controller.getTurns() <= 3 && game.isActivePlayer(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/s/SerraInquisitors.java b/Mage.Sets/src/mage/cards/s/SerraInquisitors.java new file mode 100644 index 00000000000..dacf3b265cd --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SerraInquisitors.java @@ -0,0 +1,49 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility; +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; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; + +import java.util.UUID; + +/** + * + * @author noahg + */ +public final class SerraInquisitors extends CardImpl { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("black creatures"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLACK)); + } + + public SerraInquisitors(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Whenever Serra Inquisitors blocks or becomes blocked by one or more black creatures, Serra Inquisitors gets +2/+0 until end of turn. + this.addAbility(new BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(new BoostSourceEffect(2, 0, Duration.EndOfTurn), filter, false)); + } + + public SerraInquisitors(final SerraInquisitors card) { + super(card); + } + + @Override + public SerraInquisitors copy() { + return new SerraInquisitors(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SerumPowder.java b/Mage.Sets/src/mage/cards/s/SerumPowder.java index cdc8e4b6e8b..955f9a5bf62 100644 --- a/Mage.Sets/src/mage/cards/s/SerumPowder.java +++ b/Mage.Sets/src/mage/cards/s/SerumPowder.java @@ -87,7 +87,7 @@ class SerumPowderReplaceEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/s/SeshiroTheAnointed.java b/Mage.Sets/src/mage/cards/s/SeshiroTheAnointed.java index af2cdf3a2a8..cca4023c354 100644 --- a/Mage.Sets/src/mage/cards/s/SeshiroTheAnointed.java +++ b/Mage.Sets/src/mage/cards/s/SeshiroTheAnointed.java @@ -81,7 +81,7 @@ class SeshiroTheAnointedAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event; Permanent p = game.getPermanent(event.getSourceId()); - if (damageEvent.isCombatDamage() && p != null && p.hasSubtype(SubType.SNAKE, game) && p.getControllerId().equals(controllerId)) { + if (damageEvent.isCombatDamage() && p != null && p.hasSubtype(SubType.SNAKE, game) && p.isControlledBy(controllerId)) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java b/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java index b68584e3c43..4a2a86accd7 100644 --- a/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java +++ b/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java @@ -73,7 +73,7 @@ class SettleTheWreckageEffect extends OneShotEffect { Iterator creatureIds = game.getCombat().getAttackers().iterator(); while (creatureIds.hasNext()) { Permanent creature = game.getPermanent(creatureIds.next()); - if (creature != null && creature.getControllerId().equals(player.getId())) { + if (creature != null && creature.isControlledBy(player.getId())) { toExile.add(creature); attackers++; } diff --git a/Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java b/Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java index 8839aaea5e5..c85fcab35df 100644 --- a/Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java +++ b/Mage.Sets/src/mage/cards/s/ShadowOfTheGrave.java @@ -63,7 +63,7 @@ class ShadowOfTheGraveEffect extends OneShotEffect { && watcher != null) { for (Card card : watcher.getCardsCycledOrDiscardedThisTurn(controller.getId()).getCards(game)) { if (game.getState().getZone(card.getId()) == Zone.GRAVEYARD //must come from their graveyard - && card.getOwnerId().equals(controller.getId())) { //confirm ownership, but it should not be possible to get not ownwd cards here + && card.isOwnedBy(controller.getId())) { //confirm ownership, but it should not be possible to get not ownwd cards here controller.moveCardToHandWithInfo(card, source.getId(), game, true); } } diff --git a/Mage.Sets/src/mage/cards/s/ShamanOfForgottenWays.java b/Mage.Sets/src/mage/cards/s/ShamanOfForgottenWays.java index 8a3d88c5ec2..8718cc44df4 100644 --- a/Mage.Sets/src/mage/cards/s/ShamanOfForgottenWays.java +++ b/Mage.Sets/src/mage/cards/s/ShamanOfForgottenWays.java @@ -92,7 +92,7 @@ class ShamanOfForgottenWaysManaCondition implements Condition { @Override public boolean apply(Game game, Ability source) { MageObject object = source.getSourceObject(game); - return object != null && (object instanceof Spell) && object.isCreature(); + return object instanceof Spell && object.isCreature(); } } diff --git a/Mage.Sets/src/mage/cards/s/ShannaSisaysLegacy.java b/Mage.Sets/src/mage/cards/s/ShannaSisaysLegacy.java index 5477904286e..6041c378550 100644 --- a/Mage.Sets/src/mage/cards/s/ShannaSisaysLegacy.java +++ b/Mage.Sets/src/mage/cards/s/ShannaSisaysLegacy.java @@ -104,7 +104,7 @@ class ShannaSisaysLegacyEffect extends ContinuousRuleModifyingEffectImpl { StackObject stackObject = (StackObject) game.getStack().getStackObject(event.getSourceId()); if (targetCard != null && stackObject != null && targetCard.getId().equals(source.getSourceId())) { if (stackObject instanceof Ability) { - if (!stackObject.getControllerId().equals(source.getControllerId())) { + if (!stackObject.isControlledBy(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/s/ShapeOfTheWiitigo.java b/Mage.Sets/src/mage/cards/s/ShapeOfTheWiitigo.java new file mode 100644 index 00000000000..3e33b199b6b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShapeOfTheWiitigo.java @@ -0,0 +1,133 @@ +package mage.cards.s; + +import java.util.*; + +import mage.MageObjectReference; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.counter.AddCountersAttachedEffect; +import mage.abilities.effects.common.counter.RemoveCountersAttachedEffect; +import mage.constants.*; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.effects.common.AttachEffect; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.watchers.Watcher; + +/** + * + * @author noahg + */ +public final class ShapeOfTheWiitigo extends CardImpl { + + public ShapeOfTheWiitigo(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}{G}{G}"); + + 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 Shape of the Wiitigo enters the battlefield, put six +1/+1 counters on enchanted creature. + this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersAttachedEffect(CounterType.P1P1.createInstance(6), "enchanted creature"))); + + // At the beginning of your upkeep, put a +1/+1 counter on enchanted creature if it attacked or blocked since your last upkeep. Otherwise, remove a +1/+1 counter from it. + Ability triggeredAbility = new BeginningOfUpkeepTriggeredAbility( + new ConditionalOneShotEffect(new AddCountersAttachedEffect(CounterType.P1P1.createInstance(1), "enchanted creature"), + new RemoveCountersAttachedEffect(CounterType.P1P1.createInstance(1), "it"), + new AttachedAttackedOrBlockedSinceYourLastUpkeepCondition(), + "put a +1/+1 counter on enchanted creature if it attacked or blocked since your last " + + "upkeep. Otherwise, remove a +1/+1 counter from it"), TargetController.YOU, false); + triggeredAbility.addWatcher(new AttackedOrBlockedSinceYourLastUpkeepWatcher()); + this.addAbility(triggeredAbility); + } + + public ShapeOfTheWiitigo(final ShapeOfTheWiitigo card) { + super(card); + } + + @Override + public ShapeOfTheWiitigo copy() { + return new ShapeOfTheWiitigo(this); + } +} + +class AttachedAttackedOrBlockedSinceYourLastUpkeepCondition implements Condition { + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId()); + AttackedOrBlockedSinceYourLastUpkeepWatcher watcher = (AttackedOrBlockedSinceYourLastUpkeepWatcher) game.getState().getWatchers().get(AttackedOrBlockedSinceYourLastUpkeepWatcher.class.getSimpleName()); + if (permanent != null && permanent.getAttachedTo() != null && watcher != null) { + Permanent attachedTo = game.getBattlefield().getPermanent(permanent.getAttachedTo()); + if (attachedTo == null) { + attachedTo = (Permanent) game.getLastKnownInformation(permanent.getAttachedTo(), Zone.BATTLEFIELD); + } + if (attachedTo != null) { + return watcher.attackedSinceLastUpkeep(new MageObjectReference(attachedTo.getId(), attachedTo.getZoneChangeCounter(game), game), source.getControllerId()); + } + } + return false; + } + + @Override + public String toString() { + return "it attacked or blocked since your last upkeep"; + } +} + +class AttackedOrBlockedSinceYourLastUpkeepWatcher extends Watcher{ + + //Map of each player to the creatures that attacked or blocked since their last upkeep + private final Map> attackedOrBlockedCreatures = new HashMap<>(); + + public AttackedOrBlockedSinceYourLastUpkeepWatcher() { + super(AttackedOrBlockedSinceYourLastUpkeepWatcher.class.getSimpleName(), WatcherScope.GAME); + } + + public AttackedOrBlockedSinceYourLastUpkeepWatcher(AttackedOrBlockedSinceYourLastUpkeepWatcher watcher) { + super(watcher); + for (Map.Entry> entry : watcher.attackedOrBlockedCreatures.entrySet()) { + Set allAttackersCopy = new HashSet<>(entry.getValue()); + attackedOrBlockedCreatures.put(entry.getKey(), allAttackersCopy); + } + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.UPKEEP_STEP_POST){ + //Clear + attackedOrBlockedCreatures.put(event.getPlayerId(), new HashSet<>()); + } else if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED || event.getType() == GameEvent.EventType.BLOCKER_DECLARED) { + MageObjectReference mor = new MageObjectReference(event.getSourceId(), game); + for (UUID player : game.getPlayerList()){ + if (!attackedOrBlockedCreatures.containsKey(player)) { + attackedOrBlockedCreatures.put(player, new HashSet<>()); + } + attackedOrBlockedCreatures.get(player).add(mor); + } + } + } + + public boolean attackedSinceLastUpkeep(MageObjectReference mor, UUID upkeepPlayer){ + return attackedOrBlockedCreatures.get(upkeepPlayer).contains(mor); + } + + @Override + public AttackedOrBlockedSinceYourLastUpkeepWatcher copy() { + return new AttackedOrBlockedSinceYourLastUpkeepWatcher(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/ShapersSanctuary.java b/Mage.Sets/src/mage/cards/s/ShapersSanctuary.java index 60c09594412..76469436309 100644 --- a/Mage.Sets/src/mage/cards/s/ShapersSanctuary.java +++ b/Mage.Sets/src/mage/cards/s/ShapersSanctuary.java @@ -61,7 +61,7 @@ class CreaturesYouControlTargetedTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); Player targetter = game.getPlayer(event.getPlayerId()); - if (permanent != null && permanent.getControllerId().equals(this.getControllerId()) && permanent.isCreature()) { + if (permanent != null && permanent.isControlledBy(this.getControllerId()) && permanent.isCreature()) { Object object = game.getObject(event.getSourceId()); if (object != null && targetter != null && targetter.hasOpponent(this.getControllerId(), game)) { return true; diff --git a/Mage.Sets/src/mage/cards/s/ShiningShoal.java b/Mage.Sets/src/mage/cards/s/ShiningShoal.java index 861eef89810..5733872da8c 100644 --- a/Mage.Sets/src/mage/cards/s/ShiningShoal.java +++ b/Mage.Sets/src/mage/cards/s/ShiningShoal.java @@ -111,7 +111,7 @@ class ShiningShoalRedirectDamageTargetEffect extends RedirectDamageFromSourceToT // check creature first Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.isCreature()) { - if (permanent.getControllerId().equals(source.getControllerId())) { + if (permanent.isControlledBy(source.getControllerId())) { // it's your creature redirectTarget = source.getTargets().get(1); return true; diff --git a/Mage.Sets/src/mage/cards/s/ShipbreakerKraken.java b/Mage.Sets/src/mage/cards/s/ShipbreakerKraken.java index a0f0afcd480..d43cfaed037 100644 --- a/Mage.Sets/src/mage/cards/s/ShipbreakerKraken.java +++ b/Mage.Sets/src/mage/cards/s/ShipbreakerKraken.java @@ -90,7 +90,7 @@ class ShipbreakerKrakenReplacementEffect extends ContinuousRuleModifyingEffectIm // the battlefield triggered ability the source dies (or will be exiled), then the ZONE_CHANGE or LOST_CONTROL // event will happen before this effect is applied ever) Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (sourcePermanent == null || !sourcePermanent.getControllerId().equals(source.getControllerId())) { + if (sourcePermanent == null || !sourcePermanent.isControlledBy(source.getControllerId())) { discard(); return false; } diff --git a/Mage.Sets/src/mage/cards/s/ShireiShizosCaretaker.java b/Mage.Sets/src/mage/cards/s/ShireiShizosCaretaker.java index 003933e4937..6e0d7d255f4 100644 --- a/Mage.Sets/src/mage/cards/s/ShireiShizosCaretaker.java +++ b/Mage.Sets/src/mage/cards/s/ShireiShizosCaretaker.java @@ -80,7 +80,7 @@ class ShireiShizosCaretakerTriggeredAbility extends TriggeredAbilityImpl { Card card = game.getCard(zEvent.getTargetId()); if (card != null && LKIpermanent != null - && card.getOwnerId().equals(this.controllerId) + && card.isOwnedBy(this.controllerId) && zEvent.getToZone() == Zone.GRAVEYARD && zEvent.getFromZone() == Zone.BATTLEFIELD && card.isCreature() diff --git a/Mage.Sets/src/mage/cards/s/ShrivelingRot.java b/Mage.Sets/src/mage/cards/s/ShrivelingRot.java index 9d2961830a5..57c8db95357 100644 --- a/Mage.Sets/src/mage/cards/s/ShrivelingRot.java +++ b/Mage.Sets/src/mage/cards/s/ShrivelingRot.java @@ -148,7 +148,7 @@ class ShrivelingRotEffect extends OneShotEffect { Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); if (permanent != null) { if (permanent.getZoneChangeCounter(game) + 1 == game.getState().getZoneChangeCounter(permanent.getId()) - && !game.getState().getZone(permanent.getId()).equals(Zone.GRAVEYARD)) { + && game.getState().getZone(permanent.getId()) != Zone.GRAVEYARD) { // A replacement effect has moved the card to another zone as graveyard return true; } diff --git a/Mage.Sets/src/mage/cards/s/SidisiBroodTyrant.java b/Mage.Sets/src/mage/cards/s/SidisiBroodTyrant.java index 3a3c4e1f8a8..933cbb20ce9 100644 --- a/Mage.Sets/src/mage/cards/s/SidisiBroodTyrant.java +++ b/Mage.Sets/src/mage/cards/s/SidisiBroodTyrant.java @@ -78,7 +78,7 @@ class SidisiBroodTyrantTriggeredAbility extends TriggeredAbilityImpl { Set cardType = card.getCardType(); if (cardOwnerId != null - && card.getOwnerId().equals(getControllerId()) + && card.isOwnedBy(getControllerId()) && cardType != null && card.isCreature()) { return true; diff --git a/Mage.Sets/src/mage/cards/s/SiegeBehemoth.java b/Mage.Sets/src/mage/cards/s/SiegeBehemoth.java index 2eaaafa5734..96675daffaf 100644 --- a/Mage.Sets/src/mage/cards/s/SiegeBehemoth.java +++ b/Mage.Sets/src/mage/cards/s/SiegeBehemoth.java @@ -3,19 +3,21 @@ package mage.cards.s; import java.util.UUID; import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.DamageAsThoughNotBlockedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.SourceAttackingCondition; import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.AsThoughEffectImpl; 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.SubType; -import mage.constants.Duration; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; /** * @@ -34,15 +36,9 @@ public final class SiegeBehemoth extends CardImpl { // Hexproof this.addAbility(HexproofAbility.getInstance()); + // As long as Siege Behemoth is attacking, for each creature you control, you may have that creature assign its combat damage as though it weren't blocked. - // TODO: DamageAsThoughNotBlockedAbility should be done by rule modifying effect instead of adding ability (if controlled creature looses all abilities it should'nt loose this effect) - this.addAbility(new SimpleStaticAbility( - Zone.BATTLEFIELD, - new ConditionalContinuousEffect( - new GainAbilityControlledEffect(DamageAsThoughNotBlockedAbility.getInstance(), Duration.WhileOnBattlefield, filter), - SourceAttackingCondition.instance, - "As long as {this} is attacking, for each creature you control, you may have that creature assign its combat damage as though it weren't blocked" - ))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SiegeBehemothEffect())); } public SiegeBehemoth(final SiegeBehemoth card) { @@ -54,3 +50,39 @@ public final class SiegeBehemoth extends CardImpl { return new SiegeBehemoth(this); } } + +class SiegeBehemothEffect extends AsThoughEffectImpl { + + public SiegeBehemothEffect() { + super(AsThoughEffectType.DAMAGE_NOT_BLOCKED, Duration.WhileOnBattlefield, Outcome.Damage); + this.staticText = "As long as {this} is attacking, for each creature you control, you may have that creature assign its combat damage as though it weren't blocked"; + } + + public SiegeBehemothEffect(SiegeBehemothEffect effect) { + super(effect); + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game); + if (sourcePermanent != null && sourcePermanent.isAttacking()){ + Player controller = game.getPlayer(source.getControllerId()); + Permanent otherCreature = game.getPermanent(sourceId); + if (controller != null && otherCreature != null && otherCreature.isControlledBy(controller.getId())){ + return controller.chooseUse(Outcome.Damage, "Do you wish to assign damage for " + + otherCreature.getLogName() + " as though it weren't blocked?", source, game); + } + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public SiegeBehemothEffect copy() { + return new SiegeBehemothEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SigilCaptain.java b/Mage.Sets/src/mage/cards/s/SigilCaptain.java index c216469dfd1..e14f9428f69 100644 --- a/Mage.Sets/src/mage/cards/s/SigilCaptain.java +++ b/Mage.Sets/src/mage/cards/s/SigilCaptain.java @@ -69,7 +69,7 @@ class SigilCaptainTriggeredAbility extends TriggeredAbilityImpl { if (permanent == null) { return false; } - if (permanent.getControllerId().equals(controllerId) + if (permanent.isControlledBy(controllerId) && permanent.getPower().getValue() == 1 && permanent.getToughness().getValue() == 1) { for (Effect effect : this.getEffects()) { diff --git a/Mage.Sets/src/mage/cards/s/SigilOfValor.java b/Mage.Sets/src/mage/cards/s/SigilOfValor.java index f7954a8225a..aafeddaf209 100644 --- a/Mage.Sets/src/mage/cards/s/SigilOfValor.java +++ b/Mage.Sets/src/mage/cards/s/SigilOfValor.java @@ -75,13 +75,12 @@ class SigilOfValorTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getActivePlayerId().equals(getControllerId())) { + if (game.isActivePlayer(getControllerId())) { if (game.getCombat().attacksAlone()) { Permanent equipment = game.getPermanent(getSourceId()); UUID attackerId = game.getCombat().getAttackers().get(0); if (equipment != null - && equipment.getAttachedTo() != null - && equipment.getAttachedTo().equals(attackerId)) { + && equipment.isAttachedTo(attackerId)) { this.getEffects().get(0).setTargetPointer(new FixedTarget(attackerId)); return true; } diff --git a/Mage.Sets/src/mage/cards/s/SilasRennSeekerAdept.java b/Mage.Sets/src/mage/cards/s/SilasRennSeekerAdept.java index 040f3ae781f..9343d54c7d9 100644 --- a/Mage.Sets/src/mage/cards/s/SilasRennSeekerAdept.java +++ b/Mage.Sets/src/mage/cards/s/SilasRennSeekerAdept.java @@ -79,7 +79,7 @@ class SilasRennSeekerAdeptPlayEffect extends AsThoughEffectImpl { UUID targetId = getTargetPointer().getFirst(game, source); if (targetId != null) { return targetId.equals(objectId) - && source.getControllerId().equals(affectedControllerId); + && source.isControlledBy(affectedControllerId); } else { // the target card has changed zone meanwhile, so the effect is no longer needed discard(); diff --git a/Mage.Sets/src/mage/cards/s/SilverfurPartisan.java b/Mage.Sets/src/mage/cards/s/SilverfurPartisan.java index b7c15d5eaad..4caebce8f99 100644 --- a/Mage.Sets/src/mage/cards/s/SilverfurPartisan.java +++ b/Mage.Sets/src/mage/cards/s/SilverfurPartisan.java @@ -75,7 +75,7 @@ class CreaturesYouControlBecomesTargetTriggeredAbility extends TriggeredAbilityI @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getControllerId().equals(this.controllerId) && (permanent.hasSubtype(SubType.WOLF, game) || permanent.hasSubtype(SubType.WEREWOLF, game))) { + if (permanent != null && permanent.isControlledBy(this.controllerId) && (permanent.hasSubtype(SubType.WOLF, game) || permanent.hasSubtype(SubType.WEREWOLF, game))) { MageObject object = game.getObject(event.getSourceId()); if (object != null && object instanceof Spell) { Card c = (Spell) object; diff --git a/Mage.Sets/src/mage/cards/s/SimicGuildmage.java b/Mage.Sets/src/mage/cards/s/SimicGuildmage.java index 0a5fe6fefd5..45d3b6eec78 100644 --- a/Mage.Sets/src/mage/cards/s/SimicGuildmage.java +++ b/Mage.Sets/src/mage/cards/s/SimicGuildmage.java @@ -110,7 +110,7 @@ class MoveCounterFromTargetToTargetEffect extends OneShotEffect { if (source.getTargets().size() > 1) { toPermanent = game.getPermanent(source.getTargets().get(1).getFirstTarget()); } - if (fromPermanent == null || toPermanent == null || !fromPermanent.getControllerId().equals(toPermanent.getControllerId())) { + if (fromPermanent == null || toPermanent == null || !fromPermanent.isControlledBy(toPermanent.getControllerId())) { return false; } fromPermanent.removeCounters(CounterType.P1P1.createInstance(1), game); @@ -136,7 +136,7 @@ class SameControllerPredicate implements ObjectSourcePlayerPredicate choices = new TreeSet<>(); Collection cards = game.getCards(); for (Card gameCard : cards) { - if (gameCard.getOwnerId().equals(targetPlayer.getId())) { + if (gameCard.isOwnedBy(targetPlayer.getId())) { choices.add(gameCard.getName()); } } diff --git a/Mage.Sets/src/mage/cards/s/SphinxsDecree.java b/Mage.Sets/src/mage/cards/s/SphinxsDecree.java index ec0f5cb46b3..2b841942ca1 100644 --- a/Mage.Sets/src/mage/cards/s/SphinxsDecree.java +++ b/Mage.Sets/src/mage/cards/s/SphinxsDecree.java @@ -103,7 +103,7 @@ class SphinxsDecreeCantCastEffect extends ContinuousRuleModifyingEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { UUID opponentId = getTargetPointer().getFirst(game, source); - if (game.getActivePlayerId().equals(opponentId)) { + if (game.isActivePlayer(opponentId)) { if (playersNextTurn == 0) { playersNextTurn = game.getTurnNum(); } diff --git a/Mage.Sets/src/mage/cards/s/SpitefulReturned.java b/Mage.Sets/src/mage/cards/s/SpitefulReturned.java index d0728b58953..3bca683888a 100644 --- a/Mage.Sets/src/mage/cards/s/SpitefulReturned.java +++ b/Mage.Sets/src/mage/cards/s/SpitefulReturned.java @@ -86,7 +86,7 @@ class SpitefulReturnedTriggeredAbility extends TriggeredAbilityImpl { return true; } } else { - if (sourcePermanent.getAttachedTo() != null && sourcePermanent.getAttachedTo().equals(event.getSourceId())) { + if (sourcePermanent.isAttachedTo(event.getSourceId())) { UUID defender = game.getCombat().getDefendingPlayerId(sourcePermanent.getAttachedTo(), game); this.getEffects().get(0).setTargetPointer(new FixedTarget(defender)); return true; diff --git a/Mage.Sets/src/mage/cards/s/SqueeTheImmortal.java b/Mage.Sets/src/mage/cards/s/SqueeTheImmortal.java index adfc361ed05..4e08bb419d1 100644 --- a/Mage.Sets/src/mage/cards/s/SqueeTheImmortal.java +++ b/Mage.Sets/src/mage/cards/s/SqueeTheImmortal.java @@ -71,7 +71,7 @@ class SqueePlayEffect extends AsThoughEffectImpl { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { if (sourceId.equals(source.getSourceId())) { Card card = game.getCard(source.getSourceId()); - if (card != null && card.getOwnerId().equals(affectedControllerId) + if (card != null && card.isOwnedBy(affectedControllerId) && (game.getState().getZone(source.getSourceId()) == Zone.EXILED || game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD)) { return true; diff --git a/Mage.Sets/src/mage/cards/s/SquirrelPoweredScheme.java b/Mage.Sets/src/mage/cards/s/SquirrelPoweredScheme.java index 3534b19b439..d717fb812e4 100644 --- a/Mage.Sets/src/mage/cards/s/SquirrelPoweredScheme.java +++ b/Mage.Sets/src/mage/cards/s/SquirrelPoweredScheme.java @@ -62,7 +62,7 @@ class SquirrelPoweredSchemeEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { // ignore planar dies (dice roll amount of planar dies is equal to 0) - return event.getAmount() > 0 && source.getControllerId().equals(event.getPlayerId()); + return event.getAmount() > 0 && source.isControlledBy(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/s/SteamfloggerBoss.java b/Mage.Sets/src/mage/cards/s/SteamfloggerBoss.java index eded96e94b8..f30cd75e2a5 100644 --- a/Mage.Sets/src/mage/cards/s/SteamfloggerBoss.java +++ b/Mage.Sets/src/mage/cards/s/SteamfloggerBoss.java @@ -1,11 +1,9 @@ - package mage.cards.s; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; @@ -17,7 +15,6 @@ import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; -import static mage.filter.predicate.permanent.ControllerControlsIslandPredicate.filter; /** * @@ -25,6 +22,9 @@ import static mage.filter.predicate.permanent.ControllerControlsIslandPredicate. */ public final class SteamfloggerBoss extends CardImpl { + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent(SubType.RIGGER, "Rigger creatures"); + public SteamfloggerBoss(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); @@ -34,15 +34,28 @@ public final class SteamfloggerBoss extends CardImpl { this.toughness = new MageInt(3); // Other Rigger creatures you control get +1/+0 and have haste. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, - new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield, new FilterCreaturePermanent(SubType.RIGGER, "Rigger creatures"), true)); - Effect effect = new GainAbilityControlledEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter); - effect.setText("and have haste"); - ability.addEffect(effect); + Ability ability = new SimpleStaticAbility( + Zone.BATTLEFIELD, + new BoostControlledEffect( + 1, 0, Duration.WhileOnBattlefield, + filter, true + ) + ); + ability.addEffect(new GainAbilityControlledEffect( + HasteAbility.getInstance(), + Duration.WhileOnBattlefield, + filter + ).setText("and have haste")); this.addAbility(ability); // If a Rigger you control would assemble a Contraption, it assembles two Contraptions instead. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect("If a Rigger you control would assemble a Contraption, it assembles two Contraptions instead. (NOT IMPLEMENTED)"))); + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + new InfoEffect( + "If a Rigger you control would assemble a Contraption, " + + "it assembles two Contraptions instead. (NOT IMPLEMENTED)" + ) + )); } diff --git a/Mage.Sets/src/mage/cards/s/SteelSquirrel.java b/Mage.Sets/src/mage/cards/s/SteelSquirrel.java index 0a5f82b69c2..c8f992ceec2 100644 --- a/Mage.Sets/src/mage/cards/s/SteelSquirrel.java +++ b/Mage.Sets/src/mage/cards/s/SteelSquirrel.java @@ -76,7 +76,7 @@ class SteelSquirrelTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (this.getControllerId().equals(event.getPlayerId()) && event.getFlag()) { + if (this.isControlledBy(event.getPlayerId()) && event.getFlag()) { if (event.getAmount() >= 5) { for (Effect effect : this.getEffects()) { effect.setValue("rolled", event.getAmount()); diff --git a/Mage.Sets/src/mage/cards/s/StensiaMasquerade.java b/Mage.Sets/src/mage/cards/s/StensiaMasquerade.java index 3716bc5fa36..61f2a5dc8ac 100644 --- a/Mage.Sets/src/mage/cards/s/StensiaMasquerade.java +++ b/Mage.Sets/src/mage/cards/s/StensiaMasquerade.java @@ -88,7 +88,7 @@ class StensiaMasqueradeTriggeredAbility extends TriggeredAbilityImpl { DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; Permanent permanent = game.getPermanent(event.getSourceId()); if (damageEvent.isCombatDamage() && permanent != null - && permanent.hasSubtype(SubType.VAMPIRE, game) && permanent.getControllerId().equals(controllerId)) { + && permanent.hasSubtype(SubType.VAMPIRE, game) && permanent.isControlledBy(controllerId)) { this.getEffects().clear(); AddCountersTargetEffect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); effect.setTargetPointer(new FixedTarget(permanent.getId())); diff --git a/Mage.Sets/src/mage/cards/s/StolenStrategy.java b/Mage.Sets/src/mage/cards/s/StolenStrategy.java index 07b0556f1e9..18e01088465 100644 --- a/Mage.Sets/src/mage/cards/s/StolenStrategy.java +++ b/Mage.Sets/src/mage/cards/s/StolenStrategy.java @@ -133,7 +133,7 @@ class StolenStrategyCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - if (sourceId.equals(cardId) && source.getControllerId().equals(affectedControllerId)) { + if (sourceId.equals(cardId) && source.isControlledBy(affectedControllerId)) { ExileZone exileZone = game.getState().getExile().getExileZone(exileId); return exileZone != null && exileZone.contains(cardId); } @@ -164,7 +164,7 @@ class StolenStrategySpendAnyManaEffect extends AsThoughEffectImpl implements AsT @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) && (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)) diff --git a/Mage.Sets/src/mage/cards/s/StreetSavvy.java b/Mage.Sets/src/mage/cards/s/StreetSavvy.java new file mode 100644 index 00000000000..f7d89d9b120 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StreetSavvy.java @@ -0,0 +1,80 @@ +package mage.cards.s; + +import java.util.UUID; + +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.constants.*; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.effects.common.AttachEffect; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; + +/** + * + * @author noahg + */ +public final class StreetSavvy extends CardImpl { + + public StreetSavvy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); + + 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 +0/+2 and can block creatures with landwalk abilities as though they didn't have those abilities. + SimpleStaticAbility staticAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(0 ,2) + .setText("Enchanted creature gets +0/+2 and can block creatures with landwalk abilities as though they didn't have those abilities.")); + staticAbility.addEffect(new StreetSavvyEffect()); + this.addAbility(staticAbility); + } + + public StreetSavvy(final StreetSavvy card) { + super(card); + } + + @Override + public StreetSavvy copy() { + return new StreetSavvy(this); + } +} + +class StreetSavvyEffect extends AsThoughEffectImpl { + + public StreetSavvyEffect() { + super(AsThoughEffectType.BLOCK_LANDWALK, Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = ""; + } + + public StreetSavvyEffect(final StreetSavvyEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public StreetSavvyEffect copy() { + return new StreetSavvyEffect(this); + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game); + return sourcePermanent != null && sourceId.equals(sourcePermanent.getAttachedTo()); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/StromkirkOccultist.java b/Mage.Sets/src/mage/cards/s/StromkirkOccultist.java index 7e0974aa053..ff3405bd2a5 100644 --- a/Mage.Sets/src/mage/cards/s/StromkirkOccultist.java +++ b/Mage.Sets/src/mage/cards/s/StromkirkOccultist.java @@ -117,7 +117,7 @@ class StromkirkOccultistPlayFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && objectId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index 4bba3ef9154..10dcad1ec4d 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -1,4 +1,3 @@ - package mage.cards.s; import java.util.UUID; @@ -65,8 +64,8 @@ class SunbirdsInvocationTriggeredAbility extends SpellCastControllerTriggeredAbi if (event.getPlayerId().equals(getControllerId())) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null - && spell.getFromZone().equals(Zone.HAND) - && spell.getOwnerId().equals(getControllerId())) { // must be from the controller's hand + && spell.getFromZone() == Zone.HAND + && spell.isOwnedBy(getControllerId())) { // must be from the controller's hand if (spell.getCard() != null) { for (Effect effect : getEffects()) { effect.setTargetPointer(new FixedTarget(spell.getId())); @@ -136,14 +135,7 @@ class SunbirdsInvocationEffect extends OneShotEffect { } } } - } - - while (!cards.isEmpty()) { - Card card = cards.getRandom(game); - if (card != null) { - cards.remove(card); - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); - } + controller.putCardsOnBottomOfLibrary(cards, game, source, false); } return true; } diff --git a/Mage.Sets/src/mage/cards/s/SwiftSilence.java b/Mage.Sets/src/mage/cards/s/SwiftSilence.java new file mode 100644 index 00000000000..d0619b05d60 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SwiftSilence.java @@ -0,0 +1,79 @@ +package mage.cards.s; + +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.stack.Spell; +import mage.game.stack.StackObject; +import mage.players.Player; + +/** + * + * @author noahg + */ +public final class SwiftSilence extends CardImpl { + + public SwiftSilence(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}{U}{U}"); + + + // Counter all other spells. Draw a card for each spell countered this way. + this.getSpellAbility().addEffect(new SwiftSilenceEffect()); + } + + public SwiftSilence(final SwiftSilence card) { + super(card); + } + + @Override + public SwiftSilence copy() { + return new SwiftSilence(this); + } +} + +class SwiftSilenceEffect extends OneShotEffect { + + public SwiftSilenceEffect() { + super(Outcome.Detriment); + staticText = "Counter all other spells. Draw a card for each spell countered this way."; + } + + public SwiftSilenceEffect(final SwiftSilenceEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + List spellsToCounter = new LinkedList<>(); + for (StackObject stackObject : game.getStack()) { + if (stackObject instanceof Spell && !stackObject.getId().equals(source.getSourceObject(game).getId())) { + spellsToCounter.add((Spell) stackObject); + } + } + int toDraw = 0; + for (Spell spell : spellsToCounter) { + if (game.getStack().counter(spell.getId(), source.getSourceId(), game)){ + toDraw++; + } + } + Player controller = game.getPlayer(source.getControllerId()); + if (toDraw > 0 && controller != null){ + controller.drawCards(toDraw, game); + } + return true; + } + + @Override + public SwiftSilenceEffect copy() { + return new SwiftSilenceEffect(this); + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/t/TajuruPreserver.java b/Mage.Sets/src/mage/cards/t/TajuruPreserver.java index f077b37d8d7..27f8fac2ced 100644 --- a/Mage.Sets/src/mage/cards/t/TajuruPreserver.java +++ b/Mage.Sets/src/mage/cards/t/TajuruPreserver.java @@ -72,7 +72,7 @@ class TajuruPreserverEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { + if (permanent != null && permanent.isControlledBy(source.getControllerId())) { MageObject object = game.getObject(event.getSourceId()); if (object instanceof PermanentCard) { if (game.getOpponents(source.getControllerId()).contains(((PermanentCard)object).getControllerId())) { diff --git a/Mage.Sets/src/mage/cards/t/TalonsOfWildwood.java b/Mage.Sets/src/mage/cards/t/TalonsOfWildwood.java index e90adec696b..a843c1a9464 100644 --- a/Mage.Sets/src/mage/cards/t/TalonsOfWildwood.java +++ b/Mage.Sets/src/mage/cards/t/TalonsOfWildwood.java @@ -42,7 +42,7 @@ public final class TalonsOfWildwood extends CardImpl { // Enchanted creature gets +1/+1 and has trample. ability = new SimpleStaticAbility( - Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield) + Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 1, Duration.WhileOnBattlefield) ); ability.addEffect(new GainAbilityAttachedEffect( TrampleAbility.getInstance(), diff --git a/Mage.Sets/src/mage/cards/t/TalusPaladin.java b/Mage.Sets/src/mage/cards/t/TalusPaladin.java index 87db0899133..2619c545e02 100644 --- a/Mage.Sets/src/mage/cards/t/TalusPaladin.java +++ b/Mage.Sets/src/mage/cards/t/TalusPaladin.java @@ -82,7 +82,7 @@ class TalusPaladinTriggeredAbility extends TriggeredAbilityImpl { Permanent ally = game.getPermanent(event.getTargetId()); if (ally != null) { if (ally.hasSubtype(SubType.ALLY, game) - && ally.getControllerId().equals(this.getControllerId())) { + && ally.isControlledBy(this.getControllerId())) { if (event.getTargetId().equals(this.getSourceId()) || event.getTargetId().equals(ally.getId())) { return true; diff --git a/Mage.Sets/src/mage/cards/t/Tamanoa.java b/Mage.Sets/src/mage/cards/t/Tamanoa.java index 58d3f70fed5..a567e0c2c0c 100644 --- a/Mage.Sets/src/mage/cards/t/Tamanoa.java +++ b/Mage.Sets/src/mage/cards/t/Tamanoa.java @@ -72,7 +72,7 @@ class TamanoaDealsDamageTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { MageObject eventSourceObject = game.getObject(event.getSourceId()); if (eventSourceObject != null && !eventSourceObject.isCreature()) { - if (getControllerId().equals(game.getControllerId(event.getSourceId()))) { + if (isControlledBy(game.getControllerId(event.getSourceId()))) { this.getEffects().forEach((effect) -> { effect.setValue("damage", event.getAmount()); }); diff --git a/Mage.Sets/src/mage/cards/t/TamiyoFieldResearcher.java b/Mage.Sets/src/mage/cards/t/TamiyoFieldResearcher.java index f3316cca383..c7d568a392c 100644 --- a/Mage.Sets/src/mage/cards/t/TamiyoFieldResearcher.java +++ b/Mage.Sets/src/mage/cards/t/TamiyoFieldResearcher.java @@ -150,7 +150,7 @@ class TamiyoFieldResearcherDelayedTriggeredAbility extends DelayedTriggeredAbili @Override public boolean isInactive(Game game) { - return game.getActivePlayerId().equals(getControllerId()) && game.getTurnNum() != startingTurn; + return game.isActivePlayer(getControllerId()) && game.getTurnNum() != startingTurn; } @Override diff --git a/Mage.Sets/src/mage/cards/t/TangleKelp.java b/Mage.Sets/src/mage/cards/t/TangleKelp.java index 25ae12d2858..d4dde772dfe 100644 --- a/Mage.Sets/src/mage/cards/t/TangleKelp.java +++ b/Mage.Sets/src/mage/cards/t/TangleKelp.java @@ -106,7 +106,7 @@ class DontUntapIfAttackedLastTurnEnchantedEffect extends ContinuousRuleModifying Permanent enchantment = game.getPermanent(source.getSourceId()); if (enchantment != null && enchantment.getAttachedTo() != null && event.getTargetId().equals(enchantment.getAttachedTo())) { Permanent permanent = game.getPermanent(enchantment.getAttachedTo()); - if (permanent != null && permanent.getControllerId().equals(game.getActivePlayerId())) { + if (permanent != null && permanent.isControlledBy(game.getActivePlayerId())) { AttackedLastTurnWatcher watcher = (AttackedLastTurnWatcher) game.getState().getWatchers().get(AttackedLastTurnWatcher.class.getSimpleName()); if (watcher != null) { Set attackingCreatures = watcher.getAttackedLastTurnCreatures(permanent.getControllerId()); diff --git a/Mage.Sets/src/mage/cards/t/Taunt.java b/Mage.Sets/src/mage/cards/t/Taunt.java index 377d64a8993..cff6d3e77c2 100644 --- a/Mage.Sets/src/mage/cards/t/Taunt.java +++ b/Mage.Sets/src/mage/cards/t/Taunt.java @@ -55,14 +55,14 @@ class TauntEffect extends RequirementEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { - return permanent.getControllerId().equals(this.getTargetPointer().getFirst(game, source)); + return permanent.isControlledBy(this.getTargetPointer().getFirst(game, source)); } @Override public boolean isInactive(Ability source, Game game) { return startingTurn != game.getTurnNum() && (game.getPhase().getType() == TurnPhase.END && - game.getActivePlayerId().equals(this.getTargetPointer().getFirst(game, source))); + game.isActivePlayer(this.getTargetPointer().getFirst(game, source))); } @Override diff --git a/Mage.Sets/src/mage/cards/t/TeferiMageOfZhalfir.java b/Mage.Sets/src/mage/cards/t/TeferiMageOfZhalfir.java index 9f9672c7285..be586c41a5b 100644 --- a/Mage.Sets/src/mage/cards/t/TeferiMageOfZhalfir.java +++ b/Mage.Sets/src/mage/cards/t/TeferiMageOfZhalfir.java @@ -89,13 +89,13 @@ class TeferiMageOfZhalfirAddFlashEffect extends ContinuousEffectImpl { } // in Exile for (Card card : game.getState().getExile().getAllCards(game)) { - if (card.getOwnerId().equals(controller.getId()) && card.isCreature()) { + if (card.isOwnedBy(controller.getId()) && card.isCreature()) { game.getState().addOtherAbility(card, FlashAbility.getInstance()); } } // in Library (e.g. for Mystical Teachings) for (Card card : controller.getLibrary().getCards(game)) { - if (card.getOwnerId().equals(controller.getId()) && card.isCreature()) { + if (card.isOwnedBy(controller.getId()) && card.isCreature()) { game.getState().addOtherAbility(card, FlashAbility.getInstance()); } } diff --git a/Mage.Sets/src/mage/cards/t/TelimTorsEdict.java b/Mage.Sets/src/mage/cards/t/TelimTorsEdict.java index 7b3b24804dd..e065dbebbbb 100644 --- a/Mage.Sets/src/mage/cards/t/TelimTorsEdict.java +++ b/Mage.Sets/src/mage/cards/t/TelimTorsEdict.java @@ -58,7 +58,7 @@ class TelimTorsEdictPredicate implements ObjectPlayerPredicate input, Game game) { Permanent permanent = input.getObject(); UUID playerId = input.getPlayerId(); - if (permanent.getControllerId().equals(playerId) || permanent.getOwnerId().equals(playerId)) { + if (permanent.isControlledBy(playerId) || permanent.isOwnedBy(playerId)) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/t/TempleAltisaur.java b/Mage.Sets/src/mage/cards/t/TempleAltisaur.java index 2f07f760a1c..c4f1afe7dd5 100644 --- a/Mage.Sets/src/mage/cards/t/TempleAltisaur.java +++ b/Mage.Sets/src/mage/cards/t/TempleAltisaur.java @@ -77,7 +77,7 @@ class TempleAltisaurPreventEffect extends PreventionEffectImpl { if (permanent != null && !permanent.getId().equals(source.getSourceId()) && permanent.hasSubtype(SubType.DINOSAUR, game) - && permanent.getControllerId().equals(source.getControllerId())) { + && permanent.isControlledBy(source.getControllerId())) { return super.applies(event, source, game); } } diff --git a/Mage.Sets/src/mage/cards/t/ThadaAdelAcquisitor.java b/Mage.Sets/src/mage/cards/t/ThadaAdelAcquisitor.java index 5c0bcb2aa94..e5777b82a6e 100644 --- a/Mage.Sets/src/mage/cards/t/ThadaAdelAcquisitor.java +++ b/Mage.Sets/src/mage/cards/t/ThadaAdelAcquisitor.java @@ -116,7 +116,7 @@ class ThadaAdelPlayFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) + return source.isControlledBy(affectedControllerId) && sourceId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/t/TheBigIdea.java b/Mage.Sets/src/mage/cards/t/TheBigIdea.java index 44d3391a6b5..6bb1285d164 100644 --- a/Mage.Sets/src/mage/cards/t/TheBigIdea.java +++ b/Mage.Sets/src/mage/cards/t/TheBigIdea.java @@ -118,7 +118,7 @@ class TheBigIdeaReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (!this.used) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } return false; } diff --git a/Mage.Sets/src/mage/cards/t/TheEldestReborn.java b/Mage.Sets/src/mage/cards/t/TheEldestReborn.java index f38a938116b..666e52d657f 100644 --- a/Mage.Sets/src/mage/cards/t/TheEldestReborn.java +++ b/Mage.Sets/src/mage/cards/t/TheEldestReborn.java @@ -14,6 +14,7 @@ import mage.constants.SubType; import mage.constants.TargetController; import mage.filter.FilterCard; import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.target.common.TargetCardInGraveyard; @@ -33,6 +34,15 @@ public final class TheEldestReborn extends CardImpl { )); } + private static final FilterControlledPermanent filterSacrifice = new FilterControlledPermanent("creature or planeswalker"); + static { + filterSacrifice.add(Predicates.or( + new CardTypePredicate(CardType.CREATURE), + new CardTypePredicate(CardType.PLANESWALKER) + )); + + } + public TheEldestReborn(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}"); @@ -42,7 +52,7 @@ public final class TheEldestReborn extends CardImpl { SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III); // I — Each opponent sacrifices a creature or planeswalker. sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, - new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_CREATURE_OR_PLANESWALKER_A) + new SacrificeOpponentsEffect(filterSacrifice) ); // II — Each opponent discards a card. diff --git a/Mage.Sets/src/mage/cards/t/TheFallen.java b/Mage.Sets/src/mage/cards/t/TheFallen.java index 59388577ce8..8676d61c573 100644 --- a/Mage.Sets/src/mage/cards/t/TheFallen.java +++ b/Mage.Sets/src/mage/cards/t/TheFallen.java @@ -65,7 +65,7 @@ class TheFallenEffect extends OneShotEffect { TheFallenWatcher watcher = (TheFallenWatcher) game.getState().getWatchers().get(TheFallenWatcher.class.getSimpleName()); if (watcher != null && watcher.getPlayersAndWalkersDealtDamageThisGame(source.getSourceId()) != null) { for (UUID playerId : watcher.getPlayersAndWalkersDealtDamageThisGame(source.getSourceId())) { - if (!source.getControllerId().equals(playerId)) { + if (!source.isControlledBy(playerId)) { game.damagePlayerOrPlaneswalker(playerId, 1, source.getSourceId(), game, false, true); } } diff --git a/Mage.Sets/src/mage/cards/t/TheFlameOfKeld.java b/Mage.Sets/src/mage/cards/t/TheFlameOfKeld.java index 0e7bcab7161..1fb9383bfb7 100644 --- a/Mage.Sets/src/mage/cards/t/TheFlameOfKeld.java +++ b/Mage.Sets/src/mage/cards/t/TheFlameOfKeld.java @@ -83,7 +83,7 @@ class TheFlameOfKeldDamageEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (source.getControllerId().equals(game.getControllerId(event.getSourceId()))) { + if (source.isControlledBy(game.getControllerId(event.getSourceId()))) { MageObject sourceObject; Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); if (sourcePermanent == null) { diff --git a/Mage.Sets/src/mage/cards/t/TheGitrogMonster.java b/Mage.Sets/src/mage/cards/t/TheGitrogMonster.java index b126d89cbbd..8fc2ee9ce18 100644 --- a/Mage.Sets/src/mage/cards/t/TheGitrogMonster.java +++ b/Mage.Sets/src/mage/cards/t/TheGitrogMonster.java @@ -83,7 +83,7 @@ class TheGitrogMonsterTriggeredAbility extends TriggeredAbilityImpl { UUID cardOwnerId = card.getOwnerId(); Set cardType = card.getCardType(); if (cardOwnerId != null - && card.getOwnerId().equals(getControllerId()) + && card.isOwnedBy(getControllerId()) && cardType != null && card.isLand()) { return true; diff --git a/Mage.Sets/src/mage/cards/t/TheUrDragon.java b/Mage.Sets/src/mage/cards/t/TheUrDragon.java index ca68b29fa0a..ac9fbb04948 100644 --- a/Mage.Sets/src/mage/cards/t/TheUrDragon.java +++ b/Mage.Sets/src/mage/cards/t/TheUrDragon.java @@ -1,16 +1,12 @@ - package mage.cards.t; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; import mage.MageInt; -import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; import mage.abilities.keyword.FlyingAbility; @@ -22,8 +18,6 @@ import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.watchers.Watcher; /** * @author TheElk801 @@ -60,7 +54,7 @@ public final class TheUrDragon extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Whenever one or more Dragons you control attack, draw that many cards, then you may put a permanent card from your hand onto the battlefield - this.addAbility(new TheUrDragonTriggeredAbility(), new DragonsAttackedWatcher()); + this.addAbility(new TheUrDragonTriggeredAbility()); } public TheUrDragon(final TheUrDragon card) { @@ -73,46 +67,10 @@ public final class TheUrDragon extends CardImpl { } } -class DragonsAttackedWatcher extends Watcher { - - public final Set attackedThisTurnCreatures = new HashSet<>(); - - public DragonsAttackedWatcher() { - super(DragonsAttackedWatcher.class.getSimpleName(), WatcherScope.GAME); - } - - public DragonsAttackedWatcher(final DragonsAttackedWatcher watcher) { - super(watcher); - this.attackedThisTurnCreatures.addAll(watcher.attackedThisTurnCreatures); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.BEGIN_COMBAT_STEP_PRE) { - this.attackedThisTurnCreatures.clear(); - } - if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED) { - if (game.getPermanent(event.getSourceId()).hasSubtype(SubType.DRAGON, game)) { - this.attackedThisTurnCreatures.add(new MageObjectReference(event.getSourceId(), game)); - } - } - } - - public Set getAttackedThisTurnCreatures() { - return this.attackedThisTurnCreatures; - } - - @Override - public DragonsAttackedWatcher copy() { - return new DragonsAttackedWatcher(this); - } - -} - class TheUrDragonTriggeredAbility extends TriggeredAbilityImpl { public TheUrDragonTriggeredAbility() { - super(Zone.BATTLEFIELD, new TheUrDragonEffect(), false); + super(Zone.BATTLEFIELD, null, false); } public TheUrDragonTriggeredAbility(final TheUrDragonTriggeredAbility ability) { @@ -131,58 +89,27 @@ class TheUrDragonTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { + int attackingDragons = 0; for (UUID attacker : game.getCombat().getAttackers()) { Permanent creature = game.getPermanent(attacker); if (creature != null && creature.getControllerId() != null - && creature.getControllerId().equals(this.getControllerId()) + && creature.isControlledBy(this.getControllerId()) && creature.hasSubtype(SubType.DRAGON, game)) { - return true; + attackingDragons++; } } + if (attackingDragons > 0) { + this.getEffects().clear(); + addEffect(new DrawCardSourceControllerEffect(attackingDragons)); + addEffect(new PutCardFromHandOntoBattlefieldEffect()); + return true; + } return false; } @Override public String getRule() { - return "Whenever one or more Dragons you control attack, " + super.getRule(); - } -} - -class TheUrDragonEffect extends OneShotEffect { - - public TheUrDragonEffect() { - super(Outcome.Benefit); - this.staticText = "draw that many cards, then you may put a permanent card from your hand onto the battlefield"; - } - - public TheUrDragonEffect(final TheUrDragonEffect effect) { - super(effect); - } - - @Override - public TheUrDragonEffect copy() { - return new TheUrDragonEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - DragonsAttackedWatcher watcher = (DragonsAttackedWatcher) game.getState().getWatchers().get(DragonsAttackedWatcher.class.getSimpleName()); - if (watcher != null) { - int attackingDragons = 0; - for (MageObjectReference attacker : watcher.getAttackedThisTurnCreatures()) { - if (attacker.getPermanentOrLKIBattlefield(game).getControllerId().equals(controller.getId())) { - attackingDragons++; - } - } - if (attackingDragons > 0) { - controller.drawCards(attackingDragons, game); - } - return new PutCardFromHandOntoBattlefieldEffect().apply(game, source); - } - } - return false; + return "Whenever one or more Dragons you control attack, draw that many cards, then you may put a permanent card from your hand onto the battlefield."; } } diff --git a/Mage.Sets/src/mage/cards/t/ThopterSpyNetwork.java b/Mage.Sets/src/mage/cards/t/ThopterSpyNetwork.java index 7b9393e5bb3..8514dc92551 100644 --- a/Mage.Sets/src/mage/cards/t/ThopterSpyNetwork.java +++ b/Mage.Sets/src/mage/cards/t/ThopterSpyNetwork.java @@ -108,7 +108,7 @@ class ThopterSpyNetworkDamageTriggeredAbility extends TriggeredAbilityImpl { if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER) { if (((DamagedPlayerEvent) event).isCombatDamage()) { Permanent creature = game.getPermanent(event.getSourceId()); - if (creature != null && creature.getControllerId().equals(controllerId) + if (creature != null && creature.isControlledBy(controllerId) && creature.isArtifact() && !damagedPlayerIds.contains(event.getTargetId())) { damagedPlayerIds.add(event.getTargetId()); return true; diff --git a/Mage.Sets/src/mage/cards/t/ThoughtDissector.java b/Mage.Sets/src/mage/cards/t/ThoughtDissector.java new file mode 100644 index 00000000000..2238235f421 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThoughtDissector.java @@ -0,0 +1,106 @@ +package mage.cards.t; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.VariableManaCost; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; +import mage.abilities.effects.OneShotEffect; +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.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetOpponent; + +import java.util.UUID; + +/** + * + * @author noahg + */ +public final class ThoughtDissector extends CardImpl { + + public ThoughtDissector(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + + + // {X}, {tap}: Target opponent reveals cards from the top of their library until an artifact card or X cards are revealed, whichever comes first. If an artifact card is revealed this way, put it onto the battlefield under your control and sacrifice Thought Dissector. Put the rest of the revealed cards into that player's graveyard. + SimpleActivatedAbility abilitiy = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ThoughtDissectorEffect(), new VariableManaCost()); + abilitiy.addCost(new TapSourceCost()); + abilitiy.addTarget(new TargetOpponent()); + this.addAbility(abilitiy); + } + + public ThoughtDissector(final ThoughtDissector card) { + super(card); + } + + @Override + public ThoughtDissector copy() { + return new ThoughtDissector(this); + } +} + +class ThoughtDissectorEffect extends OneShotEffect { + + private static final ManacostVariableValue amount = new ManacostVariableValue(); + + public ThoughtDissectorEffect() { + super(Outcome.Detriment); + staticText = "Target opponent reveals cards from the top of their library until an artifact card or X cards are revealed, whichever comes first. If an artifact card is revealed this way, put it onto the battlefield under your control and sacrifice {this}. Put the rest of the revealed cards into that player's graveyard."; + } + + public ThoughtDissectorEffect(final ThoughtDissectorEffect effect) { + super(effect); + } + + @Override + public ThoughtDissectorEffect copy() { + return new ThoughtDissectorEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player targetOpponent = game.getPlayer(targetPointer.getFirst(game, source)); + int max = amount.calculate(game, source, this); + if (targetOpponent != null && controller != null && max > 0) { + int numberOfCard = 0; + Card artifact = null; + CardsImpl nonArtifacts = new CardsImpl(); + CardsImpl reveal = new CardsImpl(); + for (Card card : targetOpponent.getLibrary().getCards(game)) { + reveal.add(card); + if (card.isArtifact()) { + artifact = card; + break; + } else { + numberOfCard++; + if (numberOfCard > max){ + break; + } + nonArtifacts.add(card); + } + } + targetOpponent.revealCards(source, reveal, game); + if (artifact != null) { + game.applyEffects(); + controller.moveCards(artifact, Zone.BATTLEFIELD, source, game); + Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game); + if (sourcePermanent != null) { + sourcePermanent.sacrifice(source.getSourceId(), game); + } + } + targetOpponent.moveCards(nonArtifacts, Zone.GRAVEYARD, source, game); + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/t/ThousandYearElixir.java b/Mage.Sets/src/mage/cards/t/ThousandYearElixir.java index c41b0293b9f..41ed3921e2d 100644 --- a/Mage.Sets/src/mage/cards/t/ThousandYearElixir.java +++ b/Mage.Sets/src/mage/cards/t/ThousandYearElixir.java @@ -76,6 +76,6 @@ class ThousandYearElixirEffect extends AsThoughEffectImpl { Permanent permanent = game.getPermanent(sourceId); return permanent != null && permanent.isCreature() - && permanent.getControllerId().equals(source.getControllerId()); + && permanent.isControlledBy(source.getControllerId()); } } diff --git a/Mage.Sets/src/mage/cards/t/ThreeWishes.java b/Mage.Sets/src/mage/cards/t/ThreeWishes.java index b6d14874cca..a88b1df88d8 100644 --- a/Mage.Sets/src/mage/cards/t/ThreeWishes.java +++ b/Mage.Sets/src/mage/cards/t/ThreeWishes.java @@ -187,7 +187,7 @@ class ThreeWishesPlayFromExileEffect extends AsThoughEffectImpl { return exile != null && getTargetPointer().getFirst(game, source) != null && getTargetPointer().getFirst(game, source).equals(sourceId) - && source.getControllerId().equals(affectedControllerId) + && source.isControlledBy(affectedControllerId) && game.getState().getZone(sourceId) == Zone.EXILED && exile.contains(sourceId); } diff --git a/Mage.Sets/src/mage/cards/t/ThroneofGeth.java b/Mage.Sets/src/mage/cards/t/ThroneOfGeth.java similarity index 80% rename from Mage.Sets/src/mage/cards/t/ThroneofGeth.java rename to Mage.Sets/src/mage/cards/t/ThroneOfGeth.java index 1707d089180..329851cf1b1 100644 --- a/Mage.Sets/src/mage/cards/t/ThroneofGeth.java +++ b/Mage.Sets/src/mage/cards/t/ThroneOfGeth.java @@ -20,27 +20,31 @@ import mage.target.common.TargetControlledPermanent; * * @author Loki */ -public final class ThroneofGeth extends CardImpl { +public final class ThroneOfGeth extends CardImpl { + private static final FilterControlledPermanent filter = new FilterControlledPermanent("an artifact"); static { filter.add(new CardTypePredicate(CardType.ARTIFACT)); } - public ThroneofGeth (UUID ownerId, CardSetInfo setInfo) { + public ThroneOfGeth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + + // {T}, Sacrifice an artifact: Proliferate. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ProliferateEffect(), new TapSourceCost()); ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); this.addAbility(ability); } - public ThroneofGeth (final ThroneofGeth card) { + public ThroneOfGeth(final ThroneOfGeth card) { super(card); } @Override - public ThroneofGeth copy() { - return new ThroneofGeth(this); + public ThroneOfGeth copy() { + return new ThroneOfGeth(this); } } diff --git a/Mage.Sets/src/mage/cards/t/TianaShipsCaretaker.java b/Mage.Sets/src/mage/cards/t/TianaShipsCaretaker.java index 4c4d968a162..832e96d5de7 100644 --- a/Mage.Sets/src/mage/cards/t/TianaShipsCaretaker.java +++ b/Mage.Sets/src/mage/cards/t/TianaShipsCaretaker.java @@ -96,7 +96,7 @@ class TianaShipsCaretakerTriggeredAbility extends TriggeredAbilityImpl { && zEvent.getFromZone() == Zone.BATTLEFIELD && (permanent.isArtifact() && permanent.hasSubtype(SubType.EQUIPMENT, game) || permanent.isEnchantment() && permanent.hasSubtype(SubType.AURA, game)) - && permanent.getControllerId().equals(this.controllerId)) { + && permanent.isControlledBy(this.controllerId)) { this.getEffects().setTargetPointer(new FixedTarget(zEvent.getTargetId())); return true; } diff --git a/Mage.Sets/src/mage/cards/t/TidebinderMage.java b/Mage.Sets/src/mage/cards/t/TidebinderMage.java index cdc97d7c4a8..bc6348a8590 100644 --- a/Mage.Sets/src/mage/cards/t/TidebinderMage.java +++ b/Mage.Sets/src/mage/cards/t/TidebinderMage.java @@ -97,7 +97,7 @@ class TidebinderMageEffect extends ContinuousRuleModifyingEffectImpl { // the battlefield triggered ability the source dies (or will be exiled), then the ZONE_CHANGE or LOST_CONTROL // event will happen before this effect is applied ever) Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (sourcePermanent == null || !sourcePermanent.getControllerId().equals(source.getControllerId())) { + if (sourcePermanent == null || !sourcePermanent.isControlledBy(source.getControllerId())) { discard(); return false; } @@ -118,7 +118,7 @@ class TidebinderMageEffect extends ContinuousRuleModifyingEffectImpl { if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) { if (event.getTargetId().equals(targetPointer.getFirst(game, source))) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && game.getActivePlayerId().equals(permanent.getControllerId())) { + if (permanent != null && game.isActivePlayer(permanent.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/t/TimeOfIce.java b/Mage.Sets/src/mage/cards/t/TimeOfIce.java index fddf8a086e0..10780d7b643 100644 --- a/Mage.Sets/src/mage/cards/t/TimeOfIce.java +++ b/Mage.Sets/src/mage/cards/t/TimeOfIce.java @@ -119,7 +119,7 @@ class TimeOfIceEffect extends ContinuousRuleModifyingEffectImpl { if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getTargetId().equals(targetPointer.getFirst(game, source))) { Permanent targetCreature = game.getPermanent(targetPointer.getFirst(game, source)); if (targetCreature != null) { - return targetCreature.getControllerId().equals(game.getActivePlayerId()); + return targetCreature.isControlledBy(game.getActivePlayerId()); } else { discard(); return false; diff --git a/Mage.Sets/src/mage/cards/t/TimeVault.java b/Mage.Sets/src/mage/cards/t/TimeVault.java index 3e559518512..7586d9f3a89 100644 --- a/Mage.Sets/src/mage/cards/t/TimeVault.java +++ b/Mage.Sets/src/mage/cards/t/TimeVault.java @@ -78,7 +78,7 @@ class TimeVaultReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (source.getControllerId().equals(event.getPlayerId())) { + if (source.isControlledBy(event.getPlayerId())) { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null && permanent.isTapped()) { return true; diff --git a/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java b/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java index 4d3fbc6db7a..bda573aa8b2 100644 --- a/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java +++ b/Mage.Sets/src/mage/cards/t/TormentOfScarabs.java @@ -80,7 +80,7 @@ class TormentOfScarabsAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent enchantment = game.getPermanent(this.getSourceId()); if (enchantment != null && enchantment.getAttachedTo() != null) { - if (game.getActivePlayerId().equals(enchantment.getAttachedTo())) { + if (game.isActivePlayer(enchantment.getAttachedTo())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/t/TravelingPlague.java b/Mage.Sets/src/mage/cards/t/TravelingPlague.java index 148be5c523b..d079c2c44b4 100644 --- a/Mage.Sets/src/mage/cards/t/TravelingPlague.java +++ b/Mage.Sets/src/mage/cards/t/TravelingPlague.java @@ -135,7 +135,7 @@ class TravelingPlagueEffect extends OneShotEffect { if (enchantedCreature != null) { Player controllerOfEnchantedCreature = game.getPlayer(enchantedCreature.getControllerId()); if (travelingPlague != null - && game.getState().getZone(travelingPlague.getId()).equals(Zone.GRAVEYARD) // aura must come from the graveyard + && game.getState().getZone(travelingPlague.getId()) == Zone.GRAVEYARD // aura must come from the graveyard && controllerOfEnchantedCreature != null) { TargetPermanent target = new TargetPermanent(new FilterCreaturePermanent("creature to enchant with " + travelingPlague.getName())); target.setNotTarget(true); diff --git a/Mage.Sets/src/mage/cards/t/TreacherousTerrain.java b/Mage.Sets/src/mage/cards/t/TreacherousTerrain.java index 8650e8c92b0..248c68496b8 100644 --- a/Mage.Sets/src/mage/cards/t/TreacherousTerrain.java +++ b/Mage.Sets/src/mage/cards/t/TreacherousTerrain.java @@ -61,7 +61,7 @@ class TreacherousTerrainEffect extends OneShotEffect { if (player != null) { int amount = 0; for (Permanent permanent : permanents) { - if (permanent.getControllerId().equals(playerId)) { + if (permanent.isControlledBy(playerId)) { amount++; } } diff --git a/Mage.Sets/src/mage/cards/t/TrostaniSelesnyasVoice.java b/Mage.Sets/src/mage/cards/t/TrostaniSelesnyasVoice.java index 9e23a771fe8..5d1a729b304 100644 --- a/Mage.Sets/src/mage/cards/t/TrostaniSelesnyasVoice.java +++ b/Mage.Sets/src/mage/cards/t/TrostaniSelesnyasVoice.java @@ -78,7 +78,7 @@ class TrostaniSelesnyasVoiceTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent.isCreature() - && permanent.getControllerId().equals(this.controllerId) + && permanent.isControlledBy(this.controllerId) && !Objects.equals(event.getTargetId(), this.getSourceId())) { Effect effect = this.getEffects().get(0); // life is determined during resolution so it has to be retrieved there (e.g. Giant Growth before resolution) diff --git a/Mage.Sets/src/mage/cards/t/TrueNameNemesis.java b/Mage.Sets/src/mage/cards/t/TrueNameNemesis.java index 2ed94431b8c..bc5fefd8179 100644 --- a/Mage.Sets/src/mage/cards/t/TrueNameNemesis.java +++ b/Mage.Sets/src/mage/cards/t/TrueNameNemesis.java @@ -84,16 +84,16 @@ class ProtectionFromPlayerAbility extends ProtectionAbility { UUID playerId = (UUID) game.getState().getValue(this.getSourceId() + "_player"); if (playerId != null && source != null) { if (source instanceof Permanent) { - return !((Permanent) source).getControllerId().equals(playerId); + return !((Permanent) source).isControlledBy(playerId); } if (source instanceof Spell) { - return !((Spell) source).getControllerId().equals(playerId); + return !((Spell) source).isControlledBy(playerId); } if (source instanceof StackObject) { - return !((StackObject) source).getControllerId().equals(playerId); + return !((StackObject) source).isControlledBy(playerId); } if (source instanceof Card) { // e.g. for Vengeful Pharaoh - return !((Card) source).getOwnerId().equals(playerId); + return !((Card) source).isOwnedBy(playerId); } } return true; diff --git a/Mage.Sets/src/mage/cards/t/TruthOrTale.java b/Mage.Sets/src/mage/cards/t/TruthOrTale.java new file mode 100644 index 00000000000..f76c7eed66e --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TruthOrTale.java @@ -0,0 +1,126 @@ +package mage.cards.t; + +import java.util.*; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Library; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetCard; +import mage.target.common.TargetOpponent; +import mage.util.GameLog; + +/** + * + * @author noahg + */ +public final class TruthOrTale extends CardImpl { + + public TruthOrTale(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + + // Reveal the top five cards of your library and separate them into two piles. An opponent chooses one of those piles. Put a card from the chosen pile into your hand, then put all other cards revealed this way on the bottom of your library in any order. + this.getSpellAbility().addEffect(new TruthOrTaleEffect()); + } + + public TruthOrTale(final TruthOrTale card) { + super(card); + } + + @Override + public TruthOrTale copy() { + return new TruthOrTale(this); + } +} + +class TruthOrTaleEffect extends OneShotEffect { + + public TruthOrTaleEffect() { + super(Outcome.DrawCard); + this.staticText = "Reveal the top five cards of your library and separate them into two piles. An opponent chooses one of those piles. Put a card from the chosen pile into your hand, then put all other cards revealed this way on the bottom of your library in any order"; + } + + public TruthOrTaleEffect(final TruthOrTaleEffect effect) { + super(effect); + } + + @Override + public TruthOrTaleEffect copy() { + return new TruthOrTaleEffect(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; + } + + Cards cards = new CardsImpl(); + cards.addAll(controller.getLibrary().getTopCards(game, 5)); + 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()); + } + + if (opponent != null) { + TargetCard target = new TargetCard(0, cards.size(), Zone.LIBRARY, new FilterCard("cards to put in the first pile")); + List pile1 = new ArrayList<>(); + target.setRequired(false); + if (controller.choose(Outcome.Neutral, cards, target, game)) { + List targets = target.getTargets(); + for (UUID targetId : targets) { + Card card = game.getCard(targetId); + if (card != null) { + pile1.add(card); + } + } + } + List pile2 = new ArrayList<>(); + for (UUID cardId : cards) { + Card card = game.getCard(cardId); + if (card != null && !pile1.contains(card)) { + pile2.add(card); + } + } + boolean choice = opponent.choosePile(Outcome.Detriment, "Choose a pile for " + controller.getName() + " to choose a card from.", pile1, pile2, game); + + List chosen = choice ? pile1 : pile2; + if (!chosen.isEmpty()) { + Cards chosenCards = new CardsImpl(new HashSet<>(chosen)); + TargetCard finalChosenCardTarget = new TargetCard(Zone.LIBRARY,new FilterCard("card to put into your hand")); + if (controller.choose(Outcome.DrawCard, chosenCards, finalChosenCardTarget, game)){ + Card finalChosenCard = game.getCard(finalChosenCardTarget.getFirstTarget()); + if (finalChosenCard != null) { + if (!game.isSimulation()) { + game.informPlayers(controller.getName() + " chose to put " + finalChosenCard.getIdName() + " into their hand."); + } + cards.remove(finalChosenCard); + controller.moveCards(finalChosenCard, Zone.HAND, source, game); + } + } + } + + controller.putCardsOnBottomOfLibrary(cards, game, source, true); + } + + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TsabosDecree.java b/Mage.Sets/src/mage/cards/t/TsabosDecree.java index 325c3479d46..422d34b0756 100644 --- a/Mage.Sets/src/mage/cards/t/TsabosDecree.java +++ b/Mage.Sets/src/mage/cards/t/TsabosDecree.java @@ -84,7 +84,7 @@ class TsabosDecreeEffect extends OneShotEffect { FilterCreaturePermanent filterCreaturePermanent = new FilterCreaturePermanent(); filterCreaturePermanent.add(new SubtypePredicate(SubType.byDescription(typeChoice.getChoice()))); for (Permanent creature : game.getBattlefield().getActivePermanents(filterCreaturePermanent, source.getSourceId(), game)) { - if (creature.getControllerId().equals(targetPlayer.getId())) { + if (creature.isControlledBy(targetPlayer.getId())) { creature.destroy(source.getSourceId(), game, true); } } diff --git a/Mage.Sets/src/mage/cards/t/TuktukScrapper.java b/Mage.Sets/src/mage/cards/t/TuktukScrapper.java index f2b30cff515..c7b772f03cf 100644 --- a/Mage.Sets/src/mage/cards/t/TuktukScrapper.java +++ b/Mage.Sets/src/mage/cards/t/TuktukScrapper.java @@ -78,7 +78,7 @@ class TuktukScrapperTriggeredAbility extends TriggeredAbilityImpl { return true; } if (permanent.hasSubtype(SubType.ALLY, game) - && permanent.getControllerId().equals(this.getControllerId())) { + && permanent.isControlledBy(this.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/t/Turnabout.java b/Mage.Sets/src/mage/cards/t/Turnabout.java index 7a0c468d93a..47e2ae27a84 100644 --- a/Mage.Sets/src/mage/cards/t/Turnabout.java +++ b/Mage.Sets/src/mage/cards/t/Turnabout.java @@ -112,14 +112,14 @@ class TurnaboutEffect extends OneShotEffect { if (choiceImpl.getChoice().equals("Untap")) { filter.add(new TappedPredicate()); for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { - if (permanent.getControllerId().equals(target)) { + if (permanent.isControlledBy(target)) { permanent.untap(game); } } } else { filter.add(Predicates.not(new TappedPredicate())); for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { - if (permanent.getControllerId().equals(target)) { + if (permanent.isControlledBy(target)) { permanent.tap(game); } } diff --git a/Mage.Sets/src/mage/cards/t/TwilightShepherd.java b/Mage.Sets/src/mage/cards/t/TwilightShepherd.java index a6de912d3dc..fe12c72f726 100644 --- a/Mage.Sets/src/mage/cards/t/TwilightShepherd.java +++ b/Mage.Sets/src/mage/cards/t/TwilightShepherd.java @@ -90,7 +90,7 @@ class TwilightShepherdEffect extends OneShotEffect { if (game.getState().getZoneChangeCounter(mor.getSourceId()) == mor.getZoneChangeCounter()) { Card card = game.getCard(mor.getSourceId()); if (card != null - && card.getOwnerId().equals(source.getControllerId())) { + && card.isOwnedBy(source.getControllerId())) { cardsToHand.add(card); } } diff --git a/Mage.Sets/src/mage/cards/t/TwistAllegiance.java b/Mage.Sets/src/mage/cards/t/TwistAllegiance.java index 19527d1eab0..625aa011232 100644 --- a/Mage.Sets/src/mage/cards/t/TwistAllegiance.java +++ b/Mage.Sets/src/mage/cards/t/TwistAllegiance.java @@ -67,8 +67,8 @@ class TwistAllegianceEffect extends OneShotEffect { if (controller != null) { for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) { // only creatures of controller & target opponent - if (permanent.getControllerId().equals(source.getControllerId()) || permanent.getControllerId().equals(targetOpponent.getId())) { - UUID newController = permanent.getControllerId().equals(source.getControllerId()) ? targetOpponent.getId() : source.getControllerId(); + if (permanent.isControlledBy(source.getControllerId()) || permanent.isControlledBy(targetOpponent.getId())) { + UUID newController = permanent.isControlledBy(source.getControllerId()) ? targetOpponent.getId() : source.getControllerId(); ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfTurn, true, newController); effect.setTargetPointer(new FixedTarget(permanent.getId())); game.addEffect(effect, source); diff --git a/Mage.Sets/src/mage/cards/u/UnconventionalTactics.java b/Mage.Sets/src/mage/cards/u/UnconventionalTactics.java index edf1e272102..81b45ca9078 100644 --- a/Mage.Sets/src/mage/cards/u/UnconventionalTactics.java +++ b/Mage.Sets/src/mage/cards/u/UnconventionalTactics.java @@ -92,7 +92,7 @@ class UnconventionalTacticsTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent.isCreature() - && permanent.getControllerId().equals(this.controllerId) + && permanent.isControlledBy(this.controllerId) && filter.match(permanent, game)) { return true; } diff --git a/Mage.Sets/src/mage/cards/u/UndeadAlchemist.java b/Mage.Sets/src/mage/cards/u/UndeadAlchemist.java index 4a9e3c16905..2953587af90 100644 --- a/Mage.Sets/src/mage/cards/u/UndeadAlchemist.java +++ b/Mage.Sets/src/mage/cards/u/UndeadAlchemist.java @@ -124,7 +124,7 @@ class UndeadAlchemistEffect extends ReplacementEffectImpl { if (damageEvent.isCombatDamage()) { UUID controllerId = source.getControllerId(); Permanent permanent = game.getPermanent(event.getSourceId()); - if (permanent != null && permanent.hasSubtype(SubType.ZOMBIE, game) && permanent.getControllerId().equals(controllerId)) { + if (permanent != null && permanent.hasSubtype(SubType.ZOMBIE, game) && permanent.isControlledBy(controllerId)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/u/UndiscoveredParadise.java b/Mage.Sets/src/mage/cards/u/UndiscoveredParadise.java index f23896135d5..17395c33701 100644 --- a/Mage.Sets/src/mage/cards/u/UndiscoveredParadise.java +++ b/Mage.Sets/src/mage/cards/u/UndiscoveredParadise.java @@ -89,7 +89,7 @@ class AtBeginningOfUntapDelayedTriggeredAbility extends DelayedTriggeredAbility @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getActivePlayerId().equals(controllerId)) { + if (game.isActivePlayer(controllerId)) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/u/UneshCriosphinxSovereign.java b/Mage.Sets/src/mage/cards/u/UneshCriosphinxSovereign.java index 0fe34235226..d48aeec950d 100644 --- a/Mage.Sets/src/mage/cards/u/UneshCriosphinxSovereign.java +++ b/Mage.Sets/src/mage/cards/u/UneshCriosphinxSovereign.java @@ -98,7 +98,7 @@ class UneshCriosphinxSovereignTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null - && permanent.getOwnerId().equals(controllerId) + && permanent.isOwnedBy(controllerId) && permanent.isCreature() && (event.getTargetId().equals(getSourceId()) || filter.match(permanent, game))) { return true; diff --git a/Mage.Sets/src/mage/cards/u/UnwindingClock.java b/Mage.Sets/src/mage/cards/u/UnwindingClock.java index 51f5f1d1b28..4c0b8767398 100644 --- a/Mage.Sets/src/mage/cards/u/UnwindingClock.java +++ b/Mage.Sets/src/mage/cards/u/UnwindingClock.java @@ -67,7 +67,7 @@ class UnwindingClockEffect extends ContinuousEffectImpl { applied = Boolean.FALSE; } if (!applied && layer == Layer.RulesEffects) { - if (!game.getActivePlayerId().equals(source.getControllerId()) && game.getStep().getType() == PhaseStep.UNTAP) { + if (!game.isActivePlayer(source.getControllerId()) && game.getStep().getType() == PhaseStep.UNTAP) { game.getState().setValue(source.getSourceId() + "applied", true); for (Permanent artifact : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { boolean untap = true; diff --git a/Mage.Sets/src/mage/cards/u/UrbanBurgeoning.java b/Mage.Sets/src/mage/cards/u/UrbanBurgeoning.java index bc55f6d0cb7..2b9c1d2c91d 100644 --- a/Mage.Sets/src/mage/cards/u/UrbanBurgeoning.java +++ b/Mage.Sets/src/mage/cards/u/UrbanBurgeoning.java @@ -82,7 +82,7 @@ class UrbanBurgeoningUntapEffect extends ContinuousEffectImpl { applied = Boolean.FALSE; } if (!applied && layer == Layer.RulesEffects) { - if (!game.getActivePlayerId().equals(source.getControllerId()) && game.getStep().getType() == PhaseStep.UNTAP) { + if (!game.isActivePlayer(source.getControllerId()) && game.getStep().getType() == PhaseStep.UNTAP) { game.getState().setValue(source.getSourceId() + "applied", true); Permanent land = game.getPermanent(source.getSourceId()); boolean untap = true; diff --git a/Mage.Sets/src/mage/cards/v/ValakutTheMoltenPinnacle.java b/Mage.Sets/src/mage/cards/v/ValakutTheMoltenPinnacle.java index 85ceb9e6644..be270c64770 100644 --- a/Mage.Sets/src/mage/cards/v/ValakutTheMoltenPinnacle.java +++ b/Mage.Sets/src/mage/cards/v/ValakutTheMoltenPinnacle.java @@ -80,7 +80,7 @@ class ValakutTheMoltenPinnacleTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.isLand() && permanent.getControllerId().equals(this.getControllerId())) { + if (permanent != null && permanent.isLand() && permanent.isControlledBy(this.getControllerId())) { if (permanent.hasSubtype(SubType.MOUNTAIN, game)) { return true; } diff --git a/Mage.Sets/src/mage/cards/v/ValeronWardens.java b/Mage.Sets/src/mage/cards/v/ValeronWardens.java index 905fbed1c20..e2d71a168f1 100644 --- a/Mage.Sets/src/mage/cards/v/ValeronWardens.java +++ b/Mage.Sets/src/mage/cards/v/ValeronWardens.java @@ -69,7 +69,7 @@ class ValeronWardensTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); - return permanent != null && permanent.getControllerId().equals(getControllerId()); + return permanent != null && permanent.isControlledBy(getControllerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java index b57f1eed130..c29c57a9a21 100644 --- a/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java +++ b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java @@ -120,7 +120,7 @@ class CastFromNonHandZoneTargetEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { if (getTargetPointer().getTargets(game, source).contains(objectId) - && source.getControllerId().equals(affectedControllerId)) { + && source.isControlledBy(affectedControllerId)) { Card card = game.getCard(objectId); if (card != null) { return true; diff --git a/Mage.Sets/src/mage/cards/v/VanquishersBanner.java b/Mage.Sets/src/mage/cards/v/VanquishersBanner.java index 327fef11cf4..87a0cc004f9 100644 --- a/Mage.Sets/src/mage/cards/v/VanquishersBanner.java +++ b/Mage.Sets/src/mage/cards/v/VanquishersBanner.java @@ -87,7 +87,7 @@ class DrawCardIfCreatureTypeAbility extends TriggeredAbilityImpl { if (spell != null && spell.isCreature() && spell.hasSubtype(subType, game) - && spell.getControllerId().equals(getControllerId())) { + && spell.isControlledBy(getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/v/VeilstoneAmulet.java b/Mage.Sets/src/mage/cards/v/VeilstoneAmulet.java index 9d8b3643944..b08a759db3c 100644 --- a/Mage.Sets/src/mage/cards/v/VeilstoneAmulet.java +++ b/Mage.Sets/src/mage/cards/v/VeilstoneAmulet.java @@ -72,7 +72,7 @@ class VeilstoneAmuletEffect extends ContinuousRuleModifyingEffectImpl { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null) { if (permanent.isCreature() && - permanent.getControllerId().equals(ability.getControllerId()) && + permanent.isControlledBy(ability.getControllerId()) && game.getPlayer(ability.getControllerId()).hasOpponent(event.getPlayerId(), game)) { return true; } diff --git a/Mage.Sets/src/mage/cards/v/VengefulPharaoh.java b/Mage.Sets/src/mage/cards/v/VengefulPharaoh.java index a1e545299ff..25d66d6245b 100644 --- a/Mage.Sets/src/mage/cards/v/VengefulPharaoh.java +++ b/Mage.Sets/src/mage/cards/v/VengefulPharaoh.java @@ -109,7 +109,7 @@ class VengefulPharaohTriggeredAbility extends TriggeredAbilityImpl { } if (event.getType() == EventType.DAMAGED_PLANESWALKER && ((DamagedEvent) event).isCombatDamage()) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getControllerId().equals(this.getControllerId())) { + if (permanent != null && permanent.isControlledBy(this.getControllerId())) { if (!game.getPhase().getStep().equals(stepTriggeredPlansewalker) || game.getTurnNum() != turnTriggeredPlaneswalker) { stepTriggeredPlansewalker = game.getPhase().getStep(); turnTriggeredPlaneswalker = game.getTurnNum(); diff --git a/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java b/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java index 65c86cf7d69..130a1948602 100644 --- a/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java +++ b/Mage.Sets/src/mage/cards/v/VerdantSunsAvatar.java @@ -66,7 +66,7 @@ class VerdantSunsAvatarTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.isCreature() - && permanent.getControllerId().equals(this.controllerId)) { + && permanent.isControlledBy(this.controllerId)) { Effect effect = this.getEffects().get(0); // Life is determined during resolution so it has to be retrieved there (e.g. Giant Growth before resolution) effect.setValue("lifeSource", event.getTargetId()); diff --git a/Mage.Sets/src/mage/cards/v/VigeanIntuition.java b/Mage.Sets/src/mage/cards/v/VigeanIntuition.java new file mode 100644 index 00000000000..29f91842a77 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VigeanIntuition.java @@ -0,0 +1,124 @@ +package mage.cards.v; + +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.*; +import mage.choices.Choice; +import mage.choices.ChoiceImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.token.SaprolingToken; +import mage.players.Library; +import mage.players.Player; + +/** + * + * @author noahg + */ +public final class VigeanIntuition extends CardImpl { + + public VigeanIntuition(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{G}{U}"); + + + // Choose a card type, then reveal the top four cards of your library. Put all cards of the chosen type revealed this way into your hand and the rest into your graveyard. + this.getSpellAbility().addEffect(new VigeanIntuitionEffect()); + } + + public VigeanIntuition(final VigeanIntuition card) { + super(card); + } + + @Override + public VigeanIntuition copy() { + return new VigeanIntuition(this); + } +} + +class VigeanIntuitionEffect 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 VigeanIntuitionEffect() { + super(Outcome.Benefit); + staticText = "Choose a card type, then reveal the top four cards of your library. Put all cards of the chosen type revealed this way into your hand and the rest into your graveyard"; + } + + public VigeanIntuitionEffect(final VigeanIntuitionEffect effect) { + super(effect); + } + + @Override + public VigeanIntuitionEffect copy() { + return new VigeanIntuitionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + MageObject sourceObject = game.getObject(source.getSourceId()); + Player player = game.getPlayer(source.getControllerId()); + Library library = player.getLibrary(); + if (player != null && sourceObject != null && library != null) { + Choice choiceImpl = new ChoiceImpl(); + choiceImpl.setChoices(choice); + if (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) { + Set top = library.getTopCards(game, 4); + player.revealCards(source, new CardsImpl(top), game); + Cards putInHand = new CardsImpl(); + Cards putInGraveyard = new CardsImpl(); + for (Card card : top) { + if (card != null && card.getCardType().contains(type)) { + putInHand.add(card); + } else { + putInGraveyard.add(card); + } + } + player.moveCards(putInHand, Zone.HAND, source, game); + player.moveCards(putInGraveyard, Zone.GRAVEYARD, source, game); + return true; + } + } + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/v/VigilForTheLost.java b/Mage.Sets/src/mage/cards/v/VigilForTheLost.java index 463316ebc78..b5de68f55e5 100644 --- a/Mage.Sets/src/mage/cards/v/VigilForTheLost.java +++ b/Mage.Sets/src/mage/cards/v/VigilForTheLost.java @@ -66,7 +66,7 @@ class VigilForTheLostTriggeredAbility extends TriggeredAbilityImpl { if (((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD && ((ZoneChangeEvent)event).getFromZone() == Zone.BATTLEFIELD) { Permanent p = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (p.getControllerId().equals(this.getControllerId()) && p.isCreature()) { + if (p.isControlledBy(this.getControllerId()) && p.isCreature()) { return true; } } diff --git a/Mage.Sets/src/mage/cards/v/VivienOfTheArkbow.java b/Mage.Sets/src/mage/cards/v/VivienOfTheArkbow.java index af43a37d6d0..f40809e0bb2 100644 --- a/Mage.Sets/src/mage/cards/v/VivienOfTheArkbow.java +++ b/Mage.Sets/src/mage/cards/v/VivienOfTheArkbow.java @@ -51,6 +51,7 @@ public final class VivienOfTheArkbow extends CardImpl { ability = new LoyaltyAbility(new DamageWithPowerTargetEffect(), -3); ability.addTarget(new TargetControlledCreaturePermanent()); ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); // −9: Creatures you control get +4/+4 and gain trample until end of turn. ability = new LoyaltyAbility( diff --git a/Mage.Sets/src/mage/cards/v/VivienReid.java b/Mage.Sets/src/mage/cards/v/VivienReid.java index f9ac19d2b53..2e3468420a7 100644 --- a/Mage.Sets/src/mage/cards/v/VivienReid.java +++ b/Mage.Sets/src/mage/cards/v/VivienReid.java @@ -61,7 +61,7 @@ public final class VivienReid extends CardImpl { )); // -3: Destroy target artifact, enchantment, or creature with flying. - Ability ability = new LoyaltyAbility(new DestroyTargetEffect()); + Ability ability = new LoyaltyAbility(new DestroyTargetEffect(), -3); ability.addTarget(new TargetPermanent(filter2)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/v/VizierOfRemedies.java b/Mage.Sets/src/mage/cards/v/VizierOfRemedies.java index 9eb1d5063c2..2823ffa75b1 100644 --- a/Mage.Sets/src/mage/cards/v/VizierOfRemedies.java +++ b/Mage.Sets/src/mage/cards/v/VizierOfRemedies.java @@ -76,7 +76,7 @@ class VizierOfRemediesReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (source != null && source.getControllerId() != null) { - if (source.getControllerId().equals(game.getControllerId(event.getTargetId())) + if (source.isControlledBy(game.getControllerId(event.getTargetId())) && event.getData() != null && event.getData().equals(CounterType.M1M1.getName()) && event.getAmount() > 0) { return true; diff --git a/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java b/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java index f55d382826a..cfca3c4884a 100644 --- a/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java +++ b/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java @@ -160,7 +160,7 @@ class VizierOfTheMenagerieManaEffect extends AsThoughEffectImpl implements AsTho @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (source.getControllerId().equals(affectedControllerId)) { + if (source.isControlledBy(affectedControllerId)) { MageObject mageObject = game.getObject(objectId); return mageObject != null && mageObject.isCreature(); diff --git a/Mage.Sets/src/mage/cards/v/VoiceOfResurgence.java b/Mage.Sets/src/mage/cards/v/VoiceOfResurgence.java index deea39da29e..08b9cd0334a 100644 --- a/Mage.Sets/src/mage/cards/v/VoiceOfResurgence.java +++ b/Mage.Sets/src/mage/cards/v/VoiceOfResurgence.java @@ -51,4 +51,6 @@ public final class VoiceOfResurgence extends CardImpl { public VoiceOfResurgence copy() { return new VoiceOfResurgence(this); } -} \ No newline at end of file + +} + diff --git a/Mage.Sets/src/mage/cards/v/VraskaTheUnseen.java b/Mage.Sets/src/mage/cards/v/VraskaTheUnseen.java index cc1310933b3..7699a25e1ea 100644 --- a/Mage.Sets/src/mage/cards/v/VraskaTheUnseen.java +++ b/Mage.Sets/src/mage/cards/v/VraskaTheUnseen.java @@ -112,7 +112,7 @@ class VraskaTheUnseenGainAbilityEffect extends ContinuousEffectImpl { @Override public boolean isInactive(Ability source, Game game) { if (startingTurn != 0 && game.getTurnNum() != startingTurn) { - if (game.getActivePlayerId().equals(source.getControllerId())) { + if (game.isActivePlayer(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/w/WakeThrasher.java b/Mage.Sets/src/mage/cards/w/WakeThrasher.java index c801aba05de..cea61f17380 100644 --- a/Mage.Sets/src/mage/cards/w/WakeThrasher.java +++ b/Mage.Sets/src/mage/cards/w/WakeThrasher.java @@ -67,7 +67,7 @@ class BecomesUntappedControlledPermanentTriggeredAbility extends TriggeredAbilit @Override public boolean checkTrigger(GameEvent event, Game game) { - return game.getPermanent(event.getTargetId()).getControllerId().equals(this.controllerId); + return game.getPermanent(event.getTargetId()).isControlledBy(this.controllerId); } @Override diff --git a/Mage.Sets/src/mage/cards/w/WallOfDiffusion.java b/Mage.Sets/src/mage/cards/w/WallOfDiffusion.java index 0371561cfd8..2e330180827 100644 --- a/Mage.Sets/src/mage/cards/w/WallOfDiffusion.java +++ b/Mage.Sets/src/mage/cards/w/WallOfDiffusion.java @@ -6,6 +6,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.common.CanBlockAsThoughtItHadShadowEffect; import mage.abilities.keyword.DefenderAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -33,7 +34,7 @@ public final class WallOfDiffusion extends CardImpl { // Defender this.addAbility(DefenderAbility.getInstance()); // Wall of Diffusion can block creatures with shadow as though Wall of Diffusion had shadow. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockAsThoughtIthadShadowEffect(Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockAsThoughtItHadShadowEffect(Duration.WhileOnBattlefield))); } public WallOfDiffusion(final WallOfDiffusion card) { @@ -44,32 +45,4 @@ public final class WallOfDiffusion extends CardImpl { public WallOfDiffusion copy() { return new WallOfDiffusion(this); } -} - -class CanBlockAsThoughtIthadShadowEffect extends AsThoughEffectImpl { - - public CanBlockAsThoughtIthadShadowEffect(Duration duration) { - super(AsThoughEffectType.BLOCK_SHADOW, duration, Outcome.Benefit); - staticText = "{this} can block creatures with shadow as though {this} had shadow"; - } - - public CanBlockAsThoughtIthadShadowEffect(final CanBlockAsThoughtIthadShadowEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public CanBlockAsThoughtIthadShadowEffect copy() { - return new CanBlockAsThoughtIthadShadowEffect(this); - } - - @Override - public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - return sourceId.equals(source.getSourceId()); - } - -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/w/WallOfDust.java b/Mage.Sets/src/mage/cards/w/WallOfDust.java index a9438e53022..5998d54a4c4 100644 --- a/Mage.Sets/src/mage/cards/w/WallOfDust.java +++ b/Mage.Sets/src/mage/cards/w/WallOfDust.java @@ -76,7 +76,7 @@ class WallOfDustRestrictionEffect extends RestrictionEffect { if (targetPermanent == null) { return true; } - if (nextTurnTargetController == 0 && startingTurn != game.getTurnNum() && game.getActivePlayerId().equals(targetPermanent.getControllerId())) { + if (nextTurnTargetController == 0 && startingTurn != game.getTurnNum() && game.isActivePlayer(targetPermanent.getControllerId())) { nextTurnTargetController = game.getTurnNum(); } return game.getPhase().getType() == TurnPhase.END && nextTurnTargetController > 0 && game.getTurnNum() > nextTurnTargetController; @@ -95,7 +95,7 @@ class WallOfDustRestrictionEffect extends RestrictionEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { if (permanent.getId().equals(getTargetPointer().getFirst(game, source))) { - if (game.getActivePlayerId().equals(permanent.getControllerId())) { + if (game.isActivePlayer(permanent.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/w/Warbringer.java b/Mage.Sets/src/mage/cards/w/Warbringer.java index bf29775672e..4d40a5f31ed 100644 --- a/Mage.Sets/src/mage/cards/w/Warbringer.java +++ b/Mage.Sets/src/mage/cards/w/Warbringer.java @@ -71,7 +71,7 @@ class WarbringerSpellsCostReductionEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { - if (abilityToModify.getControllerId().equals(source.getControllerId())) { + if (abilityToModify.isControlledBy(source.getControllerId())) { Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); if (spell != null) { return DashedCondition.instance.apply(game, abilityToModify); diff --git a/Mage.Sets/src/mage/cards/w/WarstormSurge.java b/Mage.Sets/src/mage/cards/w/WarstormSurge.java index 0849d7e543b..71475721b2d 100644 --- a/Mage.Sets/src/mage/cards/w/WarstormSurge.java +++ b/Mage.Sets/src/mage/cards/w/WarstormSurge.java @@ -62,7 +62,7 @@ class WarstormSurgeTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent.isCreature() - && permanent.getControllerId().equals(this.controllerId)) { + && permanent.isControlledBy(this.controllerId)) { Effect effect = this.getEffects().get(0); effect.setValue("damageSource", event.getTargetId()); return true; diff --git a/Mage.Sets/src/mage/cards/w/WebOfInertia.java b/Mage.Sets/src/mage/cards/w/WebOfInertia.java index 8d099bd7cdf..6739e5cf828 100644 --- a/Mage.Sets/src/mage/cards/w/WebOfInertia.java +++ b/Mage.Sets/src/mage/cards/w/WebOfInertia.java @@ -105,7 +105,7 @@ class WebOfInertiaRestrictionEffect extends RestrictionEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { - return permanent.getControllerId().equals(attackerID); + return permanent.isControlledBy(attackerID); } @Override diff --git a/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java b/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java index e0562104d32..96cd3c87fbe 100644 --- a/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java +++ b/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java @@ -66,7 +66,7 @@ class WellOfKnowledgeConditionalActivatedAbility extends ActivatedAbilityImpl { public ActivationStatus canActivate(UUID playerId, Game game) { if (condition.apply(game, this) && costs.canPay(this, sourceId, playerId, game) - && game.getActivePlayerId().equals(playerId)) { + && game.isActivePlayer(playerId)) { this.activatorId = playerId; return ActivationStatus.getTrue(); } diff --git a/Mage.Sets/src/mage/cards/w/WharfInfiltrator.java b/Mage.Sets/src/mage/cards/w/WharfInfiltrator.java index a4dc0e26eb4..207fd6e1288 100644 --- a/Mage.Sets/src/mage/cards/w/WharfInfiltrator.java +++ b/Mage.Sets/src/mage/cards/w/WharfInfiltrator.java @@ -83,7 +83,7 @@ class WharfInfiltratorDiscardAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Card card = game.getCard(event.getTargetId()); - if (getControllerId().equals(event.getPlayerId()) && card != null && card.isCreature()) { + if (isControlledBy(event.getPlayerId()) && card != null && card.isCreature()) { return true; } return false; diff --git a/Mage.Sets/src/mage/cards/w/WheelOfSunAndMoon.java b/Mage.Sets/src/mage/cards/w/WheelOfSunAndMoon.java index 662038c9b84..af23559ad45 100644 --- a/Mage.Sets/src/mage/cards/w/WheelOfSunAndMoon.java +++ b/Mage.Sets/src/mage/cards/w/WheelOfSunAndMoon.java @@ -85,7 +85,7 @@ class WheelOfSunAndMoonEffect extends ReplacementEffectImpl { if (card != null) { Permanent enchantment = game.getPermanent(source.getSourceId()); if (enchantment != null && enchantment.getAttachedTo() != null - && card.getOwnerId().equals(enchantment.getAttachedTo())) { + && card.isOwnedBy(enchantment.getAttachedTo())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/w/WildDefiance.java b/Mage.Sets/src/mage/cards/w/WildDefiance.java index fa2787c9955..6d2fd536150 100644 --- a/Mage.Sets/src/mage/cards/w/WildDefiance.java +++ b/Mage.Sets/src/mage/cards/w/WildDefiance.java @@ -63,7 +63,7 @@ class CreaturesYouControlBecomesTargetTriggeredAbility extends TriggeredAbilityI @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getControllerId().equals(this.controllerId) && permanent.isCreature()) { + if (permanent != null && permanent.isControlledBy(this.controllerId) && permanent.isCreature()) { MageObject object = game.getObject(event.getSourceId()); if (object != null && object instanceof Spell) { Card c = (Spell) object; diff --git a/Mage.Sets/src/mage/cards/w/Willbreaker.java b/Mage.Sets/src/mage/cards/w/Willbreaker.java index 32c6e2669c0..0c1faff0ba3 100644 --- a/Mage.Sets/src/mage/cards/w/Willbreaker.java +++ b/Mage.Sets/src/mage/cards/w/Willbreaker.java @@ -67,7 +67,7 @@ class WillbreakerTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (getControllerId().equals(event.getPlayerId())) { + if (isControlledBy(event.getPlayerId())) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.isCreature()) { Player controller = game.getPlayer(getControllerId()); diff --git a/Mage.Sets/src/mage/cards/w/WillingTestSubject.java b/Mage.Sets/src/mage/cards/w/WillingTestSubject.java index e68c4c3eb03..5b48449d828 100644 --- a/Mage.Sets/src/mage/cards/w/WillingTestSubject.java +++ b/Mage.Sets/src/mage/cards/w/WillingTestSubject.java @@ -79,7 +79,7 @@ class WillingTestSubjectTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (this.getControllerId().equals(event.getPlayerId()) && event.getFlag()) { + if (this.isControlledBy(event.getPlayerId()) && event.getFlag()) { if (event.getAmount() >= 4) { return true; } diff --git a/Mage.Sets/src/mage/cards/w/WindingConstrictor.java b/Mage.Sets/src/mage/cards/w/WindingConstrictor.java index 0d780cdf00a..3d113229f5e 100644 --- a/Mage.Sets/src/mage/cards/w/WindingConstrictor.java +++ b/Mage.Sets/src/mage/cards/w/WindingConstrictor.java @@ -79,7 +79,7 @@ class WindingConstrictorPermanentEffect extends ReplacementEffectImpl { } return permanent != null && (permanent.isCreature() || permanent.isArtifact()) - && permanent.getControllerId().equals(source.getControllerId()); + && permanent.isControlledBy(source.getControllerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/w/Witchstalker.java b/Mage.Sets/src/mage/cards/w/Witchstalker.java index 42b10d3ee86..6c8f6fedd7e 100644 --- a/Mage.Sets/src/mage/cards/w/Witchstalker.java +++ b/Mage.Sets/src/mage/cards/w/Witchstalker.java @@ -78,7 +78,7 @@ class WitchstalkerTriggeredAbility extends TriggeredAbilityImpl { return spell != null && filter.match(spell,game) && game.getOpponents(this.getControllerId()).contains(spell.getControllerId()) - && game.getActivePlayerId().equals(this.getControllerId()); + && game.isActivePlayer(this.getControllerId()); } @Override diff --git a/Mage.Sets/src/mage/cards/w/WordOfUndoing.java b/Mage.Sets/src/mage/cards/w/WordOfUndoing.java index a249db86de7..af5518c6ff0 100644 --- a/Mage.Sets/src/mage/cards/w/WordOfUndoing.java +++ b/Mage.Sets/src/mage/cards/w/WordOfUndoing.java @@ -67,7 +67,7 @@ class WordOfUndoingReturnToHandEffect extends OneShotEffect { if (target != null) { for (UUID attachmentId : target.getAttachments()) { Permanent attachment = game.getPermanent(attachmentId); - if (attachment != null && attachment.getControllerId().equals(source.getControllerId()) + if (attachment != null && attachment.isControlledBy(source.getControllerId()) && attachment.hasSubtype(SubType.AURA, game) && attachment.getColor(game).isWhite()) { attachments.add(attachment); } diff --git a/Mage.Sets/src/mage/cards/w/WordsOfWar.java b/Mage.Sets/src/mage/cards/w/WordsOfWar.java index 86cd074ca96..927d2d5b3e5 100644 --- a/Mage.Sets/src/mage/cards/w/WordsOfWar.java +++ b/Mage.Sets/src/mage/cards/w/WordsOfWar.java @@ -95,7 +95,7 @@ class WordsOfWarEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (!this.used) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } return false; } diff --git a/Mage.Sets/src/mage/cards/w/WordsOfWaste.java b/Mage.Sets/src/mage/cards/w/WordsOfWaste.java index dbbe02e3d49..3db705865eb 100644 --- a/Mage.Sets/src/mage/cards/w/WordsOfWaste.java +++ b/Mage.Sets/src/mage/cards/w/WordsOfWaste.java @@ -75,6 +75,6 @@ class WordsOfWasteEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } } diff --git a/Mage.Sets/src/mage/cards/w/WordsOfWilding.java b/Mage.Sets/src/mage/cards/w/WordsOfWilding.java index 4363863c312..ffe65dcdb54 100644 --- a/Mage.Sets/src/mage/cards/w/WordsOfWilding.java +++ b/Mage.Sets/src/mage/cards/w/WordsOfWilding.java @@ -75,6 +75,6 @@ class WordsOfWildingEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } } diff --git a/Mage.Sets/src/mage/cards/w/WordsOfWind.java b/Mage.Sets/src/mage/cards/w/WordsOfWind.java index 13f7ad58513..da3860a0893 100644 --- a/Mage.Sets/src/mage/cards/w/WordsOfWind.java +++ b/Mage.Sets/src/mage/cards/w/WordsOfWind.java @@ -95,7 +95,7 @@ class WordsOfWindEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (!this.used) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } return false; } diff --git a/Mage.Sets/src/mage/cards/w/WordsOfWorship.java b/Mage.Sets/src/mage/cards/w/WordsOfWorship.java index 7e2716d8efa..907167a2657 100644 --- a/Mage.Sets/src/mage/cards/w/WordsOfWorship.java +++ b/Mage.Sets/src/mage/cards/w/WordsOfWorship.java @@ -81,7 +81,7 @@ class WordsOfWorshipEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (!this.used) { - return source.getControllerId().equals(event.getPlayerId()); + return source.isControlledBy(event.getPlayerId()); } return false; } diff --git a/Mage.Sets/src/mage/cards/w/WorldheartPhoenix.java b/Mage.Sets/src/mage/cards/w/WorldheartPhoenix.java index 3e0d059b641..12af950b7b8 100644 --- a/Mage.Sets/src/mage/cards/w/WorldheartPhoenix.java +++ b/Mage.Sets/src/mage/cards/w/WorldheartPhoenix.java @@ -80,7 +80,7 @@ public final class WorldheartPhoenix extends CardImpl { @Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - if (sourceId.equals(source.getSourceId()) && source.getControllerId().equals(affectedControllerId)) { + if (sourceId.equals(source.getSourceId()) && source.isControlledBy(affectedControllerId)) { if (game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { Player player = game.getPlayer(affectedControllerId); if (player != null) { diff --git a/Mage.Sets/src/mage/cards/w/Worship.java b/Mage.Sets/src/mage/cards/w/Worship.java index 53220fb1e14..3290eea0cfe 100644 --- a/Mage.Sets/src/mage/cards/w/Worship.java +++ b/Mage.Sets/src/mage/cards/w/Worship.java @@ -58,7 +58,7 @@ class WorshipReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (source.getControllerId().equals(event.getPlayerId())) { + if (source.isControlledBy(event.getPlayerId())) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && (controller.getLife() - event.getAmount()) < 1 diff --git a/Mage.Sets/src/mage/cards/w/WortTheRaidmother.java b/Mage.Sets/src/mage/cards/w/WortTheRaidmother.java index bc160dda183..6fae1461700 100644 --- a/Mage.Sets/src/mage/cards/w/WortTheRaidmother.java +++ b/Mage.Sets/src/mage/cards/w/WortTheRaidmother.java @@ -81,7 +81,7 @@ class WortGainConspireEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { for (StackObject stackObject : game.getStack()) { // only spells cast, so no copies of spells - if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.getControllerId().equals(source.getControllerId())) { + if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.isControlledBy(source.getControllerId())) { Spell spell = (Spell) stackObject; if (filter.match(stackObject, game)) { game.getState().addOtherAbility(spell.getCard(), conspireAbility); diff --git a/Mage.Sets/src/mage/cards/w/WreathofGeists.java b/Mage.Sets/src/mage/cards/w/WreathOfGeists.java similarity index 86% rename from Mage.Sets/src/mage/cards/w/WreathofGeists.java rename to Mage.Sets/src/mage/cards/w/WreathOfGeists.java index 7a9da11ab0a..8991b23d966 100644 --- a/Mage.Sets/src/mage/cards/w/WreathofGeists.java +++ b/Mage.Sets/src/mage/cards/w/WreathOfGeists.java @@ -23,9 +23,9 @@ import mage.target.common.TargetCreaturePermanent; * * @author nantuko */ -public final class WreathofGeists extends CardImpl { +public final class WreathOfGeists extends CardImpl { - public WreathofGeists(UUID ownerId, CardSetInfo setInfo) { + public WreathOfGeists(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}"); this.subtype.add(SubType.AURA); @@ -43,12 +43,12 @@ public final class WreathofGeists extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(value, value))); } - public WreathofGeists(final WreathofGeists card) { + public WreathOfGeists(final WreathOfGeists card) { super(card); } @Override - public WreathofGeists copy() { - return new WreathofGeists(this); + public WreathOfGeists copy() { + return new WreathOfGeists(this); } } diff --git a/Mage.Sets/src/mage/cards/w/WritOfPassage.java b/Mage.Sets/src/mage/cards/w/WritOfPassage.java index e6dad8e19ae..040f218574d 100644 --- a/Mage.Sets/src/mage/cards/w/WritOfPassage.java +++ b/Mage.Sets/src/mage/cards/w/WritOfPassage.java @@ -96,7 +96,6 @@ class WritOfPassageAttachedEffect extends RestrictionEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { Permanent attachment = game.getPermanent(source.getSourceId()); - return attachment != null && attachment.getAttachedTo() != null - && attachment.getAttachedTo().equals(permanent.getId()); + return attachment != null && attachment.isAttachedTo(permanent.getId()); } } diff --git a/Mage.Sets/src/mage/cards/x/XenicPoltergeist.java b/Mage.Sets/src/mage/cards/x/XenicPoltergeist.java index 2b0cbb13875..33d6e8756f5 100644 --- a/Mage.Sets/src/mage/cards/x/XenicPoltergeist.java +++ b/Mage.Sets/src/mage/cards/x/XenicPoltergeist.java @@ -84,7 +84,7 @@ class XenicPoltergeistEffect extends ContinuousEffectImpl { @Override public boolean isInactive(Ability source, Game game) { if (game.getPhase().getStep().getType() == PhaseStep.UPKEEP) { - if (game.getActivePlayerId().equals(source.getControllerId())) { + if (game.isActivePlayer(source.getControllerId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/y/YawgmothsAgenda.java b/Mage.Sets/src/mage/cards/y/YawgmothsAgenda.java index b03f24343fb..fbf46de1dab 100644 --- a/Mage.Sets/src/mage/cards/y/YawgmothsAgenda.java +++ b/Mage.Sets/src/mage/cards/y/YawgmothsAgenda.java @@ -135,7 +135,7 @@ class YawgmothsAgendaReplacementEffect extends ReplacementEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD) { Card card = game.getCard(event.getTargetId()); - if (card != null && card.getOwnerId().equals(source.getControllerId())) { + if (card != null && card.isOwnedBy(source.getControllerId())) { Permanent permanent = ((ZoneChangeEvent) event).getTarget(); if (permanent == null || !(permanent instanceof PermanentToken)) { return true; diff --git a/Mage.Sets/src/mage/cards/y/YawgmothsWill.java b/Mage.Sets/src/mage/cards/y/YawgmothsWill.java index ada8e06646c..8690dbd141a 100644 --- a/Mage.Sets/src/mage/cards/y/YawgmothsWill.java +++ b/Mage.Sets/src/mage/cards/y/YawgmothsWill.java @@ -125,7 +125,7 @@ class YawgmothsWillReplacementEffect extends ReplacementEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD) { Card card = game.getCard(event.getTargetId()); - if (card != null && card.getOwnerId().equals(source.getControllerId())) { + if (card != null && card.isOwnedBy(source.getControllerId())) { Permanent permanent = ((ZoneChangeEvent) event).getTarget(); if (permanent == null || !(permanent instanceof PermanentToken)) { return true; diff --git a/Mage.Sets/src/mage/cards/y/YidrisMaelstromWielder.java b/Mage.Sets/src/mage/cards/y/YidrisMaelstromWielder.java index 2d2ccb801c2..2f73bc50243 100644 --- a/Mage.Sets/src/mage/cards/y/YidrisMaelstromWielder.java +++ b/Mage.Sets/src/mage/cards/y/YidrisMaelstromWielder.java @@ -71,7 +71,7 @@ class YidrisMaelstromWielderGainCascadeEffect extends ContinuousEffectImpl { if (controller != null) { for (StackObject stackObject : game.getStack()) { // only spells cast, so no copies of spells - if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.getControllerId().equals(source.getControllerId())) { + if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.isControlledBy(source.getControllerId())) { Spell spell = (Spell) stackObject; if (spell.getFromZone() == Zone.HAND) { game.getState().addOtherAbility(spell.getCard(), cascadeAbility); diff --git a/Mage.Sets/src/mage/cards/y/YoungPyromancer.java b/Mage.Sets/src/mage/cards/y/YoungPyromancer.java index 8ead874f5c7..6f7b3b631f3 100644 --- a/Mage.Sets/src/mage/cards/y/YoungPyromancer.java +++ b/Mage.Sets/src/mage/cards/y/YoungPyromancer.java @@ -1,4 +1,3 @@ - package mage.cards.y; import java.util.UUID; @@ -27,7 +26,10 @@ public final class YoungPyromancer extends CardImpl { this.toughness = new MageInt(1); // Whenever you cast an instant or sorcery spell, create a 1/1 red Elemental creature token. - this.addAbility(new SpellCastControllerTriggeredAbility(new CreateTokenEffect(new YoungPyromancerElementalToken()), StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY, false)); + this.addAbility(new SpellCastControllerTriggeredAbility( + new CreateTokenEffect(new YoungPyromancerElementalToken()), + StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY, false + )); } diff --git a/Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java b/Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java index 8c7f524cf91..7b76cdcb2f4 100644 --- a/Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java +++ b/Mage.Sets/src/mage/cards/z/ZadaHedronGrinder.java @@ -100,7 +100,7 @@ class ZadaHedronGrinderTriggeredAbility extends TriggeredAbilityImpl { private boolean isControlledInstantOrSorcery(Spell spell) { return spell != null - && (spell.getControllerId().equals(this.getControllerId())) + && (spell.isControlledBy(this.getControllerId())) && (spell.isInstant() || spell.isSorcery()); } diff --git a/Mage.Sets/src/mage/cards/z/ZameckGuildmage.java b/Mage.Sets/src/mage/cards/z/ZameckGuildmage.java index 4706cd7ccb6..4c785c41979 100644 --- a/Mage.Sets/src/mage/cards/z/ZameckGuildmage.java +++ b/Mage.Sets/src/mage/cards/z/ZameckGuildmage.java @@ -69,7 +69,7 @@ class ZameckGuildmageEntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); - return permanent != null && permanent.getControllerId().equals(source.getControllerId()) && permanent.isCreature(); + return permanent != null && permanent.isControlledBy(source.getControllerId()) && permanent.isCreature(); } @Override diff --git a/Mage.Sets/src/mage/sets/Alliances.java b/Mage.Sets/src/mage/sets/Alliances.java index a2638ba711b..1553e50b598 100644 --- a/Mage.Sets/src/mage/sets/Alliances.java +++ b/Mage.Sets/src/mage/sets/Alliances.java @@ -89,6 +89,7 @@ public final class Alliances extends ExpansionSet { cards.add(new SetCardInfo("Inheritance", 4, Rarity.UNCOMMON, mage.cards.i.Inheritance.class)); cards.add(new SetCardInfo("Insidious Bookworms", "51a", Rarity.COMMON, mage.cards.i.InsidiousBookworms.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Insidious Bookworms", "51b", Rarity.COMMON, mage.cards.i.InsidiousBookworms.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ivory Gargoyle", 5, Rarity.RARE, mage.cards.i.IvoryGargoyle.class)); cards.add(new SetCardInfo("Juniper Order Advocate", 6, Rarity.UNCOMMON, mage.cards.j.JuniperOrderAdvocate.class)); cards.add(new SetCardInfo("Kaysa", 96, Rarity.RARE, mage.cards.k.Kaysa.class)); cards.add(new SetCardInfo("Keeper of Tresserhorn", 52, Rarity.RARE, mage.cards.k.KeeperOfTresserhorn.class)); diff --git a/Mage.Sets/src/mage/sets/Coldsnap.java b/Mage.Sets/src/mage/sets/Coldsnap.java index 6fbb6b7f9d4..21790372da1 100644 --- a/Mage.Sets/src/mage/sets/Coldsnap.java +++ b/Mage.Sets/src/mage/sets/Coldsnap.java @@ -35,6 +35,7 @@ public final class Coldsnap extends ExpansionSet { cards.add(new SetCardInfo("Arctic Nishoba", 102, Rarity.UNCOMMON, mage.cards.a.ArcticNishoba.class)); cards.add(new SetCardInfo("Arcum Dagsson", 27, Rarity.RARE, mage.cards.a.ArcumDagsson.class)); cards.add(new SetCardInfo("Aurochs Herd", 103, Rarity.COMMON, mage.cards.a.AurochsHerd.class)); + cards.add(new SetCardInfo("Balduvian Fallen", 51, Rarity.UNCOMMON, mage.cards.b.BalduvianFallen.class)); cards.add(new SetCardInfo("Balduvian Frostwaker", 28, Rarity.UNCOMMON, mage.cards.b.BalduvianFrostwaker.class)); cards.add(new SetCardInfo("Balduvian Rage", 76, Rarity.UNCOMMON, mage.cards.b.BalduvianRage.class)); cards.add(new SetCardInfo("Balduvian Warlord", 77, Rarity.UNCOMMON, mage.cards.b.BalduvianWarlord.class)); @@ -52,6 +53,7 @@ public final class Coldsnap extends ExpansionSet { cards.add(new SetCardInfo("Commandeer", 29, Rarity.RARE, mage.cards.c.Commandeer.class)); cards.add(new SetCardInfo("Controvert", 30, Rarity.UNCOMMON, mage.cards.c.Controvert.class)); cards.add(new SetCardInfo("Counterbalance", 31, Rarity.UNCOMMON, mage.cards.c.Counterbalance.class)); + cards.add(new SetCardInfo("Cover of Winter", 3, Rarity.RARE, mage.cards.c.CoverOfWinter.class)); cards.add(new SetCardInfo("Cryoclasm", 79, Rarity.UNCOMMON, mage.cards.c.Cryoclasm.class)); cards.add(new SetCardInfo("Darien, King of Kjeldor", 4, Rarity.RARE, mage.cards.d.DarienKingOfKjeldor.class)); cards.add(new SetCardInfo("Dark Depths", 145, Rarity.RARE, mage.cards.d.DarkDepths.class)); @@ -141,6 +143,7 @@ public final class Coldsnap extends ExpansionSet { cards.add(new SetCardInfo("Rune Snag", 46, Rarity.COMMON, mage.cards.r.RuneSnag.class)); cards.add(new SetCardInfo("Scrying Sheets", 149, Rarity.RARE, mage.cards.s.ScryingSheets.class)); cards.add(new SetCardInfo("Sek'Kuar, Deathkeeper", 131, Rarity.RARE, mage.cards.s.SekKuarDeathkeeper.class)); + cards.add(new SetCardInfo("Shape of the Wiitigo", 120, Rarity.RARE, mage.cards.s.ShapeOfTheWiitigo.class)); cards.add(new SetCardInfo("Sheltering Ancient", 121, Rarity.UNCOMMON, mage.cards.s.ShelteringAncient.class)); cards.add(new SetCardInfo("Simian Brawler", 122, Rarity.COMMON, mage.cards.s.SimianBrawler.class)); cards.add(new SetCardInfo("Skred", 97, Rarity.COMMON, mage.cards.s.Skred.class)); diff --git a/Mage.Sets/src/mage/sets/CoreSet2019.java b/Mage.Sets/src/mage/sets/CoreSet2019.java index 34b7cb26f60..132743ef002 100644 --- a/Mage.Sets/src/mage/sets/CoreSet2019.java +++ b/Mage.Sets/src/mage/sets/CoreSet2019.java @@ -1,6 +1,14 @@ package mage.sets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import mage.cards.Card; import mage.cards.ExpansionSet; +import mage.cards.repository.CardCriteria; +import mage.cards.repository.CardInfo; +import mage.cards.repository.CardRepository; +import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.SetType; @@ -15,11 +23,14 @@ public final class CoreSet2019 extends ExpansionSet { public static CoreSet2019 getInstance() { return instance; } + List savedSpecialCommon = new ArrayList<>(); + protected final List savedSpecialLand = new ArrayList<>(); private CoreSet2019() { super("Core Set 2019", "M19", ExpansionSet.buildDate(2018, 7, 13), SetType.CORE); this.hasBoosters = true; this.hasBasicLands = true; + this.numBoosterSpecial = 0; this.numBoosterLands = 1; this.numBoosterCommon = 10; this.numBoosterUncommon = 3; @@ -27,6 +38,11 @@ public final class CoreSet2019 extends ExpansionSet { this.ratioBoosterMythic = 8; this.numBoosterDoubleFaced = -1; this.maxCardNumberInBooster = 280; + + // Core 2019 boosters have a 5/12 chance of basic land being replaced + // with the common taplands, which DO NOT appear in the common slot. + this.ratioBoosterSpecialLand = 12; + this.ratioBoosterSpecialLandNumerator = 5; cards.add(new SetCardInfo("Abnormal Endurance", 85, Rarity.COMMON, mage.cards.a.AbnormalEndurance.class)); cards.add(new SetCardInfo("Act of Treason", 127, Rarity.COMMON, mage.cards.a.ActOfTreason.class)); @@ -192,6 +208,7 @@ public final class CoreSet2019 extends ExpansionSet { cards.add(new SetCardInfo("Marauder's Axe", 240, Rarity.COMMON, mage.cards.m.MaraudersAxe.class)); cards.add(new SetCardInfo("Meandering River", 253, Rarity.COMMON, mage.cards.m.MeanderingRiver.class)); cards.add(new SetCardInfo("Mentor of the Meek", 27, Rarity.RARE, mage.cards.m.MentorOfTheMeek.class)); + cards.add(new SetCardInfo("Metamorphic Alteration", 60, Rarity.RARE, mage.cards.m.MetamorphicAlteration.class)); cards.add(new SetCardInfo("Meteor Golem", 241, Rarity.UNCOMMON, mage.cards.m.MeteorGolem.class)); cards.add(new SetCardInfo("Mighty Leap", 28, Rarity.COMMON, mage.cards.m.MightyLeap.class)); cards.add(new SetCardInfo("Militia Bugler", 29, Rarity.UNCOMMON, mage.cards.m.MilitiaBugler.class)); @@ -343,4 +360,45 @@ public final class CoreSet2019 extends ExpansionSet { cards.add(new SetCardInfo("Windreader Sphinx", 84, Rarity.RARE, mage.cards.w.WindreaderSphinx.class)); cards.add(new SetCardInfo("Woodland Stream", 260, Rarity.COMMON, mage.cards.w.WoodlandStream.class)); } + + @Override + public List getCardsByRarity(Rarity rarity) { + // Common cards retrievement of Core Set 2019 boosters - prevent the retrievement of the common lands (e.g. Meandering River) + if (rarity == Rarity.COMMON) { + List savedCardsInfos = savedCards.get(rarity); + if (savedCardsInfos == null) { + CardCriteria criteria = new CardCriteria(); + criteria.rarities(Rarity.COMMON); + criteria.setCodes(this.code).notTypes(CardType.LAND); + savedCardsInfos = CardRepository.instance.findCards(criteria); + if (maxCardNumberInBooster != Integer.MAX_VALUE) { + savedCardsInfos.removeIf(next -> next.getCardNumberAsInt() > maxCardNumberInBooster && rarity != Rarity.LAND); + } + savedCards.put(rarity, savedCardsInfos); + } + // Return a copy of the saved cards information, as not to let modify the original. + return new ArrayList<>(savedCardsInfos); + } else { + return super.getCardsByRarity(rarity); + } + } + + @Override + // the common taplands replacing the basic land + public List getSpecialLand() + { + if (savedSpecialLand.isEmpty()) + { + CardCriteria criteria = new CardCriteria(); + criteria.setCodes(this.code); + criteria.rarities(Rarity.COMMON); + criteria.types(CardType.LAND); + savedSpecialLand.addAll(CardRepository.instance.findCards(criteria)); + } + + return new ArrayList<>(savedSpecialLand); + } + + + } diff --git a/Mage.Sets/src/mage/sets/Darksteel.java b/Mage.Sets/src/mage/sets/Darksteel.java index 7a443fd8873..c5cdc1d0dd3 100644 --- a/Mage.Sets/src/mage/sets/Darksteel.java +++ b/Mage.Sets/src/mage/sets/Darksteel.java @@ -170,6 +170,7 @@ public final class Darksteel extends ExpansionSet { cards.add(new SetCardInfo("Tel-Jilad Outrider", 87, Rarity.COMMON, mage.cards.t.TelJiladOutrider.class)); cards.add(new SetCardInfo("Tel-Jilad Wolf", 88, Rarity.COMMON, mage.cards.t.TelJiladWolf.class)); cards.add(new SetCardInfo("Test of Faith", 17, Rarity.UNCOMMON, mage.cards.t.TestOfFaith.class)); + cards.add(new SetCardInfo("Thought Dissector", 152, Rarity.RARE, mage.cards.t.ThoughtDissector.class)); cards.add(new SetCardInfo("Thunderstaff", 153, Rarity.UNCOMMON, mage.cards.t.Thunderstaff.class)); cards.add(new SetCardInfo("Trinisphere", 154, Rarity.RARE, mage.cards.t.Trinisphere.class)); cards.add(new SetCardInfo("Turn the Tables", 18, Rarity.RARE, mage.cards.t.TurnTheTables.class)); diff --git a/Mage.Sets/src/mage/sets/Dissension.java b/Mage.Sets/src/mage/sets/Dissension.java index 7fafc036eca..3aabb0d2cee 100644 --- a/Mage.Sets/src/mage/sets/Dissension.java +++ b/Mage.Sets/src/mage/sets/Dissension.java @@ -38,6 +38,7 @@ public final class Dissension extends ExpansionSet { cards.add(new SetCardInfo("Azorius First-Wing", 105, Rarity.COMMON, mage.cards.a.AzoriusFirstWing.class)); cards.add(new SetCardInfo("Azorius Guildmage", 141, Rarity.UNCOMMON, mage.cards.a.AzoriusGuildmage.class)); cards.add(new SetCardInfo("Azorius Herald", 2, Rarity.UNCOMMON, mage.cards.a.AzoriusHerald.class)); + cards.add(new SetCardInfo("Azorius Ploy", 106, Rarity.UNCOMMON, mage.cards.a.AzoriusPloy.class)); cards.add(new SetCardInfo("Azorius Signet", 159, Rarity.COMMON, mage.cards.a.AzoriusSignet.class)); cards.add(new SetCardInfo("Beacon Hawk", 3, Rarity.COMMON, mage.cards.b.BeaconHawk.class)); cards.add(new SetCardInfo("Biomantic Mastery", 142, Rarity.RARE, mage.cards.b.BiomanticMastery.class)); @@ -73,8 +74,10 @@ public final class Dissension extends ExpansionSet { cards.add(new SetCardInfo("Entropic Eidolon", 45, Rarity.COMMON, mage.cards.e.EntropicEidolon.class)); cards.add(new SetCardInfo("Evolution Vat", 161, Rarity.RARE, mage.cards.e.EvolutionVat.class)); cards.add(new SetCardInfo("Experiment Kraj", 110, Rarity.RARE, mage.cards.e.ExperimentKraj.class)); + cards.add(new SetCardInfo("Fertile Imagination", 84, Rarity.UNCOMMON, mage.cards.f.FertileImagination.class)); cards.add(new SetCardInfo("Flame-Kin War Scout", 61, Rarity.UNCOMMON, mage.cards.f.FlameKinWarScout.class)); cards.add(new SetCardInfo("Flaring Flame-Kin", 62, Rarity.UNCOMMON, mage.cards.f.FlaringFlameKin.class)); + cards.add(new SetCardInfo("Flash Foliage", 85, Rarity.UNCOMMON, mage.cards.f.FlashFoliage.class)); cards.add(new SetCardInfo("Freewind Equenaut", 9, Rarity.COMMON, mage.cards.f.FreewindEquenaut.class)); cards.add(new SetCardInfo("Ghost Quarter", 173, Rarity.UNCOMMON, mage.cards.g.GhostQuarter.class)); cards.add(new SetCardInfo("Gnat Alley Creeper", 63, Rarity.UNCOMMON, mage.cards.g.GnatAlleyCreeper.class)); @@ -105,6 +108,9 @@ public final class Dissension extends ExpansionSet { cards.add(new SetCardInfo("Minister of Impediments", 144, Rarity.COMMON, mage.cards.m.MinisterOfImpediments.class)); cards.add(new SetCardInfo("Mistral Charger", 13, Rarity.UNCOMMON, mage.cards.m.MistralCharger.class)); cards.add(new SetCardInfo("Momir Vig, Simic Visionary", 118, Rarity.RARE, mage.cards.m.MomirVigSimicVisionary.class)); + cards.add(new SetCardInfo("Muse Vessel", 163, Rarity.RARE, mage.cards.m.MuseVessel.class)); + cards.add(new SetCardInfo("Nettling Curse", 48, Rarity.COMMON, mage.cards.n.NettlingCurse.class)); + cards.add(new SetCardInfo("Nightcreep", 49, Rarity.UNCOMMON, mage.cards.n.Nightcreep.class)); cards.add(new SetCardInfo("Nihilistic Glee", 50, Rarity.RARE, mage.cards.n.NihilisticGlee.class)); cards.add(new SetCardInfo("Novijen, Heart of Progress", 175, Rarity.UNCOMMON, mage.cards.n.NovijenHeartOfProgress.class)); cards.add(new SetCardInfo("Novijen Sages", 27, Rarity.RARE, mage.cards.n.NovijenSages.class)); @@ -131,10 +137,12 @@ public final class Dissension extends ExpansionSet { cards.add(new SetCardInfo("Pure // Simple", 154, Rarity.UNCOMMON, mage.cards.p.PureSimple.class)); cards.add(new SetCardInfo("Ragamuffyn", 51, Rarity.UNCOMMON, mage.cards.r.Ragamuffyn.class)); cards.add(new SetCardInfo("Rain of Gore", 126, Rarity.RARE, mage.cards.r.RainOfGore.class)); + cards.add(new SetCardInfo("Rakdos Augermage", 127, Rarity.RARE, mage.cards.r.RakdosAugermage.class)); cards.add(new SetCardInfo("Rakdos Carnarium", 178, Rarity.COMMON, mage.cards.r.RakdosCarnarium.class)); cards.add(new SetCardInfo("Rakdos Guildmage", 145, Rarity.UNCOMMON, mage.cards.r.RakdosGuildmage.class)); cards.add(new SetCardInfo("Rakdos Ickspitter", 128, Rarity.COMMON, mage.cards.r.RakdosIckspitter.class)); cards.add(new SetCardInfo("Rakdos Pit Dragon", 69, Rarity.RARE, mage.cards.r.RakdosPitDragon.class)); + cards.add(new SetCardInfo("Rakdos Riteknife", 164, Rarity.RARE, mage.cards.r.RakdosRiteknife.class)); cards.add(new SetCardInfo("Rakdos Signet", 165, Rarity.COMMON, mage.cards.r.RakdosSignet.class)); cards.add(new SetCardInfo("Rakdos the Defiler", 129, Rarity.RARE, mage.cards.r.RakdosTheDefiler.class)); cards.add(new SetCardInfo("Ratcatcher", 52, Rarity.RARE, mage.cards.r.Ratcatcher.class)); @@ -169,7 +177,9 @@ public final class Dissension extends ExpansionSet { cards.add(new SetCardInfo("Stoic Ephemera", 19, Rarity.UNCOMMON, mage.cards.s.StoicEphemera.class)); cards.add(new SetCardInfo("Stomp and Howl", 96, Rarity.UNCOMMON, mage.cards.s.StompAndHowl.class)); cards.add(new SetCardInfo("Stormscale Anarch", 74, Rarity.RARE, mage.cards.s.StormscaleAnarch.class)); + cards.add(new SetCardInfo("Street Savvy", 97, Rarity.COMMON, mage.cards.s.StreetSavvy.class)); cards.add(new SetCardInfo("Supply // Demand", 157, Rarity.UNCOMMON, mage.cards.s.SupplyDemand.class)); + cards.add(new SetCardInfo("Swift Silence", 132, Rarity.RARE, mage.cards.s.SwiftSilence.class)); cards.add(new SetCardInfo("Taste for Mayhem", 75, Rarity.COMMON, mage.cards.t.TasteForMayhem.class)); cards.add(new SetCardInfo("Thrive", 98, Rarity.COMMON, mage.cards.t.Thrive.class)); cards.add(new SetCardInfo("Tidespout Tyrant", 34, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); @@ -185,6 +195,7 @@ public final class Dissension extends ExpansionSet { cards.add(new SetCardInfo("Vesper Ghoul", 57, Rarity.COMMON, mage.cards.v.VesperGhoul.class)); cards.add(new SetCardInfo("Vigean Graftmage", 35, Rarity.UNCOMMON, mage.cards.v.VigeanGraftmage.class)); cards.add(new SetCardInfo("Vigean Hydropon", 135, Rarity.COMMON, mage.cards.v.VigeanHydropon.class)); + cards.add(new SetCardInfo("Vigean Intuition", 136, Rarity.UNCOMMON, mage.cards.v.VigeanIntuition.class)); cards.add(new SetCardInfo("Vision Skeins", 36, Rarity.COMMON, mage.cards.v.VisionSkeins.class)); cards.add(new SetCardInfo("Voidslime", 137, Rarity.RARE, mage.cards.v.Voidslime.class)); cards.add(new SetCardInfo("Wakestone Gargoyle", 21, Rarity.RARE, mage.cards.w.WakestoneGargoyle.class)); diff --git a/Mage.Sets/src/mage/sets/Dominaria.java b/Mage.Sets/src/mage/sets/Dominaria.java index 4fd36ededd6..6e48f762fed 100644 --- a/Mage.Sets/src/mage/sets/Dominaria.java +++ b/Mage.Sets/src/mage/sets/Dominaria.java @@ -117,7 +117,7 @@ public final class Dominaria extends ExpansionSet { cards.add(new SetCardInfo("Ghitu Journeymage", 126, Rarity.COMMON, mage.cards.g.GhituJourneymage.class)); cards.add(new SetCardInfo("Ghitu Lavarunner", 127, Rarity.COMMON, mage.cards.g.GhituLavarunner.class)); cards.add(new SetCardInfo("Gideon's Reproach", 19, Rarity.COMMON, mage.cards.g.GideonsReproach.class)); - cards.add(new SetCardInfo("Gift of Growth", 163, Rarity.COMMON, mage.cards.g.GiftofGrowth.class)); + cards.add(new SetCardInfo("Gift of Growth", 163, Rarity.COMMON, mage.cards.g.GiftOfGrowth.class)); cards.add(new SetCardInfo("Gilded Lotus", 215, Rarity.RARE, mage.cards.g.GildedLotus.class)); cards.add(new SetCardInfo("Goblin Barrage", 128, Rarity.UNCOMMON, mage.cards.g.GoblinBarrage.class)); cards.add(new SetCardInfo("Goblin Chainwhirler", 129, Rarity.RARE, mage.cards.g.GoblinChainwhirler.class)); diff --git a/Mage.Sets/src/mage/sets/DragonsMaze.java b/Mage.Sets/src/mage/sets/DragonsMaze.java index d9e10a58ea8..8e01820b2a5 100644 --- a/Mage.Sets/src/mage/sets/DragonsMaze.java +++ b/Mage.Sets/src/mage/sets/DragonsMaze.java @@ -202,10 +202,10 @@ public final class DragonsMaze extends ExpansionSet { CardCriteria criteria = new CardCriteria(); criteria.setCodes(this.code).notTypes(CardType.LAND); criteria.rarities(rarity).doubleFaced(false); - if (maxCardNumberInBooster != Integer.MAX_VALUE) { - criteria.maxCardNumber(maxCardNumberInBooster); - } savedCardsInfos = CardRepository.instance.findCards(criteria); + if (maxCardNumberInBooster != Integer.MAX_VALUE) { + savedCardsInfos.removeIf(next -> next.getCardNumberAsInt() > maxCardNumberInBooster && rarity != Rarity.LAND); + } savedCards.put(rarity, savedCardsInfos); } // Return a copy of the saved cards information, as not to modify the original. diff --git a/Mage.Sets/src/mage/sets/Exodus.java b/Mage.Sets/src/mage/sets/Exodus.java index 03228018197..c80118de2c2 100644 --- a/Mage.Sets/src/mage/sets/Exodus.java +++ b/Mage.Sets/src/mage/sets/Exodus.java @@ -68,8 +68,9 @@ public final class Exodus extends ExpansionSet { cards.add(new SetCardInfo("Hatred", 64, Rarity.RARE, mage.cards.h.Hatred.class)); cards.add(new SetCardInfo("High Ground", 7, Rarity.UNCOMMON, mage.cards.h.HighGround.class)); cards.add(new SetCardInfo("Jackalope Herd", 111, Rarity.COMMON, mage.cards.j.JackalopeHerd.class)); + cards.add(new SetCardInfo("Keeper of the Beasts", 112, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheBeasts.class)); cards.add(new SetCardInfo("Keeper of the Dead", 65, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheDead.class)); - cards.add(new SetCardInfo("Keeper of the Light", 8, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheLight.class)); + cards.add(new SetCardInfo("Keeper of the Light", 8, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheLight.class)); cards.add(new SetCardInfo("Killer Whale", 37, Rarity.UNCOMMON, mage.cards.k.KillerWhale.class)); cards.add(new SetCardInfo("Kor Chant", 9, Rarity.COMMON, mage.cards.k.KorChant.class)); cards.add(new SetCardInfo("Mage il-Vec", 86, Rarity.COMMON, mage.cards.m.MageIlVec.class)); diff --git a/Mage.Sets/src/mage/sets/FateReforged.java b/Mage.Sets/src/mage/sets/FateReforged.java index e500a7f1bf2..0cc077d3ed3 100644 --- a/Mage.Sets/src/mage/sets/FateReforged.java +++ b/Mage.Sets/src/mage/sets/FateReforged.java @@ -236,10 +236,10 @@ public final class FateReforged extends ExpansionSet { CardCriteria criteria = new CardCriteria(); criteria.rarities(Rarity.COMMON); criteria.setCodes(this.code).notTypes(CardType.LAND); - if (maxCardNumberInBooster != Integer.MAX_VALUE) { - criteria.maxCardNumber(maxCardNumberInBooster); - } savedCardsInfos = CardRepository.instance.findCards(criteria); + if (maxCardNumberInBooster != Integer.MAX_VALUE) { + savedCardsInfos.removeIf(next -> next.getCardNumberAsInt() > maxCardNumberInBooster && rarity != Rarity.LAND); + } savedCards.put(rarity, savedCardsInfos); } // Return a copy of the saved cards information, as not to let modify the original. diff --git a/Mage.Sets/src/mage/sets/Guildpact.java b/Mage.Sets/src/mage/sets/Guildpact.java index 5eadbe6723e..1e3a1611318 100644 --- a/Mage.Sets/src/mage/sets/Guildpact.java +++ b/Mage.Sets/src/mage/sets/Guildpact.java @@ -29,6 +29,7 @@ public final class Guildpact extends ExpansionSet { this.ratioBoosterMythic = 0; cards.add(new SetCardInfo("Absolver Thrull", 1, Rarity.COMMON, mage.cards.a.AbsolverThrull.class)); cards.add(new SetCardInfo("Abyssal Nocturnus", 43, Rarity.RARE, mage.cards.a.AbyssalNocturnus.class)); + cards.add(new SetCardInfo("Aetherplasm", 22, Rarity.UNCOMMON, mage.cards.a.Aetherplasm.class)); cards.add(new SetCardInfo("Agent of Masks", 100, Rarity.UNCOMMON, mage.cards.a.AgentOfMasks.class)); cards.add(new SetCardInfo("Angel of Despair", 101, Rarity.RARE, mage.cards.a.AngelOfDespair.class)); cards.add(new SetCardInfo("Battering Wurm", 79, Rarity.UNCOMMON, mage.cards.b.BatteringWurm.class)); @@ -44,6 +45,7 @@ public final class Guildpact extends ExpansionSet { cards.add(new SetCardInfo("Castigate", 106, Rarity.COMMON, mage.cards.c.Castigate.class)); cards.add(new SetCardInfo("Caustic Rain", 44, Rarity.UNCOMMON, mage.cards.c.CausticRain.class)); cards.add(new SetCardInfo("Cerebral Vortex", 107, Rarity.RARE, mage.cards.c.CerebralVortex.class)); + cards.add(new SetCardInfo("Conjurer's Ban", 108, Rarity.UNCOMMON, mage.cards.c.ConjurersBan.class)); cards.add(new SetCardInfo("Crash Landing", 82, Rarity.UNCOMMON, mage.cards.c.CrashLanding.class)); cards.add(new SetCardInfo("Cremate", 45, Rarity.COMMON, mage.cards.c.Cremate.class)); cards.add(new SetCardInfo("Cry of Contrition", 46, Rarity.COMMON, mage.cards.c.CryOfContrition.class)); @@ -129,6 +131,7 @@ public final class Guildpact extends ExpansionSet { cards.add(new SetCardInfo("Pillory of the Sleepless", 125, Rarity.COMMON, mage.cards.p.PilloryOfTheSleepless.class)); cards.add(new SetCardInfo("Plagued Rusalka", 56, Rarity.UNCOMMON, mage.cards.p.PlaguedRusalka.class)); cards.add(new SetCardInfo("Poisonbelly Ogre", 57, Rarity.COMMON, mage.cards.p.PoisonbellyOgre.class)); + cards.add(new SetCardInfo("Predatory Focus", 92, Rarity.UNCOMMON, mage.cards.p.PredatoryFocus.class)); cards.add(new SetCardInfo("Primeval Light", 93, Rarity.UNCOMMON, mage.cards.p.PrimevalLight.class)); cards.add(new SetCardInfo("Pyromatics", 72, Rarity.COMMON, mage.cards.p.Pyromatics.class)); cards.add(new SetCardInfo("Quicken", 31, Rarity.RARE, mage.cards.q.Quicken.class)); diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java index 99ea988fc6c..52e35f67724 100644 --- a/Mage.Sets/src/mage/sets/Homelands.java +++ b/Mage.Sets/src/mage/sets/Homelands.java @@ -1,4 +1,3 @@ - package mage.sets; import mage.cards.ExpansionSet; @@ -104,10 +103,14 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Forget", 26, Rarity.RARE, mage.cards.f.Forget.class)); cards.add(new SetCardInfo("Funeral March", 48, Rarity.UNCOMMON, mage.cards.f.FuneralMarch.class)); cards.add(new SetCardInfo("Ghost Hounds", 49, Rarity.UNCOMMON, mage.cards.g.GhostHounds.class)); + cards.add(new SetCardInfo("Giant Oyster", 28, Rarity.UNCOMMON, mage.cards.g.GiantOyster.class)); + cards.add(new SetCardInfo("Giant Albatross", "27a", Rarity.COMMON, mage.cards.g.GiantAlbatross.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Giant Albatross", "27b", Rarity.COMMON, mage.cards.g.GiantAlbatross.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grandmother Sengir", 50, Rarity.RARE, mage.cards.g.GrandmotherSengir.class)); cards.add(new SetCardInfo("Greater Werewolf", 51, Rarity.UNCOMMON, mage.cards.g.GreaterWerewolf.class)); cards.add(new SetCardInfo("Hazduhr the Abbot", 8, Rarity.RARE, mage.cards.h.HazduhrTheAbbot.class)); cards.add(new SetCardInfo("Headstone", 52, Rarity.COMMON, mage.cards.h.Headstone.class)); + cards.add(new SetCardInfo("Heart Wolf", 75, Rarity.RARE, mage.cards.h.HeartWolf.class)); cards.add(new SetCardInfo("Hungry Mist", "88a", Rarity.COMMON, mage.cards.h.HungryMist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hungry Mist", "88b", Rarity.COMMON, mage.cards.h.HungryMist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ihsan's Shade", 53, Rarity.UNCOMMON, mage.cards.i.IhsansShade.class)); @@ -115,6 +118,7 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Ironclaw Curse", 76, Rarity.RARE, mage.cards.i.IronclawCurse.class)); cards.add(new SetCardInfo("Jinx", 29, Rarity.COMMON, mage.cards.j.Jinx.class)); cards.add(new SetCardInfo("Joven", 77, Rarity.COMMON, mage.cards.j.Joven.class)); + cards.add(new SetCardInfo("Joven's Ferrets", 89, Rarity.COMMON, mage.cards.j.JovensFerrets.class)); cards.add(new SetCardInfo("Joven's Tools", 108, Rarity.UNCOMMON, mage.cards.j.JovensTools.class)); cards.add(new SetCardInfo("Koskun Falls", 55, Rarity.RARE, mage.cards.k.KoskunFalls.class)); cards.add(new SetCardInfo("Koskun Keep", 114, Rarity.UNCOMMON, mage.cards.k.KoskunKeep.class)); @@ -132,6 +136,7 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Narwhal", 35, Rarity.RARE, mage.cards.n.Narwhal.class)); cards.add(new SetCardInfo("Orcish Mine", 78, Rarity.UNCOMMON, mage.cards.o.OrcishMine.class)); cards.add(new SetCardInfo("Primal Order", 92, Rarity.RARE, mage.cards.p.PrimalOrder.class)); + cards.add(new SetCardInfo("Prophecy", 11, Rarity.COMMON, mage.cards.p.Prophecy.class)); cards.add(new SetCardInfo("Rashka the Slayer", 12, Rarity.RARE, mage.cards.r.RashkaTheSlayer.class)); cards.add(new SetCardInfo("Reef Pirates", "36a", Rarity.COMMON, ReefPirates.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Reef Pirates", "36b", Rarity.COMMON, ReefPirates.class, NON_FULL_USE_VARIOUS)); @@ -141,13 +146,16 @@ public final class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Root Spider", 94, Rarity.UNCOMMON, mage.cards.r.RootSpider.class)); cards.add(new SetCardInfo("Roots", 95, Rarity.UNCOMMON, mage.cards.r.Roots.class)); cards.add(new SetCardInfo("Roterothopter", 109, Rarity.COMMON, mage.cards.r.Roterothopter.class)); + cards.add(new SetCardInfo("Rysorian Badger", 96, Rarity.RARE, mage.cards.r.RysorianBadger.class)); cards.add(new SetCardInfo("Samite Alchemist", 117, Rarity.COMMON, mage.cards.s.SamiteAlchemist.class)); cards.add(new SetCardInfo("Sea Sprite", 38, Rarity.UNCOMMON, mage.cards.s.SeaSprite.class)); + cards.add(new SetCardInfo("Sea Troll", 39, Rarity.UNCOMMON, mage.cards.s.SeaTroll.class)); cards.add(new SetCardInfo("Sengir Autocrat", 56, Rarity.UNCOMMON, mage.cards.s.SengirAutocrat.class)); cards.add(new SetCardInfo("Sengir Bats", "57a", Rarity.COMMON, SengirBats.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sengir Bats", "57b", Rarity.COMMON, SengirBats.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Serra Aviary", 14, Rarity.RARE, mage.cards.s.SerraAviary.class)); cards.add(new SetCardInfo("Serra Bestiary", 15, Rarity.UNCOMMON, mage.cards.s.SerraBestiary.class)); + cards.add(new SetCardInfo("Serra Inquisitors", 16, Rarity.UNCOMMON, mage.cards.s.SerraInquisitors.class)); cards.add(new SetCardInfo("Serra Paladin", 17, Rarity.COMMON, mage.cards.s.SerraPaladin.class)); cards.add(new SetCardInfo("Serrated Arrows", 110, Rarity.COMMON, mage.cards.s.SerratedArrows.class)); cards.add(new SetCardInfo("Shrink", "97a", Rarity.COMMON, mage.cards.s.Shrink.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/Innistrad.java b/Mage.Sets/src/mage/sets/Innistrad.java index 62ea025a4ef..b32374439f6 100644 --- a/Mage.Sets/src/mage/sets/Innistrad.java +++ b/Mage.Sets/src/mage/sets/Innistrad.java @@ -309,7 +309,7 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Wooden Stake", 237, Rarity.COMMON, mage.cards.w.WoodenStake.class)); cards.add(new SetCardInfo("Woodland Cemetery", 249, Rarity.RARE, mage.cards.w.WoodlandCemetery.class)); cards.add(new SetCardInfo("Woodland Sleuth", 210, Rarity.COMMON, mage.cards.w.WoodlandSleuth.class)); - cards.add(new SetCardInfo("Wreath of Geists", 211, Rarity.UNCOMMON, mage.cards.w.WreathofGeists.class)); + cards.add(new SetCardInfo("Wreath of Geists", 211, Rarity.UNCOMMON, mage.cards.w.WreathOfGeists.class)); } } diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java index d466ec8914b..c3f9f8ffbf1 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionII.java +++ b/Mage.Sets/src/mage/sets/MastersEditionII.java @@ -141,9 +141,11 @@ public final class MastersEditionII extends ExpansionSet { cards.add(new SetCardInfo("Infernal Darkness", 97, Rarity.RARE, mage.cards.i.InfernalDarkness.class)); cards.add(new SetCardInfo("Inheritance", 18, Rarity.UNCOMMON, mage.cards.i.Inheritance.class)); cards.add(new SetCardInfo("Ironclaw Orcs", 132, Rarity.COMMON, mage.cards.i.IronclawOrcs.class)); + cards.add(new SetCardInfo("Ivory Gargoyle", 19, Rarity.RARE, mage.cards.i.IvoryGargoyle.class)); cards.add(new SetCardInfo("Jester's Mask", 211, Rarity.RARE, mage.cards.j.JestersMask.class)); cards.add(new SetCardInfo("Jeweled Amulet", 212, Rarity.UNCOMMON, mage.cards.j.JeweledAmulet.class)); cards.add(new SetCardInfo("Johtull Wurm", 168, Rarity.UNCOMMON, mage.cards.j.JohtullWurm.class)); + cards.add(new SetCardInfo("Joven's Ferrets", 169, Rarity.UNCOMMON, mage.cards.j.JovensFerrets.class)); cards.add(new SetCardInfo("Juniper Order Advocate", 20, Rarity.UNCOMMON, mage.cards.j.JuniperOrderAdvocate.class)); cards.add(new SetCardInfo("Karplusan Giant", 133, Rarity.UNCOMMON, mage.cards.k.KarplusanGiant.class)); cards.add(new SetCardInfo("Kaysa", 170, Rarity.RARE, mage.cards.k.Kaysa.class)); diff --git a/Mage.Sets/src/mage/sets/Mirage.java b/Mage.Sets/src/mage/sets/Mirage.java index d67f5b34103..845414da3a6 100644 --- a/Mage.Sets/src/mage/sets/Mirage.java +++ b/Mage.Sets/src/mage/sets/Mirage.java @@ -1,6 +1,7 @@ package mage.sets; import mage.cards.ExpansionSet; +import mage.cards.d.Delirium; import mage.constants.Rarity; import mage.constants.SetType; @@ -83,6 +84,7 @@ public final class Mirage extends ExpansionSet { cards.add(new SetCardInfo("Dark Banishing", 115, Rarity.COMMON, mage.cards.d.DarkBanishing.class)); cards.add(new SetCardInfo("Dark Ritual", 116, Rarity.COMMON, mage.cards.d.DarkRitual.class)); cards.add(new SetCardInfo("Dazzling Beauty", 8, Rarity.COMMON, mage.cards.d.DazzlingBeauty.class)); + cards.add(new SetCardInfo("Delirium", 260, Rarity.UNCOMMON, Delirium.class)); cards.add(new SetCardInfo("Dirtwater Wraith", 117, Rarity.COMMON, mage.cards.d.DirtwaterWraith.class)); cards.add(new SetCardInfo("Disempower", 9, Rarity.COMMON, mage.cards.d.Disempower.class)); cards.add(new SetCardInfo("Disenchant", 10, Rarity.COMMON, mage.cards.d.Disenchant.class)); diff --git a/Mage.Sets/src/mage/sets/MirrodinBesieged.java b/Mage.Sets/src/mage/sets/MirrodinBesieged.java index cd5df52cafb..31c5cc90a67 100644 --- a/Mage.Sets/src/mage/sets/MirrodinBesieged.java +++ b/Mage.Sets/src/mage/sets/MirrodinBesieged.java @@ -38,7 +38,7 @@ public final class MirrodinBesieged extends ExpansionSet { cards.add(new SetCardInfo("Blue Sun's Zenith", 20, Rarity.RARE, mage.cards.b.BlueSunsZenith.class)); cards.add(new SetCardInfo("Bonehoard", 100, Rarity.RARE, mage.cards.b.Bonehoard.class)); cards.add(new SetCardInfo("Brass Squire", 101, Rarity.UNCOMMON, mage.cards.b.BrassSquire.class)); - cards.add(new SetCardInfo("Burn the Impure", 59, Rarity.COMMON, mage.cards.b.BurntheImpure.class)); + cards.add(new SetCardInfo("Burn the Impure", 59, Rarity.COMMON, mage.cards.b.BurnTheImpure.class)); cards.add(new SetCardInfo("Caustic Hound", 40, Rarity.COMMON, mage.cards.c.CausticHound.class)); cards.add(new SetCardInfo("Choking Fumes", 4, Rarity.UNCOMMON, mage.cards.c.ChokingFumes.class)); cards.add(new SetCardInfo("Concussive Bolt", 60, Rarity.COMMON, mage.cards.c.ConcussiveBolt.class)); diff --git a/Mage.Sets/src/mage/sets/PlanarChaos.java b/Mage.Sets/src/mage/sets/PlanarChaos.java index dc3ca252a1b..6856533d5cf 100644 --- a/Mage.Sets/src/mage/sets/PlanarChaos.java +++ b/Mage.Sets/src/mage/sets/PlanarChaos.java @@ -61,6 +61,7 @@ public final class PlanarChaos extends ExpansionSet { cards.add(new SetCardInfo("Deadly Grub", 69, Rarity.COMMON, mage.cards.d.DeadlyGrub.class)); cards.add(new SetCardInfo("Deadwood Treefolk", 126, Rarity.UNCOMMON, mage.cards.d.DeadwoodTreefolk.class)); cards.add(new SetCardInfo("Detritivore", 96, Rarity.RARE, mage.cards.d.Detritivore.class)); + cards.add(new SetCardInfo("Dichotomancy", 38, Rarity.RARE, mage.cards.d.Dichotomancy.class)); cards.add(new SetCardInfo("Dismal Failure", 39, Rarity.UNCOMMON, mage.cards.d.DismalFailure.class)); cards.add(new SetCardInfo("Dormant Sliver", 156, Rarity.UNCOMMON, mage.cards.d.DormantSliver.class)); cards.add(new SetCardInfo("Dreamscape Artist", 40, Rarity.COMMON, mage.cards.d.DreamscapeArtist.class)); @@ -114,6 +115,7 @@ public final class PlanarChaos extends ExpansionSet { cards.add(new SetCardInfo("Midnight Charm", 74, Rarity.COMMON, mage.cards.m.MidnightCharm.class)); cards.add(new SetCardInfo("Mire Boa", 135, Rarity.COMMON, mage.cards.m.MireBoa.class)); cards.add(new SetCardInfo("Mirri the Cursed", 75, Rarity.RARE, mage.cards.m.MirriTheCursed.class)); + cards.add(new SetCardInfo("Molten Firebird", 117, Rarity.RARE, mage.cards.m.MoltenFirebird.class)); cards.add(new SetCardInfo("Muck Drubb", 76, Rarity.UNCOMMON, mage.cards.m.MuckDrubb.class)); cards.add(new SetCardInfo("Mycologist", 27, Rarity.UNCOMMON, mage.cards.m.Mycologist.class)); cards.add(new SetCardInfo("Necrotic Sliver", 159, Rarity.UNCOMMON, mage.cards.n.NecroticSliver.class)); diff --git a/Mage.Sets/src/mage/sets/Portal.java b/Mage.Sets/src/mage/sets/Portal.java index 81b744f91e3..81162ed77cf 100644 --- a/Mage.Sets/src/mage/sets/Portal.java +++ b/Mage.Sets/src/mage/sets/Portal.java @@ -34,226 +34,226 @@ public final class Portal extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Alabaster Dragon", 163, Rarity.RARE, mage.cards.a.AlabasterDragon.class)); - cards.add(new SetCardInfo("Alluring Scent", 80, Rarity.RARE, mage.cards.a.AlluringScent.class)); - cards.add(new SetCardInfo("Anaconda", 81, Rarity.UNCOMMON, mage.cards.a.Anaconda.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Anaconda", 82, Rarity.UNCOMMON, mage.cards.a.Anaconda.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ancestral Memories", 41, Rarity.RARE, mage.cards.a.AncestralMemories.class)); - cards.add(new SetCardInfo("Angelic Blessing", 164, Rarity.COMMON, mage.cards.a.AngelicBlessing.class)); - cards.add(new SetCardInfo("Archangel", 165, Rarity.RARE, mage.cards.a.Archangel.class)); - cards.add(new SetCardInfo("Ardent Militia", 166, Rarity.UNCOMMON, mage.cards.a.ArdentMilitia.class)); - cards.add(new SetCardInfo("Armageddon", 167, Rarity.RARE, mage.cards.a.Armageddon.class)); - cards.add(new SetCardInfo("Armored Pegasus", 168, Rarity.COMMON, mage.cards.a.ArmoredPegasus.class)); - cards.add(new SetCardInfo("Arrogant Vampire", 1, Rarity.UNCOMMON, mage.cards.a.ArrogantVampire.class)); - cards.add(new SetCardInfo("Assassin's Blade", 2, Rarity.UNCOMMON, mage.cards.a.AssassinsBlade.class)); - cards.add(new SetCardInfo("Balance of Power", 42, Rarity.RARE, mage.cards.b.BalanceOfPower.class)); - cards.add(new SetCardInfo("Baleful Stare", 43, Rarity.UNCOMMON, mage.cards.b.BalefulStare.class)); - cards.add(new SetCardInfo("Bee Sting", 83, Rarity.UNCOMMON, mage.cards.b.BeeSting.class)); - cards.add(new SetCardInfo("Blaze", 122, Rarity.UNCOMMON, mage.cards.b.Blaze.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Blaze", 123, Rarity.UNCOMMON, mage.cards.b.Blaze.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Blessed Reversal", 169, Rarity.RARE, mage.cards.b.BlessedReversal.class)); - cards.add(new SetCardInfo("Blinding Light", 170, Rarity.RARE, mage.cards.b.BlindingLight.class)); - cards.add(new SetCardInfo("Bog Imp", 3, Rarity.COMMON, mage.cards.b.BogImp.class)); - cards.add(new SetCardInfo("Bog Raiders", 4, Rarity.COMMON, mage.cards.b.BogRaiders.class)); - cards.add(new SetCardInfo("Bog Wraith", 5, Rarity.UNCOMMON, mage.cards.b.BogWraith.class)); - cards.add(new SetCardInfo("Boiling Seas", 124, Rarity.UNCOMMON, mage.cards.b.BoilingSeas.class)); - cards.add(new SetCardInfo("Border Guard", 171, Rarity.COMMON, mage.cards.b.BorderGuard.class)); - cards.add(new SetCardInfo("Breath of Life", 172, Rarity.COMMON, mage.cards.b.BreathOfLife.class)); - cards.add(new SetCardInfo("Bull Hippo", 84, Rarity.UNCOMMON, mage.cards.b.BullHippo.class)); - cards.add(new SetCardInfo("Burning Cloak", 125, Rarity.COMMON, mage.cards.b.BurningCloak.class)); - cards.add(new SetCardInfo("Capricious Sorcerer", 44, Rarity.RARE, mage.cards.c.CapriciousSorcerer.class)); - cards.add(new SetCardInfo("Charging Bandits", 6, Rarity.UNCOMMON, mage.cards.c.ChargingBandits.class)); - cards.add(new SetCardInfo("Charging Paladin", 173, Rarity.UNCOMMON, mage.cards.c.ChargingPaladin.class)); - cards.add(new SetCardInfo("Charging Rhino", 85, Rarity.RARE, mage.cards.c.ChargingRhino.class)); - cards.add(new SetCardInfo("Cloak of Feathers", 45, Rarity.COMMON, mage.cards.c.CloakOfFeathers.class)); - cards.add(new SetCardInfo("Cloud Dragon", 46, Rarity.RARE, mage.cards.c.CloudDragon.class)); - cards.add(new SetCardInfo("Cloud Pirates", 47, Rarity.COMMON, mage.cards.c.CloudPirates.class)); - cards.add(new SetCardInfo("Cloud Spirit", 48, Rarity.UNCOMMON, mage.cards.c.CloudSpirit.class)); - cards.add(new SetCardInfo("Command of Unsummoning", 49, Rarity.UNCOMMON, mage.cards.c.CommandOfUnsummoning.class)); - cards.add(new SetCardInfo("Coral Eel", 50, Rarity.COMMON, mage.cards.c.CoralEel.class)); - cards.add(new SetCardInfo("Craven Giant", 126, Rarity.COMMON, mage.cards.c.CravenGiant.class)); - cards.add(new SetCardInfo("Craven Knight", 7, Rarity.COMMON, mage.cards.c.CravenKnight.class)); - cards.add(new SetCardInfo("Cruel Bargain", 8, Rarity.RARE, mage.cards.c.CruelBargain.class)); - cards.add(new SetCardInfo("Cruel Fate", 51, Rarity.RARE, mage.cards.c.CruelFate.class)); - cards.add(new SetCardInfo("Cruel Tutor", 9, Rarity.RARE, mage.cards.c.CruelTutor.class)); - cards.add(new SetCardInfo("Deep-Sea Serpent", 52, Rarity.UNCOMMON, mage.cards.d.DeepSeaSerpent.class)); - cards.add(new SetCardInfo("Deep Wood", 86, Rarity.UNCOMMON, mage.cards.d.DeepWood.class)); - cards.add(new SetCardInfo("Defiant Stand", 174, Rarity.UNCOMMON, mage.cards.d.DefiantStand.class)); + cards.add(new SetCardInfo("Alabaster Dragon", 1, Rarity.RARE, mage.cards.a.AlabasterDragon.class)); + cards.add(new SetCardInfo("Alluring Scent", 157, Rarity.RARE, mage.cards.a.AlluringScent.class)); + cards.add(new SetCardInfo("Anaconda", "158a", Rarity.UNCOMMON, mage.cards.a.Anaconda.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Anaconda", "158b", Rarity.UNCOMMON, mage.cards.a.Anaconda.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ancestral Memories", 40, Rarity.RARE, mage.cards.a.AncestralMemories.class)); + cards.add(new SetCardInfo("Angelic Blessing", 2, Rarity.COMMON, mage.cards.a.AngelicBlessing.class)); + cards.add(new SetCardInfo("Archangel", 3, Rarity.RARE, mage.cards.a.Archangel.class)); + cards.add(new SetCardInfo("Ardent Militia", 4, Rarity.UNCOMMON, mage.cards.a.ArdentMilitia.class)); + cards.add(new SetCardInfo("Armageddon", 5, Rarity.RARE, mage.cards.a.Armageddon.class)); + cards.add(new SetCardInfo("Armored Pegasus", 6, Rarity.COMMON, mage.cards.a.ArmoredPegasus.class)); + cards.add(new SetCardInfo("Arrogant Vampire", 79, Rarity.UNCOMMON, mage.cards.a.ArrogantVampire.class)); + cards.add(new SetCardInfo("Assassin's Blade", 80, Rarity.UNCOMMON, mage.cards.a.AssassinsBlade.class)); + cards.add(new SetCardInfo("Balance of Power", 41, Rarity.RARE, mage.cards.b.BalanceOfPower.class)); + cards.add(new SetCardInfo("Baleful Stare", 42, Rarity.UNCOMMON, mage.cards.b.BalefulStare.class)); + cards.add(new SetCardInfo("Bee Sting", 159, Rarity.UNCOMMON, mage.cards.b.BeeSting.class)); + cards.add(new SetCardInfo("Blaze", "118a", Rarity.UNCOMMON, mage.cards.b.Blaze.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Blaze", "118b", Rarity.UNCOMMON, mage.cards.b.Blaze.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Blessed Reversal", 7, Rarity.RARE, mage.cards.b.BlessedReversal.class)); + cards.add(new SetCardInfo("Blinding Light", 8, Rarity.RARE, mage.cards.b.BlindingLight.class)); + cards.add(new SetCardInfo("Bog Imp", 81, Rarity.COMMON, mage.cards.b.BogImp.class)); + cards.add(new SetCardInfo("Bog Raiders", 82, Rarity.COMMON, mage.cards.b.BogRaiders.class)); + cards.add(new SetCardInfo("Bog Wraith", 83, Rarity.UNCOMMON, mage.cards.b.BogWraith.class)); + cards.add(new SetCardInfo("Boiling Seas", 119, Rarity.UNCOMMON, mage.cards.b.BoilingSeas.class)); + cards.add(new SetCardInfo("Border Guard", 9, Rarity.COMMON, mage.cards.b.BorderGuard.class)); + cards.add(new SetCardInfo("Breath of Life", 10, Rarity.COMMON, mage.cards.b.BreathOfLife.class)); + cards.add(new SetCardInfo("Bull Hippo", 160, Rarity.UNCOMMON, mage.cards.b.BullHippo.class)); + cards.add(new SetCardInfo("Burning Cloak", 120, Rarity.COMMON, mage.cards.b.BurningCloak.class)); + cards.add(new SetCardInfo("Capricious Sorcerer", 43, Rarity.RARE, mage.cards.c.CapriciousSorcerer.class)); + cards.add(new SetCardInfo("Charging Bandits", 84, Rarity.UNCOMMON, mage.cards.c.ChargingBandits.class)); + cards.add(new SetCardInfo("Charging Paladin", 11, Rarity.UNCOMMON, mage.cards.c.ChargingPaladin.class)); + cards.add(new SetCardInfo("Charging Rhino", 161, Rarity.RARE, mage.cards.c.ChargingRhino.class)); + cards.add(new SetCardInfo("Cloak of Feathers", 44, Rarity.COMMON, mage.cards.c.CloakOfFeathers.class)); + cards.add(new SetCardInfo("Cloud Dragon", 45, Rarity.RARE, mage.cards.c.CloudDragon.class)); + cards.add(new SetCardInfo("Cloud Pirates", 46, Rarity.COMMON, mage.cards.c.CloudPirates.class)); + cards.add(new SetCardInfo("Cloud Spirit", 47, Rarity.UNCOMMON, mage.cards.c.CloudSpirit.class)); + cards.add(new SetCardInfo("Command of Unsummoning", 48, Rarity.UNCOMMON, mage.cards.c.CommandOfUnsummoning.class)); + cards.add(new SetCardInfo("Coral Eel", 49, Rarity.COMMON, mage.cards.c.CoralEel.class)); + cards.add(new SetCardInfo("Craven Giant", 121, Rarity.COMMON, mage.cards.c.CravenGiant.class)); + cards.add(new SetCardInfo("Craven Knight", 85, Rarity.COMMON, mage.cards.c.CravenKnight.class)); + cards.add(new SetCardInfo("Cruel Bargain", 86, Rarity.RARE, mage.cards.c.CruelBargain.class)); + cards.add(new SetCardInfo("Cruel Fate", 50, Rarity.RARE, mage.cards.c.CruelFate.class)); + cards.add(new SetCardInfo("Cruel Tutor", 87, Rarity.RARE, mage.cards.c.CruelTutor.class)); + cards.add(new SetCardInfo("Deep Wood", 162, Rarity.UNCOMMON, mage.cards.d.DeepWood.class)); + cards.add(new SetCardInfo("Deep-Sea Serpent", 51, Rarity.UNCOMMON, mage.cards.d.DeepSeaSerpent.class)); + cards.add(new SetCardInfo("Defiant Stand", 12, Rarity.UNCOMMON, mage.cards.d.DefiantStand.class)); cards.add(new SetCardInfo("Deja Vu", 53, Rarity.COMMON, mage.cards.d.DejaVu.class)); - cards.add(new SetCardInfo("Desert Drake", 127, Rarity.UNCOMMON, mage.cards.d.DesertDrake.class)); - cards.add(new SetCardInfo("Devastation", 128, Rarity.RARE, mage.cards.d.Devastation.class)); - cards.add(new SetCardInfo("Devoted Hero", 175, Rarity.COMMON, mage.cards.d.DevotedHero.class)); - cards.add(new SetCardInfo("Djinn of the Lamp", 54, Rarity.RARE, mage.cards.d.DjinnOfTheLamp.class)); - cards.add(new SetCardInfo("Dread Charge", 10, Rarity.RARE, mage.cards.d.DreadCharge.class)); - cards.add(new SetCardInfo("Dread Reaper", 11, Rarity.RARE, mage.cards.d.DreadReaper.class)); - cards.add(new SetCardInfo("Dry Spell", 12, Rarity.UNCOMMON, DrySpell.class)); - cards.add(new SetCardInfo("Earthquake", 129, Rarity.RARE, mage.cards.e.Earthquake.class)); - cards.add(new SetCardInfo("Ebon Dragon", 13, Rarity.RARE, mage.cards.e.EbonDragon.class)); - cards.add(new SetCardInfo("Elite Cat Warrior", 87, Rarity.COMMON, EliteCatWarrior.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Elite Cat Warrior", 88, Rarity.COMMON, EliteCatWarrior.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Elven Cache", 89, Rarity.COMMON, mage.cards.e.ElvenCache.class)); - cards.add(new SetCardInfo("Elvish Ranger", 90, Rarity.COMMON, mage.cards.e.ElvishRanger.class)); - cards.add(new SetCardInfo("Endless Cockroaches", 14, Rarity.RARE, mage.cards.e.EndlessCockroaches.class)); - cards.add(new SetCardInfo("Exhaustion", 55, Rarity.RARE, mage.cards.e.Exhaustion.class)); - cards.add(new SetCardInfo("False Peace", 176, Rarity.COMMON, mage.cards.f.FalsePeace.class)); - cards.add(new SetCardInfo("Feral Shadow", 15, Rarity.COMMON, mage.cards.f.FeralShadow.class)); - cards.add(new SetCardInfo("Final Strike", 16, Rarity.RARE, mage.cards.f.FinalStrike.class)); - cards.add(new SetCardInfo("Fire Dragon", 130, Rarity.RARE, mage.cards.f.FireDragon.class)); - cards.add(new SetCardInfo("Fire Imp", 131, Rarity.UNCOMMON, mage.cards.f.FireImp.class)); - cards.add(new SetCardInfo("Fire Snake", 132, Rarity.COMMON, mage.cards.f.FireSnake.class)); - cards.add(new SetCardInfo("Fire Tempest", 133, Rarity.RARE, mage.cards.f.FireTempest.class)); - cards.add(new SetCardInfo("Flashfires", 134, Rarity.UNCOMMON, mage.cards.f.Flashfires.class)); - cards.add(new SetCardInfo("Fleet-Footed Monk", 177, Rarity.COMMON, mage.cards.f.FleetFootedMonk.class)); - cards.add(new SetCardInfo("Flux", 56, Rarity.UNCOMMON, mage.cards.f.Flux.class)); - cards.add(new SetCardInfo("Foot Soldiers", 178, Rarity.COMMON, mage.cards.f.FootSoldiers.class)); - cards.add(new SetCardInfo("Forest", 203, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 204, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 205, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 206, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Fruition", 91, Rarity.COMMON, mage.cards.f.Fruition.class)); - cards.add(new SetCardInfo("Giant Octopus", 57, Rarity.COMMON, mage.cards.g.GiantOctopus.class)); - cards.add(new SetCardInfo("Giant Spider", 92, Rarity.COMMON, mage.cards.g.GiantSpider.class)); - cards.add(new SetCardInfo("Gift of Estates", 179, Rarity.RARE, mage.cards.g.GiftOfEstates.class)); - cards.add(new SetCardInfo("Goblin Bully", 136, Rarity.COMMON, mage.cards.g.GoblinBully.class)); - cards.add(new SetCardInfo("Gorilla Warrior", 93, Rarity.COMMON, mage.cards.g.GorillaWarrior.class)); - cards.add(new SetCardInfo("Gravedigger", 17, Rarity.UNCOMMON, mage.cards.g.Gravedigger.class)); - cards.add(new SetCardInfo("Grizzly Bears", 94, Rarity.COMMON, mage.cards.g.GrizzlyBears.class)); - cards.add(new SetCardInfo("Hand of Death", 18, Rarity.COMMON, mage.cards.h.HandOfDeath.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Hand of Death", 19, Rarity.COMMON, mage.cards.h.HandOfDeath.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Harsh Justice", 180, Rarity.RARE, mage.cards.h.HarshJustice.class)); - cards.add(new SetCardInfo("Highland Giant", 137, Rarity.COMMON, mage.cards.h.HighlandGiant.class)); - cards.add(new SetCardInfo("Hill Giant", 138, Rarity.COMMON, mage.cards.h.HillGiant.class)); - cards.add(new SetCardInfo("Horned Turtle", 58, Rarity.COMMON, mage.cards.h.HornedTurtle.class)); - cards.add(new SetCardInfo("Howling Fury", 20, Rarity.COMMON, mage.cards.h.HowlingFury.class)); - cards.add(new SetCardInfo("Hulking Cyclops", 139, Rarity.UNCOMMON, mage.cards.h.HulkingCyclops.class)); - cards.add(new SetCardInfo("Hulking Goblin", 140, Rarity.COMMON, mage.cards.h.HulkingGoblin.class)); - cards.add(new SetCardInfo("Hurricane", 95, Rarity.RARE, mage.cards.h.Hurricane.class)); - cards.add(new SetCardInfo("Ingenious Thief", 59, Rarity.UNCOMMON, mage.cards.i.IngeniousThief.class)); - cards.add(new SetCardInfo("Island", 207, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 208, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 209, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 210, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Jungle Lion", 96, Rarity.COMMON, mage.cards.j.JungleLion.class)); - cards.add(new SetCardInfo("Keen-Eyed Archers", 181, Rarity.COMMON, mage.cards.k.KeenEyedArchers.class)); - cards.add(new SetCardInfo("King's Assassin", 21, Rarity.RARE, mage.cards.k.KingsAssassin.class)); - cards.add(new SetCardInfo("Knight Errant", 182, Rarity.COMMON, mage.cards.k.KnightErrant.class)); - cards.add(new SetCardInfo("Last Chance", 141, Rarity.RARE, mage.cards.l.LastChance.class)); - cards.add(new SetCardInfo("Lava Axe", 142, Rarity.COMMON, mage.cards.l.LavaAxe.class)); - cards.add(new SetCardInfo("Lava Flow", 143, Rarity.UNCOMMON, mage.cards.l.LavaFlow.class)); - cards.add(new SetCardInfo("Lizard Warrior", 144, Rarity.COMMON, mage.cards.l.LizardWarrior.class)); - cards.add(new SetCardInfo("Man-o'-War", 60, Rarity.UNCOMMON, mage.cards.m.ManOWar.class)); - cards.add(new SetCardInfo("Mercenary Knight", 22, Rarity.RARE, mage.cards.m.MercenaryKnight.class)); - cards.add(new SetCardInfo("Merfolk of the Pearl Trident", 61, Rarity.COMMON, mage.cards.m.MerfolkOfThePearlTrident.class)); - cards.add(new SetCardInfo("Mind Knives", 23, Rarity.COMMON, mage.cards.m.MindKnives.class)); - cards.add(new SetCardInfo("Mind Rot", 24, Rarity.COMMON, mage.cards.m.MindRot.class)); - cards.add(new SetCardInfo("Minotaur Warrior", 145, Rarity.COMMON, mage.cards.m.MinotaurWarrior.class)); - cards.add(new SetCardInfo("Mobilize", 97, Rarity.COMMON, mage.cards.m.Mobilize.class)); - cards.add(new SetCardInfo("Monstrous Growth", 98, Rarity.COMMON, mage.cards.m.MonstrousGrowth.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Monstrous Growth", 99, Rarity.COMMON, mage.cards.m.MonstrousGrowth.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Moon Sprite", 100, Rarity.UNCOMMON, mage.cards.m.MoonSprite.class)); + cards.add(new SetCardInfo("Desert Drake", 122, Rarity.UNCOMMON, mage.cards.d.DesertDrake.class)); + cards.add(new SetCardInfo("Devastation", 123, Rarity.RARE, mage.cards.d.Devastation.class)); + cards.add(new SetCardInfo("Devoted Hero", 13, Rarity.COMMON, mage.cards.d.DevotedHero.class)); + cards.add(new SetCardInfo("Djinn of the Lamp", 52, Rarity.RARE, mage.cards.d.DjinnOfTheLamp.class)); + cards.add(new SetCardInfo("Dread Charge", 88, Rarity.RARE, mage.cards.d.DreadCharge.class)); + cards.add(new SetCardInfo("Dread Reaper", 89, Rarity.RARE, mage.cards.d.DreadReaper.class)); + cards.add(new SetCardInfo("Dry Spell", 90, Rarity.UNCOMMON, DrySpell.class)); + cards.add(new SetCardInfo("Earthquake", 124, Rarity.RARE, mage.cards.e.Earthquake.class)); + cards.add(new SetCardInfo("Ebon Dragon", 91, Rarity.RARE, mage.cards.e.EbonDragon.class)); + cards.add(new SetCardInfo("Elite Cat Warrior", "163a", Rarity.COMMON, EliteCatWarrior.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elite Cat Warrior", "163b", Rarity.COMMON, EliteCatWarrior.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elven Cache", 164, Rarity.COMMON, mage.cards.e.ElvenCache.class)); + cards.add(new SetCardInfo("Elvish Ranger", 165, Rarity.COMMON, mage.cards.e.ElvishRanger.class)); + cards.add(new SetCardInfo("Endless Cockroaches", 92, Rarity.RARE, mage.cards.e.EndlessCockroaches.class)); + cards.add(new SetCardInfo("Exhaustion", 54, Rarity.RARE, mage.cards.e.Exhaustion.class)); + cards.add(new SetCardInfo("False Peace", 14, Rarity.COMMON, mage.cards.f.FalsePeace.class)); + cards.add(new SetCardInfo("Feral Shadow", 93, Rarity.COMMON, mage.cards.f.FeralShadow.class)); + cards.add(new SetCardInfo("Final Strike", 94, Rarity.RARE, mage.cards.f.FinalStrike.class)); + cards.add(new SetCardInfo("Fire Dragon", 125, Rarity.RARE, mage.cards.f.FireDragon.class)); + cards.add(new SetCardInfo("Fire Imp", 126, Rarity.UNCOMMON, mage.cards.f.FireImp.class)); + cards.add(new SetCardInfo("Fire Snake", 127, Rarity.COMMON, mage.cards.f.FireSnake.class)); + cards.add(new SetCardInfo("Fire Tempest", 128, Rarity.RARE, mage.cards.f.FireTempest.class)); + cards.add(new SetCardInfo("Flashfires", 129, Rarity.UNCOMMON, mage.cards.f.Flashfires.class)); + cards.add(new SetCardInfo("Fleet-Footed Monk", 15, Rarity.COMMON, mage.cards.f.FleetFootedMonk.class)); + cards.add(new SetCardInfo("Flux", 55, Rarity.UNCOMMON, mage.cards.f.Flux.class)); + cards.add(new SetCardInfo("Foot Soldiers", 16, Rarity.COMMON, mage.cards.f.FootSoldiers.class)); + cards.add(new SetCardInfo("Forest", 212, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 213, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 214, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 215, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Fruition", 166, Rarity.COMMON, mage.cards.f.Fruition.class)); + cards.add(new SetCardInfo("Giant Octopus", 56, Rarity.COMMON, mage.cards.g.GiantOctopus.class)); + cards.add(new SetCardInfo("Giant Spider", 167, Rarity.COMMON, mage.cards.g.GiantSpider.class)); + cards.add(new SetCardInfo("Gift of Estates", 17, Rarity.RARE, mage.cards.g.GiftOfEstates.class)); + cards.add(new SetCardInfo("Goblin Bully", 131, Rarity.COMMON, mage.cards.g.GoblinBully.class)); + cards.add(new SetCardInfo("Gorilla Warrior", 168, Rarity.COMMON, mage.cards.g.GorillaWarrior.class)); + cards.add(new SetCardInfo("Gravedigger", 95, Rarity.UNCOMMON, mage.cards.g.Gravedigger.class)); + cards.add(new SetCardInfo("Grizzly Bears", 169, Rarity.COMMON, mage.cards.g.GrizzlyBears.class)); + cards.add(new SetCardInfo("Hand of Death", "96a", Rarity.COMMON, mage.cards.h.HandOfDeath.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Hand of Death", "96b", Rarity.COMMON, mage.cards.h.HandOfDeath.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Harsh Justice", 18, Rarity.RARE, mage.cards.h.HarshJustice.class)); + cards.add(new SetCardInfo("Highland Giant", 132, Rarity.COMMON, mage.cards.h.HighlandGiant.class)); + cards.add(new SetCardInfo("Hill Giant", 133, Rarity.COMMON, mage.cards.h.HillGiant.class)); + cards.add(new SetCardInfo("Horned Turtle", 57, Rarity.COMMON, mage.cards.h.HornedTurtle.class)); + cards.add(new SetCardInfo("Howling Fury", 97, Rarity.COMMON, mage.cards.h.HowlingFury.class)); + cards.add(new SetCardInfo("Hulking Cyclops", 134, Rarity.UNCOMMON, mage.cards.h.HulkingCyclops.class)); + cards.add(new SetCardInfo("Hulking Goblin", 135, Rarity.COMMON, mage.cards.h.HulkingGoblin.class)); + cards.add(new SetCardInfo("Hurricane", 170, Rarity.RARE, mage.cards.h.Hurricane.class)); + cards.add(new SetCardInfo("Ingenious Thief", 58, Rarity.UNCOMMON, mage.cards.i.IngeniousThief.class)); + cards.add(new SetCardInfo("Island", 200, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 201, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 202, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 203, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jungle Lion", 171, Rarity.COMMON, mage.cards.j.JungleLion.class)); + cards.add(new SetCardInfo("Keen-Eyed Archers", 19, Rarity.COMMON, mage.cards.k.KeenEyedArchers.class)); + cards.add(new SetCardInfo("King's Assassin", 98, Rarity.RARE, mage.cards.k.KingsAssassin.class)); + cards.add(new SetCardInfo("Knight Errant", 20, Rarity.COMMON, mage.cards.k.KnightErrant.class)); + cards.add(new SetCardInfo("Last Chance", 136, Rarity.RARE, mage.cards.l.LastChance.class)); + cards.add(new SetCardInfo("Lava Axe", 137, Rarity.COMMON, mage.cards.l.LavaAxe.class)); + cards.add(new SetCardInfo("Lava Flow", 138, Rarity.UNCOMMON, mage.cards.l.LavaFlow.class)); + cards.add(new SetCardInfo("Lizard Warrior", 139, Rarity.COMMON, mage.cards.l.LizardWarrior.class)); + cards.add(new SetCardInfo("Man-o'-War", 59, Rarity.UNCOMMON, mage.cards.m.ManOWar.class)); + cards.add(new SetCardInfo("Mercenary Knight", 99, Rarity.RARE, mage.cards.m.MercenaryKnight.class)); + cards.add(new SetCardInfo("Merfolk of the Pearl Trident", 60, Rarity.COMMON, mage.cards.m.MerfolkOfThePearlTrident.class)); + cards.add(new SetCardInfo("Mind Knives", 100, Rarity.COMMON, mage.cards.m.MindKnives.class)); + cards.add(new SetCardInfo("Mind Rot", 101, Rarity.COMMON, mage.cards.m.MindRot.class)); + cards.add(new SetCardInfo("Minotaur Warrior", 140, Rarity.COMMON, mage.cards.m.MinotaurWarrior.class)); + cards.add(new SetCardInfo("Mobilize", 172, Rarity.COMMON, mage.cards.m.Mobilize.class)); + cards.add(new SetCardInfo("Monstrous Growth", "173a", Rarity.COMMON, mage.cards.m.MonstrousGrowth.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Monstrous Growth", "173b", Rarity.COMMON, mage.cards.m.MonstrousGrowth.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Moon Sprite", 174, Rarity.UNCOMMON, mage.cards.m.MoonSprite.class)); + cards.add(new SetCardInfo("Mountain Goat", 141, Rarity.UNCOMMON, mage.cards.m.MountainGoat.class)); + cards.add(new SetCardInfo("Mountain", 208, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 209, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 210, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 211, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 212, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 213, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 214, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain Goat", 146, Rarity.UNCOMMON, mage.cards.m.MountainGoat.class)); - cards.add(new SetCardInfo("Muck Rats", 25, Rarity.COMMON, mage.cards.m.MuckRats.class)); - cards.add(new SetCardInfo("Mystic Denial", 62, Rarity.UNCOMMON, mage.cards.m.MysticDenial.class)); - cards.add(new SetCardInfo("Natural Order", 101, Rarity.RARE, mage.cards.n.NaturalOrder.class)); - cards.add(new SetCardInfo("Natural Spring", 102, Rarity.UNCOMMON, mage.cards.n.NaturalSpring.class)); - cards.add(new SetCardInfo("Nature's Cloak", 103, Rarity.RARE, mage.cards.n.NaturesCloak.class)); - cards.add(new SetCardInfo("Nature's Lore", 104, Rarity.COMMON, mage.cards.n.NaturesLore.class)); - cards.add(new SetCardInfo("Nature's Ruin", 26, Rarity.UNCOMMON, mage.cards.n.NaturesRuin.class)); - cards.add(new SetCardInfo("Needle Storm", 105, Rarity.UNCOMMON, mage.cards.n.NeedleStorm.class)); - cards.add(new SetCardInfo("Noxious Toad", 27, Rarity.UNCOMMON, mage.cards.n.NoxiousToad.class)); - cards.add(new SetCardInfo("Omen", 63, Rarity.COMMON, mage.cards.o.Omen.class)); - cards.add(new SetCardInfo("Owl Familiar", 64, Rarity.COMMON, mage.cards.o.OwlFamiliar.class)); - cards.add(new SetCardInfo("Panther Warriors", 106, Rarity.COMMON, mage.cards.p.PantherWarriors.class)); - cards.add(new SetCardInfo("Path of Peace", 183, Rarity.COMMON, mage.cards.p.PathOfPeace.class)); - cards.add(new SetCardInfo("Personal Tutor", 65, Rarity.UNCOMMON, mage.cards.p.PersonalTutor.class)); - cards.add(new SetCardInfo("Phantom Warrior", 66, Rarity.RARE, mage.cards.p.PhantomWarrior.class)); - cards.add(new SetCardInfo("Pillaging Horde", 147, Rarity.RARE, mage.cards.p.PillagingHorde.class)); - cards.add(new SetCardInfo("Plains", 215, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 216, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 217, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 218, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plant Elemental", 107, Rarity.UNCOMMON, mage.cards.p.PlantElemental.class)); - cards.add(new SetCardInfo("Primeval Force", 108, Rarity.RARE, mage.cards.p.PrimevalForce.class)); - cards.add(new SetCardInfo("Prosperity", 67, Rarity.RARE, mage.cards.p.Prosperity.class)); - cards.add(new SetCardInfo("Pyroclasm", 148, Rarity.RARE, mage.cards.p.Pyroclasm.class)); - cards.add(new SetCardInfo("Python", 28, Rarity.COMMON, mage.cards.p.Python.class)); - cards.add(new SetCardInfo("Raging Cougar", 149, Rarity.COMMON, mage.cards.r.RagingCougar.class)); - cards.add(new SetCardInfo("Raging Goblin", 150, Rarity.COMMON, mage.cards.r.RagingGoblin.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Raging Goblin", 151, Rarity.COMMON, mage.cards.r.RagingGoblin.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Raging Minotaur", 152, Rarity.COMMON, mage.cards.r.RagingMinotaur.class)); - cards.add(new SetCardInfo("Rain of Salt", 153, Rarity.UNCOMMON, mage.cards.r.RainOfSalt.class)); - cards.add(new SetCardInfo("Rain of Tears", 29, Rarity.UNCOMMON, mage.cards.r.RainOfTears.class)); - cards.add(new SetCardInfo("Raise Dead", 30, Rarity.COMMON, mage.cards.r.RaiseDead.class)); - cards.add(new SetCardInfo("Redwood Treefolk", 109, Rarity.COMMON, mage.cards.r.RedwoodTreefolk.class)); - cards.add(new SetCardInfo("Regal Unicorn", 184, Rarity.COMMON, mage.cards.r.RegalUnicorn.class)); - cards.add(new SetCardInfo("Renewing Dawn", 185, Rarity.UNCOMMON, mage.cards.r.RenewingDawn.class)); - cards.add(new SetCardInfo("Rowan Treefolk", 110, Rarity.COMMON, mage.cards.r.RowanTreefolk.class)); - cards.add(new SetCardInfo("Sacred Knight", 186, Rarity.COMMON, mage.cards.s.SacredKnight.class)); - cards.add(new SetCardInfo("Sacred Nectar", 187, Rarity.COMMON, mage.cards.s.SacredNectar.class)); - cards.add(new SetCardInfo("Scorching Spear", 154, Rarity.COMMON, mage.cards.s.ScorchingSpear.class)); - cards.add(new SetCardInfo("Scorching Winds", 155, Rarity.UNCOMMON, mage.cards.s.ScorchingWinds.class)); - cards.add(new SetCardInfo("Seasoned Marshal", 188, Rarity.UNCOMMON, mage.cards.s.SeasonedMarshal.class)); - cards.add(new SetCardInfo("Serpent Assassin", 31, Rarity.RARE, mage.cards.s.SerpentAssassin.class)); - cards.add(new SetCardInfo("Serpent Warrior", 32, Rarity.COMMON, mage.cards.s.SerpentWarrior.class)); - cards.add(new SetCardInfo("Skeletal Crocodile", 33, Rarity.COMMON, mage.cards.s.SkeletalCrocodile.class)); - cards.add(new SetCardInfo("Skeletal Snake", 34, Rarity.COMMON, mage.cards.s.SkeletalSnake.class)); - cards.add(new SetCardInfo("Snapping Drake", 68, Rarity.COMMON, mage.cards.s.SnappingDrake.class)); - cards.add(new SetCardInfo("Sorcerous Sight", 69, Rarity.COMMON, mage.cards.s.SorcerousSight.class)); - cards.add(new SetCardInfo("Soul Shred", 35, Rarity.COMMON, mage.cards.s.SoulShred.class)); - cards.add(new SetCardInfo("Spined Wurm", 111, Rarity.COMMON, mage.cards.s.SpinedWurm.class)); - cards.add(new SetCardInfo("Spiritual Guardian", 189, Rarity.RARE, mage.cards.s.SpiritualGuardian.class)); - cards.add(new SetCardInfo("Spitting Earth", 156, Rarity.COMMON, mage.cards.s.SpittingEarth.class)); - cards.add(new SetCardInfo("Spotted Griffin", 190, Rarity.COMMON, mage.cards.s.SpottedGriffin.class)); - cards.add(new SetCardInfo("Stalking Tiger", 112, Rarity.COMMON, mage.cards.s.StalkingTiger.class)); - cards.add(new SetCardInfo("Starlight", 191, Rarity.UNCOMMON, mage.cards.s.Starlight.class)); - cards.add(new SetCardInfo("Starlit Angel", 192, Rarity.UNCOMMON, mage.cards.s.StarlitAngel.class)); - cards.add(new SetCardInfo("Steadfastness", 193, Rarity.COMMON, mage.cards.s.Steadfastness.class)); - cards.add(new SetCardInfo("Stern Marshal", 194, Rarity.RARE, mage.cards.s.SternMarshal.class)); - cards.add(new SetCardInfo("Stone Rain", 157, Rarity.COMMON, mage.cards.s.StoneRain.class)); - cards.add(new SetCardInfo("Storm Crow", 70, Rarity.COMMON, mage.cards.s.StormCrow.class)); - cards.add(new SetCardInfo("Summer Bloom", 113, Rarity.RARE, mage.cards.s.SummerBloom.class)); - cards.add(new SetCardInfo("Swamp", 219, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 220, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 221, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 222, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sylvan Tutor", 114, Rarity.RARE, mage.cards.s.SylvanTutor.class)); - cards.add(new SetCardInfo("Symbol of Unsummoning", 71, Rarity.COMMON, mage.cards.s.SymbolOfUnsummoning.class)); - cards.add(new SetCardInfo("Taunt", 72, Rarity.RARE, mage.cards.t.Taunt.class)); - cards.add(new SetCardInfo("Temporary Truce", 195, Rarity.RARE, mage.cards.t.TemporaryTruce.class)); - cards.add(new SetCardInfo("Theft of Dreams", 73, Rarity.UNCOMMON, mage.cards.t.TheftOfDreams.class)); - cards.add(new SetCardInfo("Thing from the Deep", 74, Rarity.RARE, mage.cards.t.ThingFromTheDeep.class)); - cards.add(new SetCardInfo("Thundering Wurm", 115, Rarity.RARE, mage.cards.t.ThunderingWurm.class)); - cards.add(new SetCardInfo("Thundermare", 158, Rarity.RARE, mage.cards.t.Thundermare.class)); - cards.add(new SetCardInfo("Tidal Surge", 75, Rarity.COMMON, mage.cards.t.TidalSurge.class)); - cards.add(new SetCardInfo("Time Ebb", 76, Rarity.COMMON, mage.cards.t.TimeEbb.class)); - cards.add(new SetCardInfo("Touch of Brilliance", 77, Rarity.COMMON, mage.cards.t.TouchOfBrilliance.class)); - cards.add(new SetCardInfo("Treetop Defense", 116, Rarity.RARE, mage.cards.t.TreetopDefense.class)); - cards.add(new SetCardInfo("Undying Beast", 36, Rarity.COMMON, mage.cards.u.UndyingBeast.class)); - cards.add(new SetCardInfo("Untamed Wilds", 117, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); - cards.add(new SetCardInfo("Valorous Charge", 196, Rarity.UNCOMMON, mage.cards.v.ValorousCharge.class)); - cards.add(new SetCardInfo("Vampiric Feast", 37, Rarity.UNCOMMON, mage.cards.v.VampiricFeast.class)); - cards.add(new SetCardInfo("Vampiric Touch", 38, Rarity.COMMON, mage.cards.v.VampiricTouch.class)); - cards.add(new SetCardInfo("Venerable Monk", 197, Rarity.UNCOMMON, mage.cards.v.VenerableMonk.class)); - cards.add(new SetCardInfo("Vengeance", 198, Rarity.UNCOMMON, mage.cards.v.Vengeance.class)); - cards.add(new SetCardInfo("Virtue's Ruin", 39, Rarity.UNCOMMON, mage.cards.v.VirtuesRuin.class)); - cards.add(new SetCardInfo("Volcanic Dragon", 159, Rarity.RARE, mage.cards.v.VolcanicDragon.class)); - cards.add(new SetCardInfo("Volcanic Hammer", 160, Rarity.COMMON, mage.cards.v.VolcanicHammer.class)); - cards.add(new SetCardInfo("Wall of Granite", 161, Rarity.UNCOMMON, mage.cards.w.WallOfGranite.class)); - cards.add(new SetCardInfo("Wall of Swords", 199, Rarity.UNCOMMON, mage.cards.w.WallOfSwords.class)); - cards.add(new SetCardInfo("Warrior's Charge", 200, Rarity.COMMON, WarriorsCharge.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Warrior's Charge", 201, Rarity.COMMON, WarriorsCharge.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Whiptail Wurm", 118, Rarity.UNCOMMON, mage.cards.w.WhiptailWurm.class)); - cards.add(new SetCardInfo("Wicked Pact", 40, Rarity.RARE, mage.cards.w.WickedPact.class)); - cards.add(new SetCardInfo("Willow Dryad", 119, Rarity.COMMON, mage.cards.w.WillowDryad.class)); - cards.add(new SetCardInfo("Wind Drake", 78, Rarity.COMMON, mage.cards.w.WindDrake.class)); - cards.add(new SetCardInfo("Winds of Change", 162, Rarity.RARE, mage.cards.w.WindsOfChange.class)); - cards.add(new SetCardInfo("Winter's Grasp", 120, Rarity.UNCOMMON, mage.cards.w.WintersGrasp.class)); - cards.add(new SetCardInfo("Withering Gaze", 79, Rarity.UNCOMMON, mage.cards.w.WitheringGaze.class)); - cards.add(new SetCardInfo("Wood Elves", 121, Rarity.RARE, mage.cards.w.WoodElves.class)); - cards.add(new SetCardInfo("Wrath of God", 202, Rarity.RARE, mage.cards.w.WrathOfGod.class)); + cards.add(new SetCardInfo("Muck Rats", 102, Rarity.COMMON, mage.cards.m.MuckRats.class)); + cards.add(new SetCardInfo("Mystic Denial", 61, Rarity.UNCOMMON, mage.cards.m.MysticDenial.class)); + cards.add(new SetCardInfo("Natural Order", 175, Rarity.RARE, mage.cards.n.NaturalOrder.class)); + cards.add(new SetCardInfo("Natural Spring", 176, Rarity.UNCOMMON, mage.cards.n.NaturalSpring.class)); + cards.add(new SetCardInfo("Nature's Cloak", 177, Rarity.RARE, mage.cards.n.NaturesCloak.class)); + cards.add(new SetCardInfo("Nature's Lore", 178, Rarity.COMMON, mage.cards.n.NaturesLore.class)); + cards.add(new SetCardInfo("Nature's Ruin", 103, Rarity.UNCOMMON, mage.cards.n.NaturesRuin.class)); + cards.add(new SetCardInfo("Needle Storm", 179, Rarity.UNCOMMON, mage.cards.n.NeedleStorm.class)); + cards.add(new SetCardInfo("Noxious Toad", 104, Rarity.UNCOMMON, mage.cards.n.NoxiousToad.class)); + cards.add(new SetCardInfo("Omen", 62, Rarity.COMMON, mage.cards.o.Omen.class)); + cards.add(new SetCardInfo("Owl Familiar", 63, Rarity.COMMON, mage.cards.o.OwlFamiliar.class)); + cards.add(new SetCardInfo("Panther Warriors", 180, Rarity.COMMON, mage.cards.p.PantherWarriors.class)); + cards.add(new SetCardInfo("Path of Peace", 21, Rarity.COMMON, mage.cards.p.PathOfPeace.class)); + cards.add(new SetCardInfo("Personal Tutor", 64, Rarity.UNCOMMON, mage.cards.p.PersonalTutor.class)); + cards.add(new SetCardInfo("Phantom Warrior", 65, Rarity.RARE, mage.cards.p.PhantomWarrior.class)); + cards.add(new SetCardInfo("Pillaging Horde", 142, Rarity.RARE, mage.cards.p.PillagingHorde.class)); + cards.add(new SetCardInfo("Plains", 196, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 197, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 198, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 199, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plant Elemental", 181, Rarity.UNCOMMON, mage.cards.p.PlantElemental.class)); + cards.add(new SetCardInfo("Primeval Force", 182, Rarity.RARE, mage.cards.p.PrimevalForce.class)); + cards.add(new SetCardInfo("Prosperity", 66, Rarity.RARE, mage.cards.p.Prosperity.class)); + cards.add(new SetCardInfo("Pyroclasm", 143, Rarity.RARE, mage.cards.p.Pyroclasm.class)); + cards.add(new SetCardInfo("Python", 105, Rarity.COMMON, mage.cards.p.Python.class)); + cards.add(new SetCardInfo("Raging Cougar", 144, Rarity.COMMON, mage.cards.r.RagingCougar.class)); + cards.add(new SetCardInfo("Raging Goblin", "145a", Rarity.COMMON, mage.cards.r.RagingGoblin.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Raging Goblin", "145b", Rarity.COMMON, mage.cards.r.RagingGoblin.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Raging Minotaur", 146, Rarity.COMMON, mage.cards.r.RagingMinotaur.class)); + cards.add(new SetCardInfo("Rain of Salt", 147, Rarity.UNCOMMON, mage.cards.r.RainOfSalt.class)); + cards.add(new SetCardInfo("Rain of Tears", 106, Rarity.UNCOMMON, mage.cards.r.RainOfTears.class)); + cards.add(new SetCardInfo("Raise Dead", 107, Rarity.COMMON, mage.cards.r.RaiseDead.class)); + cards.add(new SetCardInfo("Redwood Treefolk", 183, Rarity.COMMON, mage.cards.r.RedwoodTreefolk.class)); + cards.add(new SetCardInfo("Regal Unicorn", 22, Rarity.COMMON, mage.cards.r.RegalUnicorn.class)); + cards.add(new SetCardInfo("Renewing Dawn", 23, Rarity.UNCOMMON, mage.cards.r.RenewingDawn.class)); + cards.add(new SetCardInfo("Rowan Treefolk", 184, Rarity.COMMON, mage.cards.r.RowanTreefolk.class)); + cards.add(new SetCardInfo("Sacred Knight", 24, Rarity.COMMON, mage.cards.s.SacredKnight.class)); + cards.add(new SetCardInfo("Sacred Nectar", 25, Rarity.COMMON, mage.cards.s.SacredNectar.class)); + cards.add(new SetCardInfo("Scorching Spear", 148, Rarity.COMMON, mage.cards.s.ScorchingSpear.class)); + cards.add(new SetCardInfo("Scorching Winds", 149, Rarity.UNCOMMON, mage.cards.s.ScorchingWinds.class)); + cards.add(new SetCardInfo("Seasoned Marshal", 26, Rarity.UNCOMMON, mage.cards.s.SeasonedMarshal.class)); + cards.add(new SetCardInfo("Serpent Assassin", 108, Rarity.RARE, mage.cards.s.SerpentAssassin.class)); + cards.add(new SetCardInfo("Serpent Warrior", 109, Rarity.COMMON, mage.cards.s.SerpentWarrior.class)); + cards.add(new SetCardInfo("Skeletal Crocodile", 110, Rarity.COMMON, mage.cards.s.SkeletalCrocodile.class)); + cards.add(new SetCardInfo("Skeletal Snake", 111, Rarity.COMMON, mage.cards.s.SkeletalSnake.class)); + cards.add(new SetCardInfo("Snapping Drake", 67, Rarity.COMMON, mage.cards.s.SnappingDrake.class)); + cards.add(new SetCardInfo("Sorcerous Sight", 68, Rarity.COMMON, mage.cards.s.SorcerousSight.class)); + cards.add(new SetCardInfo("Soul Shred", 112, Rarity.COMMON, mage.cards.s.SoulShred.class)); + cards.add(new SetCardInfo("Spined Wurm", 185, Rarity.COMMON, mage.cards.s.SpinedWurm.class)); + cards.add(new SetCardInfo("Spiritual Guardian", 27, Rarity.RARE, mage.cards.s.SpiritualGuardian.class)); + cards.add(new SetCardInfo("Spitting Earth", 150, Rarity.COMMON, mage.cards.s.SpittingEarth.class)); + cards.add(new SetCardInfo("Spotted Griffin", 28, Rarity.COMMON, mage.cards.s.SpottedGriffin.class)); + cards.add(new SetCardInfo("Stalking Tiger", 186, Rarity.COMMON, mage.cards.s.StalkingTiger.class)); + cards.add(new SetCardInfo("Starlight", 29, Rarity.UNCOMMON, mage.cards.s.Starlight.class)); + cards.add(new SetCardInfo("Starlit Angel", 30, Rarity.UNCOMMON, mage.cards.s.StarlitAngel.class)); + cards.add(new SetCardInfo("Steadfastness", 31, Rarity.COMMON, mage.cards.s.Steadfastness.class)); + cards.add(new SetCardInfo("Stern Marshal", 32, Rarity.RARE, mage.cards.s.SternMarshal.class)); + cards.add(new SetCardInfo("Stone Rain", 151, Rarity.COMMON, mage.cards.s.StoneRain.class)); + cards.add(new SetCardInfo("Storm Crow", 69, Rarity.COMMON, mage.cards.s.StormCrow.class)); + cards.add(new SetCardInfo("Summer Bloom", 187, Rarity.RARE, mage.cards.s.SummerBloom.class)); + cards.add(new SetCardInfo("Swamp", 204, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 205, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 206, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 207, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sylvan Tutor", 188, Rarity.RARE, mage.cards.s.SylvanTutor.class)); + cards.add(new SetCardInfo("Symbol of Unsummoning", 70, Rarity.COMMON, mage.cards.s.SymbolOfUnsummoning.class)); + cards.add(new SetCardInfo("Taunt", 71, Rarity.RARE, mage.cards.t.Taunt.class)); + cards.add(new SetCardInfo("Temporary Truce", 33, Rarity.RARE, mage.cards.t.TemporaryTruce.class)); + cards.add(new SetCardInfo("Theft of Dreams", 72, Rarity.UNCOMMON, mage.cards.t.TheftOfDreams.class)); + cards.add(new SetCardInfo("Thing from the Deep", 73, Rarity.RARE, mage.cards.t.ThingFromTheDeep.class)); + cards.add(new SetCardInfo("Thundering Wurm", 189, Rarity.RARE, mage.cards.t.ThunderingWurm.class)); + cards.add(new SetCardInfo("Thundermare", 152, Rarity.RARE, mage.cards.t.Thundermare.class)); + cards.add(new SetCardInfo("Tidal Surge", 74, Rarity.COMMON, mage.cards.t.TidalSurge.class)); + cards.add(new SetCardInfo("Time Ebb", 75, Rarity.COMMON, mage.cards.t.TimeEbb.class)); + cards.add(new SetCardInfo("Touch of Brilliance", 76, Rarity.COMMON, mage.cards.t.TouchOfBrilliance.class)); + cards.add(new SetCardInfo("Treetop Defense", 190, Rarity.RARE, mage.cards.t.TreetopDefense.class)); + cards.add(new SetCardInfo("Undying Beast", 113, Rarity.COMMON, mage.cards.u.UndyingBeast.class)); + cards.add(new SetCardInfo("Untamed Wilds", 191, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); + cards.add(new SetCardInfo("Valorous Charge", 34, Rarity.UNCOMMON, mage.cards.v.ValorousCharge.class)); + cards.add(new SetCardInfo("Vampiric Feast", 114, Rarity.UNCOMMON, mage.cards.v.VampiricFeast.class)); + cards.add(new SetCardInfo("Vampiric Touch", 115, Rarity.COMMON, mage.cards.v.VampiricTouch.class)); + cards.add(new SetCardInfo("Venerable Monk", 35, Rarity.UNCOMMON, mage.cards.v.VenerableMonk.class)); + cards.add(new SetCardInfo("Vengeance", 36, Rarity.UNCOMMON, mage.cards.v.Vengeance.class)); + cards.add(new SetCardInfo("Virtue's Ruin", 116, Rarity.UNCOMMON, mage.cards.v.VirtuesRuin.class)); + cards.add(new SetCardInfo("Volcanic Dragon", 153, Rarity.RARE, mage.cards.v.VolcanicDragon.class)); + cards.add(new SetCardInfo("Volcanic Hammer", 154, Rarity.COMMON, mage.cards.v.VolcanicHammer.class)); + cards.add(new SetCardInfo("Wall of Granite", 155, Rarity.UNCOMMON, mage.cards.w.WallOfGranite.class)); + cards.add(new SetCardInfo("Wall of Swords", 37, Rarity.UNCOMMON, mage.cards.w.WallOfSwords.class)); + cards.add(new SetCardInfo("Warrior's Charge", "38a", Rarity.COMMON, WarriorsCharge.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Warrior's Charge", "38b", Rarity.COMMON, WarriorsCharge.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Whiptail Wurm", 192, Rarity.UNCOMMON, mage.cards.w.WhiptailWurm.class)); + cards.add(new SetCardInfo("Wicked Pact", 117, Rarity.RARE, mage.cards.w.WickedPact.class)); + cards.add(new SetCardInfo("Willow Dryad", 193, Rarity.COMMON, mage.cards.w.WillowDryad.class)); + cards.add(new SetCardInfo("Wind Drake", 77, Rarity.COMMON, mage.cards.w.WindDrake.class)); + cards.add(new SetCardInfo("Winds of Change", 156, Rarity.RARE, mage.cards.w.WindsOfChange.class)); + cards.add(new SetCardInfo("Winter's Grasp", 194, Rarity.UNCOMMON, mage.cards.w.WintersGrasp.class)); + cards.add(new SetCardInfo("Withering Gaze", 78, Rarity.UNCOMMON, mage.cards.w.WitheringGaze.class)); + cards.add(new SetCardInfo("Wood Elves", 195, Rarity.RARE, mage.cards.w.WoodElves.class)); + cards.add(new SetCardInfo("Wrath of God", 39, Rarity.RARE, mage.cards.w.WrathOfGod.class)); } } diff --git a/Mage.Sets/src/mage/sets/PortalSecondAge.java b/Mage.Sets/src/mage/sets/PortalSecondAge.java index bb316e198fe..1efd4d74214 100644 --- a/Mage.Sets/src/mage/sets/PortalSecondAge.java +++ b/Mage.Sets/src/mage/sets/PortalSecondAge.java @@ -31,57 +31,57 @@ public final class PortalSecondAge extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Abyssal Nightstalker", 1, Rarity.UNCOMMON, mage.cards.a.AbyssalNightstalker.class)); + cards.add(new SetCardInfo("Abyssal Nightstalker", 61, Rarity.UNCOMMON, mage.cards.a.AbyssalNightstalker.class)); cards.add(new SetCardInfo("Air Elemental", 31, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); - cards.add(new SetCardInfo("Alaborn Cavalier", 121, Rarity.UNCOMMON, mage.cards.a.AlabornCavalier.class)); - cards.add(new SetCardInfo("Alaborn Grenadier", 122, Rarity.COMMON, mage.cards.a.AlabornGrenadier.class)); - cards.add(new SetCardInfo("Alaborn Musketeer", 123, Rarity.COMMON, mage.cards.a.AlabornMusketeer.class)); - cards.add(new SetCardInfo("Alaborn Trooper", 124, Rarity.COMMON, mage.cards.a.AlabornTrooper.class)); - cards.add(new SetCardInfo("Alaborn Veteran", 125, Rarity.RARE, mage.cards.a.AlabornVeteran.class)); - cards.add(new SetCardInfo("Alaborn Zealot", 126, Rarity.UNCOMMON, mage.cards.a.AlabornZealot.class)); - cards.add(new SetCardInfo("Alluring Scent", 61, Rarity.RARE, mage.cards.a.AlluringScent.class)); - cards.add(new SetCardInfo("Ancient Craving", 2, Rarity.RARE, mage.cards.a.AncientCraving.class)); - cards.add(new SetCardInfo("Angelic Blessing", 129, Rarity.COMMON, mage.cards.a.AngelicBlessing.class)); - cards.add(new SetCardInfo("Angelic Wall", 130, Rarity.COMMON, mage.cards.a.AngelicWall.class)); - cards.add(new SetCardInfo("Angel of Fury", 127, Rarity.RARE, mage.cards.a.AngelOfFury.class)); - cards.add(new SetCardInfo("Angel of Mercy", 128, Rarity.UNCOMMON, mage.cards.a.AngelOfMercy.class)); + cards.add(new SetCardInfo("Alaborn Cavalier", 1, Rarity.UNCOMMON, mage.cards.a.AlabornCavalier.class)); + cards.add(new SetCardInfo("Alaborn Grenadier", 2, Rarity.COMMON, mage.cards.a.AlabornGrenadier.class)); + cards.add(new SetCardInfo("Alaborn Musketeer", 3, Rarity.COMMON, mage.cards.a.AlabornMusketeer.class)); + cards.add(new SetCardInfo("Alaborn Trooper", 4, Rarity.COMMON, mage.cards.a.AlabornTrooper.class)); + cards.add(new SetCardInfo("Alaborn Veteran", 5, Rarity.RARE, mage.cards.a.AlabornVeteran.class)); + cards.add(new SetCardInfo("Alaborn Zealot", 6, Rarity.UNCOMMON, mage.cards.a.AlabornZealot.class)); + cards.add(new SetCardInfo("Alluring Scent", 121, Rarity.RARE, mage.cards.a.AlluringScent.class)); + cards.add(new SetCardInfo("Ancient Craving", 62, Rarity.RARE, mage.cards.a.AncientCraving.class)); + cards.add(new SetCardInfo("Angel of Fury", 7, Rarity.RARE, mage.cards.a.AngelOfFury.class)); + cards.add(new SetCardInfo("Angel of Mercy", 8, Rarity.UNCOMMON, mage.cards.a.AngelOfMercy.class)); + cards.add(new SetCardInfo("Angelic Blessing", 9, Rarity.COMMON, mage.cards.a.AngelicBlessing.class)); + cards.add(new SetCardInfo("Angelic Wall", 10, Rarity.COMMON, mage.cards.a.AngelicWall.class)); cards.add(new SetCardInfo("Apprentice Sorcerer", 32, Rarity.UNCOMMON, mage.cards.a.ApprenticeSorcerer.class)); - cards.add(new SetCardInfo("Archangel", 131, Rarity.RARE, mage.cards.a.Archangel.class)); - cards.add(new SetCardInfo("Armageddon", 132, Rarity.RARE, mage.cards.a.Armageddon.class)); + cards.add(new SetCardInfo("Archangel", 11, Rarity.RARE, mage.cards.a.Archangel.class)); + cards.add(new SetCardInfo("Armageddon", 12, Rarity.RARE, mage.cards.a.Armageddon.class)); cards.add(new SetCardInfo("Armored Galleon", 33, Rarity.UNCOMMON, mage.cards.a.ArmoredGalleon.class)); - cards.add(new SetCardInfo("Armored Griffin", 133, Rarity.UNCOMMON, mage.cards.a.ArmoredGriffin.class)); - cards.add(new SetCardInfo("Barbtooth Wurm", 62, Rarity.COMMON, mage.cards.b.BarbtoothWurm.class)); - cards.add(new SetCardInfo("Bargain", 134, Rarity.UNCOMMON, mage.cards.b.Bargain.class)); - cards.add(new SetCardInfo("Bear Cub", 63, Rarity.COMMON, mage.cards.b.BearCub.class)); - cards.add(new SetCardInfo("Bee Sting", 64, Rarity.UNCOMMON, mage.cards.b.BeeSting.class)); + cards.add(new SetCardInfo("Armored Griffin", 13, Rarity.UNCOMMON, mage.cards.a.ArmoredGriffin.class)); + cards.add(new SetCardInfo("Barbtooth Wurm", 122, Rarity.COMMON, mage.cards.b.BarbtoothWurm.class)); + cards.add(new SetCardInfo("Bargain", 14, Rarity.UNCOMMON, mage.cards.b.Bargain.class)); + cards.add(new SetCardInfo("Bear Cub", 123, Rarity.COMMON, mage.cards.b.BearCub.class)); + cards.add(new SetCardInfo("Bee Sting", 124, Rarity.UNCOMMON, mage.cards.b.BeeSting.class)); cards.add(new SetCardInfo("Blaze", 91, Rarity.UNCOMMON, mage.cards.b.Blaze.class)); - cards.add(new SetCardInfo("Bloodcurdling Scream", 3, Rarity.UNCOMMON, mage.cards.b.BloodcurdlingScream.class)); - cards.add(new SetCardInfo("Breath of Life", 135, Rarity.COMMON, mage.cards.b.BreathOfLife.class)); + cards.add(new SetCardInfo("Bloodcurdling Scream", 63, Rarity.UNCOMMON, mage.cards.b.BloodcurdlingScream.class)); + cards.add(new SetCardInfo("Breath of Life", 15, Rarity.COMMON, mage.cards.b.BreathOfLife.class)); cards.add(new SetCardInfo("Brimstone Dragon", 92, Rarity.RARE, mage.cards.b.BrimstoneDragon.class)); - cards.add(new SetCardInfo("Brutal Nightstalker", 4, Rarity.UNCOMMON, mage.cards.b.BrutalNightstalker.class)); - cards.add(new SetCardInfo("Chorus of Woe", 5, Rarity.COMMON, mage.cards.c.ChorusOfWoe.class)); + cards.add(new SetCardInfo("Brutal Nightstalker", 64, Rarity.UNCOMMON, mage.cards.b.BrutalNightstalker.class)); + cards.add(new SetCardInfo("Chorus of Woe", 65, Rarity.COMMON, mage.cards.c.ChorusOfWoe.class)); cards.add(new SetCardInfo("Coastal Wizard", 34, Rarity.RARE, mage.cards.c.CoastalWizard.class)); - cards.add(new SetCardInfo("Coercion", 6, Rarity.UNCOMMON, mage.cards.c.Coercion.class)); - cards.add(new SetCardInfo("Cruel Edict", 7, Rarity.COMMON, mage.cards.c.CruelEdict.class)); - cards.add(new SetCardInfo("Dakmor Bat", 8, Rarity.COMMON, mage.cards.d.DakmorBat.class)); - cards.add(new SetCardInfo("Dakmor Plague", 9, Rarity.UNCOMMON, mage.cards.d.DakmorPlague.class)); - cards.add(new SetCardInfo("Dakmor Scorpion", 10, Rarity.COMMON, mage.cards.d.DakmorScorpion.class)); - cards.add(new SetCardInfo("Dakmor Sorceress", 11, Rarity.RARE, mage.cards.d.DakmorSorceress.class)); - cards.add(new SetCardInfo("Dark Offering", 12, Rarity.UNCOMMON, mage.cards.d.DarkOffering.class)); - cards.add(new SetCardInfo("Deathcoil Wurm", 65, Rarity.RARE, mage.cards.d.DeathcoilWurm.class)); - cards.add(new SetCardInfo("Deep Wood", 66, Rarity.UNCOMMON, mage.cards.d.DeepWood.class)); - cards.add(new SetCardInfo("Deja Vu", 35, Rarity.COMMON, mage.cards.d.DejaVu.class)); - cards.add(new SetCardInfo("Denizen of the Deep", 36, Rarity.RARE, mage.cards.d.DenizenOfTheDeep.class)); + cards.add(new SetCardInfo("Coercion", 66, Rarity.UNCOMMON, mage.cards.c.Coercion.class)); + cards.add(new SetCardInfo("Cruel Edict", 67, Rarity.COMMON, mage.cards.c.CruelEdict.class)); + cards.add(new SetCardInfo("Dakmor Bat", 68, Rarity.COMMON, mage.cards.d.DakmorBat.class)); + cards.add(new SetCardInfo("Dakmor Plague", 69, Rarity.UNCOMMON, mage.cards.d.DakmorPlague.class)); + cards.add(new SetCardInfo("Dakmor Scorpion", 70, Rarity.COMMON, mage.cards.d.DakmorScorpion.class)); + cards.add(new SetCardInfo("Dakmor Sorceress", 71, Rarity.RARE, mage.cards.d.DakmorSorceress.class)); + cards.add(new SetCardInfo("Dark Offering", 72, Rarity.UNCOMMON, mage.cards.d.DarkOffering.class)); + cards.add(new SetCardInfo("Deathcoil Wurm", 125, Rarity.RARE, mage.cards.d.DeathcoilWurm.class)); + cards.add(new SetCardInfo("Deep Wood", 126, Rarity.UNCOMMON, mage.cards.d.DeepWood.class)); + cards.add(new SetCardInfo("Deja Vu", 36, Rarity.COMMON, mage.cards.d.DejaVu.class)); + cards.add(new SetCardInfo("Denizen of the Deep", 35, Rarity.RARE, mage.cards.d.DenizenOfTheDeep.class)); cards.add(new SetCardInfo("Earthquake", 94, Rarity.RARE, mage.cards.e.Earthquake.class)); cards.add(new SetCardInfo("Exhaustion", 37, Rarity.RARE, mage.cards.e.Exhaustion.class)); cards.add(new SetCardInfo("Extinguish", 38, Rarity.COMMON, mage.cards.e.Extinguish.class)); cards.add(new SetCardInfo("Eye Spy", 39, Rarity.UNCOMMON, mage.cards.e.EyeSpy.class)); cards.add(new SetCardInfo("False Summoning", 40, Rarity.COMMON, mage.cards.f.FalseSummoning.class)); - cards.add(new SetCardInfo("Festival of Trokin", 136, Rarity.COMMON, mage.cards.f.FestivalOfTrokin.class)); - cards.add(new SetCardInfo("Forest", 151, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 152, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 153, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Foul Spirit", 13, Rarity.UNCOMMON, mage.cards.f.FoulSpirit.class)); + cards.add(new SetCardInfo("Festival of Trokin", 16, Rarity.COMMON, mage.cards.f.FestivalOfTrokin.class)); + cards.add(new SetCardInfo("Forest", 163, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 164, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 165, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Foul Spirit", 73, Rarity.UNCOMMON, mage.cards.f.FoulSpirit.class)); cards.add(new SetCardInfo("Goblin Cavaliers", 95, Rarity.COMMON, mage.cards.g.GoblinCavaliers.class)); cards.add(new SetCardInfo("Goblin Firestarter", 96, Rarity.UNCOMMON, mage.cards.g.GoblinFirestarter.class)); cards.add(new SetCardInfo("Goblin General", 97, Rarity.RARE, mage.cards.g.GoblinGeneral.class)); @@ -93,106 +93,106 @@ public final class PortalSecondAge extends ExpansionSet { cards.add(new SetCardInfo("Goblin Raider", 103, Rarity.COMMON, mage.cards.g.GoblinRaider.class)); cards.add(new SetCardInfo("Goblin War Cry", 104, Rarity.UNCOMMON, mage.cards.g.GoblinWarCry.class)); cards.add(new SetCardInfo("Goblin War Strike", 105, Rarity.COMMON, mage.cards.g.GoblinWarStrike.class)); - cards.add(new SetCardInfo("Golden Bear", 67, Rarity.COMMON, mage.cards.g.GoldenBear.class)); - cards.add(new SetCardInfo("Hand of Death", 14, Rarity.COMMON, mage.cards.h.HandOfDeath.class)); - cards.add(new SetCardInfo("Harmony of Nature", 68, Rarity.UNCOMMON, mage.cards.h.HarmonyOfNature.class)); - cards.add(new SetCardInfo("Hidden Horror", 15, Rarity.RARE, mage.cards.h.HiddenHorror.class)); - cards.add(new SetCardInfo("Hurricane", 69, Rarity.RARE, mage.cards.h.Hurricane.class)); - cards.add(new SetCardInfo("Ironhoof Ox", 70, Rarity.UNCOMMON, mage.cards.i.IronhoofOx.class)); + cards.add(new SetCardInfo("Golden Bear", 127, Rarity.COMMON, mage.cards.g.GoldenBear.class)); + cards.add(new SetCardInfo("Hand of Death", 74, Rarity.COMMON, mage.cards.h.HandOfDeath.class)); + cards.add(new SetCardInfo("Harmony of Nature", 128, Rarity.UNCOMMON, mage.cards.h.HarmonyOfNature.class)); + cards.add(new SetCardInfo("Hidden Horror", 75, Rarity.RARE, mage.cards.h.HiddenHorror.class)); + cards.add(new SetCardInfo("Hurricane", 129, Rarity.RARE, mage.cards.h.Hurricane.class)); + cards.add(new SetCardInfo("Ironhoof Ox", 130, Rarity.UNCOMMON, mage.cards.i.IronhoofOx.class)); cards.add(new SetCardInfo("Island", 154, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 155, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 156, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jagged Lightning", 106, Rarity.UNCOMMON, mage.cards.j.JaggedLightning.class)); - cards.add(new SetCardInfo("Just Fate", 137, Rarity.RARE, mage.cards.j.JustFate.class)); - cards.add(new SetCardInfo("Kiss of Death", 16, Rarity.UNCOMMON, mage.cards.k.KissOfDeath.class)); + cards.add(new SetCardInfo("Just Fate", 17, Rarity.RARE, mage.cards.j.JustFate.class)); + cards.add(new SetCardInfo("Kiss of Death", 76, Rarity.UNCOMMON, mage.cards.k.KissOfDeath.class)); cards.add(new SetCardInfo("Lava Axe", 107, Rarity.COMMON, mage.cards.l.LavaAxe.class)); - cards.add(new SetCardInfo("Lone Wolf", 71, Rarity.UNCOMMON, mage.cards.l.LoneWolf.class)); - cards.add(new SetCardInfo("Lurking Nightstalker", 17, Rarity.COMMON, mage.cards.l.LurkingNightstalker.class)); - cards.add(new SetCardInfo("Lynx", 72, Rarity.COMMON, mage.cards.l.Lynx.class)); + cards.add(new SetCardInfo("Lone Wolf", 131, Rarity.UNCOMMON, mage.cards.l.LoneWolf.class)); + cards.add(new SetCardInfo("Lurking Nightstalker", 77, Rarity.COMMON, mage.cards.l.LurkingNightstalker.class)); + cards.add(new SetCardInfo("Lynx", 132, Rarity.COMMON, mage.cards.l.Lynx.class)); cards.add(new SetCardInfo("Magma Giant", 108, Rarity.RARE, mage.cards.m.MagmaGiant.class)); - cards.add(new SetCardInfo("Mind Rot", 18, Rarity.COMMON, mage.cards.m.MindRot.class)); - cards.add(new SetCardInfo("Moaning Spirit", 19, Rarity.COMMON, mage.cards.m.MoaningSpirit.class)); - cards.add(new SetCardInfo("Monstrous Growth", 73, Rarity.COMMON, mage.cards.m.MonstrousGrowth.class)); - cards.add(new SetCardInfo("Mountain", 157, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 158, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 159, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Muck Rats", 20, Rarity.COMMON, mage.cards.m.MuckRats.class)); + cards.add(new SetCardInfo("Mind Rot", 78, Rarity.COMMON, mage.cards.m.MindRot.class)); + cards.add(new SetCardInfo("Moaning Spirit", 79, Rarity.COMMON, mage.cards.m.MoaningSpirit.class)); + cards.add(new SetCardInfo("Monstrous Growth", 133, Rarity.COMMON, mage.cards.m.MonstrousGrowth.class)); + cards.add(new SetCardInfo("Mountain", 160, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 161, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 162, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Muck Rats", 80, Rarity.COMMON, mage.cards.m.MuckRats.class)); cards.add(new SetCardInfo("Mystic Denial", 41, Rarity.UNCOMMON, mage.cards.m.MysticDenial.class)); - cards.add(new SetCardInfo("Natural Spring", 74, Rarity.COMMON, mage.cards.n.NaturalSpring.class)); - cards.add(new SetCardInfo("Nature's Lore", 75, Rarity.COMMON, mage.cards.n.NaturesLore.class)); - cards.add(new SetCardInfo("Nightstalker Engine", 21, Rarity.RARE, mage.cards.n.NightstalkerEngine.class)); - cards.add(new SetCardInfo("Norwood Archers", 76, Rarity.COMMON, mage.cards.n.NorwoodArchers.class)); - cards.add(new SetCardInfo("Norwood Priestess", 77, Rarity.RARE, mage.cards.n.NorwoodPriestess.class)); - cards.add(new SetCardInfo("Norwood Ranger", 78, Rarity.COMMON, mage.cards.n.NorwoodRanger.class)); - cards.add(new SetCardInfo("Norwood Riders", 79, Rarity.COMMON, mage.cards.n.NorwoodRiders.class)); - cards.add(new SetCardInfo("Norwood Warrior", 80, Rarity.COMMON, mage.cards.n.NorwoodWarrior.class)); + cards.add(new SetCardInfo("Natural Spring", 134, Rarity.COMMON, mage.cards.n.NaturalSpring.class)); + cards.add(new SetCardInfo("Nature's Lore", 135, Rarity.COMMON, mage.cards.n.NaturesLore.class)); + cards.add(new SetCardInfo("Nightstalker Engine", 81, Rarity.RARE, mage.cards.n.NightstalkerEngine.class)); + cards.add(new SetCardInfo("Norwood Archers", 136, Rarity.COMMON, mage.cards.n.NorwoodArchers.class)); + cards.add(new SetCardInfo("Norwood Priestess", 137, Rarity.RARE, mage.cards.n.NorwoodPriestess.class)); + cards.add(new SetCardInfo("Norwood Ranger", 138, Rarity.COMMON, mage.cards.n.NorwoodRanger.class)); + cards.add(new SetCardInfo("Norwood Riders", 139, Rarity.COMMON, mage.cards.n.NorwoodRiders.class)); + cards.add(new SetCardInfo("Norwood Warrior", 140, Rarity.COMMON, mage.cards.n.NorwoodWarrior.class)); cards.add(new SetCardInfo("Obsidian Giant", 109, Rarity.UNCOMMON, mage.cards.o.ObsidianGiant.class)); cards.add(new SetCardInfo("Ogre Arsonist", 110, Rarity.UNCOMMON, mage.cards.o.OgreArsonist.class)); cards.add(new SetCardInfo("Ogre Berserker", 111, Rarity.COMMON, mage.cards.o.OgreBerserker.class)); cards.add(new SetCardInfo("Ogre Taskmaster", 112, Rarity.UNCOMMON, mage.cards.o.OgreTaskmaster.class)); cards.add(new SetCardInfo("Ogre Warrior", 113, Rarity.COMMON, mage.cards.o.OgreWarrior.class)); - cards.add(new SetCardInfo("Path of Peace", 138, Rarity.COMMON, mage.cards.p.PathOfPeace.class)); - cards.add(new SetCardInfo("Plains", 160, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 161, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 162, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plated Wurm", 81, Rarity.COMMON, mage.cards.p.PlatedWurm.class)); - cards.add(new SetCardInfo("Predatory Nightstalker", 22, Rarity.UNCOMMON, mage.cards.p.PredatoryNightstalker.class)); - cards.add(new SetCardInfo("Prowling Nightstalker", 23, Rarity.COMMON, mage.cards.p.ProwlingNightstalker.class)); + cards.add(new SetCardInfo("Path of Peace", 18, Rarity.COMMON, mage.cards.p.PathOfPeace.class)); + cards.add(new SetCardInfo("Plains", 151, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 152, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 153, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plated Wurm", 141, Rarity.COMMON, mage.cards.p.PlatedWurm.class)); + cards.add(new SetCardInfo("Predatory Nightstalker", 82, Rarity.UNCOMMON, mage.cards.p.PredatoryNightstalker.class)); + cards.add(new SetCardInfo("Prowling Nightstalker", 83, Rarity.COMMON, mage.cards.p.ProwlingNightstalker.class)); cards.add(new SetCardInfo("Raging Goblin", 114, Rarity.COMMON, mage.cards.r.RagingGoblin.class)); - cards.add(new SetCardInfo("Raiding Nightstalker", 24, Rarity.COMMON, mage.cards.r.RaidingNightstalker.class)); - cards.add(new SetCardInfo("Rain of Daggers", 25, Rarity.RARE, mage.cards.r.RainOfDaggers.class)); - cards.add(new SetCardInfo("Raise Dead", 26, Rarity.COMMON, mage.cards.r.RaiseDead.class)); - cards.add(new SetCardInfo("Rally the Troops", 139, Rarity.UNCOMMON, mage.cards.r.RallyTheTroops.class)); - cards.add(new SetCardInfo("Ravenous Rats", 27, Rarity.COMMON, mage.cards.r.RavenousRats.class)); - cards.add(new SetCardInfo("Razorclaw Bear", 82, Rarity.RARE, mage.cards.r.RazorclawBear.class)); + cards.add(new SetCardInfo("Raiding Nightstalker", 84, Rarity.COMMON, mage.cards.r.RaidingNightstalker.class)); + cards.add(new SetCardInfo("Rain of Daggers", 85, Rarity.RARE, mage.cards.r.RainOfDaggers.class)); + cards.add(new SetCardInfo("Raise Dead", 86, Rarity.COMMON, mage.cards.r.RaiseDead.class)); + cards.add(new SetCardInfo("Rally the Troops", 19, Rarity.UNCOMMON, mage.cards.r.RallyTheTroops.class)); + cards.add(new SetCardInfo("Ravenous Rats", 87, Rarity.COMMON, mage.cards.r.RavenousRats.class)); + cards.add(new SetCardInfo("Razorclaw Bear", 142, Rarity.RARE, mage.cards.r.RazorclawBear.class)); cards.add(new SetCardInfo("Relentless Assault", 115, Rarity.RARE, mage.cards.r.RelentlessAssault.class)); cards.add(new SetCardInfo("Remove", 43, Rarity.UNCOMMON, mage.cards.r.Remove.class)); - cards.add(new SetCardInfo("Renewing Touch", 83, Rarity.UNCOMMON, mage.cards.r.RenewingTouch.class)); - cards.add(new SetCardInfo("Return of the Nightstalkers", 28, Rarity.RARE, mage.cards.r.ReturnOfTheNightstalkers.class)); - cards.add(new SetCardInfo("Righteous Charge", 140, Rarity.COMMON, mage.cards.r.RighteousCharge.class)); - cards.add(new SetCardInfo("Righteous Fury", 141, Rarity.RARE, mage.cards.r.RighteousFury.class)); - cards.add(new SetCardInfo("River Bear", 84, Rarity.UNCOMMON, mage.cards.r.RiverBear.class)); - cards.add(new SetCardInfo("Salvage", 85, Rarity.COMMON, mage.cards.s.Salvage.class)); + cards.add(new SetCardInfo("Renewing Touch", 143, Rarity.UNCOMMON, mage.cards.r.RenewingTouch.class)); + cards.add(new SetCardInfo("Return of the Nightstalkers", 88, Rarity.RARE, mage.cards.r.ReturnOfTheNightstalkers.class)); + cards.add(new SetCardInfo("Righteous Charge", 20, Rarity.COMMON, mage.cards.r.RighteousCharge.class)); + cards.add(new SetCardInfo("Righteous Fury", 21, Rarity.RARE, mage.cards.r.RighteousFury.class)); + cards.add(new SetCardInfo("River Bear", 144, Rarity.UNCOMMON, mage.cards.r.RiverBear.class)); + cards.add(new SetCardInfo("Salvage", 145, Rarity.COMMON, mage.cards.s.Salvage.class)); cards.add(new SetCardInfo("Screeching Drake", 44, Rarity.COMMON, mage.cards.s.ScreechingDrake.class)); cards.add(new SetCardInfo("Sea Drake", 45, Rarity.UNCOMMON, mage.cards.s.SeaDrake.class)); cards.add(new SetCardInfo("Sleight of Hand", 46, Rarity.COMMON, mage.cards.s.SleightOfHand.class)); cards.add(new SetCardInfo("Spitting Earth", 116, Rarity.COMMON, mage.cards.s.SpittingEarth.class)); - cards.add(new SetCardInfo("Steam Catapult", 142, Rarity.RARE, mage.cards.s.SteamCatapult.class)); + cards.add(new SetCardInfo("Steam Catapult", 22, Rarity.RARE, mage.cards.s.SteamCatapult.class)); cards.add(new SetCardInfo("Steam Frigate", 47, Rarity.COMMON, mage.cards.s.SteamFrigate.class)); cards.add(new SetCardInfo("Stone Rain", 117, Rarity.COMMON, mage.cards.s.StoneRain.class)); - cards.add(new SetCardInfo("Swamp", 163, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 164, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 165, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swarm of Rats", 29, Rarity.COMMON, mage.cards.s.SwarmOfRats.class)); - cards.add(new SetCardInfo("Sylvan Basilisk", 86, Rarity.RARE, mage.cards.s.SylvanBasilisk.class)); - cards.add(new SetCardInfo("Sylvan Yeti", 87, Rarity.RARE, mage.cards.s.SylvanYeti.class)); + cards.add(new SetCardInfo("Swamp", 157, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 158, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 159, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swarm of Rats", 89, Rarity.COMMON, mage.cards.s.SwarmOfRats.class)); + cards.add(new SetCardInfo("Sylvan Basilisk", 146, Rarity.RARE, mage.cards.s.SylvanBasilisk.class)); + cards.add(new SetCardInfo("Sylvan Yeti", 147, Rarity.RARE, mage.cards.s.SylvanYeti.class)); cards.add(new SetCardInfo("Talas Air Ship", 48, Rarity.COMMON, mage.cards.t.TalasAirShip.class)); cards.add(new SetCardInfo("Talas Explorer", 49, Rarity.COMMON, mage.cards.t.TalasExplorer.class)); cards.add(new SetCardInfo("Talas Merchant", 50, Rarity.COMMON, mage.cards.t.TalasMerchant.class)); cards.add(new SetCardInfo("Talas Researcher", 51, Rarity.RARE, mage.cards.t.TalasResearcher.class)); cards.add(new SetCardInfo("Talas Scout", 52, Rarity.COMMON, mage.cards.t.TalasScout.class)); cards.add(new SetCardInfo("Talas Warrior", 53, Rarity.RARE, mage.cards.t.TalasWarrior.class)); - cards.add(new SetCardInfo("Temple Acolyte", 143, Rarity.COMMON, mage.cards.t.TempleAcolyte.class)); - cards.add(new SetCardInfo("Temple Elder", 144, Rarity.UNCOMMON, mage.cards.t.TempleElder.class)); + cards.add(new SetCardInfo("Temple Acolyte", 23, Rarity.COMMON, mage.cards.t.TempleAcolyte.class)); + cards.add(new SetCardInfo("Temple Elder", 24, Rarity.UNCOMMON, mage.cards.t.TempleElder.class)); cards.add(new SetCardInfo("Temporal Manipulation", 54, Rarity.RARE, mage.cards.t.TemporalManipulation.class)); cards.add(new SetCardInfo("Theft of Dreams", 55, Rarity.UNCOMMON, mage.cards.t.TheftOfDreams.class)); cards.add(new SetCardInfo("Tidal Surge", 56, Rarity.COMMON, mage.cards.t.TidalSurge.class)); cards.add(new SetCardInfo("Time Ebb", 57, Rarity.COMMON, mage.cards.t.TimeEbb.class)); cards.add(new SetCardInfo("Touch of Brilliance", 58, Rarity.COMMON, mage.cards.t.TouchOfBrilliance.class)); - cards.add(new SetCardInfo("Town Sentry", 145, Rarity.COMMON, mage.cards.t.TownSentry.class)); - cards.add(new SetCardInfo("Tree Monkey", 88, Rarity.COMMON, mage.cards.t.TreeMonkey.class)); + cards.add(new SetCardInfo("Town Sentry", 25, Rarity.COMMON, mage.cards.t.TownSentry.class)); + cards.add(new SetCardInfo("Tree Monkey", 148, Rarity.COMMON, mage.cards.t.TreeMonkey.class)); cards.add(new SetCardInfo("Tremor", 118, Rarity.COMMON, mage.cards.t.Tremor.class)); - cards.add(new SetCardInfo("Trokin High Guard", 146, Rarity.COMMON, mage.cards.t.TrokinHighGuard.class)); + cards.add(new SetCardInfo("Trokin High Guard", 26, Rarity.COMMON, mage.cards.t.TrokinHighGuard.class)); cards.add(new SetCardInfo("Undo", 59, Rarity.UNCOMMON, mage.cards.u.Undo.class)); - cards.add(new SetCardInfo("Untamed Wilds", 89, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); - cards.add(new SetCardInfo("Vampiric Spirit", 30, Rarity.RARE, mage.cards.v.VampiricSpirit.class)); - cards.add(new SetCardInfo("Vengeance", 147, Rarity.UNCOMMON, mage.cards.v.Vengeance.class)); + cards.add(new SetCardInfo("Untamed Wilds", 149, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); + cards.add(new SetCardInfo("Vampiric Spirit", 90, Rarity.RARE, mage.cards.v.VampiricSpirit.class)); + cards.add(new SetCardInfo("Vengeance", 27, Rarity.UNCOMMON, mage.cards.v.Vengeance.class)); cards.add(new SetCardInfo("Volcanic Hammer", 119, Rarity.COMMON, mage.cards.v.VolcanicHammer.class)); - cards.add(new SetCardInfo("Volunteer Militia", 148, Rarity.COMMON, mage.cards.v.VolunteerMilitia.class)); - cards.add(new SetCardInfo("Warrior's Stand", 149, Rarity.UNCOMMON, mage.cards.w.WarriorsStand.class)); + cards.add(new SetCardInfo("Volunteer Militia", 28, Rarity.COMMON, mage.cards.v.VolunteerMilitia.class)); + cards.add(new SetCardInfo("Warrior's Stand", 29, Rarity.UNCOMMON, mage.cards.w.WarriorsStand.class)); + cards.add(new SetCardInfo("Wild Griffin", 30, Rarity.COMMON, mage.cards.w.WildGriffin.class)); + cards.add(new SetCardInfo("Wild Ox", 150, Rarity.UNCOMMON, mage.cards.w.WildOx.class)); cards.add(new SetCardInfo("Wildfire", 120, Rarity.RARE, mage.cards.w.Wildfire.class)); - cards.add(new SetCardInfo("Wild Griffin", 150, Rarity.COMMON, mage.cards.w.WildGriffin.class)); - cards.add(new SetCardInfo("Wild Ox", 90, Rarity.UNCOMMON, mage.cards.w.WildOx.class)); cards.add(new SetCardInfo("Wind Sail", 60, Rarity.COMMON, mage.cards.w.WindSail.class)); } } diff --git a/Mage.Sets/src/mage/sets/ScarsOfMirrodin.java b/Mage.Sets/src/mage/sets/ScarsOfMirrodin.java index 93cf471f043..0742778d39d 100644 --- a/Mage.Sets/src/mage/sets/ScarsOfMirrodin.java +++ b/Mage.Sets/src/mage/sets/ScarsOfMirrodin.java @@ -244,7 +244,7 @@ public final class ScarsOfMirrodin extends ExpansionSet { cards.add(new SetCardInfo("Tel-Jilad Defiance", 129, Rarity.COMMON, mage.cards.t.TelJiladDefiance.class)); cards.add(new SetCardInfo("Tel-Jilad Fallen", 130, Rarity.COMMON, mage.cards.t.TelJiladFallen.class)); cards.add(new SetCardInfo("Tempered Steel", 24, Rarity.RARE, mage.cards.t.TemperedSteel.class)); - cards.add(new SetCardInfo("Throne of Geth", 211, Rarity.UNCOMMON, mage.cards.t.ThroneofGeth.class)); + cards.add(new SetCardInfo("Throne of Geth", 211, Rarity.UNCOMMON, mage.cards.t.ThroneOfGeth.class)); cards.add(new SetCardInfo("Thrummingbird", 47, Rarity.UNCOMMON, mage.cards.t.Thrummingbird.class)); cards.add(new SetCardInfo("Tower of Calamities", 212, Rarity.RARE, mage.cards.t.TowerOfCalamities.class)); cards.add(new SetCardInfo("Trigon of Corruption", 213, Rarity.UNCOMMON, mage.cards.t.TrigonOfCorruption.class)); diff --git a/Mage.Sets/src/mage/sets/TimeSpiral.java b/Mage.Sets/src/mage/sets/TimeSpiral.java index dd82083812d..be584c20ac9 100644 --- a/Mage.Sets/src/mage/sets/TimeSpiral.java +++ b/Mage.Sets/src/mage/sets/TimeSpiral.java @@ -26,6 +26,7 @@ public final class TimeSpiral extends ExpansionSet { this.numBoosterRare = 1; this.ratioBoosterMythic = 0; cards.add(new SetCardInfo("Academy Ruins", 269, Rarity.RARE, mage.cards.a.AcademyRuins.class)); + cards.add(new SetCardInfo("Aetherflame Wall", 142, Rarity.COMMON, mage.cards.a.AetherflameWall.class)); cards.add(new SetCardInfo("Amrou Scout", 1, Rarity.COMMON, mage.cards.a.AmrouScout.class)); cards.add(new SetCardInfo("Amrou Seekers", 2, Rarity.COMMON, mage.cards.a.AmrouSeekers.class)); cards.add(new SetCardInfo("Ancestral Vision", 48, Rarity.RARE, mage.cards.a.AncestralVision.class)); @@ -293,6 +294,7 @@ public final class TimeSpiral extends ExpansionSet { cards.add(new SetCardInfo("Trickbind", 88, Rarity.RARE, mage.cards.t.Trickbind.class)); cards.add(new SetCardInfo("Triskelavus", 266, Rarity.RARE, mage.cards.t.Triskelavus.class)); cards.add(new SetCardInfo("Tromp the Domains", 230, Rarity.UNCOMMON, mage.cards.t.TrompTheDomains.class)); + cards.add(new SetCardInfo("Truth or Tale", 89, Rarity.UNCOMMON, mage.cards.t.TruthOrTale.class)); cards.add(new SetCardInfo("Two-Headed Sliver", 183, Rarity.COMMON, mage.cards.t.TwoHeadedSliver.class)); cards.add(new SetCardInfo("Undying Rage", 184, Rarity.UNCOMMON, mage.cards.u.UndyingRage.class)); cards.add(new SetCardInfo("Unyaro Bees", 231, Rarity.RARE, mage.cards.u.UnyaroBees.class)); diff --git a/Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java b/Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java index c73f2796052..da2fe23c4bf 100644 --- a/Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java +++ b/Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java @@ -67,6 +67,7 @@ public final class TimeSpiralTimeshifted extends ExpansionSet { cards.add(new SetCardInfo("Gaea's Liege", 78, Rarity.SPECIAL, mage.cards.g.GaeasLiege.class)); cards.add(new SetCardInfo("Gemstone Mine", 119, Rarity.RARE, mage.cards.g.GemstoneMine.class)); cards.add(new SetCardInfo("Ghost Ship", 21, Rarity.SPECIAL, mage.cards.g.GhostShip.class)); + cards.add(new SetCardInfo("Giant Oyster", 22, Rarity.SPECIAL, mage.cards.g.GiantOyster.class)); cards.add(new SetCardInfo("Goblin Snowman", 64, Rarity.UNCOMMON, mage.cards.g.GoblinSnowman.class)); cards.add(new SetCardInfo("Grinning Totem", 110, Rarity.SPECIAL, mage.cards.g.GrinningTotem.class)); cards.add(new SetCardInfo("Hail Storm", 79, Rarity.SPECIAL, mage.cards.h.HailStorm.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java index 446b670ccbd..ac8367bab6c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java @@ -1,9 +1,9 @@ - package org.mage.test.cards.mana; import mage.abilities.keyword.FlyingAbility; import mage.constants.PhaseStep; import mage.constants.Zone; +import org.junit.Ignore; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -48,6 +48,7 @@ public class ConditionalManaTest extends CardTestPlayerBase { } @Test + @Ignore public void testWorkingWithReflectingPool() { addCard(Zone.BATTLEFIELD, playerA, "Cavern of Souls", 1); // can give {C] or {any} mana ({any} with restrictions) addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1); // must give {C} or {any} mana from the Cavern, but without restrictions diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java index a5c43cb548d..95cbd92c19c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/HarvesterDruidTest.java @@ -1,10 +1,10 @@ - package org.mage.test.cards.mana; import mage.abilities.mana.ManaOptions; import mage.constants.PhaseStep; import mage.constants.Zone; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; import static org.mage.test.utils.ManaOptionsTestUtils.*; @@ -16,6 +16,7 @@ import static org.mage.test.utils.ManaOptionsTestUtils.*; public class HarvesterDruidTest extends CardTestPlayerBase { @Test + @Ignore public void testOneInstance() { addCard(Zone.BATTLEFIELD, playerA, "Island", 1); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); @@ -34,6 +35,7 @@ public class HarvesterDruidTest extends CardTestPlayerBase { } @Test + @Ignore public void testTwoInstances() { addCard(Zone.BATTLEFIELD, playerA, "Island", 1); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java index f384df1e5d5..5ba92659ea8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ReflectingPoolTest.java @@ -1,4 +1,3 @@ - package org.mage.test.cards.mana; import mage.abilities.mana.ManaOptions; @@ -6,6 +5,7 @@ import mage.constants.ManaType; import mage.constants.PhaseStep; import mage.constants.Zone; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -133,6 +133,7 @@ public class ReflectingPoolTest extends CardTestPlayerBase { * producing mana */ @Test + @Ignore public void testWithDifferentLands() { addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); @@ -161,7 +162,6 @@ public class ReflectingPoolTest extends CardTestPlayerBase { assertManaOptions("{W}{W}", options); } - @Test public void testReflectingPoolGiveNonMana() { addCard(Zone.HAND, playerA, bear1, 1); @@ -215,6 +215,7 @@ public class ReflectingPoolTest extends CardTestPlayerBase { } @Test + @Ignore public void testReflectingPoolAnyManaNeedWithoutCondition() { // any mana source without conditions (use any mana at any time) addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); @@ -232,6 +233,7 @@ public class ReflectingPoolTest extends CardTestPlayerBase { } @Test + @Ignore public void testReflectingPoolAnyManaNeedWithCondition() { // any mana source have condition to use (Reflecting Pool must ignore that condition) addCard(Zone.BATTLEFIELD, playerA, "Cavern of Souls", 1); // {C} or {any} @@ -256,7 +258,7 @@ public class ReflectingPoolTest extends CardTestPlayerBase { activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add one mana of any"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {W}"); - setChoice(playerA,"Black"); + setChoice(playerA, "Black"); setStopAt(1, PhaseStep.PRECOMBAT_MAIN); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/SylvokExplorerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/SylvokExplorerTest.java index 68a88a788bd..7351eba115b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/SylvokExplorerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/SylvokExplorerTest.java @@ -1,10 +1,10 @@ - package org.mage.test.cards.mana; import mage.abilities.mana.ManaOptions; import mage.constants.PhaseStep; import mage.constants.Zone; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -32,6 +32,7 @@ public class SylvokExplorerTest extends CardTestPlayerBase { * mage.abilities.mana.AnyColorLandsProduceManaEffect.getNetMana(AnyColorLandsProduceManaAbility.java:181) */ @Test + @Ignore public void testOneInstance() { addCard(Zone.BATTLEFIELD, playerB, "Island", 1); addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/VorinclexVoiceOfHungerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/VorinclexVoiceOfHungerTest.java index d6ec862b443..8a225060589 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/VorinclexVoiceOfHungerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/VorinclexVoiceOfHungerTest.java @@ -4,6 +4,7 @@ import mage.constants.ManaType; import mage.constants.PhaseStep; import mage.constants.Zone; import mage.counters.CounterType; +import org.junit.Ignore; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -90,6 +91,7 @@ public class VorinclexVoiceOfHungerTest extends CardTestPlayerBase { } @Test + @Ignore public void testCastWithGemstoneCavern() { // Trample // Whenever you tap a land for mana, add one mana of any type that land produced. diff --git a/Mage.Tests/src/test/java/org/mage/test/game/ends/PhageTheUntouchableTest.java b/Mage.Tests/src/test/java/org/mage/test/game/ends/PhageTheUntouchableTest.java index b068f3030dc..8679e5c112d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/game/ends/PhageTheUntouchableTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/game/ends/PhageTheUntouchableTest.java @@ -44,7 +44,7 @@ public class PhageTheUntouchableTest extends CardTestPlayerBase { Assert.assertTrue("Game has ended.", currentGame.hasEnded()); Assert.assertTrue("Player A has won.", playerA.hasWon()); - Assert.assertTrue("Game ist At end phase", currentGame.getPhase().getType().equals(TurnPhase.END)); + Assert.assertTrue("Game ist At end phase", currentGame.getPhase().getType() == TurnPhase.END); } diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index e39ab59a368..bf2a95d8702 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -985,7 +985,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement int actualCount = 0; for (ExileZone exile : currentGame.getExile().getExileZones()) { for (Card card : exile.getCards(currentGame)) { - if (card.getOwnerId().equals(owner.getId())) { + if (card.isOwnedBy(owner.getId())) { actualCount++; } } @@ -1005,7 +1005,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement int actualCount = 0; for (ExileZone exile : currentGame.getExile().getExileZones()) { for (Card card : exile.getCards(currentGame)) { - if (card.getOwnerId().equals(owner.getId()) && card.getName().equals(cardName)) { + if (card.isOwnedBy(owner.getId()) && card.getName().equals(cardName)) { actualCount++; } } diff --git a/Mage.Tests/src/test/java/org/mage/test/sets/BoosterGenerationTest.java b/Mage.Tests/src/test/java/org/mage/test/sets/BoosterGenerationTest.java index 9511ab69d23..b6da9a2d9e5 100644 --- a/Mage.Tests/src/test/java/org/mage/test/sets/BoosterGenerationTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/sets/BoosterGenerationTest.java @@ -7,6 +7,9 @@ import java.util.List; import mage.cards.Card; import mage.cards.repository.CardInfo; import mage.cards.repository.CardScanner; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.sets.CoreSet2019; import mage.sets.FateReforged; import mage.sets.MastersEditionII; import mage.sets.MastersEditionIV; @@ -99,6 +102,19 @@ public class BoosterGenerationTest extends MageTestBase { } } + @Test + public void testCoreSet2019_DualLandsAreGenerated() { + List allCards = new ArrayList<>(); + for (int i = 0; i < 50; i++) { + List booster = CoreSet2019.getInstance().createBooster(); + // check that booster contains a land card + assertTrue(booster.stream().anyMatch(card -> card.getCardType().contains(CardType.LAND))); + allCards.addAll(booster); + } + // check that some dual lands were generated + assertTrue(allCards.stream().anyMatch(card -> card.getCardType().contains(CardType.LAND) && card.getRarity().equals(Rarity.COMMON))); + } + private static String str(List cards) { StringBuilder sb = new StringBuilder("["); Iterator iterator = cards.iterator(); diff --git a/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java b/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java index b72003e40f6..e7d2c5e9461 100644 --- a/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/utils/ManaOptionsTest.java @@ -454,4 +454,103 @@ public class ManaOptionsTest extends CardTestPlayerBase { Assert.assertEquals("mana variations don't fit", 1, manaOptions.size()); assertManaOptions("{C}{C}", manaOptions); } + + @Test + public void testManaSourcesWithCosts() { + // {T}: Add {C} to your mana pool. + // {5}, {T}: Add {W}{U}{B}{R}{G} to your mana pool. + addCard(Zone.BATTLEFIELD, playerA, "Crystal Quarry", 1); + + // {T}: Add {C} to your mana pool. + // {W/B}, {T}: Add {W}{W}, {W}{B}, or {B}{B} to your mana pool. + addCard(Zone.BATTLEFIELD, playerA, "Fetid Heath", 3); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 3); + + setStopAt(1, PhaseStep.UPKEEP); + execute(); + + ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); + assertDuplicatedManaOptions(manaOptions); + + Assert.assertEquals("mana variations don't fit", 16, manaOptions.size()); + assertManaOptions("{C}{C}{C}{C}{W}{W}{W}", manaOptions); + assertManaOptions("{C}{C}{C}{W}{W}{W}{W}", manaOptions); + assertManaOptions("{C}{C}{C}{W}{W}{W}{B}", manaOptions); + assertManaOptions("{C}{C}{C}{W}{W}{B}{B}", manaOptions); + assertManaOptions("{C}{C}{W}{W}{W}{W}{W}", manaOptions); + assertManaOptions("{C}{C}{W}{W}{W}{W}{B}", manaOptions); + assertManaOptions("{C}{C}{W}{W}{W}{B}{B}", manaOptions); + assertManaOptions("{C}{C}{W}{W}{B}{B}{B}", manaOptions); + assertManaOptions("{C}{C}{W}{B}{B}{B}{B}", manaOptions); + assertManaOptions("{C}{W}{W}{W}{W}{W}{W}", manaOptions); + assertManaOptions("{C}{W}{W}{W}{W}{W}{B}", manaOptions); + assertManaOptions("{C}{W}{W}{W}{W}{B}{B}", manaOptions); + assertManaOptions("{C}{W}{W}{W}{B}{B}{B}", manaOptions); + assertManaOptions("{C}{W}{W}{B}{B}{B}{B}", manaOptions); + assertManaOptions("{C}{W}{B}{B}{B}{B}{B}", manaOptions); + assertManaOptions("{C}{B}{B}{B}{B}{B}{B}", manaOptions); + } + + @Test + public void testSungrassPrairie() { + // {1}, {T}: Add {G}{W}. + addCard(Zone.BATTLEFIELD, playerA, "Sungrass Prairie", 1); + // {T}: Add one mana of any color to your mana pool. + addCard(Zone.BATTLEFIELD, playerA, "Alloy Myr", 2); + + setStopAt(3, PhaseStep.PRECOMBAT_MAIN); + execute(); + + ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); + assertDuplicatedManaOptions(manaOptions); + + Assert.assertEquals("mana variations don't fit", 2, manaOptions.size()); + + assertManaOptions("{W}{G}{Any}", manaOptions); + assertManaOptions("{Any}{Any}", manaOptions); + } + + @Test + public void testSungrassPrairie2() { + // {1}, {T}: Add {G}{W}. + addCard(Zone.BATTLEFIELD, playerA, "Sungrass Prairie", 5); + // ({T}: Add {U} or {W} to your mana pool.) + addCard(Zone.BATTLEFIELD, playerA, "Tundra", 9); + // ({T}: Add {G} or {U} to your mana pool.) + addCard(Zone.BATTLEFIELD, playerA, "Tropical Island", 3); + + setStopAt(3, PhaseStep.PRECOMBAT_MAIN); + execute(); + + ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); + assertDuplicatedManaOptions(manaOptions); + + Assert.assertEquals("mana variations don't fit", 88, manaOptions.size()); + + assertManaOptions("{W}{W}{W}{W}{W}{W}{W}{W}{W}{G}{G}{G}{G}{G}{G}{G}{G}", manaOptions); + assertManaOptions("{W}{W}{W}{W}{W}{W}{W}{W}{U}{G}{G}{G}{G}{G}{G}{G}{G}", manaOptions); + } + + @Test + public void testSungrassPrairie3() { + // {1}, {T}: Add {G}{W}. + addCard(Zone.BATTLEFIELD, playerA, "Sungrass Prairie", 1); + // ({T}: Add {U} or {W} to your mana pool.) + addCard(Zone.BATTLEFIELD, playerA, "Tundra", 1); + // ({T}: Add {G} or {U} to your mana pool.) + addCard(Zone.BATTLEFIELD, playerA, "Tropical Island", 1); + + setStopAt(3, PhaseStep.PRECOMBAT_MAIN); + execute(); + + ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); + assertDuplicatedManaOptions(manaOptions); + + Assert.assertEquals("mana variations don't fit", 4, manaOptions.size()); + assertManaOptions("{U}{U}", manaOptions); + assertManaOptions("{W}{G}{G}", manaOptions); + assertManaOptions("{W}{U}{G}", manaOptions); + assertManaOptions("{W}{W}{G}", manaOptions); + } + } diff --git a/Mage/src/main/java/mage/MageObjectReference.java b/Mage/src/main/java/mage/MageObjectReference.java index c9e67326439..ff72668e405 100644 --- a/Mage/src/main/java/mage/MageObjectReference.java +++ b/Mage/src/main/java/mage/MageObjectReference.java @@ -1,4 +1,3 @@ - package mage; import java.io.Serializable; @@ -24,6 +23,11 @@ public class MageObjectReference implements Comparable, Ser private final int zoneChangeCounter; public MageObjectReference(MageObject mageObject, Game game) { + if (mageObject == null) { + this.sourceId = null; + this.zoneChangeCounter = -1; + return; + } this.sourceId = mageObject.getId(); this.zoneChangeCounter = mageObject.getZoneChangeCounter(game); } diff --git a/Mage/src/main/java/mage/Mana.java b/Mage/src/main/java/mage/Mana.java index 1788fd264e4..f6a594292fb 100644 --- a/Mage/src/main/java/mage/Mana.java +++ b/Mage/src/main/java/mage/Mana.java @@ -1051,7 +1051,8 @@ public class Mana implements Comparable, Serializable, Copyable { /** * Returns if this {@link Mana} object has more than or equal values of mana - * as the passed in {@link Mana} object. + * as the passed in {@link Mana} object. Ignores {Any} mana to prevent + * endless iterations. * * @param mana the mana to compare with * @return if this object has more than or equal mana to the passed in @@ -1090,13 +1091,44 @@ public class Mana implements Comparable, Serializable, Copyable { moreMana = mana1; lessMana = mana2; } - if (lessMana.getWhite() > moreMana.getWhite() - || lessMana.getRed() > moreMana.getRed() - || lessMana.getGreen() > moreMana.getGreen() - || lessMana.getBlue() > moreMana.getBlue() - || lessMana.getBlack() > moreMana.getBlack() - || lessMana.getColorless() > moreMana.getColorless() - || lessMana.getAny() > moreMana.getAny()) { + int anyDiff = mana2.getAny() - mana1.getAny(); + if (lessMana.getWhite() > moreMana.getWhite()) { + anyDiff -= lessMana.getWhite() - moreMana.getWhite(); + if (anyDiff < 0) { + return null; + } + } + if (lessMana.getRed() > moreMana.getRed()) { + anyDiff -= lessMana.getRed() - moreMana.getRed(); + if (anyDiff < 0) { + return null; + } + } + if (lessMana.getGreen() > moreMana.getGreen()) { + anyDiff -= lessMana.getGreen() - moreMana.getGreen(); + if (anyDiff < 0) { + return null; + } + } + if (lessMana.getBlue() > moreMana.getBlue()) { + anyDiff -= lessMana.getBlue() - moreMana.getBlue(); + if (anyDiff < 0) { + return null; + } + } + if (lessMana.getBlack() > moreMana.getBlack()) { + anyDiff -= lessMana.getBlack() - moreMana.getBlack(); + if (anyDiff < 0) { + return null; + } + } + if (lessMana.getColorless() > moreMana.getColorless()) { + anyDiff -= lessMana.getColorless() - moreMana.getColorless(); + if (anyDiff < 0) { + return null; + } + } + if (lessMana.getAny() > moreMana.getAny()) { return null; } return moreMana; diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index 4f63e57609a..800b1242a3c 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -910,7 +910,7 @@ public abstract class AbilityImpl implements Ability { } MageObject object = game.getObject(this.getSourceId()); // emblem/planes are always actual - if (object != null && (object instanceof Emblem || object instanceof Plane)) { + if (object instanceof Emblem || object instanceof Plane) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java index aaf3ece4068..6b48461d8f7 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java @@ -178,7 +178,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa break; case OWNER: Permanent permanent = game.getPermanent(getSourceId()); - if (!permanent.getOwnerId().equals(playerId)) { + if (!permanent.isOwnedBy(playerId)) { return ActivationStatus.getFalse(); } break; @@ -191,7 +191,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa Permanent enchantment = game.getPermanent(getSourceId()); if (enchantment != null && enchantment.getAttachedTo() != null) { Permanent enchanted = game.getPermanent(enchantment.getAttachedTo()); - if (enchanted != null && enchanted.getControllerId().equals(playerId)) { + if (enchanted != null && enchanted.isControlledBy(playerId)) { break; } } @@ -223,7 +223,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa } else if (mageObject instanceof Plane) { return ((Plane) mageObject).getControllerId().equals(playerId); } else if (game.getState().getZone(this.sourceId) != Zone.BATTLEFIELD) { - return ((Card) mageObject).getOwnerId().equals(playerId); + return ((Card) mageObject).isOwnedBy(playerId); } } return false; diff --git a/Mage/src/main/java/mage/abilities/PlayLandAbility.java b/Mage/src/main/java/mage/abilities/PlayLandAbility.java index 928882f8229..939f28e328e 100644 --- a/Mage/src/main/java/mage/abilities/PlayLandAbility.java +++ b/Mage/src/main/java/mage/abilities/PlayLandAbility.java @@ -31,7 +31,7 @@ public class PlayLandAbility extends ActivatedAbilityImpl { return ActivationStatus.getFalse(); } //20091005 - 114.2a - return new ActivationStatus(game.getActivePlayerId().equals(playerId) && game.getPlayer(playerId).canPlayLand() && game.canPlaySorcery(playerId), permittingObject); + return new ActivationStatus(game.isActivePlayer(playerId) && game.getPlayer(playerId).canPlayLand() && game.canPlaySorcery(playerId), permittingObject); } @Override diff --git a/Mage/src/main/java/mage/abilities/SpecialActions.java b/Mage/src/main/java/mage/abilities/SpecialActions.java index 716acff4d18..ed2da19d372 100644 --- a/Mage/src/main/java/mage/abilities/SpecialActions.java +++ b/Mage/src/main/java/mage/abilities/SpecialActions.java @@ -27,7 +27,7 @@ public class SpecialActions extends AbilitiesImpl { public LinkedHashMap getControlledBy(UUID controllerId, boolean manaAction) { LinkedHashMap controlledBy = new LinkedHashMap<>(); for (SpecialAction action: this) { - if (action.getControllerId().equals(controllerId) && action.isManaAction() == manaAction) { + if (action.isControlledBy(controllerId) && action.isManaAction() == manaAction) { controlledBy.put(action.id, action); } } diff --git a/Mage/src/main/java/mage/abilities/SpellAbility.java b/Mage/src/main/java/mage/abilities/SpellAbility.java index d6e29580d61..04e9d0cbc77 100644 --- a/Mage/src/main/java/mage/abilities/SpellAbility.java +++ b/Mage/src/main/java/mage/abilities/SpellAbility.java @@ -76,7 +76,7 @@ public class SpellAbility extends ActivatedAbilityImpl { MageObjectReference permittingSource = game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, playerId, game); if (permittingSource == null) { Card card = game.getCard(sourceId); - if (!(card != null && card.getOwnerId().equals(playerId))) { + if (!(card != null && card.isOwnedBy(playerId))) { return ActivationStatus.getFalse(); } } diff --git a/Mage/src/main/java/mage/abilities/common/AllyEntersBattlefieldTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AllyEntersBattlefieldTriggeredAbility.java index 7ef05216fdc..85716ef8017 100644 --- a/Mage/src/main/java/mage/abilities/common/AllyEntersBattlefieldTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AllyEntersBattlefieldTriggeredAbility.java @@ -31,7 +31,7 @@ public class AllyEntersBattlefieldTriggeredAbility extends TriggeredAbilityImpl @Override public boolean checkTrigger(GameEvent event, Game game) { EntersTheBattlefieldEvent ebe = (EntersTheBattlefieldEvent) event; - return ebe.getTarget().getControllerId().equals(this.controllerId) + return ebe.getTarget().isControlledBy(this.controllerId) && (event.getTargetId().equals(this.getSourceId()) || (ebe.getTarget().hasSubtype(SubType.ALLY, game) && !event.getTargetId().equals(this.getSourceId()))); } diff --git a/Mage/src/main/java/mage/abilities/common/AttackedByCreatureTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AttackedByCreatureTriggeredAbility.java index d0272977943..89c0741a67b 100644 --- a/Mage/src/main/java/mage/abilities/common/AttackedByCreatureTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AttackedByCreatureTriggeredAbility.java @@ -60,7 +60,7 @@ public class AttackedByCreatureTriggeredAbility extends TriggeredAbilityImpl { UUID defendingPlayer = game.getCombat().getDefendingPlayerId(event.getSourceId(), game); Permanent attackingCreature = game.getPermanent(event.getSourceId()); if (filter.match(attackingCreature, game) - && getControllerId().equals(defendingPlayer) + && isControlledBy(defendingPlayer) && attackingCreature != null) { switch (setTargetPointer) { case PERMANENT: diff --git a/Mage/src/main/java/mage/abilities/common/AttacksAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AttacksAllTriggeredAbility.java index 14e601238f3..3b47bc1c16f 100644 --- a/Mage/src/main/java/mage/abilities/common/AttacksAllTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AttacksAllTriggeredAbility.java @@ -67,7 +67,7 @@ public class AttacksAllTriggeredAbility extends TriggeredAbilityImpl { check = true; } else { Permanent planeswalker = game.getPermanent(event.getTargetId()); - if (planeswalker != null && planeswalker.isPlaneswalker() && planeswalker.getControllerId().equals(getControllerId())) { + if (planeswalker != null && planeswalker.isPlaneswalker() && planeswalker.isControlledBy(getControllerId())) { check = true; } } diff --git a/Mage/src/main/java/mage/abilities/common/AttacksAloneTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AttacksAloneTriggeredAbility.java index b8e819da4b8..f88cf4762ea 100644 --- a/Mage/src/main/java/mage/abilities/common/AttacksAloneTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AttacksAloneTriggeredAbility.java @@ -37,7 +37,7 @@ public class AttacksAloneTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if(game.getActivePlayerId().equals(this.controllerId) ) { + if(game.isActivePlayer(this.controllerId) ) { UUID creatureId = this.getSourceId(); if(creatureId != null) { if(game.getCombat().attacksAlone() && Objects.equals(creatureId, game.getCombat().getAttackers().get(0))) { diff --git a/Mage/src/main/java/mage/abilities/common/BecomesMonstrousTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BecomesMonstrousTriggeredAbility.java index 41ddae73ad1..70eeed7514e 100644 --- a/Mage/src/main/java/mage/abilities/common/BecomesMonstrousTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/BecomesMonstrousTriggeredAbility.java @@ -41,7 +41,7 @@ public class BecomesMonstrousTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.isCreature() - && (permanent.getControllerId().equals(getControllerId()))) { + && (permanent.isControlledBy(getControllerId()))) { this.getEffects().setTargetPointer(new FixedTarget(permanent, game)); return true; } diff --git a/Mage/src/main/java/mage/abilities/common/BeginningOfDrawTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BeginningOfDrawTriggeredAbility.java index 04c2da9409f..bb91497e55a 100644 --- a/Mage/src/main/java/mage/abilities/common/BeginningOfDrawTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/BeginningOfDrawTriggeredAbility.java @@ -77,7 +77,7 @@ public class BeginningOfDrawTriggeredAbility extends TriggeredAbilityImpl { Permanent attachment = game.getPermanent(sourceId); if (attachment != null && attachment.getAttachedTo() != null) { Permanent attachedTo = game.getPermanent(attachment.getAttachedTo()); - if (attachedTo != null && attachedTo.getControllerId().equals(event.getPlayerId())) { + if (attachedTo != null && attachedTo.isControlledBy(event.getPlayerId())) { if (getTargets().isEmpty()) { this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId())); } diff --git a/Mage/src/main/java/mage/abilities/common/BeginningOfEndStepTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BeginningOfEndStepTriggeredAbility.java index 9b725a36538..abbebcf05e3 100644 --- a/Mage/src/main/java/mage/abilities/common/BeginningOfEndStepTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/BeginningOfEndStepTriggeredAbility.java @@ -79,7 +79,7 @@ public class BeginningOfEndStepTriggeredAbility extends TriggeredAbilityImpl { Permanent attachment = game.getPermanent(sourceId); if (attachment != null && attachment.getAttachedTo() != null) { Permanent attachedTo = game.getPermanent(attachment.getAttachedTo()); - if (attachedTo != null && attachedTo.getControllerId().equals(event.getPlayerId())) { + if (attachedTo != null && attachedTo.isControlledBy(event.getPlayerId())) { if (getTargets().isEmpty()) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getPlayerId())); diff --git a/Mage/src/main/java/mage/abilities/common/BeginningOfUpkeepTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BeginningOfUpkeepTriggeredAbility.java index ee91ec32cb4..49d7c0a70e3 100644 --- a/Mage/src/main/java/mage/abilities/common/BeginningOfUpkeepTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/BeginningOfUpkeepTriggeredAbility.java @@ -91,7 +91,7 @@ public class BeginningOfUpkeepTriggeredAbility extends TriggeredAbilityImpl { Permanent attachment = game.getPermanent(sourceId); if (attachment != null && attachment.getAttachedTo() != null) { Permanent attachedTo = game.getPermanent(attachment.getAttachedTo()); - if (attachedTo != null && attachedTo.getControllerId().equals(event.getPlayerId())) { + if (attachedTo != null && attachedTo.isControlledBy(event.getPlayerId())) { if (setTargetPointer && getTargets().isEmpty()) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getPlayerId())); diff --git a/Mage/src/main/java/mage/abilities/common/BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility.java new file mode 100644 index 00000000000..76bee0ed4e0 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility.java @@ -0,0 +1,92 @@ + +package mage.abilities.common; + +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.combat.CombatGroup; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * + * @author North, Loki + */ +public class BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility extends TriggeredAbilityImpl { + + protected FilterPermanent filter; + protected String rule; + + public BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(Effect effect, boolean optional) { + this(effect, StaticFilters.FILTER_PERMANENT_CREATURE, optional, null); + } + + public BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional) { + this(effect, filter, optional, null); + } + + public BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional, String rule) { + super(Zone.BATTLEFIELD, effect, optional); + this.filter = filter; + this.rule = rule; + } + + public BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(final BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility ability) { + super(ability); + this.filter = ability.filter; + this.rule = ability.rule; + + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARED_BLOCKERS; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + for (CombatGroup group : game.getCombat().getGroups()) { + if (group.getAttackers().contains(sourceId)){ + if (filter == null){ + return group.getBlocked(); + } + for (UUID uuid : group.getBlockers()){ + Permanent permanent = game.getPermanentOrLKIBattlefield(uuid); + if (permanent != null && filter.match(permanent, game)){ + return true; + } + } + } else if (group.getBlockers().contains(sourceId)){ + if (filter == null){ + return true; + } + for (UUID uuid : group.getAttackers()){ + Permanent permanent = game.getPermanentOrLKIBattlefield(uuid); + if (permanent != null && filter.match(permanent, game)){ + return true; + } + } + } + } + return false; + } + + @Override + public String getRule() { + if (rule != null) { + return rule; + } + return "Whenever {this} blocks or becomes blocked by one or more " + (filter != null ? filter.getMessage() : "creatures") + ", " + super.getRule(); + } + + @Override + public BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility copy() { + return new BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(this); + } +} diff --git a/Mage/src/main/java/mage/abilities/common/ControlledCreaturesDealCombatDamagePlayerTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/ControlledCreaturesDealCombatDamagePlayerTriggeredAbility.java index e16db409c8e..71c0d50bde7 100644 --- a/Mage/src/main/java/mage/abilities/common/ControlledCreaturesDealCombatDamagePlayerTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/ControlledCreaturesDealCombatDamagePlayerTriggeredAbility.java @@ -55,7 +55,7 @@ public class ControlledCreaturesDealCombatDamagePlayerTriggeredAbility extends T if (event.getType() == EventType.DAMAGED_PLAYER) { DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; Permanent p = game.getPermanent(event.getSourceId()); - if (damageEvent.isCombatDamage() && p != null && p.getControllerId().equals(this.getControllerId())) { + if (damageEvent.isCombatDamage() && p != null && p.isControlledBy(this.getControllerId())) { madeDamage = true; damagedPlayerIds.add(event.getPlayerId()); } diff --git a/Mage/src/main/java/mage/abilities/common/CreatureEntersBattlefieldTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/CreatureEntersBattlefieldTriggeredAbility.java index 19ee35058a9..ba3e9555d74 100644 --- a/Mage/src/main/java/mage/abilities/common/CreatureEntersBattlefieldTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/CreatureEntersBattlefieldTriggeredAbility.java @@ -94,7 +94,7 @@ public class CreatureEntersBattlefieldTriggeredAbility extends TriggeredAbilityI public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (filter.match(permanent, sourceId, controllerId, game) - && (permanent.getControllerId().equals(this.controllerId) ^ opponentController)) { + && (permanent.isControlledBy(this.controllerId) ^ opponentController)) { if (!this.getTargets().isEmpty()) { Target target = this.getTargets().get(0); if (target instanceof TargetPlayer) { diff --git a/Mage/src/main/java/mage/abilities/common/DealsDamageToACreatureAttachedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DealsDamageToACreatureAttachedTriggeredAbility.java index 5cf8d73b167..10a3024d065 100644 --- a/Mage/src/main/java/mage/abilities/common/DealsDamageToACreatureAttachedTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DealsDamageToACreatureAttachedTriggeredAbility.java @@ -48,8 +48,7 @@ public class DealsDamageToACreatureAttachedTriggeredAbility extends TriggeredAbi if (!combatOnly || ((DamagedCreatureEvent) event).isCombatDamage()) { Permanent attachment = game.getPermanent(this.getSourceId()); if (attachment != null - && attachment.getAttachedTo() != null - && event.getSourceId().equals(attachment.getAttachedTo())) { + && attachment.isAttachedTo(event.getSourceId())) { if (setTargetPointer) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getTargetId())); diff --git a/Mage/src/main/java/mage/abilities/common/DealsDamageToAPlayerAttachedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DealsDamageToAPlayerAttachedTriggeredAbility.java index d3ff537c9bb..9fdf532e9f7 100644 --- a/Mage/src/main/java/mage/abilities/common/DealsDamageToAPlayerAttachedTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DealsDamageToAPlayerAttachedTriggeredAbility.java @@ -67,7 +67,7 @@ public class DealsDamageToAPlayerAttachedTriggeredAbility extends TriggeredAbili } } if (targetController == TargetController.YOU) { - if (!this.getControllerId().equals(event.getPlayerId())) { + if (!this.isControlledBy(event.getPlayerId())) { return false; } } diff --git a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldControlledTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldControlledTriggeredAbility.java index 1b5434c9501..0d273a2c80e 100644 --- a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldControlledTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldControlledTriggeredAbility.java @@ -53,7 +53,7 @@ public class EntersBattlefieldControlledTriggeredAbility extends EntersBattlefie public boolean checkTrigger(GameEvent event, Game game) { if (super.checkTrigger(event, game)) { Permanent permanent = game.getPermanent(event.getTargetId()); - return permanent != null && permanent.getControllerId().equals(this.getControllerId()); + return permanent != null && permanent.isControlledBy(this.getControllerId()); } return false; } diff --git a/Mage/src/main/java/mage/abilities/common/ExertCreatureControllerTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/ExertCreatureControllerTriggeredAbility.java index ff91f35fb00..8598ec694ea 100644 --- a/Mage/src/main/java/mage/abilities/common/ExertCreatureControllerTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/ExertCreatureControllerTriggeredAbility.java @@ -27,7 +27,7 @@ public class ExertCreatureControllerTriggeredAbility extends TriggeredAbilityImp @Override public boolean checkTrigger(GameEvent event, Game game) { - boolean weAreExerting = getControllerId().equals(event.getPlayerId()); + boolean weAreExerting = isControlledBy(event.getPlayerId()); Permanent exerted = game.getPermanent(event.getTargetId()); boolean exertedIsCreature = (exerted != null) && exerted.isCreature(); return weAreExerting && exertedIsCreature; diff --git a/Mage/src/main/java/mage/abilities/common/LandfallAbility.java b/Mage/src/main/java/mage/abilities/common/LandfallAbility.java index e31252feb01..3718685a67a 100644 --- a/Mage/src/main/java/mage/abilities/common/LandfallAbility.java +++ b/Mage/src/main/java/mage/abilities/common/LandfallAbility.java @@ -48,7 +48,7 @@ public class LandfallAbility extends TriggeredAbilityImpl { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.isLand() - && permanent.getControllerId().equals(this.controllerId)) { + && permanent.isControlledBy(this.controllerId)) { triggeringLand = permanent; if (setTargetPointer == SetTargetPointer.PERMANENT) { for (Effect effect : getAllEffects()) { diff --git a/Mage/src/main/java/mage/abilities/common/PutIntoGraveFromBattlefieldAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/PutIntoGraveFromBattlefieldAllTriggeredAbility.java index a67372514e4..df73e1f2efa 100644 --- a/Mage/src/main/java/mage/abilities/common/PutIntoGraveFromBattlefieldAllTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/PutIntoGraveFromBattlefieldAllTriggeredAbility.java @@ -51,7 +51,7 @@ public class PutIntoGraveFromBattlefieldAllTriggeredAbility extends TriggeredAbi if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { if (filter.match(zEvent.getTarget(), this.getSourceId(), this.getControllerId(), game)) { - if (onlyToControllerGraveyard && !this.getControllerId().equals(game.getOwnerId(zEvent.getTargetId()))) { + if (onlyToControllerGraveyard && !this.isControlledBy(game.getOwnerId(zEvent.getTargetId()))) { return false; } if (setTargetPointer) { diff --git a/Mage/src/main/java/mage/abilities/common/SacrificeIfCastAtInstantTimeTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/SacrificeIfCastAtInstantTimeTriggeredAbility.java index 2e00f8551fb..9fac7a0a948 100644 --- a/Mage/src/main/java/mage/abilities/common/SacrificeIfCastAtInstantTimeTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/SacrificeIfCastAtInstantTimeTriggeredAbility.java @@ -43,7 +43,7 @@ public class SacrificeIfCastAtInstantTimeTriggeredAbility extends TriggeredAbili // CHECK Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null && spell.getSourceId().equals(getSourceId())) { - return !(game.isMainPhase() && game.getActivePlayerId().equals(event.getPlayerId()) && game.getStack().size() == 1); + return !(game.isMainPhase() && game.isActivePlayer(event.getPlayerId()) && game.getStack().size() == 1); } return false; } diff --git a/Mage/src/main/java/mage/abilities/common/SpellCounteredControllerTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/SpellCounteredControllerTriggeredAbility.java index ffa9768a1df..a0d3c0f0e84 100644 --- a/Mage/src/main/java/mage/abilities/common/SpellCounteredControllerTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/SpellCounteredControllerTriggeredAbility.java @@ -48,7 +48,7 @@ public class SpellCounteredControllerTriggeredAbility extends TriggeredAbilityIm if (stackObjectThatCountered == null) { stackObjectThatCountered = (StackObject) game.getLastKnownInformation(event.getSourceId(), Zone.STACK); } - if (stackObjectThatCountered != null && stackObjectThatCountered.getControllerId().equals(getControllerId())) { + if (stackObjectThatCountered != null && stackObjectThatCountered.isControlledBy(getControllerId())) { StackObject counteredStackObject = (StackObject) game.getLastKnownInformation(event.getTargetId(), Zone.STACK); return counteredStackObject != null && (counteredStackObject instanceof Spell); } diff --git a/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfMainPhaseDelayedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfMainPhaseDelayedTriggeredAbility.java index 310986bb28b..23b8331c9ce 100644 --- a/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfMainPhaseDelayedTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfMainPhaseDelayedTriggeredAbility.java @@ -78,7 +78,7 @@ public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTrigger Permanent attachment = game.getPermanent(sourceId); if (attachment != null && attachment.getAttachedTo() != null) { Permanent attachedTo = game.getPermanent(attachment.getAttachedTo()); - if (attachedTo != null && attachedTo.getControllerId().equals(event.getPlayerId())) { + if (attachedTo != null && attachedTo.isControlledBy(event.getPlayerId())) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfNextEndStepDelayedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfNextEndStepDelayedTriggeredAbility.java index 81b502a4052..0fff4ee32ad 100644 --- a/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfNextEndStepDelayedTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfNextEndStepDelayedTriggeredAbility.java @@ -69,7 +69,7 @@ public class AtTheBeginOfNextEndStepDelayedTriggeredAbility extends DelayedTrigg Permanent attachment = game.getPermanent(sourceId); if (attachment != null && attachment.getAttachedTo() != null) { Permanent attachedTo = game.getPermanent(attachment.getAttachedTo()); - if (attachedTo != null && attachedTo.getControllerId().equals(event.getPlayerId())) { + if (attachedTo != null && attachedTo.isControlledBy(event.getPlayerId())) { correctEndPhase = true; } } diff --git a/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility.java new file mode 100644 index 00000000000..7fe37d42791 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility.java @@ -0,0 +1,46 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.common.delayed; + +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.constants.Duration; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author jeffwadsworth + */ +public class AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility extends DelayedTriggeredAbility { + + public AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility(Effect effect) { + this(effect, Duration.Custom, true); + } + + public AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility(Effect effect, Duration duration, boolean triggerOnlyOnce) { + super(effect, duration, triggerOnlyOnce); + } + + public AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility(AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility ability) { + super(ability); + } + + @Override + public AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility copy() { + return new AtTheBeginOfYourNextDrawStepDelayedTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DRAW_STEP_PRE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return event.getPlayerId().equals(this.controllerId); + } +} + diff --git a/Mage/src/main/java/mage/abilities/common/delayed/PactDelayedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/delayed/PactDelayedTriggeredAbility.java index 5b5ff0795f5..1bb565531ab 100644 --- a/Mage/src/main/java/mage/abilities/common/delayed/PactDelayedTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/delayed/PactDelayedTriggeredAbility.java @@ -36,7 +36,7 @@ public class PactDelayedTriggeredAbility extends DelayedTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - return game.getActivePlayerId().equals(this.getControllerId()); + return game.isActivePlayer(this.getControllerId()); } diff --git a/Mage/src/main/java/mage/abilities/condition/common/CommanderInPlayCondition.java b/Mage/src/main/java/mage/abilities/condition/common/CommanderInPlayCondition.java index ffe21e2839b..ac0d85ce0e3 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/CommanderInPlayCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/CommanderInPlayCondition.java @@ -24,7 +24,7 @@ public enum CommanderInPlayCondition implements Condition { if (controller != null) { for (UUID commanderId : controller.getCommandersIds()) { Permanent commander = game.getPermanent(commanderId); - if (commander != null && commander.getControllerId().equals(source.getControllerId())) { + if (commander != null && commander.isControlledBy(source.getControllerId())) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/condition/common/ControllerAttackedThisTurnCondition.java b/Mage/src/main/java/mage/abilities/condition/common/ControllerAttackedThisTurnCondition.java index d609bb85d6c..b327e6e2141 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/ControllerAttackedThisTurnCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/ControllerAttackedThisTurnCondition.java @@ -16,6 +16,6 @@ public enum ControllerAttackedThisTurnCondition implements Condition { @Override public boolean apply(Game game, Ability source) { AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getSimpleName()); - return source.getControllerId().equals(game.getActivePlayerId()) && watcher != null && !watcher.getAttackedThisTurnCreatures().isEmpty(); + return source.isControlledBy(game.getActivePlayerId()) && watcher != null && !watcher.getAttackedThisTurnCreatures().isEmpty(); } } diff --git a/Mage/src/main/java/mage/abilities/condition/common/IsStepCondition.java b/Mage/src/main/java/mage/abilities/condition/common/IsStepCondition.java index ea19fed5592..070fb08b36b 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/IsStepCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/IsStepCondition.java @@ -26,7 +26,7 @@ public class IsStepCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - return phaseStep == game.getStep().getType() && (!onlyDuringYourSteps || game.getActivePlayerId().equals(source.getControllerId())); + return phaseStep == game.getStep().getType() && (!onlyDuringYourSteps || game.isActivePlayer(source.getControllerId())); } @Override diff --git a/Mage/src/main/java/mage/abilities/condition/common/MeldCondition.java b/Mage/src/main/java/mage/abilities/condition/common/MeldCondition.java index 30905d724ea..4b95507e5a6 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/MeldCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/MeldCondition.java @@ -27,8 +27,8 @@ public class MeldCondition implements Condition { MageObject sourceMageObject = source.getSourceObjectIfItStillExists(game); if (sourceMageObject != null && sourceMageObject instanceof Permanent) { Permanent sourcePermanent = (Permanent) sourceMageObject; - if (sourcePermanent.getControllerId().equals(source.getControllerId()) - && sourcePermanent.getOwnerId().equals(source.getControllerId())) { + if (sourcePermanent.isControlledBy(source.getControllerId()) + && sourcePermanent.isOwnedBy(source.getControllerId())) { FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); filter.add(new NamePredicate(this.meldWithName)); filter.add(new OwnerIdPredicate(source.getControllerId())); diff --git a/Mage/src/main/java/mage/abilities/condition/common/MonarchIsSourceControllerCondition.java b/Mage/src/main/java/mage/abilities/condition/common/MonarchIsSourceControllerCondition.java index 2576e5c9ba9..deffa175d8e 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/MonarchIsSourceControllerCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/MonarchIsSourceControllerCondition.java @@ -15,7 +15,7 @@ public enum MonarchIsSourceControllerCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - return source.getControllerId().equals(game.getMonarchId()); + return source.isControlledBy(game.getMonarchId()); } @Override diff --git a/Mage/src/main/java/mage/abilities/condition/common/MyMainPhaseCondition.java b/Mage/src/main/java/mage/abilities/condition/common/MyMainPhaseCondition.java index dc53a3a610e..ae960029b08 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/MyMainPhaseCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/MyMainPhaseCondition.java @@ -20,7 +20,7 @@ public enum MyMainPhaseCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - return game.getActivePlayerId().equals(source.getControllerId()) && + return game.isActivePlayer(source.getControllerId()) && turnPhases.contains(game.getTurn().getPhase().getType()); } } diff --git a/Mage/src/main/java/mage/abilities/condition/common/MyTurnBeforeAttackersDeclaredCondition.java b/Mage/src/main/java/mage/abilities/condition/common/MyTurnBeforeAttackersDeclaredCondition.java index c78e4d8438d..abe44f72e2e 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/MyTurnBeforeAttackersDeclaredCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/MyTurnBeforeAttackersDeclaredCondition.java @@ -16,7 +16,7 @@ public enum MyTurnBeforeAttackersDeclaredCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - if (game.getActivePlayerId().equals(source.getControllerId())) { + if (game.isActivePlayer(source.getControllerId())) { TurnPhase turnPhase = game.getTurn().getPhase().getType(); if (turnPhase == TurnPhase.BEGINNING || turnPhase == TurnPhase.PRECOMBAT_MAIN) { return true; diff --git a/Mage/src/main/java/mage/abilities/condition/common/MyTurnCondition.java b/Mage/src/main/java/mage/abilities/condition/common/MyTurnCondition.java index a8a6126ee74..70309455a54 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/MyTurnCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/MyTurnCondition.java @@ -10,7 +10,7 @@ public enum MyTurnCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - return game.getActivePlayerId().equals(source.getControllerId()); + return game.isActivePlayer(source.getControllerId()); } @Override diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileSourceCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileSourceCost.java index 4414e063bcc..5e460a9b445 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileSourceCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileSourceCost.java @@ -44,7 +44,7 @@ public class ExileSourceCost extends CostImpl { public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { MageObject sourceObject = ability.getSourceObject(game); Player controller = game.getPlayer(controllerId); - if (controller != null && sourceObject != null && (sourceObject instanceof Card)) { + if (controller != null && sourceObject instanceof Card) { UUID exileZoneId = null; String exileZoneName = ""; if (toUniqueExileZone) { diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/HighestConvertedManaCostValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/HighestConvertedManaCostValue.java index d879b439e79..9d603e0bcf0 100644 --- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/HighestConvertedManaCostValue.java +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/HighestConvertedManaCostValue.java @@ -32,7 +32,7 @@ public class HighestConvertedManaCostValue implements DynamicValue { return 0; } int highCMC = 0; - for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, controller.getId(), game)) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { int cmc = permanent.getConvertedManaCost(); highCMC = Math.max(highCMC, cmc); } diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/PermanentsYouOwnThatOpponentsControlCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/PermanentsYouOwnThatOpponentsControlCount.java index 69a7ce93153..66c49c96185 100644 --- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/PermanentsYouOwnThatOpponentsControlCount.java +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/PermanentsYouOwnThatOpponentsControlCount.java @@ -17,7 +17,7 @@ public class PermanentsYouOwnThatOpponentsControlCount implements DynamicValue { int count = 0; for (Permanent permanent : game.getBattlefield().getActivePermanents(sourceAbility.getControllerId(), game)) { - if (!permanent.getOwnerId().equals(permanent.getControllerId()) && permanent.getOwnerId().equals(sourceAbility.getControllerId())) { + if (!permanent.isOwnedBy(permanent.getControllerId()) && permanent.isOwnedBy(sourceAbility.getControllerId())) { if (opponentIds.contains(permanent.getControllerId())) { count++; } diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffectImpl.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffectImpl.java index d80c1d61975..f908f16fd99 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffectImpl.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffectImpl.java @@ -180,7 +180,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu Player player = game.getPlayer(startingControllerId); if (player != null) { if (player.isInGame()) { - return game.getActivePlayerId().equals(startingControllerId) && game.getTurnNum() != startingTurn; + return game.isActivePlayer(startingControllerId) && game.getTurnNum() != startingTurn; } return player.hasReachedNextTurnAfterLeaving(); } diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java index c0427d341ed..374c7e3db3d 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java @@ -465,7 +465,7 @@ public class ContinuousEffects implements Serializable { for (SpliceCardEffect effect : spliceCardEffects) { Set abilities = spliceCardEffects.getAbility(effect.getId()); for (Ability ability : abilities) { - if (ability.getControllerId().equals(playerId) && (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, null))) { + if (ability.isControlledBy(playerId) && (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, null))) { if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) { spliceEffects.add(effect); break; diff --git a/Mage/src/main/java/mage/abilities/effects/EquipEffect.java b/Mage/src/main/java/mage/abilities/effects/EquipEffect.java new file mode 100644 index 00000000000..1a4b6ed17ad --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/EquipEffect.java @@ -0,0 +1,39 @@ +package mage.abilities.effects; + +import mage.abilities.Ability; +import mage.abilities.effects.common.AttachEffect; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.game.permanent.Permanent; + +public class EquipEffect extends AttachEffect { + + public EquipEffect(Outcome outcome) { + super(outcome, "Equip"); + } + + public EquipEffect(EquipEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + //301.5c An Equipment that’s also a creature can’t equip a creature. An Equipment that loses the subtype + // “Equipment” can’t equip a creature. An Equipment can’t equip itself. An Equipment that equips an illegal or + // nonexistent permanent becomes unattached from that permanent but remains on the battlefield. (This is a + // state-based action. See rule 704.) An Equipment can’t equip more than one creature. If a spell or ability + // would cause an Equipment to equip more than one creature, the Equipment’s controller chooses which creature + // it equips. + if (sourcePermanent != null && sourcePermanent.hasSubtype(SubType.EQUIPMENT, game) && !sourcePermanent.isCreature()) { + return super.apply(game, source); + } + return false; + } + + @Override + public EquipEffect copy(){ + return new EquipEffect(this); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/GainAbilitySpellsEffect.java b/Mage/src/main/java/mage/abilities/effects/GainAbilitySpellsEffect.java index 6804ff9b867..11545d7d271 100644 --- a/Mage/src/main/java/mage/abilities/effects/GainAbilitySpellsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/GainAbilitySpellsEffect.java @@ -41,7 +41,7 @@ public class GainAbilitySpellsEffect extends ContinuousEffectImpl { Permanent permanent = game.getPermanent(source.getSourceId()); if (player != null && permanent != null) { for (Card card : game.getExile().getAllCards(game)) { - if (card.getOwnerId().equals(source.getControllerId()) && filter.match(card, game)) { + if (card.isOwnedBy(source.getControllerId()) && filter.match(card, game)) { game.getState().addOtherAbility(card, ability); } } @@ -61,7 +61,7 @@ public class GainAbilitySpellsEffect extends ContinuousEffectImpl { } } for (StackObject stackObject : game.getStack()) { - if (stackObject.getControllerId().equals(source.getControllerId())) { + if (stackObject.isControlledBy(source.getControllerId())) { Card card = game.getCard(stackObject.getSourceId()); if (card != null && filter.match(card, game)) { if (!card.getAbilities().contains(ability)) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/CanBlockAsThoughtItHadShadowEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CanBlockAsThoughtItHadShadowEffect.java new file mode 100644 index 00000000000..2725b186366 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/CanBlockAsThoughtItHadShadowEffect.java @@ -0,0 +1,38 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.constants.AsThoughEffectType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; + +import java.util.UUID; + +public class CanBlockAsThoughtItHadShadowEffect extends AsThoughEffectImpl { + + public CanBlockAsThoughtItHadShadowEffect(Duration duration) { + super(AsThoughEffectType.BLOCK_SHADOW, duration, Outcome.Benefit); + staticText = "{this} can block creatures with shadow as though {this} had shadow"; + } + + public CanBlockAsThoughtItHadShadowEffect(final CanBlockAsThoughtItHadShadowEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public CanBlockAsThoughtItHadShadowEffect copy() { + return new CanBlockAsThoughtItHadShadowEffect(this); + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + return sourceId.equals(source.getSourceId()); + } + +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/CantBeCounteredControlledEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CantBeCounteredControlledEffect.java index 820431e0f1e..78aafb7885c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CantBeCounteredControlledEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CantBeCounteredControlledEffect.java @@ -61,7 +61,7 @@ public class CantBeCounteredControlledEffect extends ContinuousRuleModifyingEffe @Override public boolean applies(GameEvent event, Ability source, Game game) { Spell spell = game.getStack().getSpell(event.getTargetId()); - if (spell != null && spell.getControllerId().equals(source.getControllerId()) + if (spell != null && spell.isControlledBy(source.getControllerId()) && filterTarget.match(spell, source.getSourceId(), source.getControllerId(), game)) { if (filterSource == null) { return true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/CopyTokenEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CopyTokenEffect.java index 56463f3927f..63b3018d234 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CopyTokenEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CopyTokenEffect.java @@ -5,10 +5,10 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.game.permanent.token.TokenImpl; import mage.game.permanent.token.Token; public class CopyTokenEffect extends ContinuousEffectImpl { + protected Token token; public CopyTokenEffect(Token token) { @@ -28,19 +28,19 @@ public class CopyTokenEffect extends ContinuousEffectImpl { permanent.setName(token.getName()); permanent.getColor(game).setColor(token.getColor(game)); permanent.getCardType().clear(); - for (CardType type: token.getCardType()) { + for (CardType type : token.getCardType()) { permanent.addCardType(type); } permanent.getSubtype(game).clear(); - for (SubType type: token.getSubtype(game)) { + for (SubType type : token.getSubtype(game)) { permanent.getSubtype(game).add(type); } permanent.getSuperType().clear(); - for (SuperType type: token.getSuperType()) { + for (SuperType type : token.getSuperType()) { permanent.addSuperType(type); } permanent.getAbilities().clear(); - for (Ability ability: token.getAbilities()) { + for (Ability ability : token.getAbilities()) { permanent.addAbility(ability, game); } permanent.getPower().setValue(token.getPower().getValue()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreatureExploresTriggeredAbility.java b/Mage/src/main/java/mage/abilities/effects/common/CreatureExploresTriggeredAbility.java index 3ccefeef6bd..12654a1b432 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreatureExploresTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreatureExploresTriggeredAbility.java @@ -26,7 +26,7 @@ public class CreatureExploresTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent creature = game.getPermanentOrLKIBattlefield(event.getTargetId()); if (creature != null) { - return creature.getControllerId().equals(getControllerId()); + return creature.isControlledBy(getControllerId()); } return false; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DetainAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DetainAllEffect.java index 9cb85eaa08d..410568577fa 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DetainAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DetainAllEffect.java @@ -77,7 +77,7 @@ class DetainAllRestrictionEffect extends RestrictionEffect { for (FixedTarget fixedTarget : this.detainedObjects) { Permanent permanent = game.getPermanent(fixedTarget.getFirst(game, source)); if (permanent != null) { - permanent.addInfo(new StringBuilder("detain").append(getId()).toString(), "[Detained]", game); + permanent.addInfo("detain" + getId(), "[Detained]", game); } } } @@ -85,11 +85,11 @@ class DetainAllRestrictionEffect extends RestrictionEffect { @Override public boolean isInactive(Ability source, Game game) { if (game.getPhase().getStep().getType() == PhaseStep.UNTAP && game.getStep().getStepPart() == Step.StepPart.PRE) { - if (game.getActivePlayerId().equals(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) { + if (game.isActivePlayer(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) { for (FixedTarget fixedTarget : this.detainedObjects) { Permanent permanent = game.getPermanent(fixedTarget.getFirst(game, source)); if (permanent != null) { - permanent.addInfo(new StringBuilder("detain").append(getId()).toString(), "", game); + permanent.addInfo("detain" + getId(), "", game); } } return true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/DetainTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DetainTargetEffect.java index 8ab62eee6dd..57b2a4c89ff 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DetainTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DetainTargetEffect.java @@ -118,7 +118,7 @@ class DetainRestrictionEffect extends RestrictionEffect { @Override public boolean isInactive(Ability source, Game game) { if (game.getPhase().getStep().getType() == PhaseStep.UNTAP && game.getStep().getStepPart() == Step.StepPart.PRE) { - if (game.getActivePlayerId().equals(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) { + if (game.isActivePlayer(source.getControllerId()) || game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) { for (UUID targetId : this.getTargetPointer().getTargets(game, source)) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/DoIfCostPaid.java b/Mage/src/main/java/mage/abilities/effects/common/DoIfCostPaid.java index e0882ae4466..a68dc8e27f4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DoIfCostPaid.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DoIfCostPaid.java @@ -141,6 +141,7 @@ public class DoIfCostPaid extends OneShotEffect { String costText = cost.getText(); if (costText != null && !costText.toLowerCase(Locale.ENGLISH).startsWith("put") + && !costText.toLowerCase(Locale.ENGLISH).startsWith("return") && !costText.toLowerCase(Locale.ENGLISH).startsWith("exile") && !costText.toLowerCase(Locale.ENGLISH).startsWith("discard") && !costText.toLowerCase(Locale.ENGLISH).startsWith("sacrifice") diff --git a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersNextUntapStepSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersNextUntapStepSourceEffect.java index 7ce2f8b92a4..c5351ce1fc4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersNextUntapStepSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersNextUntapStepSourceEffect.java @@ -60,7 +60,7 @@ public class DontUntapInControllersNextUntapStepSourceEffect extends ContinuousR } // remember the turn of the untap step the effect has to be applied if (event.getType() == GameEvent.EventType.UNTAP_STEP - && game.getActivePlayerId().equals(source.getControllerId())) { + && game.isActivePlayer(source.getControllerId())) { if (validForTurnNum == game.getTurnNum()) { // the turn has a second untap step but the effect is already related to the first untap step discard(); return false; @@ -70,7 +70,7 @@ public class DontUntapInControllersNextUntapStepSourceEffect extends ContinuousR // skip untap action if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP - && game.getActivePlayerId().equals(source.getControllerId()) + && game.isActivePlayer(source.getControllerId()) && event.getTargetId().equals(source.getSourceId())) { discard(); return true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java index 2fa58dbf5cd..49d5651cbf7 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java @@ -101,8 +101,8 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR for (UUID targetId : getTargetPointer().getTargets(game, source)) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - if (game.getActivePlayerId().equals(permanent.getControllerId()) - && ((onlyIfControlledByPlayer == null) || (game.getActivePlayerId().equals(onlyIfControlledByPlayer)))) { // if effect works only for specific player, all permanents have to be set to handled in that players untap step + if (game.isActivePlayer(permanent.getControllerId()) + && ((onlyIfControlledByPlayer == null) || (game.isActivePlayer(onlyIfControlledByPlayer)))) { // if effect works only for specific player, all permanents have to be set to handled in that players untap step if (!handledTargetsDuringTurn.containsKey(targetId)) { // it's the untep step of the current controller and the effect was not handled for this target yet, so do it now handledTargetsDuringTurn.put(targetId, false); @@ -127,8 +127,8 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR && !handledTargetsDuringTurn.get(event.getTargetId()) && getTargetPointer().getTargets(game, source).contains(event.getTargetId())) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && game.getActivePlayerId().equals(permanent.getControllerId())) { - if ((onlyIfControlledByPlayer == null) || game.getActivePlayerId().equals(onlyIfControlledByPlayer)) { // If onlyIfControlledByPlayer is set, then don't apply unless we're currently controlled by the specified player. + if (permanent != null && game.isActivePlayer(permanent.getControllerId())) { + if ((onlyIfControlledByPlayer == null) || game.isActivePlayer(onlyIfControlledByPlayer)) { // If onlyIfControlledByPlayer is set, then don't apply unless we're currently controlled by the specified player. handledTargetsDuringTurn.put(event.getTargetId(), !twoSteps); return true; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepAllEffect.java index 152ec2f29ce..f7d139f97c5 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepAllEffect.java @@ -61,7 +61,7 @@ public class DontUntapInControllersUntapStepAllEffect extends ContinuousRuleModi if (permanent != null) { switch(targetController) { case YOU: - if (!permanent.getControllerId().equals(source.getControllerId())) { + if (!permanent.isControlledBy(source.getControllerId())) { return false; } break; @@ -76,7 +76,7 @@ public class DontUntapInControllersUntapStepAllEffect extends ContinuousRuleModi default: throw new RuntimeException("Type of TargetController not supported!"); } - if (game.getActivePlayerId().equals(permanent.getControllerId()) && // controller's untap step + if (game.isActivePlayer(permanent.getControllerId()) && // controller's untap step filter.match(permanent, source.getSourceId(), source.getControllerId(), game)) { return true; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepEnchantedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepEnchantedEffect.java index 541bdd908e9..9371f56249b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepEnchantedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepEnchantedEffect.java @@ -60,7 +60,7 @@ public class DontUntapInControllersUntapStepEnchantedEffect extends ContinuousRu Permanent enchantment = game.getPermanent(source.getSourceId()); if (enchantment != null && enchantment.getAttachedTo() != null && event.getTargetId().equals(enchantment.getAttachedTo())) { Permanent permanent = game.getPermanent(enchantment.getAttachedTo()); - if (permanent != null && permanent.getControllerId().equals(game.getActivePlayerId())) { + if (permanent != null && permanent.isControlledBy(game.getActivePlayerId())) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepSourceEffect.java index 636677a5544..8c2d9842beb 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepSourceEffect.java @@ -50,7 +50,7 @@ public class DontUntapInControllersUntapStepSourceEffect extends ContinuousRuleM if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getTargetId().equals(source.getSourceId())) { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null && permanent.getControllerId().equals(game.getActivePlayerId())) { + if (permanent != null && permanent.isControlledBy(game.getActivePlayerId())) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepTargetEffect.java index a5fae993f38..f825e6da9fb 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepTargetEffect.java @@ -59,7 +59,7 @@ public class DontUntapInControllersUntapStepTargetEffect extends ContinuousRuleM for (UUID targetId : targetPointer.getTargets(game, source)) { if (event.getTargetId().equals(targetId)) { Permanent permanent = game.getPermanent(targetId); - if (permanent != null && game.getActivePlayerId().equals(permanent.getControllerId())) { + if (permanent != null && game.isActivePlayer(permanent.getControllerId())) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInPlayersNextUntapStepAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInPlayersNextUntapStepAllEffect.java index ba35b495d04..82f48cce45e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInPlayersNextUntapStepAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInPlayersNextUntapStepAllEffect.java @@ -81,7 +81,7 @@ public class DontUntapInPlayersNextUntapStepAllEffect extends ContinuousRuleModi } // remember the turn of the untap step the effect has to be applied if (event.getType() == EventType.UNTAP_STEP) { - if (game.getActivePlayerId().equals(getTargetPointer().getFirst(game, source))) { + if (game.isActivePlayer(getTargetPointer().getFirst(game, source))) { if (validForTurnNum == game.getTurnNum()) { // the turn has a second untap step but the effect is already related to the first untap step discard(); return false; @@ -94,13 +94,13 @@ public class DontUntapInPlayersNextUntapStepAllEffect extends ContinuousRuleModi Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null) { Player controller = game.getPlayer(source.getControllerId()); - if (!permanent.getControllerId().equals(getTargetPointer().getFirst(game, source))) { + if (!permanent.isControlledBy(getTargetPointer().getFirst(game, source))) { return false; } if (controller != null && !game.isOpponent(controller, permanent.getControllerId())) { return false; } - if (game.getActivePlayerId().equals(permanent.getControllerId()) + if (game.isActivePlayer(permanent.getControllerId()) && // controller's untap step filter.match(permanent, source.getSourceId(), source.getControllerId(), game)) { return true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/FortifyEffect.java b/Mage/src/main/java/mage/abilities/effects/common/FortifyEffect.java new file mode 100644 index 00000000000..192540d4693 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/FortifyEffect.java @@ -0,0 +1,38 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.game.permanent.Permanent; + +public class FortifyEffect extends AttachEffect{ + + public FortifyEffect(Outcome outcome) { + super(outcome, "Fortify"); + } + + public FortifyEffect(FortifyEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + //Some artifacts have the subtype “Fortification.” A Fortification can be attached to a land. It can’t legally + // be attached to an object that isn’t a land. Fortification’s analog to the equip keyword ability is the + // fortify keyword ability. Rules 301.5a–e apply to Fortifications in relation to lands just as they apply to + // Equipment in relation to creatures, with one clarification relating to rule 301.5c: a Fortification that’s + // also a creature (not a land) can’t fortify a land. (See rule 702.66, “Fortify.”) + if (sourcePermanent != null && sourcePermanent.hasSubtype(SubType.FORTIFICATION, game) && !sourcePermanent.isCreature() + && !sourcePermanent.isLand()) { + return super.apply(game, source); + } + return false; + } + + @Override + public FortifyEffect copy(){ + return new FortifyEffect(this); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/HideawayPlayEffect.java b/Mage/src/main/java/mage/abilities/effects/common/HideawayPlayEffect.java index 9480384322f..377fbcb8ee0 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/HideawayPlayEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/HideawayPlayEffect.java @@ -51,7 +51,7 @@ public class HideawayPlayEffect extends OneShotEffect { */ if (card.isLand()) { UUID playerId = controller.getId(); - if (!game.getActivePlayerId().equals(playerId) || !game.getPlayer(playerId).canPlayLand()) { + if (!game.isActivePlayer(playerId) || !game.getPlayer(playerId).canPlayLand()) { return false; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java index 87395253fa0..1fd35fb54bc 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryTopCardTargetPlayerEffect.java @@ -82,7 +82,7 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect { } } if (mayShuffleAfter) { - if (player.chooseUse(Outcome.Benefit, (player == targetPlayer ? "Shuffle your library?" : "Do you want the chosen player to shuffle his or her library?"), source, game)) { + if (player.chooseUse(Outcome.Benefit, (player == targetPlayer ? "Shuffle your library?" : "Do you want the chosen player to shuffle their library?"), source, game)) { targetPlayer.shuffleLibrary(source, game); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PopulateEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PopulateEffect.java index 6711b025212..a74f8d79626 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PopulateEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PopulateEffect.java @@ -44,7 +44,7 @@ public class PopulateEffect extends OneShotEffect { public PopulateEffect(String prefixText) { super(Outcome.Copy); - this.staticText = (!prefixText.isEmpty() ? prefixText + " p" : "P") + "opulate (Put a token onto the battlefield that's a copy of a creature token you control.)"; + this.staticText = (!prefixText.isEmpty() ? prefixText + " p" : "P") + "opulate (Create a token that's a copy of a creature token you control.)"; } public PopulateEffect(final PopulateEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/PutOnLibraryTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PutOnLibraryTargetEffect.java index c6a2ab15429..f0cd06bc606 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PutOnLibraryTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PutOnLibraryTargetEffect.java @@ -78,7 +78,7 @@ public class PutOnLibraryTargetEffect extends OneShotEffect { Cards cardsPlayer = new CardsImpl(); for (Iterator iterator = cards.iterator(); iterator.hasNext();) { Card next = iterator.next(); - if (next.getOwnerId().equals(owner.getId())) { + if (next.isOwnedBy(owner.getId())) { cardsPlayer.add(next); iterator.remove(); } @@ -97,7 +97,7 @@ public class PutOnLibraryTargetEffect extends OneShotEffect { Cards cardsPlayer = new CardsImpl(); for (Iterator iterator = permanents.iterator(); iterator.hasNext();) { Permanent next = iterator.next(); - if (next.getOwnerId().equals(owner.getId())) { + if (next.isOwnedBy(owner.getId())) { cardsPlayer.add(next); iterator.remove(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java index c3f6ed2d72a..51252895a9d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java @@ -57,7 +57,7 @@ public class ReturnToHandTargetEffect extends OneShotEffect { for (Target target : source.getTargets()) { for (UUID targetId : target.getTargets()) { MageObject mageObject = game.getObject(targetId); - if (mageObject instanceof Spell && ((Spell) mageObject).isCopy()) { + if (mageObject instanceof Spell && mageObject.isCopy()) { copyIds.add(targetId); } else if (mageObject instanceof Card) { cards.add((Card) mageObject); @@ -68,7 +68,7 @@ public class ReturnToHandTargetEffect extends OneShotEffect { for (UUID targetId : targetPointer.getTargets(game, source)) { MageObject mageObject = game.getObject(targetId); if (mageObject != null) { - if (mageObject instanceof Spell && ((Spell) mageObject).isCopy()) { + if (mageObject instanceof Spell && mageObject.isCopy()) { copyIds.add(targetId); } else { cards.add((Card) mageObject); diff --git a/Mage/src/main/java/mage/abilities/effects/common/RevealHandSourceControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/RevealHandSourceControllerEffect.java new file mode 100644 index 00000000000..c3e5e59e888 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/RevealHandSourceControllerEffect.java @@ -0,0 +1,42 @@ + +package mage.abilities.effects.common; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author noahg + */ +public class RevealHandSourceControllerEffect extends OneShotEffect { + + public RevealHandSourceControllerEffect() { + super(Outcome.Discard); + this.staticText = "reveal your hand"; + } + + public RevealHandSourceControllerEffect(final RevealHandSourceControllerEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (player != null && sourceObject != null) { + player.revealCards(sourceObject.getIdName(), player.getHand(), game); + return true; + } + return false; + } + + @Override + public RevealHandSourceControllerEffect copy() { + return new RevealHandSourceControllerEffect(this); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceEffect.java index 26e828dc580..b4e9339de44 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceEffect.java @@ -44,7 +44,7 @@ public class SacrificeSourceEffect extends OneShotEffect { if (sourceObject instanceof Permanent) { Permanent permanent = (Permanent) sourceObject; // you can only sacrifice a permanent you control - if (source.getControllerId().equals(permanent.getControllerId())) { + if (source.isControlledBy(permanent.getControllerId())) { return permanent.sacrifice(source.getSourceId(), game); } return true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/SkipNextDrawStepControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SkipNextDrawStepControllerEffect.java new file mode 100644 index 00000000000..f498b90eebb --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/SkipNextDrawStepControllerEffect.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.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.constants.PhaseStep; +import mage.game.Game; +import mage.game.turn.TurnMod; +import mage.players.Player; + +/** + * + * @author noahg + */ +public class SkipNextDrawStepControllerEffect extends OneShotEffect { + + public SkipNextDrawStepControllerEffect() { + this("you skip your next draw step"); + } + + public SkipNextDrawStepControllerEffect(String text) { + super(Outcome.Detriment); + this.staticText = text; + } + + public SkipNextDrawStepControllerEffect(SkipNextDrawStepControllerEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + game.getState().getTurnMods().add(new TurnMod(player.getId(), PhaseStep.DRAW)); + return true; + } + return false; + } + + @Override + public SkipNextDrawStepControllerEffect copy() { + return new SkipNextDrawStepControllerEffect(this); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/SkipUntapOptionalSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SkipUntapOptionalSourceEffect.java index 667c0bb2950..dbe05cd6b7f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/SkipUntapOptionalSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/SkipUntapOptionalSourceEffect.java @@ -27,7 +27,7 @@ public class SkipUntapOptionalSourceEffect extends RestrictionEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { return permanent.getId().equals(source.getSourceId()) - && permanent.getControllerId().equals(game.getActivePlayerId()) && // your untap step + && permanent.isControlledBy(game.getActivePlayerId()) && // your untap step permanent.isTapped(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/WishEffect.java b/Mage/src/main/java/mage/abilities/effects/common/WishEffect.java index 5841feef03b..62f74e35980 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/WishEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/WishEffect.java @@ -86,7 +86,7 @@ public class WishEffect extends OneShotEffect { } if (alsoFromExile) { for (Card exileCard : exile) { - if (exileCard.getOwnerId().equals(source.getControllerId()) && filter.match(exileCard, game)) { + if (exileCard.isOwnedBy(source.getControllerId()) && filter.match(exileCard, game)) { filteredCards.add(exileCard); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackControllerAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackControllerAttachedEffect.java index 04aae7f845e..09e122ede9e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackControllerAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackControllerAttachedEffect.java @@ -38,7 +38,7 @@ public class CantAttackControllerAttachedEffect extends RestrictionEffect { return false; } Permanent planeswalker = game.getPermanent(defenderId); - return planeswalker == null || !planeswalker.getControllerId().equals(source.getControllerId()); + return planeswalker == null || !planeswalker.isControlledBy(source.getControllerId()); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouOrPlaneswalkerAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouOrPlaneswalkerAllEffect.java index fa228c16e67..b603326ddff 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouOrPlaneswalkerAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouOrPlaneswalkerAllEffect.java @@ -44,7 +44,7 @@ public class CantAttackYouOrPlaneswalkerAllEffect extends RestrictionEffect { return false; } Permanent planeswalker = game.getPermanent(defenderId); - return planeswalker == null || !planeswalker.getControllerId().equals(source.getControllerId()); + return planeswalker == null || !planeswalker.isControlledBy(source.getControllerId()); } @Override diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouUnlessPayManaAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouUnlessPayManaAllEffect.java index ebf276e5612..0eef90ee664 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouUnlessPayManaAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouUnlessPayManaAllEffect.java @@ -56,7 +56,7 @@ public class CantAttackYouUnlessPayManaAllEffect extends PayCostToAttackBlockEff } } // attack target is controlling player - if (source.getControllerId().equals(event.getTargetId())) { + if (source.isControlledBy(event.getTargetId())) { return true; } // or attack target is a planeswalker of the controlling player @@ -64,7 +64,7 @@ public class CantAttackYouUnlessPayManaAllEffect extends PayCostToAttackBlockEff Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.isPlaneswalker() - && permanent.getControllerId().equals(source.getControllerId())) { + && permanent.isControlledBy(source.getControllerId())) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedAttachedEffect.java index 39647dd438b..6fc49b43cda 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedAttachedEffect.java @@ -36,7 +36,7 @@ public class CantBeBlockedAttachedEffect extends RestrictionEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { Permanent attachment = game.getPermanent(source.getSourceId()); - return attachment != null && attachment.getAttachedTo() != null - && attachment.getAttachedTo().equals(permanent.getId()); + return attachment != null + && attachment.isAttachedTo(permanent.getId()); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java index d525e0b372c..c24a7630db6 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadAllEffect.java @@ -33,7 +33,7 @@ public class GoadAllEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) { - if (!creature.getControllerId().equals(source.getControllerId())) { + if (!creature.isControlledBy(source.getControllerId())) { Effect effect = new GoadTargetEffect(); effect.setTargetPointer(new FixedTarget(creature, game)); effect.apply(game, source); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/ActivateAbilitiesAnyTimeYouCouldCastInstantEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/ActivateAbilitiesAnyTimeYouCouldCastInstantEffect.java index 3d4470dd573..4f76c81b722 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/ActivateAbilitiesAnyTimeYouCouldCastInstantEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/ActivateAbilitiesAnyTimeYouCouldCastInstantEffect.java @@ -44,7 +44,7 @@ public class ActivateAbilitiesAnyTimeYouCouldCastInstantEffect extends AsThoughE @Override public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game) { - return affectedAbility.getControllerId().equals(source.getControllerId()) + return affectedAbility.isControlledBy(source.getControllerId()) && activatedAbility.isInstance(affectedAbility); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeTargetEffect.java index c3e07473abe..b8f09330394 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeTargetEffect.java @@ -88,7 +88,7 @@ public class AddCardTypeTargetEffect extends ContinuousEffectImpl { sb.append(cardType.toString().toLowerCase(Locale.ENGLISH)).append(" "); } sb.append("in addition to its other types"); - if (getDuration().equals(Duration.EndOfTurn)) { + if (getDuration() == Duration.EndOfTurn) { sb.append(" until end of turn"); } return sb.toString(); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorAllEffect.java new file mode 100644 index 00000000000..f5cefeefbf5 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorAllEffect.java @@ -0,0 +1,154 @@ +/* + * + * 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.abilities.effects.common.continuous; + +import mage.MageObject; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.choices.ChoiceColor; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author LevelX + */ +public class BecomesColorAllEffect extends ContinuousEffectImpl { + + private ObjectColor setColor; + protected boolean loseOther; + protected FilterPermanent filter; + + /** + * Set the color of a spell or permanent + * + * @param duration + */ + public BecomesColorAllEffect(Duration duration) { + this(null, duration); + } + + public BecomesColorAllEffect(ObjectColor setColor, Duration duration) { + this(setColor, duration, new FilterPermanent("All permanents"), true, null); + } + + public BecomesColorAllEffect(ObjectColor setColor, Duration duration, FilterPermanent filter, boolean loseOther, String text) { + super(duration, Layer.ColorChangingEffects_5, SubLayer.NA, Outcome.Neutral); + this.setColor = setColor; + this.filter = filter; + this.loseOther = loseOther; + staticText = text; + } + + public BecomesColorAllEffect(final BecomesColorAllEffect effect) { + super(effect); + this.setColor = effect.setColor; + this.filter = effect.filter; + this.loseOther = effect.loseOther; + } + + @Override + public void init(Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return; + } + if (setColor == null) { + ChoiceColor choice = new ChoiceColor(); + if (!controller.choose(Outcome.PutManaInPool, choice, game)) { + discard(); + return; + } + setColor = choice.getColor(); + if (!game.isSimulation()) { + game.informPlayers(controller.getLogName() + " has chosen the color: " + setColor.toString()); + } + } + + super.init(source, game); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + if (setColor != null) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + if (permanent != null) { + switch (layer) { + case ColorChangingEffects_5: + if (loseOther) { + permanent.getColor(game).setColor(new ObjectColor()); + } + permanent.getColor(game).addColor(setColor); + break; + } + } else if (duration == Duration.Custom) { + discard(); + } + } + return true; + } + return false; + } + + @Override + public BecomesColorAllEffect copy() { + return new BecomesColorAllEffect(this); + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + StringBuilder sb = new StringBuilder(); + sb.append(filter.getMessage()); + sb.append(" become "); + if (setColor == null) { + sb.append("the color of your choice"); + } else { + sb.append(setColor.getDescription()); + } + if (!duration.toString().equals("")) { + sb.append(' ').append(duration.toString()); + } + return sb.toString(); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantCastMoreThanOneSpellEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantCastMoreThanOneSpellEffect.java index 5a50943bff1..e20ec587178 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantCastMoreThanOneSpellEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantCastMoreThanOneSpellEffect.java @@ -65,7 +65,7 @@ public class CantCastMoreThanOneSpellEffect extends ContinuousRuleModifyingEffec break; case CONTROLLER_ATTACHED_TO: Permanent attachment = game.getPermanent(source.getSourceId()); - if (attachment == null || !attachment.getAttachedTo().equals(event.getPlayerId())) { + if (attachment == null || !attachment.isAttachedTo(event.getPlayerId())) { return false; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CastAsThoughItHadFlashAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CastAsThoughItHadFlashAllEffect.java index 62d34920388..762e6539aef 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CastAsThoughItHadFlashAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CastAsThoughItHadFlashAllEffect.java @@ -51,7 +51,7 @@ public class CastAsThoughItHadFlashAllEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID affectedSpellId, Ability source, UUID affectedControllerId, Game game) { - if (anyPlayer || source.getControllerId().equals(affectedControllerId)) { + if (anyPlayer || source.isControlledBy(affectedControllerId)) { Card card = game.getCard(affectedSpellId); return card != null && filter.match(card, game); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/ExchangeControlTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/ExchangeControlTargetEffect.java index e79074f1bc3..37c32f864a9 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/ExchangeControlTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/ExchangeControlTargetEffect.java @@ -98,7 +98,7 @@ public class ExchangeControlTargetEffect extends ContinuousEffectImpl { } if (permanent1 != null && permanent2 != null) { // exchange works only for two different controllers - if (permanent1.getControllerId().equals(permanent2.getControllerId())) { + if (permanent1.isControlledBy(permanent2.getControllerId())) { // discard effect if controller of both permanents is the same discard(); return; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityControlledSpellsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityControlledSpellsEffect.java index 01becdd24b6..e58f88cda63 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityControlledSpellsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityControlledSpellsEffect.java @@ -48,7 +48,7 @@ public class GainAbilityControlledSpellsEffect extends ContinuousEffectImpl { if (player != null && permanent != null) { for (StackObject stackObject : game.getStack()) { // only spells cast, so no copies of spells - if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.getControllerId().equals(source.getControllerId())) { + if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.isControlledBy(source.getControllerId())) { Spell spell = (Spell) stackObject; if (filter.match(spell, game)) { if (!spell.getAbilities().contains(ability)) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityTargetEffect.java index d511d6e5d2f..881e3190246 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityTargetEffect.java @@ -88,7 +88,7 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl { return true; } if (durationPhaseStep != null && durationPhaseStep == game.getPhase().getStep().getType()) { - if (!sameStep && game.getActivePlayerId().equals(durationPlayerId) || game.getPlayer(durationPlayerId).hasReachedNextTurnAfterLeaving()) { + if (!sameStep && game.isActivePlayer(durationPlayerId) || game.getPlayer(durationPlayerId).hasReachedNextTurnAfterLeaving()) { return true; } } else { diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlTargetEffect.java index 455fb38e09d..993134026fa 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainControlTargetEffect.java @@ -83,7 +83,7 @@ public class GainControlTargetEffect extends ContinuousEffectImpl { Permanent permanent = game.getPermanent(permanentId); if (permanent != null) { targetStillExists = true; - if (!permanent.getControllerId().equals(controllingPlayerId)) { + if (!permanent.isControlledBy(controllingPlayerId)) { GameEvent loseControlEvent = GameEvent.getEvent(GameEvent.EventType.LOSE_CONTROL, permanentId, source.getId(), permanent.getControllerId()); if (game.replaceEvent(loseControlEvent)) { return false; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardEffect.java index 5dd1ffdc771..35e63cc3619 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardEffect.java @@ -50,7 +50,7 @@ public class PlayTheTopCardEffect extends AsThoughEffectImpl { Card cardOnTop = game.getCard(objectId); if (cardOnTop != null && affectedControllerId.equals(source.getControllerId()) - && cardOnTop.getOwnerId().equals(source.getControllerId()) + && cardOnTop.isOwnedBy(source.getControllerId()) && (!cardOnTop.getManaCost().isEmpty() || cardOnTop.isLand()) && filter.match(cardOnTop, game)) { Player player = game.getPlayer(cardOnTop.getOwnerId()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java index 1fd92243eca..76999b4f193 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java @@ -44,7 +44,7 @@ public class UntapAllDuringEachOtherPlayersUntapStepEffect extends ContinuousEff applied = Boolean.FALSE; } if (!applied && layer == Layer.RulesEffects) { - if (!source.getControllerId().equals(game.getActivePlayerId()) && game.getStep().getType() == PhaseStep.UNTAP) { + if (!source.isControlledBy(game.getActivePlayerId()) && game.getStep().getType() == PhaseStep.UNTAP) { game.getState().setValue(source.getSourceId() + "applied", true); for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { boolean untap = true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapSourceDuringEachOtherPlayersUntapStepEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapSourceDuringEachOtherPlayersUntapStepEffect.java index aa2dcbe44db..d1ede8e3a3b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapSourceDuringEachOtherPlayersUntapStepEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapSourceDuringEachOtherPlayersUntapStepEffect.java @@ -39,7 +39,7 @@ public class UntapSourceDuringEachOtherPlayersUntapStepEffect extends Continuous applied = Boolean.FALSE; } if (!applied && layer == Layer.RulesEffects) { - if (!source.getControllerId().equals(game.getActivePlayerId()) + if (!source.isControlledBy(game.getActivePlayerId()) && game.getStep() != null && game.getStep().getType() == PhaseStep.UNTAP) { game.getState().setValue(source.getSourceId() + "applied", true); diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/AbilitiesCostReductionControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/cost/AbilitiesCostReductionControllerEffect.java index 75e4ade46e6..b0b53d2d82c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/cost/AbilitiesCostReductionControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/AbilitiesCostReductionControllerEffect.java @@ -44,7 +44,7 @@ public class AbilitiesCostReductionControllerEffect extends CostModificationEffe @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { - return abilityToModify.getControllerId().equals(source.getControllerId()) + return abilityToModify.isControlledBy(source.getControllerId()) && activatedAbility.isInstance(abilityToModify); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostIncreasementControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostIncreasementControllerEffect.java index 9c1631f0717..7023fc78847 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostIncreasementControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostIncreasementControllerEffect.java @@ -69,7 +69,7 @@ public class SpellsCostIncreasementControllerEffect extends CostModificationEffe @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { - if (abilityToModify.getControllerId().equals(source.getControllerId())) { + if (abilityToModify.isControlledBy(source.getControllerId())) { Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); if (spell != null) { return this.filter.match(spell, game); diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionAllEffect.java index bc2f1e2382f..4947acadf22 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionAllEffect.java @@ -120,10 +120,10 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl { @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { - if (onlyControlled && !abilityToModify.getControllerId().equals(source.getControllerId())) { + if (onlyControlled && !abilityToModify.isControlledBy(source.getControllerId())) { return false; } - if (controllerId != null && !abilityToModify.getControllerId().equals(controllerId)) { + if (controllerId != null && !abilityToModify.isControlledBy(controllerId)) { return false; } if (abilityToModify instanceof SpellAbility) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionControllerEffect.java index 55068aec822..a58c1a2cb0f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/SpellsCostReductionControllerEffect.java @@ -114,7 +114,7 @@ public class SpellsCostReductionControllerEffect extends CostModificationEffectI @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { if (abilityToModify instanceof SpellAbility) { - if (abilityToModify.getControllerId().equals(source.getControllerId())) { + if (abilityToModify.isControlledBy(source.getControllerId())) { Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); if (spell != null) { return this.filter.match(spell, source.getSourceId(), source.getControllerId(), game); diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveCountersAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveCountersAttachedEffect.java new file mode 100644 index 00000000000..775ca85982c --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/RemoveCountersAttachedEffect.java @@ -0,0 +1,91 @@ + +package mage.abilities.effects.common.counter; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.counters.Counter; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.util.CardUtil; + +import java.util.Locale; + +/** + * + * @author noahg + */ +public class RemoveCountersAttachedEffect extends OneShotEffect { + + private Counter counter; + private DynamicValue amount; + private String textEnchanted; + + public RemoveCountersAttachedEffect(Counter counter, String textEnchanted) { + this(counter, new StaticValue(0), textEnchanted); + } + + /** + * + * @param counter + * @param amount this amount will be added to the counter instances + * @param textEnchanted text used for the enchanted permanent in rule text + */ + public RemoveCountersAttachedEffect(Counter counter, DynamicValue amount, String textEnchanted) { + super(Outcome.UnboostCreature); + this.counter = counter.copy(); + this.amount = amount; + this.textEnchanted = textEnchanted; + setText(); + } + + public RemoveCountersAttachedEffect(final RemoveCountersAttachedEffect effect) { + super(effect); + if (effect.counter != null) { + this.counter = effect.counter.copy(); + } + this.amount = effect.amount; + this.textEnchanted = effect.textEnchanted; + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null && permanent.getAttachedTo() != null) { + Permanent attachedTo = game.getPermanent(permanent.getAttachedTo()); + if (attachedTo != null && counter != null) { + Counter newCounter = counter.copy(); + newCounter.add(amount.calculate(game, source, this)); + attachedTo.removeCounters(newCounter, game); + } + return true; + } + return false; + } + + private void setText() { + StringBuilder sb = new StringBuilder(); + // put a +1/+1 counter on it + sb.append("remove "); + if (counter.getCount() > 1) { + sb.append(CardUtil.numberToText(counter.getCount())).append(' '); + sb.append(counter.getName().toLowerCase(Locale.ENGLISH)).append(" counters from "); + } else { + sb.append("a "); + sb.append(counter.getName().toLowerCase(Locale.ENGLISH)).append(" counter from "); + } + sb.append(textEnchanted); + if (!amount.getMessage().isEmpty()) { + sb.append(" for each ").append(amount.getMessage()); + } + staticText = sb.toString(); + } + + @Override + public RemoveCountersAttachedEffect copy() { + return new RemoveCountersAttachedEffect(this); + } + +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/replacement/DiesReplacementEffect.java b/Mage/src/main/java/mage/abilities/effects/common/replacement/DiesReplacementEffect.java index bf08c67125d..12ece0c7b53 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/replacement/DiesReplacementEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/replacement/DiesReplacementEffect.java @@ -29,7 +29,7 @@ public class DiesReplacementEffect extends ReplacementEffectImpl { public DiesReplacementEffect(MageObjectReference objectRef, Duration duration) { super(duration, Outcome.Exile); this.objectRef = objectRef; - staticText = "If that creature would die " + (duration.equals(Duration.EndOfTurn) ? "this turn" : "") + ", exile it instead"; + staticText = "If that creature would die " + (duration == Duration.EndOfTurn ? "this turn" : "") + ", exile it instead"; } public DiesReplacementEffect(final DiesReplacementEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/InvestigateEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/InvestigateEffect.java index 395b4fb37b2..5f0aaf40644 100644 --- a/Mage/src/main/java/mage/abilities/effects/keyword/InvestigateEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/keyword/InvestigateEffect.java @@ -19,7 +19,7 @@ public class InvestigateEffect extends CreateTokenEffect { public InvestigateEffect() { super(new ClueArtifactToken()); - this.staticText = "Investigate. (Create a colorless Clue artifact token onto the battlefield with \"{2}, Sacrifice this artifact: Draw a card.\")"; + this.staticText = "Investigate. (Create a colorless Clue artifact token with \"{2}, Sacrifice this artifact: Draw a card.\")"; } public InvestigateEffect(final InvestigateEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/keyword/AuraSwapAbility.java b/Mage/src/main/java/mage/abilities/keyword/AuraSwapAbility.java index ef351303bff..8e443916432 100644 --- a/Mage/src/main/java/mage/abilities/keyword/AuraSwapAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/AuraSwapAbility.java @@ -69,7 +69,7 @@ class AuraSwapEffect extends OneShotEffect { Permanent auraSourcePermanent = game.getPermanent(source.getSourceId()); if (auraSourcePermanent != null && auraSourcePermanent.hasSubtype(SubType.AURA, game) - && auraSourcePermanent.getOwnerId().equals(source.getControllerId())) { + && auraSourcePermanent.isOwnedBy(source.getControllerId())) { Permanent enchantedPermanent = game.getPermanent(auraSourcePermanent.getAttachedTo()); filterCardToCheck.add(new AuraCardCanAttachToPermanentId(enchantedPermanent.getId())); TargetCardInHand target = new TargetCardInHand(filterCardToCheck); diff --git a/Mage/src/main/java/mage/abilities/keyword/CumulativeUpkeepAbility.java b/Mage/src/main/java/mage/abilities/keyword/CumulativeUpkeepAbility.java index f7622a09815..546de34cf26 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CumulativeUpkeepAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/CumulativeUpkeepAbility.java @@ -16,6 +16,7 @@ import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.game.events.ManaEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -84,7 +85,7 @@ class CumulativeUpkeepEffect extends OneShotEffect { if (player.chooseUse(Outcome.Benefit, "Pay " + totalCost.getText() + '?', source, game)) { totalCost.clearPaid(); if (totalCost.payOrRollback(source, game, source.getSourceId(), source.getControllerId())) { - game.fireEvent(new GameEvent(EventType.PAID_CUMULATIVE_UPKEEP, permanent.getId(), permanent.getId(), player.getId(), ageCounter, false)); + game.fireEvent(new ManaEvent(EventType.PAID_CUMULATIVE_UPKEEP, permanent.getId(), permanent.getId(), player.getId(), totalCost.getUsedManaToPay())); return true; } } diff --git a/Mage/src/main/java/mage/abilities/keyword/EquipAbility.java b/Mage/src/main/java/mage/abilities/keyword/EquipAbility.java index 9f75eeaa3c9..6495c39ceca 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EquipAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EquipAbility.java @@ -4,6 +4,7 @@ import java.util.UUID; import mage.abilities.ActivatedAbilityImpl; import mage.abilities.costs.Cost; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.EquipEffect; import mage.abilities.effects.common.AttachEffect; import mage.constants.Outcome; import mage.constants.SubType; @@ -28,21 +29,11 @@ public class EquipAbility extends ActivatedAbilityImpl { } public EquipAbility(Outcome outcome, Cost cost, Target target) { - super(Zone.BATTLEFIELD, new AttachEffect(outcome, "Equip"), cost); + super(Zone.BATTLEFIELD, new EquipEffect(outcome), cost); this.addTarget(target); this.timing = TimingRule.SORCERY; } - @Override - public ActivationStatus canActivate(UUID playerId, Game game) { - Permanent permanent = game.getPermanent(sourceId); - if (permanent != null && permanent.hasSubtype(SubType.EQUIPMENT, game) && !permanent.isCreature()) { - return super.canActivate(playerId, game); - } else { - return ActivationStatus.getFalse(); - } - } - public EquipAbility(final EquipAbility ability) { super(ability); } diff --git a/Mage/src/main/java/mage/abilities/keyword/EvolveAbility.java b/Mage/src/main/java/mage/abilities/keyword/EvolveAbility.java index 66d3f4f063c..7e2183feb28 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EvolveAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EvolveAbility.java @@ -84,7 +84,7 @@ public class EvolveAbility extends TriggeredAbilityImpl { Permanent triggeringCreature = game.getPermanent(event.getTargetId()); if (triggeringCreature != null && triggeringCreature.isCreature() - && triggeringCreature.getControllerId().equals(this.controllerId)) { + && triggeringCreature.isControlledBy(this.controllerId)) { Permanent sourceCreature = game.getPermanent(sourceId); if (sourceCreature != null && isPowerOrThoughnessGreater(sourceCreature, triggeringCreature)) { this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getTargetId())); diff --git a/Mage/src/main/java/mage/abilities/keyword/ExaltedAbility.java b/Mage/src/main/java/mage/abilities/keyword/ExaltedAbility.java index 2f89fa3dcd7..1fe2febcd42 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ExaltedAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ExaltedAbility.java @@ -35,7 +35,7 @@ public class ExaltedAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getActivePlayerId().equals(this.controllerId)) { + if (game.isActivePlayer(this.controllerId)) { if (game.getCombat().attacksAlone()) { this.getEffects().get(0).setTargetPointer(new FixedTarget(game.getCombat().getAttackers().get(0))); return true; diff --git a/Mage/src/main/java/mage/abilities/keyword/ForecastAbility.java b/Mage/src/main/java/mage/abilities/keyword/ForecastAbility.java index db20407e78e..5e411a5c370 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ForecastAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ForecastAbility.java @@ -45,7 +45,7 @@ public class ForecastAbility extends LimitedTimesPerTurnActivatedAbility { public ActivationStatus canActivate(UUID playerId, Game game) { // May be activated only during the upkeep step of the card's owner // Because it can only be activated from a players hand it should be ok to check here with controllerId instead of card.getOwnerId(). - if (!game.getActivePlayerId().equals(controllerId) || PhaseStep.UPKEEP != game.getStep().getType()) { + if (!game.isActivePlayer(controllerId) || PhaseStep.UPKEEP != game.getStep().getType()) { return ActivationStatus.getFalse(); } return super.canActivate(playerId, game); diff --git a/Mage/src/main/java/mage/abilities/keyword/FortifyAbility.java b/Mage/src/main/java/mage/abilities/keyword/FortifyAbility.java index 43c8ab32546..748c53cf811 100644 --- a/Mage/src/main/java/mage/abilities/keyword/FortifyAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/FortifyAbility.java @@ -3,6 +3,7 @@ package mage.abilities.keyword; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.FortifyEffect; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.TimingRule; @@ -36,21 +37,11 @@ public class FortifyAbility extends ActivatedAbilityImpl { } public FortifyAbility(Outcome outcome, Cost cost, Target target) { - super(Zone.BATTLEFIELD, new AttachEffect(outcome, "Fortify"), cost); + super(Zone.BATTLEFIELD, new FortifyEffect(outcome), cost); this.addTarget(target); this.timing = TimingRule.SORCERY; } - @Override - public ActivationStatus canActivate(UUID playerId, Game game) { - Permanent permanent = game.getPermanent(sourceId); - if (permanent != null && permanent.hasSubtype(SubType.FORTIFICATION, game) && !permanent.isCreature() && !permanent.isLand()) { - return super.canActivate(playerId, game); - } else { - return ActivationStatus.getFalse(); - } - } - public FortifyAbility(final FortifyAbility ability) { super(ability); } diff --git a/Mage/src/main/java/mage/abilities/keyword/HideawayAbility.java b/Mage/src/main/java/mage/abilities/keyword/HideawayAbility.java index 28fab9980a2..2d0c6829bf4 100644 --- a/Mage/src/main/java/mage/abilities/keyword/HideawayAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/HideawayAbility.java @@ -140,7 +140,7 @@ class HideawayLookAtFaceDownCardEffect extends AsThoughEffectImpl { // TODO: Does not handle if a player had the control of the land permanent some time before // we would need to add a watcher to handle this Permanent sourcePermanet = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (sourcePermanet != null && sourcePermanet.getControllerId().equals(affectedControllerId)) { + if (sourcePermanet != null && sourcePermanet.isControlledBy(affectedControllerId)) { ExileZone exile = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); Card card = game.getCard(objectId); if (exile != null && exile.contains(objectId) && card != null) { diff --git a/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java b/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java index b32005c0537..9a1de9fd982 100644 --- a/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java @@ -107,7 +107,7 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl { public boolean applies(UUID sourceId, Ability affectedAbility, Ability source, Game game) { if (sourceId.equals(source.getSourceId())) { Card card = game.getCard(sourceId); - if (!card.getOwnerId().equals(source.getControllerId())) { + if (!card.isOwnedBy(source.getControllerId())) { return false; } // because can activate is always called twice, result from first call will be used diff --git a/Mage/src/main/java/mage/abilities/keyword/RecoverAbility.java b/Mage/src/main/java/mage/abilities/keyword/RecoverAbility.java index 12bf54f5aac..c6bac07f934 100644 --- a/Mage/src/main/java/mage/abilities/keyword/RecoverAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/RecoverAbility.java @@ -49,7 +49,7 @@ public class RecoverAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { - if (zEvent.getTarget().getOwnerId().equals(getControllerId()) + if (zEvent.getTarget().isOwnedBy(getControllerId()) && zEvent.getTarget().isCreature() && !zEvent.getTarget().getId().equals(getSourceId())) { return true; diff --git a/Mage/src/main/java/mage/abilities/keyword/RepairAbility.java b/Mage/src/main/java/mage/abilities/keyword/RepairAbility.java index 6227e4c19fd..5a270a4d9e6 100644 --- a/Mage/src/main/java/mage/abilities/keyword/RepairAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/RepairAbility.java @@ -84,7 +84,7 @@ class RepairCastFromGraveyardEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId); + return source.isControlledBy(affectedControllerId); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/SoulbondAbility.java b/Mage/src/main/java/mage/abilities/keyword/SoulbondAbility.java index e9289e3b8e2..da422af6d8f 100644 --- a/Mage/src/main/java/mage/abilities/keyword/SoulbondAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/SoulbondAbility.java @@ -78,7 +78,7 @@ public class SoulbondAbility extends EntersBattlefieldTriggeredAbility { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(getControllerId())) { if (permanent.isCreature()) { if (permanent.getId().equals(getSourceId())) { - if (permanent.getControllerId().equals(getControllerId())) { + if (permanent.isControlledBy(getControllerId())) { self = true; if (other) { return true; @@ -195,7 +195,7 @@ class SoulbondEntersOtherAbility extends EntersBattlefieldAllTriggeredAbility { // if you control both this creature and another creature and both are unpaired if (game.getBattlefield().countAll(filter, getControllerId(), game) > 0) { Permanent sourcePermanent = game.getPermanent(getSourceId()); - if (sourcePermanent != null && sourcePermanent.getControllerId().equals(getControllerId()) && sourcePermanent.getPairedCard() == null) { + if (sourcePermanent != null && sourcePermanent.isControlledBy(getControllerId()) && sourcePermanent.getPairedCard() == null) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/mana/CommanderColorIdentityManaAbility.java b/Mage/src/main/java/mage/abilities/mana/CommanderColorIdentityManaAbility.java index 054f3159369..44ad62ff232 100644 --- a/Mage/src/main/java/mage/abilities/mana/CommanderColorIdentityManaAbility.java +++ b/Mage/src/main/java/mage/abilities/mana/CommanderColorIdentityManaAbility.java @@ -1,6 +1,6 @@ - package mage.abilities.mana; +import java.util.ArrayList; import java.util.List; import java.util.UUID; import mage.Mana; @@ -42,6 +42,7 @@ public class CommanderColorIdentityManaAbility extends ActivatedManaAbilityImpl @Override public List getNetMana(Game game) { + List netManas = new ArrayList<>(); if (netMana.isEmpty() && game != null) { Player controller = game.getPlayer(getControllerId()); if (controller != null) { @@ -68,7 +69,8 @@ public class CommanderColorIdentityManaAbility extends ActivatedManaAbilityImpl } } } - return netMana; + netManas.addAll(netMana); + return netManas; } @Override diff --git a/Mage/src/main/java/mage/abilities/mana/ConditionalManaAbility.java b/Mage/src/main/java/mage/abilities/mana/ConditionalManaAbility.java index 06c2919d175..c2d0a97511f 100644 --- a/Mage/src/main/java/mage/abilities/mana/ConditionalManaAbility.java +++ b/Mage/src/main/java/mage/abilities/mana/ConditionalManaAbility.java @@ -33,8 +33,6 @@ public class ConditionalManaAbility extends ActivatedManaAbilityImpl { @Override public List getNetMana(Game game) { - List newNetMana = new ArrayList<>(); - newNetMana.addAll(conditionalManaEffect.getNetMana(game, this)); - return newNetMana; + return new ArrayList<>(conditionalManaEffect.getNetMana(game, this)); } } diff --git a/Mage/src/main/java/mage/abilities/mana/ManaOptions.java b/Mage/src/main/java/mage/abilities/mana/ManaOptions.java index 077b77fad43..bfd32e47478 100644 --- a/Mage/src/main/java/mage/abilities/mana/ManaOptions.java +++ b/Mage/src/main/java/mage/abilities/mana/ManaOptions.java @@ -53,7 +53,7 @@ public class ManaOptions extends ArrayList { boolean hasTapCost = hasTapCost(abilities.get(0)); for (Mana netMana : netManas) { for (Mana mana : copy) { - if (!hasTapCost || checkTappedForManaReplacement(abilities.get(0), game, netMana)) { + if (!hasTapCost /* || checkTappedForManaReplacement(abilities.get(0), game, netMana) */) { // Seems to produce endless iterations so deactivated for now: https://github.com/magefree/mage/issues/5023 Mana newMana = new Mana(); newMana.add(mana); newMana.add(netMana); @@ -114,6 +114,7 @@ public class ManaOptions extends ArrayList { } public void addManaWithCost(List abilities, Game game) { + int replaces = 0; if (isEmpty()) { this.add(new Mana()); } @@ -153,7 +154,7 @@ public class ManaOptions extends ArrayList { } } } - } else if (abilities.size() > 1) { + } else { //perform a union of all existing options and the new options List copy = copy(); this.clear(); @@ -187,7 +188,7 @@ public class ManaOptions extends ArrayList { Mana moreValuable = Mana.getMoreValuableMana(newMana, existingMana); if (moreValuable != null) { existingMana.setToMana(moreValuable); - logger.trace("mana replaced " + newMana.toString() + " <=> " + existingMana.toString() + " from " + ability.getRule()); + replaces++; continue CombineWithExisting; } } @@ -203,6 +204,10 @@ public class ManaOptions extends ArrayList { } } } + if (this.size() > 30 || replaces > 30) { + logger.trace("ManaOptionsCosts " + this.size() + " Ign:" + replaces + " => " + this.toString()); + logger.trace("Abilities: " + abilities.toString()); + } } public void addMana(Mana addMana) { @@ -222,7 +227,7 @@ public class ManaOptions extends ArrayList { if (options.size() == 1) { //if there is only one mana option available add it to all the existing options addMana(options.get(0)); - } else if (options.size() > 1) { + } else { //perform a union of all existing options and the new options List copy = copy(); this.clear(); @@ -255,20 +260,28 @@ public class ManaOptions extends ArrayList { this.clear(); for (Mana mana : copy) { Mana oldMan = mana.copy(); - if (mana.includesMana(cost)) { - // colorless costs can be paid with different colored mana, can lead to different color combinations + if (mana.includesMana(cost)) { // it can be paid + // generic mana costs can be paid with different colored mana, can lead to different color combinations if (cost.getGeneric() > 0 && cost.getGeneric() > (mana.getGeneric() + mana.getColorless())) { Mana coloredCost = cost.copy(); coloredCost.setGeneric(0); mana.subtract(coloredCost); + boolean oldManaWasReplaced = false; for (Mana payCombination : getPossiblePayCombinations(cost.getGeneric(), mana)) { Mana newMana = mana.copy(); newMana.subtract(payCombination); newMana.add(addMana); - if (oldMan.contains(newMana) && oldMan.count() > newMana.count()) { - newMana.setToMana(oldMan); + Mana moreValuable = Mana.getMoreValuableMana(oldMan, newMana); + if (!oldMan.equals(moreValuable)) { + this.add(newMana); + if (moreValuable != null) { + oldManaWasReplaced = true; // the new mana includes all possibilities of the old one + } } - this.add(newMana); + + } + if (!oldManaWasReplaced) { + this.add(oldMan); } } else { while (mana.includesMana(cost)) { @@ -303,28 +316,33 @@ public class ManaOptions extends ArrayList { existingManas.add(new Mana()); } for (Mana existingMana : existingManas) { - Mana manaToPay = manaAvailable.copy(); - manaToPay.subtract(existingMana); - if (manaToPay.getBlack() > 0 && !payCombinationsStrings.contains(existingMana.toString() + Mana.BlackMana(1).toString())) { - manaToPay.subtract(Mana.BlackMana(1)); + Mana manaToPayFrom = manaAvailable.copy(); + manaToPayFrom.subtract(existingMana); + if (manaToPayFrom.getBlack() > 0 && !payCombinationsStrings.contains(existingMana.toString() + Mana.BlackMana(1).toString())) { + manaToPayFrom.subtract(Mana.BlackMana(1)); addManaCombination(Mana.BlackMana(1), existingMana, payCombinations, payCombinationsStrings); } - if (manaToPay.getBlue() > 0 && !payCombinationsStrings.contains(existingMana.toString() + Mana.BlueMana(1).toString())) { - manaToPay.subtract(Mana.BlueMana(1)); + if (manaToPayFrom.getBlue() > 0 && !payCombinationsStrings.contains(existingMana.toString() + Mana.BlueMana(1).toString())) { + manaToPayFrom.subtract(Mana.BlueMana(1)); addManaCombination(Mana.BlueMana(1), existingMana, payCombinations, payCombinationsStrings); } - if (manaToPay.getGreen() > 0 && !payCombinationsStrings.contains(existingMana.toString() + Mana.GreenMana(1).toString())) { - manaToPay.subtract(Mana.GreenMana(1)); + if (manaToPayFrom.getGreen() > 0 && !payCombinationsStrings.contains(existingMana.toString() + Mana.GreenMana(1).toString())) { + manaToPayFrom.subtract(Mana.GreenMana(1)); addManaCombination(Mana.GreenMana(1), existingMana, payCombinations, payCombinationsStrings); } - if (manaToPay.getRed() > 0 && !payCombinationsStrings.contains(existingMana.toString() + Mana.RedMana(1).toString())) { - manaToPay.subtract(Mana.RedMana(1)); + if (manaToPayFrom.getRed() > 0 && !payCombinationsStrings.contains(existingMana.toString() + Mana.RedMana(1).toString())) { + manaToPayFrom.subtract(Mana.RedMana(1)); addManaCombination(Mana.RedMana(1), existingMana, payCombinations, payCombinationsStrings); } - if (manaToPay.getWhite() > 0 && !payCombinationsStrings.contains(existingMana.toString() + Mana.WhiteMana(1).toString())) { - manaToPay.subtract(Mana.WhiteMana(1)); + if (manaToPayFrom.getWhite() > 0 && !payCombinationsStrings.contains(existingMana.toString() + Mana.WhiteMana(1).toString())) { + manaToPayFrom.subtract(Mana.WhiteMana(1)); addManaCombination(Mana.WhiteMana(1), existingMana, payCombinations, payCombinationsStrings); } + // Pay with any only needed if colored payment was not possible + if (payCombinations.isEmpty() && manaToPayFrom.getAny() > 0 && !payCombinationsStrings.contains(existingMana.toString() + Mana.AnyMana(1).toString())) { + manaToPayFrom.subtract(Mana.AnyMana(1)); + addManaCombination(Mana.AnyMana(1), existingMana, payCombinations, payCombinationsStrings); + } } } } else { @@ -352,5 +370,16 @@ public class ManaOptions extends ArrayList { list.add(s); } } + // Remove fully included variations + for (int i = this.size() - 1; i >= 0; i--) { + for (int ii = 0; ii < i; ii++) { + Mana moreValuable = Mana.getMoreValuableMana(this.get(i), this.get(ii)); + if (moreValuable != null) { + this.get(ii).setToMana(moreValuable); + this.remove(i); + break; + } + } + } } } diff --git a/Mage/src/main/java/mage/abilities/mana/SimpleManaAbility.java b/Mage/src/main/java/mage/abilities/mana/SimpleManaAbility.java index 4998d58b5c5..0877a667c25 100644 --- a/Mage/src/main/java/mage/abilities/mana/SimpleManaAbility.java +++ b/Mage/src/main/java/mage/abilities/mana/SimpleManaAbility.java @@ -1,6 +1,6 @@ - package mage.abilities.mana; +import java.util.ArrayList; import java.util.List; import mage.Mana; import mage.abilities.costs.Cost; @@ -55,7 +55,7 @@ public class SimpleManaAbility extends ActivatedManaAbilityImpl { if (predictable) { return super.getNetMana(game); } - return netMana; + return new ArrayList(netMana); } } diff --git a/Mage/src/main/java/mage/abilities/mana/TriggeredManaAbility.java b/Mage/src/main/java/mage/abilities/mana/TriggeredManaAbility.java index 92054553ac6..41173683bd1 100644 --- a/Mage/src/main/java/mage/abilities/mana/TriggeredManaAbility.java +++ b/Mage/src/main/java/mage/abilities/mana/TriggeredManaAbility.java @@ -1,4 +1,3 @@ - package mage.abilities.mana; import java.util.ArrayList; @@ -54,7 +53,7 @@ public abstract class TriggeredManaAbility extends TriggeredAbilityImpl implemen } return newNetMana; } - return netMana; + return new ArrayList(netMana); } /** diff --git a/Mage/src/main/java/mage/abilities/mana/conditional/ConditionalSpellManaBuilder.java b/Mage/src/main/java/mage/abilities/mana/conditional/ConditionalSpellManaBuilder.java index c1d071e93f0..86f5939b30c 100644 --- a/Mage/src/main/java/mage/abilities/mana/conditional/ConditionalSpellManaBuilder.java +++ b/Mage/src/main/java/mage/abilities/mana/conditional/ConditionalSpellManaBuilder.java @@ -63,7 +63,7 @@ class SpellCastManaCondition extends ManaCondition implements Condition { public boolean apply(Game game, Ability source) { if (source instanceof SpellAbility) { MageObject object = game.getObject(source.getSourceId()); - if (object != null && (object instanceof StackObject)) { + if ((object instanceof StackObject)) { return filter.match((StackObject) object, source.getSourceId(), source.getControllerId(), game); } } diff --git a/Mage/src/main/java/mage/cards/Card.java b/Mage/src/main/java/mage/cards/Card.java index 7408bc8b9c2..bac8f59d403 100644 --- a/Mage/src/main/java/mage/cards/Card.java +++ b/Mage/src/main/java/mage/cards/Card.java @@ -168,4 +168,8 @@ public interface Card extends MageObject { boolean addAttachment(UUID permanentId, Game game); boolean removeAttachment(UUID permanentId, Game game); + + default boolean isOwnedBy(UUID controllerId){ + return getOwnerId().equals(controllerId); + } } diff --git a/Mage/src/main/java/mage/cards/ExpansionSet.java b/Mage/src/main/java/mage/cards/ExpansionSet.java index 290ca6f63c9..2e0750d00e1 100644 --- a/Mage/src/main/java/mage/cards/ExpansionSet.java +++ b/Mage/src/main/java/mage/cards/ExpansionSet.java @@ -88,7 +88,8 @@ public abstract class ExpansionSet implements Serializable { protected int numBoosterSpecial; protected int numBoosterLands; - protected int ratioBoosterSpecialLand = 0; // if > 0 basic lands are replaced with special land in the ratio every X land is replaced by special land + protected int ratioBoosterSpecialLand = 0; // if > 0 basic lands are replaced with special land with probability ratioBoosterSpecialLandNumerator / ratioBoosterSpecialLand + protected int ratioBoosterSpecialLandNumerator = 1; protected int numBoosterCommon; protected int numBoosterUncommon; @@ -208,7 +209,7 @@ public abstract class ExpansionSet implements Serializable { List specialLands = getSpecialLand(); List basicLands = getCardsByRarity(Rarity.LAND); for (int i = 0; i < numBoosterLands; i++) { - if (ratioBoosterSpecialLand > 0 && RandomUtil.nextInt(ratioBoosterSpecialLand) == 0 && specialLands != null) { + if (ratioBoosterSpecialLand > 0 && RandomUtil.nextInt(ratioBoosterSpecialLand) < ratioBoosterSpecialLandNumerator && specialLands != null) { addToBooster(booster, specialLands); } else { addToBooster(booster, basicLands); diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index 902185cc5ca..6b5fa163f18 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -32,7 +32,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 = 115; + private static final long CARD_CONTENT_VERSION = 116; private Dao cardDao; private Set classNames; @@ -159,7 +159,10 @@ public enum CardRepository { QueryBuilder qb = cardDao.queryBuilder(); qb.distinct().selectColumns("name"); Where where = qb.where(); - where.and(where.not().not().like("supertypes", '%' + SuperType.BASIC.name() + '%'), where.like("types", '%' + CardType.LAND.name() + '%')); + where.and( + where.not().like("supertypes", '%' + SuperType.BASIC.name() + '%'), + where.like("types", '%' + CardType.LAND.name() + '%') + ); List results = cardDao.query(qb.prepare()); for (CardInfo card : results) { int result = card.getName().indexOf(" // "); @@ -252,7 +255,10 @@ public enum CardRepository { QueryBuilder qb = cardDao.queryBuilder(); qb.distinct().selectColumns("name"); Where where = qb.where(); - where.and(where.not().like("types", '%' + CardType.CREATURE.name() + '%'), where.not().like("types", '%' + CardType.LAND.name() + '%')); + where.and( + where.not().like("types", '%' + CardType.CREATURE.name() + '%'), + where.not().like("types", '%' + CardType.LAND.name() + '%') + ); List results = cardDao.query(qb.prepare()); for (CardInfo card : results) { int result = card.getName().indexOf(" // "); @@ -275,7 +281,10 @@ public enum CardRepository { QueryBuilder qb = cardDao.queryBuilder(); qb.distinct().selectColumns("name"); Where where = qb.where(); - where.and(where.not().like("types", '%' + CardType.ARTIFACT.name() + '%'), where.not().like("types", '%' + CardType.LAND.name() + '%')); + where.and( + where.not().like("types", '%' + CardType.ARTIFACT.name() + '%'), + where.not().like("types", '%' + CardType.LAND.name() + '%') + ); List results = cardDao.query(qb.prepare()); for (CardInfo card : results) { int result = card.getName().indexOf(" // "); diff --git a/Mage/src/main/java/mage/constants/AsThoughEffectType.java b/Mage/src/main/java/mage/constants/AsThoughEffectType.java index 7afa2c60002..cf7a860cdff 100644 --- a/Mage/src/main/java/mage/constants/AsThoughEffectType.java +++ b/Mage/src/main/java/mage/constants/AsThoughEffectType.java @@ -18,6 +18,7 @@ public enum AsThoughEffectType { BLOCK_SWAMPWALK, BLOCK_MOUNTAINWALK, BLOCK_FORESTWALK, + DAMAGE_NOT_BLOCKED, BE_BLOCKED, PLAY_FROM_NOT_OWN_HAND_ZONE, CAST_AS_INSTANT, diff --git a/Mage/src/main/java/mage/designations/Monarch.java b/Mage/src/main/java/mage/designations/Monarch.java index b911345a940..0281b3c4590 100644 --- a/Mage/src/main/java/mage/designations/Monarch.java +++ b/Mage/src/main/java/mage/designations/Monarch.java @@ -84,8 +84,7 @@ class MonarchDealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbility public boolean checkTrigger(GameEvent event, Game game) { if (((DamagedPlayerEvent) event).isCombatDamage()) { MageObject damagingObject = game.getObject(event.getSourceId()); - if (damagingObject != null - && damagingObject instanceof Permanent + if (damagingObject instanceof Permanent && damagingObject.isCreature() && event.getTargetId().equals(game.getMonarchId())) { setControllerId(event.getPlayerId()); diff --git a/Mage/src/main/java/mage/filter/predicate/other/OwnerPredicate.java b/Mage/src/main/java/mage/filter/predicate/other/OwnerPredicate.java index f70c92b5cb9..1050e0d04a1 100644 --- a/Mage/src/main/java/mage/filter/predicate/other/OwnerPredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/other/OwnerPredicate.java @@ -30,18 +30,18 @@ public class OwnerPredicate implements ObjectPlayerPredicate> switch (targetOwner) { case YOU: - if (card.getOwnerId().equals(playerId)) { + if (card.isOwnedBy(playerId)) { return true; } break; case OPPONENT: - if (!card.getOwnerId().equals(playerId) + if (!card.isOwnedBy(playerId) && game.getPlayer(playerId).hasOpponent(card.getOwnerId(), game)) { return true; } break; case NOT_YOU: - if (!card.getOwnerId().equals(playerId)) { + if (!card.isOwnedBy(playerId)) { return true; } break; diff --git a/Mage/src/main/java/mage/filter/predicate/permanent/AttachedToControlledPermanentPredicate.java b/Mage/src/main/java/mage/filter/predicate/permanent/AttachedToControlledPermanentPredicate.java index afcbfc3eaa4..c8257e2c2dd 100644 --- a/Mage/src/main/java/mage/filter/predicate/permanent/AttachedToControlledPermanentPredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/permanent/AttachedToControlledPermanentPredicate.java @@ -17,7 +17,7 @@ public class AttachedToControlledPermanentPredicate implements ObjectPlayerPredi Permanent attachement = input.getObject(); if (attachement != null) { Permanent permanent = game.getPermanent(attachement.getAttachedTo()); - if (permanent != null && permanent.getControllerId().equals(input.getPlayerId())) { + if (permanent != null && permanent.isControlledBy(input.getPlayerId())) { return true; } } diff --git a/Mage/src/main/java/mage/filter/predicate/permanent/ControllerIsActivePlayerPredicate.java b/Mage/src/main/java/mage/filter/predicate/permanent/ControllerIsActivePlayerPredicate.java new file mode 100644 index 00000000000..1f0b7009741 --- /dev/null +++ b/Mage/src/main/java/mage/filter/predicate/permanent/ControllerIsActivePlayerPredicate.java @@ -0,0 +1,27 @@ + +package mage.filter.predicate.permanent; + +import mage.filter.predicate.Predicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.UUID; + +/** + * + * @author North + */ +public class ControllerIsActivePlayerPredicate implements Predicate { + @Override + public boolean apply(Permanent input, Game game) { + if(input.getControllerId() == null){ + return false; + } + return game.isActivePlayer(input.getControllerId()); + } + + @Override + public String toString() { + return "controlled by the active player"; + } +} diff --git a/Mage/src/main/java/mage/filter/predicate/permanent/ControllerPredicate.java b/Mage/src/main/java/mage/filter/predicate/permanent/ControllerPredicate.java index 1a90b57cb49..d77c180f958 100644 --- a/Mage/src/main/java/mage/filter/predicate/permanent/ControllerPredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/permanent/ControllerPredicate.java @@ -28,7 +28,7 @@ public class ControllerPredicate implements ObjectPlayerPredicate input, Game game) { - return input.getObject().getControllerId().equals(game.getCombat().getDefendingPlayerId(input.getSourceId(), game)); + return input.getObject().isControlledBy(game.getCombat().getDefendingPlayerId(input.getSourceId(), game)); } @Override diff --git a/Mage/src/main/java/mage/filter/predicate/permanent/DefendingPlayerOwnsCardPredicate.java b/Mage/src/main/java/mage/filter/predicate/permanent/DefendingPlayerOwnsCardPredicate.java index a0326cb54ec..fe044d827e1 100644 --- a/Mage/src/main/java/mage/filter/predicate/permanent/DefendingPlayerOwnsCardPredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/permanent/DefendingPlayerOwnsCardPredicate.java @@ -14,7 +14,7 @@ public class DefendingPlayerOwnsCardPredicate implements ObjectSourcePlayerPredi @Override public boolean apply(ObjectSourcePlayer input, Game game) { - return input.getObject().getOwnerId().equals(game.getCombat().getDefendingPlayerId(input.getSourceId(), game)); + return input.getObject().isOwnedBy(game.getCombat().getDefendingPlayerId(input.getSourceId(), game)); } @Override diff --git a/Mage/src/main/java/mage/game/Controllable.java b/Mage/src/main/java/mage/game/Controllable.java index aad1d744d13..025b8f3720d 100644 --- a/Mage/src/main/java/mage/game/Controllable.java +++ b/Mage/src/main/java/mage/game/Controllable.java @@ -10,4 +10,8 @@ import java.util.UUID; public interface Controllable { UUID getControllerId(); UUID getId(); + + default boolean isControlledBy(UUID controllerID){ + return getControllerId().equals(controllerID); + } } diff --git a/Mage/src/main/java/mage/game/Game.java b/Mage/src/main/java/mage/game/Game.java index 5ae398beeab..e499bf960b7 100644 --- a/Mage/src/main/java/mage/game/Game.java +++ b/Mage/src/main/java/mage/game/Game.java @@ -3,6 +3,8 @@ package mage.game; import java.io.Serializable; import java.util.*; +import java.util.stream.Collectors; + import mage.MageItem; import mage.MageObject; import mage.abilities.Ability; @@ -119,15 +121,17 @@ public interface Game extends MageItem, Serializable { * @param playerId * @return */ - default public Set getOpponents(UUID playerId) { - Set opponents = new HashSet<>(); + default Set getOpponents(UUID playerId) { Player player = getPlayer(playerId); - for (UUID opponentId : player.getInRange()) { - if (!opponentId.equals(playerId)) { - opponents.add(opponentId); - } - } - return opponents; + return player.getInRange().stream() + .filter(opponentId -> !opponentId.equals(playerId)) + .collect(Collectors.toSet()); + + } + + + default boolean isActivePlayer(UUID playerId){ + return getActivePlayerId().equals(playerId); } /** @@ -141,7 +145,7 @@ public interface Game extends MageItem, Serializable { * @param playerToCheckId * @return */ - default public boolean isOpponent(Player player, UUID playerToCheckId) { + default boolean isOpponent(Player player, UUID playerToCheckId) { return !player.getId().equals(playerToCheckId); } diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index 2292c2737b3..abfd93c49dc 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -1865,7 +1865,7 @@ public abstract class GameImpl implements Game, Serializable { //702.93e.: ...another player gains control // ...or the creature it's paired with leaves the battlefield. Permanent paired = perm.getPairedCard().getPermanent(this); - if (paired == null || !perm.getControllerId().equals(paired.getControllerId()) || paired.getPairedCard() == null) { + if (paired == null || !perm.isControlledBy(paired.getControllerId()) || paired.getPairedCard() == null) { perm.setPairedCard(null); if (paired != null && paired.getPairedCard() != null) { paired.setPairedCard(null); @@ -1876,7 +1876,7 @@ public abstract class GameImpl implements Game, Serializable { if (perm.getBandedCards() != null && !perm.getBandedCards().isEmpty()) { for (UUID bandedId : new ArrayList<>(perm.getBandedCards())) { Permanent banded = getPermanent(bandedId); - if (banded == null || !perm.getControllerId().equals(banded.getControllerId()) || !banded.getBandedCards().contains(perm.getId())) { + if (banded == null || !perm.isControlledBy(banded.getControllerId()) || !banded.getBandedCards().contains(perm.getId())) { perm.removeBandedCard(bandedId); if (banded != null && banded.getBandedCards().contains(perm.getId())) { banded.removeBandedCard(perm.getId()); @@ -1993,7 +1993,7 @@ public abstract class GameImpl implements Game, Serializable { } else if (target instanceof TargetCard) { Card attachedTo = getCard(perm.getAttachedTo()); if (attachedTo == null - || !((TargetCard) spellAbility.getTargets().get(0)).canTarget(perm.getControllerId(), perm.getAttachedTo(), spellAbility, this)) { + || !(spellAbility.getTargets().get(0)).canTarget(perm.getControllerId(), perm.getAttachedTo(), spellAbility, this)) { if (movePermanentToGraveyardWithInfo(perm)) { if (attachedTo != null) { attachedTo.removeAttachment(perm.getId(), this); @@ -2450,7 +2450,7 @@ public abstract class GameImpl implements Game, Serializable { @Override public boolean canPlaySorcery(UUID playerId) { - return isMainPhase() && getActivePlayerId().equals(playerId) && getStack().isEmpty(); + return isMainPhase() && isActivePlayer(playerId) && getStack().isEmpty(); } /** @@ -2482,7 +2482,7 @@ public abstract class GameImpl implements Game, Serializable { Set toOutside = new HashSet<>(); for (Iterator it = getBattlefield().getAllPermanents().iterator(); it.hasNext();) { Permanent perm = it.next(); - if (perm.getOwnerId().equals(playerId)) { + if (perm.isOwnedBy(playerId)) { if (perm.getAttachedTo() != null) { Permanent attachedTo = getPermanent(perm.getAttachedTo()); if (attachedTo != null) { @@ -2500,7 +2500,7 @@ public abstract class GameImpl implements Game, Serializable { } toOutside.add(perm); // it.remove(); - } else if (perm.getControllerId().equals(player.getId())) { + } else if (perm.isControlledBy(player.getId())) { // and any effects which give that player control of any objects or players end Effects: for (ContinuousEffect effect : getContinuousEffects().getLayeredEffects(this)) { @@ -2533,7 +2533,7 @@ public abstract class GameImpl implements Game, Serializable { } // Then, if that player controlled any objects on the stack not represented by cards, those objects cease to exist. this.getState().getContinuousEffects().removeInactiveEffects(this); - getStack().removeIf(object -> object.getControllerId().equals(playerId)); + getStack().removeIf(object -> object.isControlledBy(playerId)); // Then, if there are any objects still controlled by that player, those objects are exiled. applyEffects(); // to remove control from effects removed meanwhile List permanents = this.getBattlefield().getAllActivePermanents(playerId); @@ -2545,7 +2545,7 @@ public abstract class GameImpl implements Game, Serializable { for (ExileZone exile : this.getExile().getExileZones()) { for (Iterator it = exile.iterator(); it.hasNext();) { Card card = this.getCard(it.next()); - if (card != null && card.getOwnerId().equals(playerId)) { + if (card != null && card.isOwnedBy(playerId)) { it.remove(); } } @@ -2579,13 +2579,12 @@ public abstract class GameImpl implements Game, Serializable { } } } - Iterator> it = gameCards.entrySet().iterator(); while (it.hasNext()) { Entry entry = it.next(); Card card = entry.getValue(); - if (card.getOwnerId().equals(playerId)) { + if (card.isOwnedBy(playerId)) { it.remove(); } } @@ -2594,7 +2593,7 @@ public abstract class GameImpl implements Game, Serializable { // If the current monarch leaves the game. When that happens, the player whose turn it is becomes the monarch. // If the monarch leaves the game on their turn, the next player in turn order becomes the monarch. if (playerId.equals(getMonarchId())) { - if (!getActivePlayerId().equals(playerId)) { + if (!isActivePlayer(playerId)) { setMonarchId(null, getActivePlayerId()); } else { Player nextPlayer = getPlayerList().getNext(this); diff --git a/Mage/src/main/java/mage/game/combat/Combat.java b/Mage/src/main/java/mage/game/combat/Combat.java index 8fecec7c636..b9620a42cbb 100644 --- a/Mage/src/main/java/mage/game/combat/Combat.java +++ b/Mage/src/main/java/mage/game/combat/Combat.java @@ -209,7 +209,7 @@ public class Combat implements Serializable, Copyable { possibleDefenders = new HashSet<>(); for (UUID objectId : defenders) { Permanent planeswalker = game.getPermanent(objectId); - if (planeswalker != null && planeswalker.getControllerId().equals(playerToAttack)) { + if (planeswalker != null && planeswalker.isControlledBy(playerToAttack)) { possibleDefenders.add(objectId); } else if (playerToAttack.equals(objectId)) { possibleDefenders.add(objectId); @@ -964,7 +964,7 @@ public class Combat implements Serializable, Copyable { if (creatureForcedToBlock == null) { break; } - if (!creatureForcedToBlock.getControllerId().equals(player.getId())) { + if (!creatureForcedToBlock.isControlledBy(player.getId())) { // ignore creatures controlled by other players continue; } @@ -1473,7 +1473,7 @@ public class Combat implements Serializable, Copyable { } if (group.defenderIsPlaneswalker) { Permanent permanent = game.getPermanent(group.getDefenderId()); - if (permanent.getControllerId().equals(defenderId)) { + if (permanent.isControlledBy(defenderId)) { return true; } } diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index 235b2e774cb..31f316847ba 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -12,6 +12,7 @@ import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.TrampleAbility; +import mage.constants.AsThoughEffectType; import mage.constants.Outcome; import mage.filter.StaticFilters; import mage.game.Game; @@ -124,11 +125,14 @@ public class CombatGroup implements Serializable, Copyable { return; } else { Player player = game.getPlayer(defenderAssignsCombatDamage(game) ? defendingPlayerId : attacker.getControllerId()); - if (attacker.getAbilities().containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId())) { // for handling creatures like Thorn Elemental - if (player.chooseUse(Outcome.Damage, "Do you wish to assign damage for " + attacker.getLogName() + " as though it weren't blocked?", null, game)) { - blocked = false; - unblockedDamage(first, game); - } + if ((attacker.getAbilities().containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId()) && + player.chooseUse(Outcome.Damage, "Do you wish to assign damage for " + + attacker.getLogName() + " as though it weren't blocked?", null, game)) || + game.getContinuousEffects().asThough(attacker.getId(), AsThoughEffectType.DAMAGE_NOT_BLOCKED + , null, attacker.getControllerId(), game) != null) { + // for handling creatures like Thorn Elemental + blocked = false; + unblockedDamage(first, game); } if (blockers.size() == 1) { singleBlockerDamage(player, first, game); diff --git a/Mage/src/main/java/mage/game/command/emblems/AjaniAdversaryOfTyrantsEmblem.java b/Mage/src/main/java/mage/game/command/emblems/AjaniAdversaryOfTyrantsEmblem.java index 21f4e6ce1ca..3a74eac9dd7 100644 --- a/Mage/src/main/java/mage/game/command/emblems/AjaniAdversaryOfTyrantsEmblem.java +++ b/Mage/src/main/java/mage/game/command/emblems/AjaniAdversaryOfTyrantsEmblem.java @@ -3,12 +3,13 @@ package mage.game.command.emblems; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; import mage.constants.TargetController; +import mage.constants.Zone; import mage.game.command.Emblem; import mage.game.permanent.token.CatToken2; /** * - * @author spjspj + * @author TheElk801 */ public class AjaniAdversaryOfTyrantsEmblem extends Emblem { @@ -17,8 +18,8 @@ public class AjaniAdversaryOfTyrantsEmblem extends Emblem { this.setName("Emblem Ajani"); this.setExpansionSetCodeForImage("M19"); this.getAbilities().add(new BeginningOfEndStepTriggeredAbility( - new CreateTokenEffect(new CatToken2(), 3), - TargetController.YOU, false + Zone.COMMAND, new CreateTokenEffect(new CatToken2(), 3), + TargetController.YOU, null, false )); } } diff --git a/Mage/src/main/java/mage/game/command/emblems/AjaniSteadfastEmblem.java b/Mage/src/main/java/mage/game/command/emblems/AjaniSteadfastEmblem.java index 40675d7daf9..755291e0392 100644 --- a/Mage/src/main/java/mage/game/command/emblems/AjaniSteadfastEmblem.java +++ b/Mage/src/main/java/mage/game/command/emblems/AjaniSteadfastEmblem.java @@ -60,7 +60,7 @@ class AjaniSteadfastPreventEffect extends PreventionEffectImpl { if (event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { + if (permanent != null && permanent.isControlledBy(source.getControllerId())) { return super.applies(event, source, game); } } diff --git a/Mage/src/main/java/mage/game/command/emblems/DarettiScrapSavantEmblem.java b/Mage/src/main/java/mage/game/command/emblems/DarettiScrapSavantEmblem.java index 8e91c02d57d..246f783855c 100644 --- a/Mage/src/main/java/mage/game/command/emblems/DarettiScrapSavantEmblem.java +++ b/Mage/src/main/java/mage/game/command/emblems/DarettiScrapSavantEmblem.java @@ -59,7 +59,7 @@ class DarettiScrapSavantTriggeredAbility extends TriggeredAbilityImpl { if (zEvent.getToZone() == Zone.GRAVEYARD && zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getTarget().isArtifact() - && zEvent.getTarget().getOwnerId().equals(this.controllerId)) { + && zEvent.getTarget().isOwnedBy(this.controllerId)) { this.getEffects().setTargetPointer(new FixedTarget(zEvent.getTargetId())); return true; } diff --git a/Mage/src/main/java/mage/game/command/emblems/RowanKenrithEmblem.java b/Mage/src/main/java/mage/game/command/emblems/RowanKenrithEmblem.java index 5243df4bc1e..46ecdbb4e68 100644 --- a/Mage/src/main/java/mage/game/command/emblems/RowanKenrithEmblem.java +++ b/Mage/src/main/java/mage/game/command/emblems/RowanKenrithEmblem.java @@ -30,7 +30,7 @@ public class RowanKenrithEmblem extends Emblem { class RowanKenrithEmblemTriggeredAbility extends TriggeredAbilityImpl { RowanKenrithEmblemTriggeredAbility() { - super(Zone.BATTLEFIELD, new RowanKenrithEmblemEffect(), false); + super(Zone.COMMAND, new RowanKenrithEmblemEffect(), false); } RowanKenrithEmblemTriggeredAbility(final RowanKenrithEmblemTriggeredAbility ability) { diff --git a/Mage/src/main/java/mage/game/command/emblems/TezzeretArtificeMasterEmblem.java b/Mage/src/main/java/mage/game/command/emblems/TezzeretArtificeMasterEmblem.java index 24376c9a17b..397aac8c660 100644 --- a/Mage/src/main/java/mage/game/command/emblems/TezzeretArtificeMasterEmblem.java +++ b/Mage/src/main/java/mage/game/command/emblems/TezzeretArtificeMasterEmblem.java @@ -3,13 +3,14 @@ package mage.game.command.emblems; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.constants.TargetController; +import mage.constants.Zone; import mage.filter.common.FilterPermanentCard; import mage.game.command.Emblem; import mage.target.common.TargetCardInLibrary; /** * - * @author spjspj + * @author TheElk801 */ public class TezzeretArtificeMasterEmblem extends Emblem { @@ -18,9 +19,10 @@ public class TezzeretArtificeMasterEmblem extends Emblem { this.setName("Emblem Tezzeret"); this.setExpansionSetCodeForImage("M19"); this.getAbilities().add(new BeginningOfEndStepTriggeredAbility( + Zone.COMMAND, new SearchLibraryPutInPlayEffect( new TargetCardInLibrary(new FilterPermanentCard()) - ), TargetController.YOU, false + ), TargetController.YOU, null, false )); } } diff --git a/Mage/src/main/java/mage/game/command/planes/TrailOfTheMageRingsPlane.java b/Mage/src/main/java/mage/game/command/planes/TrailOfTheMageRingsPlane.java index 318f07c375c..1af66697987 100644 --- a/Mage/src/main/java/mage/game/command/planes/TrailOfTheMageRingsPlane.java +++ b/Mage/src/main/java/mage/game/command/planes/TrailOfTheMageRingsPlane.java @@ -115,7 +115,7 @@ class TrailOfTheMageRingsReboundEffect extends ContinuousEffectImpl { } for (Iterator iterator = game.getStack().iterator(); iterator.hasNext();) { StackObject stackObject = iterator.next(); - if (stackObject instanceof Spell && stackObject.getControllerId().equals(source.getControllerId())) { + if (stackObject instanceof Spell && stackObject.isControlledBy(source.getControllerId())) { Spell spell = (Spell) stackObject; Card card = spell.getCard(); if (card != null) { diff --git a/Mage/src/main/java/mage/game/permanent/Battlefield.java b/Mage/src/main/java/mage/game/permanent/Battlefield.java index 58eac0788e4..c9df6b058c6 100644 --- a/Mage/src/main/java/mage/game/permanent/Battlefield.java +++ b/Mage/src/main/java/mage/game/permanent/Battlefield.java @@ -58,7 +58,7 @@ public class Battlefield implements Serializable { public int countAll(FilterPermanent filter, UUID controllerId, Game game) { return (int) field.values() .stream() - .filter(permanent -> permanent.getControllerId().equals(controllerId) + .filter(permanent -> permanent.isControlledBy(controllerId) && filter.match(permanent, game) && permanent.isPhasedIn()) .count(); @@ -124,7 +124,7 @@ public class Battlefield implements Serializable { public boolean contains(FilterPermanent filter, UUID controllerId, int num, Game game) { return field.values() .stream() - .filter(permanent -> permanent.getControllerId().equals(controllerId) + .filter(permanent -> permanent.isControlledBy(controllerId) && filter.match(permanent, game) && permanent.isPhasedIn()) .count() >= num; @@ -213,7 +213,7 @@ public class Battlefield implements Serializable { return field.values() .stream() .filter(perm -> perm.isPhasedIn() - && perm.getControllerId().equals(controllerId)) + && perm.isControlledBy(controllerId)) .collect(Collectors.toList()); } @@ -261,7 +261,7 @@ public class Battlefield implements Serializable { public List getAllActivePermanents(FilterPermanent filter, UUID controllerId, Game game) { return field.values() .stream() - .filter(perm -> perm.isPhasedIn() && perm.getControllerId().equals(controllerId) && filter.match(perm, game)) + .filter(perm -> perm.isPhasedIn() && perm.isControlledBy(controllerId) && filter.match(perm, game)) .collect(Collectors.toList()); } @@ -333,14 +333,14 @@ public class Battlefield implements Serializable { .stream() .filter(perm -> perm.getAbilities().containsKey(PhasingAbility.getInstance().getId()) && perm.isPhasedIn() && - perm.getControllerId().equals(controllerId)) + perm.isControlledBy(controllerId)) .collect(Collectors.toList()); } public List getPhasedOut(UUID controllerId) { return field.values() .stream() - .filter(perm -> !perm.isPhasedIn() && perm.getControllerId().equals(controllerId)) + .filter(perm -> !perm.isPhasedIn() && perm.isControlledBy(controllerId)) .collect(Collectors.toList()); } diff --git a/Mage/src/main/java/mage/game/permanent/Permanent.java b/Mage/src/main/java/mage/game/permanent/Permanent.java index da6a39a9fac..1e17d0e8a9a 100644 --- a/Mage/src/main/java/mage/game/permanent/Permanent.java +++ b/Mage/src/main/java/mage/game/permanent/Permanent.java @@ -353,4 +353,11 @@ public interface Permanent extends Card, Controllable { void setCreateOrder(int createOrder); + default boolean isAttachedTo(UUID otherId){ + if(getAttachedTo() == null){ + return false; + } + return getAttachedTo().equals(otherId); + } + } diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index c90b047103b..fca0516e4d2 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java @@ -316,7 +316,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { @Override public void beginningOfTurn(Game game) { - if (game.getActivePlayerId().equals(this.controllerId)) { + if (game.isActivePlayer(this.controllerId)) { this.controlledFromStartOfControllerTurn = true; } } @@ -630,11 +630,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { @Override public List getConnectedCards(String key) { - if (this.connectedCards.containsKey(key)) { - return this.connectedCards.get(key); - } else { - return emptyList; - } + return this.connectedCards.getOrDefault(key, emptyList); } @Override diff --git a/Mage/src/main/java/mage/game/permanent/token/AvatarToken2.java b/Mage/src/main/java/mage/game/permanent/token/AvatarToken2.java index fa30088d285..b63e3e14c5b 100644 --- a/Mage/src/main/java/mage/game/permanent/token/AvatarToken2.java +++ b/Mage/src/main/java/mage/game/permanent/token/AvatarToken2.java @@ -6,8 +6,9 @@ import mage.constants.CardType; import mage.constants.SubType; public final class AvatarToken2 extends TokenImpl { + public AvatarToken2() { - super("Angel", "4/4 white Avatar creature token with flying"); + super("Avatar", "4/4 white Avatar creature token with flying"); cardType.add(CardType.CREATURE); color.setWhite(true); subtype.add(SubType.AVATAR); diff --git a/Mage/src/main/java/mage/game/permanent/token/BeastToken4.java b/Mage/src/main/java/mage/game/permanent/token/BeastToken4.java new file mode 100644 index 00000000000..d6b579b4514 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/BeastToken4.java @@ -0,0 +1,45 @@ + +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public final class BeastToken4 extends TokenImpl { + + public BeastToken4() { + this(null, 0); + } + + public BeastToken4(String setCode) { + this(setCode, 0); + } + + public BeastToken4(String setCode, int tokenType) { + super("Beast", "2/2 green Beast creature token"); + setOriginalExpansionSetCode(setCode != null ? setCode : "EXO"); + cardType.add(CardType.CREATURE); + color.setGreen(true); + subtype.add(SubType.BEAST); + power = new MageInt(2); + toughness = new MageInt(2); + + } + + public BeastToken4(final BeastToken4 token) { + super(token); + } + + @Override + public BeastToken4 copy() { + return new BeastToken4(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/BelzenlokDemonToken.java b/Mage/src/main/java/mage/game/permanent/token/BelzenlokDemonToken.java index 4ba0d93601d..81883c03a14 100644 --- a/Mage/src/main/java/mage/game/permanent/token/BelzenlokDemonToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/BelzenlokDemonToken.java @@ -21,6 +21,7 @@ import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.permanent.AnotherPredicate; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.players.Player; /** * @@ -94,9 +95,9 @@ class BelzenlokDemonTokenEffect extends OneShotEffect { if (otherCreatures > 0) { new SacrificeControllerEffect(filter, 1, "").apply(game, source); } else { - Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (permanent != null) { - permanent.damage(6, permanent.getId(), game, false, true); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + controller.damage(6, source.getSourceId(), game, false, true); } } return true; diff --git a/Mage/src/main/java/mage/game/permanent/token/YoungPyromancerElementalToken.java b/Mage/src/main/java/mage/game/permanent/token/YoungPyromancerElementalToken.java index f304fc3a0f4..a59f93d0694 100644 --- a/Mage/src/main/java/mage/game/permanent/token/YoungPyromancerElementalToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/YoungPyromancerElementalToken.java @@ -1,4 +1,3 @@ - package mage.game.permanent.token; import mage.MageInt; @@ -13,7 +12,7 @@ import mage.util.RandomUtil; public final class YoungPyromancerElementalToken extends TokenImpl { public YoungPyromancerElementalToken() { - super("Elemental", "1/1 red Elemental creature"); + super("Elemental", "1/1 red Elemental creature token"); if (getOriginalExpansionSetCode() != null && getOriginalExpansionSetCode().equals("M14")) { setTokenType(RandomUtil.nextInt(2) + 1); } diff --git a/Mage/src/main/java/mage/game/stack/Spell.java b/Mage/src/main/java/mage/game/stack/Spell.java index c729298ce46..3d137719f8a 100644 --- a/Mage/src/main/java/mage/game/stack/Spell.java +++ b/Mage/src/main/java/mage/game/stack/Spell.java @@ -244,7 +244,7 @@ public class Spell extends StackObjImpl implements Card { // card will be copied during putOntoBattlefield, so the card of CardPermanent has to be changed // TODO: Find a better way to prevent bestow creatures from being effected by creature affecting abilities Permanent permanent = game.getPermanent(card.getId()); - if (permanent != null && permanent instanceof PermanentCard) { + if (permanent instanceof PermanentCard) { permanent.setSpellAbility(ability); // otherwise spell ability without bestow will be set if (!card.getCardType().contains(CardType.CREATURE)) { card.addCardType(CardType.CREATURE); @@ -264,7 +264,7 @@ public class Spell extends StackObjImpl implements Card { updateOptionalCosts(0); if (controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null)) { Permanent permanent = game.getPermanent(card.getId()); - if (permanent != null && permanent instanceof PermanentCard) { + if (permanent instanceof PermanentCard) { ((PermanentCard) permanent).getCard().addCardType(CardType.CREATURE); ((PermanentCard) permanent).getCard().getSubtype(game).remove(SubType.AURA); return true; diff --git a/Mage/src/main/java/mage/game/stack/SpellStack.java b/Mage/src/main/java/mage/game/stack/SpellStack.java index 71ad426f8bb..8b697ba5345 100644 --- a/Mage/src/main/java/mage/game/stack/SpellStack.java +++ b/Mage/src/main/java/mage/game/stack/SpellStack.java @@ -89,10 +89,10 @@ public class SpellStack extends ArrayDeque { game.informPlayers(counteredObjectName + " is countered by " + sourceObject.getLogName()); } game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COUNTERED, objectId, sourceId, stackObject.getControllerId())); + return true; } else if (!game.isSimulation()) { game.informPlayers(counteredObjectName + " could not be countered by " + sourceObject.getLogName()); } - return true; } return false; } diff --git a/Mage/src/main/java/mage/players/Library.java b/Mage/src/main/java/mage/players/Library.java index 5841a85ce91..3c896d5b837 100644 --- a/Mage/src/main/java/mage/players/Library.java +++ b/Mage/src/main/java/mage/players/Library.java @@ -101,7 +101,7 @@ public class Library implements Serializable { } public void putOnTop(Card card, Game game) { - if (card.getOwnerId().equals(playerId)) { + if (card.isOwnedBy(playerId)) { card.setZone(Zone.LIBRARY, game); library.addFirst(card.getId()); } else { @@ -125,7 +125,7 @@ public class Library implements Serializable { } public void putOnBottom(Card card, Game game) { - if (card.getOwnerId().equals(playerId)) { + if (card.isOwnedBy(playerId)) { card.setZone(Zone.LIBRARY, game); library.remove(card.getId()); library.add(card.getId()); diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 39d60b01ffd..423ae4e208a 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -645,7 +645,7 @@ public abstract class PlayerImpl implements Player, Serializable { */ @Override public boolean putInHand(Card card, Game game) { - if (card.getOwnerId().equals(playerId)) { + if (card.isOwnedBy(playerId)) { card.setZone(Zone.HAND, game); this.hand.add(card); } else { @@ -834,7 +834,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean putInGraveyard(Card card, Game game) { - if (card.getOwnerId().equals(playerId)) { + if (card.isOwnedBy(playerId)) { this.graveyard.add(card); } else { return game.getPlayer(card.getOwnerId()).putInGraveyard(card, game); @@ -885,7 +885,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean putCardOnTopXOfLibrary(Card card, Game game, Ability source, int xFromTheTop) { - if (card.getOwnerId().equals(getId())) { + if (card.isOwnedBy(getId())) { if (library.size() + 1 < xFromTheTop) { putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, true); } else { @@ -1470,7 +1470,7 @@ public abstract class PlayerImpl implements Player, Serializable { } protected boolean isActivePlayer(Game game) { - return game.getActivePlayerId().equals(this.playerId); + return game.isActivePlayer(this.playerId); } @Override @@ -1556,7 +1556,7 @@ public abstract class PlayerImpl implements Player, Serializable { // that phased out indirectly won't phase in by itself, but instead phases in // along with the card it's attached to. Permanent attachedTo = game.getPermanent(permanent.getAttachedTo()); - if (!(attachedTo != null && attachedTo.getControllerId().equals(this.getId()))) { + if (!(attachedTo != null && attachedTo.isControlledBy(this.getId()))) { permanent.phaseOut(game, false); } } @@ -2325,7 +2325,7 @@ public abstract class PlayerImpl implements Player, Serializable { setStoredBookmark(game.bookmarkState()); // makes it possible to UNDO a declared attacker with costs from e.g. Propaganda } Permanent attacker = game.getPermanent(attackerId); - if (attacker != null && attacker.canAttack(defenderId, game) && attacker.getControllerId().equals(playerId)) { + if (attacker != null && attacker.canAttack(defenderId, game) && attacker.isControlledBy(playerId)) { if (!game.getCombat().declareAttacker(attackerId, defenderId, playerId, game)) { game.undo(playerId); } @@ -2647,6 +2647,7 @@ public abstract class PlayerImpl implements Player, Serializable { available.addMana(manaAbilities, game); } for (Abilities manaAbilities : sourceWithCosts) { + available.removeDuplicated(); available.addManaWithCost(manaAbilities, game); } @@ -2955,9 +2956,7 @@ public abstract class PlayerImpl implements Player, Serializable { // Other activated abilities LinkedHashMap useable = new LinkedHashMap<>(); getOtherUseableActivatedAbilities(card, Zone.GRAVEYARD, game, useable); - for (Ability ability : useable.values()) { - playable.add(ability); - } + playable.addAll(useable.values()); } for (ExileZone exile : game.getExile().getExileZones()) { for (Card card : exile.getCards(game)) { @@ -3024,7 +3023,7 @@ public abstract class PlayerImpl implements Player, Serializable { // activated abilities from objects in the command zone (emblems or commanders) for (CommandObject commandObject : game.getState().getCommand()) { for (ActivatedAbility ability : commandObject.getAbilities().getActivatedAbilities(Zone.COMMAND)) { - if (ability.getControllerId().equals(getId()) && canPlay(ability, availableMana, game.getObject(ability.getSourceId()), game)) { + if (ability.isControlledBy(getId()) && canPlay(ability, availableMana, game.getObject(ability.getSourceId()), game)) { playableActivated.put(ability.toString(), ability); } @@ -3579,7 +3578,7 @@ public abstract class PlayerImpl implements Player, Serializable { game.informPlayers(getLogName() + " puts " + (withName ? card.getLogName() : (card.isFaceDown(game) ? "a face down card" : "a card")) + " from " + fromZone.toString().toLowerCase(Locale.ENGLISH) + ' ' - + (card.getOwnerId().equals(this.getId()) ? "into their hand" : "into its owner's hand") + + (card.isOwnedBy(this.getId()) ? "into their hand" : "into its owner's hand") ); } result = true; @@ -3602,7 +3601,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (cards.isEmpty()) { ownerId = card.getOwnerId(); } - if (card.getOwnerId().equals(ownerId)) { + if (card.isOwnedBy(ownerId)) { it.remove(); cards.add(card); } @@ -3673,7 +3672,7 @@ public abstract class PlayerImpl implements Player, Serializable { StringBuilder sb = new StringBuilder(this.getLogName()) .append(" puts ").append(card.getLogName()).append(' ').append(card.isCopy() ? "(Copy) " : "") .append(fromZone != null ? "from " + fromZone.toString().toLowerCase(Locale.ENGLISH) + ' ' : ""); - if (card.getOwnerId().equals(getId())) { + if (card.isOwnedBy(getId())) { sb.append("into their graveyard"); } else { sb.append("it into its owner's graveyard"); @@ -3705,7 +3704,7 @@ public abstract class PlayerImpl implements Player, Serializable { sb.append("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(' '); } sb.append("to the ").append(toTop ? "top" : "bottom"); - if (card.getOwnerId().equals(getId())) { + if (card.isOwnedBy(getId())) { sb.append(" of their library"); } else { Player player = game.getPlayer(card.getOwnerId()); diff --git a/Mage/src/main/java/mage/target/common/TargetCardInASingleGraveyard.java b/Mage/src/main/java/mage/target/common/TargetCardInASingleGraveyard.java index b2a4e937e3b..86721777d32 100644 --- a/Mage/src/main/java/mage/target/common/TargetCardInASingleGraveyard.java +++ b/Mage/src/main/java/mage/target/common/TargetCardInASingleGraveyard.java @@ -34,7 +34,7 @@ public class TargetCardInASingleGraveyard extends TargetCard { Card card = game.getCard(firstTarget); Card targetCard = game.getCard(id); if (card == null || targetCard == null - || !card.getOwnerId().equals(targetCard.getOwnerId())) { + || !card.isOwnedBy(targetCard.getOwnerId())) { return false; } } diff --git a/Mage/src/main/java/mage/target/common/TargetCardInOpponentsGraveyard.java b/Mage/src/main/java/mage/target/common/TargetCardInOpponentsGraveyard.java index 13676b8da12..4ebbfa167fd 100644 --- a/Mage/src/main/java/mage/target/common/TargetCardInOpponentsGraveyard.java +++ b/Mage/src/main/java/mage/target/common/TargetCardInOpponentsGraveyard.java @@ -40,7 +40,7 @@ public class TargetCardInOpponentsGraveyard extends TargetCard { if (game.getPlayer(source.getControllerId()).hasOpponent(card.getOwnerId(), game)) { if (allFromOneOpponent && !targets.isEmpty()) { Card firstCard = game.getCard(targets.keySet().iterator().next()); - if (firstCard != null && !card.getOwnerId().equals(firstCard.getOwnerId())) { + if (firstCard != null && !card.isOwnedBy(firstCard.getOwnerId())) { return false; } } diff --git a/Mage/src/main/java/mage/target/common/TargetCreaturePermanentSameController.java b/Mage/src/main/java/mage/target/common/TargetCreaturePermanentSameController.java index 107a65d47f6..642440373a3 100644 --- a/Mage/src/main/java/mage/target/common/TargetCreaturePermanentSameController.java +++ b/Mage/src/main/java/mage/target/common/TargetCreaturePermanentSameController.java @@ -31,7 +31,7 @@ public class TargetCreaturePermanentSameController extends TargetCreaturePermane Permanent targetPermanent = game.getPermanent(targetId); if (targetPermanent != null) { if (!firstTargetPermanent.getId().equals(targetPermanent.getId())) { - if (!firstTargetPermanent.getControllerId().equals(targetPermanent.getOwnerId())) { + if (!firstTargetPermanent.isControlledBy(targetPermanent.getOwnerId())) { return false; } } diff --git a/Mage/src/main/java/mage/target/common/TargetTriggeredAbility.java b/Mage/src/main/java/mage/target/common/TargetTriggeredAbility.java index b0bad5fe749..5efeb3552d5 100644 --- a/Mage/src/main/java/mage/target/common/TargetTriggeredAbility.java +++ b/Mage/src/main/java/mage/target/common/TargetTriggeredAbility.java @@ -40,7 +40,7 @@ public class TargetTriggeredAbility extends TargetObject { return stackObject.getStackAbility() != null && (stackObject.getStackAbility() instanceof TriggeredAbility) && source != null - && stackObject.getStackAbility().getControllerId().equals(source.getControllerId()); + && stackObject.getStackAbility().isControlledBy(source.getControllerId()); } @Override @@ -53,7 +53,7 @@ public class TargetTriggeredAbility extends TargetObject { for (StackObject stackObject : game.getStack()) { if (stackObject.getStackAbility() != null && stackObject.getStackAbility() instanceof TriggeredAbility - && stackObject.getStackAbility().getControllerId().equals(sourceControllerId)) { + && stackObject.getStackAbility().isControlledBy(sourceControllerId)) { return true; } } @@ -71,7 +71,7 @@ public class TargetTriggeredAbility extends TargetObject { for (StackObject stackObject : game.getStack()) { if (stackObject.getStackAbility() != null && stackObject.getStackAbility() instanceof TriggeredAbility - && stackObject.getStackAbility().getControllerId().equals(sourceControllerId)) { + && stackObject.getStackAbility().isControlledBy(sourceControllerId)) { possibleTargets.add(stackObject.getStackAbility().getId()); } } diff --git a/Mage/src/main/java/mage/watchers/common/AttackedLastTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/AttackedLastTurnWatcher.java index 78eb6c67180..b8ca0dd44a4 100644 --- a/Mage/src/main/java/mage/watchers/common/AttackedLastTurnWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/AttackedLastTurnWatcher.java @@ -30,13 +30,11 @@ public class AttackedLastTurnWatcher extends Watcher { public AttackedLastTurnWatcher(final AttackedLastTurnWatcher watcher) { super(watcher); for (Entry> entry : watcher.attackedLastTurnCreatures.entrySet()) { - Set allAttackersCopy = new HashSet<>(); - allAttackersCopy.addAll(entry.getValue()); + Set allAttackersCopy = new HashSet<>(entry.getValue()); attackedLastTurnCreatures.put(entry.getKey(), allAttackersCopy); } for (Entry> entry : watcher.attackedThisTurnCreatures.entrySet()) { - Set allAttackersCopy = new HashSet<>(); - allAttackersCopy.addAll(entry.getValue()); + Set allAttackersCopy = new HashSet<>(entry.getValue()); attackedThisTurnCreatures.put(entry.getKey(), allAttackersCopy); } } diff --git a/Mage/src/main/java/mage/watchers/common/PermanentsEnteredBattlefieldYourLastTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/PermanentsEnteredBattlefieldYourLastTurnWatcher.java index 04db06ff031..331602e3f1f 100644 --- a/Mage/src/main/java/mage/watchers/common/PermanentsEnteredBattlefieldYourLastTurnWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/PermanentsEnteredBattlefieldYourLastTurnWatcher.java @@ -76,7 +76,7 @@ public class PermanentsEnteredBattlefieldYourLastTurnWatcher extends Watcher { } public List getPermanentsEnteringOnPlayersLastTurn(Game game, UUID playerId) { - if (game.getActivePlayerId().equals(playerId)) { + if (game.isActivePlayer(playerId)) { return enteringBattlefield.get(playerId); } return enteringBattlefieldLastTurn.get(playerId); diff --git a/Mage/src/main/java/mage/watchers/common/WasBlockedThisTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/WasBlockedThisTurnWatcher.java new file mode 100644 index 00000000000..65e44a07afc --- /dev/null +++ b/Mage/src/main/java/mage/watchers/common/WasBlockedThisTurnWatcher.java @@ -0,0 +1,53 @@ + +package mage.watchers.common; + +import mage.MageObjectReference; +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.watchers.Watcher; + +import java.util.HashSet; +import java.util.Set; + +/** + * + * @author noahg + */ +public class WasBlockedThisTurnWatcher extends Watcher { + + private final Set wasBlockedThisTurnCreatures; + + public WasBlockedThisTurnWatcher() { + super(WasBlockedThisTurnWatcher.class.getSimpleName(), WatcherScope.GAME); + wasBlockedThisTurnCreatures = new HashSet<>(); + } + + public WasBlockedThisTurnWatcher(final WasBlockedThisTurnWatcher watcher) { + super(watcher); + wasBlockedThisTurnCreatures = new HashSet<>(watcher.wasBlockedThisTurnCreatures); + } + + @Override + public Watcher copy() { + return new WasBlockedThisTurnWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED) { + this.wasBlockedThisTurnCreatures.add(new MageObjectReference(event.getTargetId(), game)); + } + } + + public Set getWasBlockedThisTurnCreatures() { + return this.wasBlockedThisTurnCreatures; + } + + @Override + public void reset() { + super.reset(); + wasBlockedThisTurnCreatures.clear(); + } + +} diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 5b095175494..8a284e2497a 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -29584,7 +29584,7 @@ Wailing Ghoul|Eldritch Moon|112|C|{1}{B}|Creature - Zombie|1|3|When Wailing Ghou Weirded Vampire|Eldritch Moon|113|C|{3}{B}|Creature - Vampire Horror|3|3|Madness {2}{B} (If you discard this card, discard it into exile. When you do, cast it for its madness cost or put it into your graveyard.)| Whispers of Emrakul|Eldritch Moon|114|U|{1}{B}|Sorcery|||Target opponent discards a card at random.$Delirium — If there are four or more card types among cards in your graveyard, that player discards two cards at random instead.| Abandon Reason|Eldritch Moon|115|U|{2}{R}|Instant|||Up to two target creatures each get +1/+0 and gain first strike until end of turn.$Madness {1}{R} (If you discard this card, discard it into exile. When you do, cast it for its madness cost or put it into your graveyard.)| -Alchemist's GreetinG|Eldritch Moon|116|C|{4}{R}|Sorcery|||Alchemist's Greeting deals 4 damage to target creature.$Madness {1}{R} (If you discard this card, discard it into exile. When you do, cast it for its madness cost or put it into your graveyard.)| +Alchemist's Greeting|Eldritch Moon|116|C|{4}{R}|Sorcery|||Alchemist's Greeting deals 4 damage to target creature.$Madness {1}{R} (If you discard this card, discard it into exile. When you do, cast it for its madness cost or put it into your graveyard.)| Assembled Alphas|Eldritch Moon|117|R|{5}{R}|Creature - Wolf|5|5|Whenever Assembled Alphas blocks or becomes blocked by a creature, Assembled Alphas deals 3 damage to that creature and 3 damage to that creature's controller.| Bedlam Reveler|Eldritch Moon|118|R|{6}{R}{R}|Creature - Devil Horror|3|4|Bedlam Reveler costs {1} less to cast for each instant or sorcery card in your graveyard.$Prowess (Whenever you cast a noncreature spell, this creature gets +1/+1 until end of turn.)$When Bedlam Reveler enters the battlefield, discard your hand, then draw three cards.| Blood Mist|Eldritch Moon|119|U|{3}{R}|Enchantment|||At the beginning of combat on your turn, target creature you control gains double strike until end of turn.| @@ -30466,7 +30466,7 @@ Skyship Plunderer|Aether Revolt|46|U|{1}{U}|Creature - Human Pirate|2|1|Flying$W Take into Custody|Aether Revolt|47|C|{U}|Instant|||Tap target creature. It doesn't untap during its controller's next untap step.| Trophy Mage|Aether Revolt|48|U|{2}{U}|Creature - Human Wizard|2|2|When Trophy Mage enters the battlefield, you may search your library for an artifact card with converted mana cost 3, reveal it, put it into your hand, then shuffle your library.| Whir of Invention|Aether Revolt|49|R|{X}{U}{U}{U}|Instant|||Improvise (Your artifacts can help cast this spell. Each artifact you tap after you're done activating mana abilities pays for {1}.)$Search your library for an artifact card with converted mana cost X or less, put it onto the battlefield, then shuffle your library.| -Wind-King Raiders|Aether Revolt|50|U|{4}{U}{U}|Creature - Human Artificer|4|3|Improvise (Your artifacts can help cast this spell. Each artifact you tap after you're done activating mana abilities pays for {1}.)$Flying| +Wind-Kin Raiders|Aether Revolt|50|U|{4}{U}{U}|Creature - Human Artificer|4|3|Improvise (Your artifacts can help cast this spell. Each artifact you tap after you're done activating mana abilities pays for {1}.)$Flying| Aether Poisoner|Aether Revolt|51|C|{1}{B}|Creature - Human Artificer|1|1|Deathtouch (Any amount of damage this deals to a creature is enough to destroy it.)$When Aether Poisoner enters the battlefield, you get {E}{E} (two energy counters).$Whenever Aether Poisoner attacks, you may pay {E}{E}. If you do, create a 1/1 colorless Servo artifact creature token.| Alley Strangler|Aether Revolt|52|C|{2}{B}|Creature - Aetherborn Rogue|2|3|Menace| Battle at the Bridge|Aether Revolt|53|R|{X}{B}|Sorcery|||Improvise (Your artifacts can help cast this spell. Each artifact you tap after you're done activating mana abilities pays for {1}.)$Target creature gets -X/-X until end of turn. You gain X life.| @@ -32680,7 +32680,7 @@ Famished Paladin|Rivals of Ixalan|8|U|{1}{W}|Creature - Vampire Knight|3|3|Famis Forerunner of the Legion|Rivals of Ixalan|9|U|{2}{W}|Creature - Vampire Knight|2|2|When Forerunner of the Legion enters the battlefield, you may search your library for a Vampire card, reveal it, then shuffle your library and put that card on top of it.$Whenever another Vampire enters the battlefield under your control, target creature gets +1/+1 until end of turn.| Imperial Ceratops|Rivals of Ixalan|10|U|{4}{W}|Creature - Dinosaur|3|5|Enrage - Whenever Imperial Ceratops is dealt damage, you gain 2 life.| Legion Conquistador|Rivals of Ixalan|11|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.| -Luminous Bond|Rivals of Ixalan|12|C|{2}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature can't attack or block.| +Luminous Bonds|Rivals of Ixalan|12|C|{2}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature can't attack or block.| Majestic Heliopterus|Rivals of Ixalan|13|U|{3}{W}|Creature - Dinosaur|2|2|Flying$Whenever Majestic Heliopterus attacks, another target Dinosaur you control gains flying until end of turn.| Martyr of Dusk|Rivals of Ixalan|14|C|{1}{W}|Creature - Vampire Soldier|2|1|When Martyr of Dusk dies, create a 1/1 white Vampire creature token with lifelink.| Moment of Triumph|Rivals of Ixalan|15|C|{W}|Instant|||Target creature gets +2/+2 until end of turn. You gain 2 life.| @@ -32711,10 +32711,10 @@ Hornswoggle|Rivals of Ixalan|39|U|{2}{U}|Instant|||Counter target creature spell Induced Amnesia|Rivals of Ixalan|40|R|{2}{U}|Enchantment|||When Induced Amnesia enters the battlefield, target player exiles all the cards in his or her hand face down, then draws that many cards.$When Induced Amnesia is put into a graveyard from the battlefield, return the exiled cards to their owner's hand.| Kitesail Corsair|Rivals of Ixalan|41|C|{1}{U}|Creature - Human Pirate|2|1|Kitesail Corsair has flying as long as it's attacking.| Kumena's Awakening|Rivals of Ixalan|42|R|{2}{U}{U}|Enchantment|||Ascend (If you control ten or more permenants, you get the city's blessing for the rest of the game.)$At the beginning of your upkeep, each player draws a card. If you have the city's blessing, instead only you draw a card.| -Mist-Cloacked Herald|Rivals of Ixalan|43|C|{U}|Creature - Merfolk Warrior|1|1|Mist-Cloaked Herald can't be blocked.| +Mist-Cloaked Herald|Rivals of Ixalan|43|C|{U}|Creature - Merfolk Warrior|1|1|Mist-Cloaked Herald can't be blocked.| Negate|Rivals of Ixalan|44|C|{1}{U}|Instant|||Counter target noncreature spell.| Nezahal, Primal Tide|Rivals of Ixalan|45|M|{5}{U}{U}|Legendary Creature - Elder Dinosaur|7|7|Nezahal, Primal Tide can't be countered.$You have no maximum hand size.$Whenever an opponent casts a noncreature spell, draw a card.$Discard three cards: Exile Nezahal. Return it to the battlefield tapped under its owner's control at the beginning of the next end step.| -Return to the Wind|Rivals of Ixalan|46|R|{2}{U}|Instant|||Exile target nonland permanent. For as long as that card remains exiled, its owner may cast it without paying its mana cost.| +Release to the Wind|Rivals of Ixalan|46|R|{2}{U}|Instant|||Exile target nonland permanent. For as long as that card remains exiled, its owner may cast it without paying its mana cost.| River Darter|Rivals of Ixalan|47|C|{2}{U}|Creature - Merfolk Warrior|2|3|River Darter can't be blocked by Dinosaurs.| Riverwise Augur|Rivals of Ixalan|48|U|{3}{U}|Creature - Merfolk Wizard|2|2|When Riverwise Augur enters the battlefield, draw three cards, then put two cards from your hand on top of your library in any order. | Sailor of Means|Rivals of Ixalan|49|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." | @@ -32726,7 +32726,7 @@ Siren Reaver|Rivals of Ixalan|54|U|{3}{U}|Creature - Siren Pirate|3|2|Raid(If you control ten or more permanents, you get the city's blessing for the rest of the game.)$As long as you have the city's blessing Slippery Scoundrel has Hexproof and can't be blocked.| Soul of the Rapids|Rivals of Ixalan|56|C|{3}{U}{U}|Creature - Elemental|3|2|Flying$Hexproof (This creature can't be the target of spells or abilities your opponents control.)| Spire Winder|Rivals of Ixalan|57|C|{3}{U}|Creature - snake|2|3|Flying$Ascend (If you control ten or more permanents, you get the city's blessing for the rest of the game.)$Spire Winder gets +1/+1 as long as you have the city's blessing.| -Sworn Gaurdian|Rivals of Ixalan|58|C|{1}{U}|Creature - Merfolk Warrior|1|3|| +Sworn Guardian|Rivals of Ixalan|58|C|{1}{U}|Creature - Merfolk Warrior|1|3|| Timestream Navigator|Rivals of Ixalan|59|M|{1}{U}|Creature - Human Pirate Wizard|1|1|Ascend (If you control ten or more permanents, you get the city's blessing for the rest of the game.)${2}{U}{U}, {T}, Put Timestream Navigator on the bottom of its owner's library: Take an extra turn after this one. Activate this ability only if you have the city's blessing.| Warkite Marauder|Rivals of Ixalan|60|R|{1}{U}|Creature - Human Pirate|2|1|Flying$Whenever Warkite Marauder attacks, target creature defending player controls loses all abilities and has base power and toughness 0/1 until end of turn.| Waterknot|Rivals of Ixalan|61|C|{1}{U}{U}|Enchantment - Aura|||Enchant Crerature$When Waterknot enters the battlefield, tap enchanted creature.$Enchanted creature doesn't untap during it's controller's untap step.| @@ -32788,7 +32788,7 @@ Stampeding Horncrest|Rivals of Ixalan|116|C|{4}{R}|Creature - Dinosaur|4|4|Stamp Storm Fleet Swashbuckler|Rivals of Ixalan|117|U|{1}{R}|Creature - Human Pirate|2|2|Ascend (If you control 10 or more permanents, you gain the city's blessing for the rest of the game.)$Storm Fleet Swashbuckler has double strike as long as you have the city's blessing.| Sun-Collared Raptor|Rivals of Ixalan|118|C|{1}{R}|Creature - Dinosaur|1|2|Trample${2}{R}: Sun-Collared Raptor gets +3/+0 until end of turn.| Swaggering Corsair|Rivals of Ixalan|119|C|{2}{R}|Creature - Human Pirate|2|2|Raid — Swaggering Corsair enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.| -Tilonali's Crown|Rivals of Ixalan|120|C|{1}{R}|Enchantment - Aura|||Enchant creature$When Tilonali's Crown enters the battlefield, it deals 1 damage to enchanted creature.$Enchanted creature gets +3/+0 and has trample.| +Tilonalli's Crown|Rivals of Ixalan|120|C|{1}{R}|Enchantment - Aura|||Enchant creature$When Tilonali's Crown enters the battlefield, it deals 1 damage to enchanted creature.$Enchanted creature gets +3/+0 and has trample.| Tilonalli's Summoner|Rivals of Ixalan|121|R|{1}{R}|Creature - Human Shaman|1|1|Ascend (If you control ten or more permanents, you get the city's blessing for the rest of the game.)$Whenever Tilonalli's Summoner attacks, you may pay {X}{R}. If you do, create X 1/1 Elemental creature tokens that are tapped and attacking. At the beginning of the next end step, exile those tokens unless you have the city's blessing.| Aggressive Urge|Rivals of Ixalan|122|C|{1}{G}|Instant|||Target creature gets +1/+1 until end of turn.$Draw a card.| Cacophodon|Rivals of Ixalan|123|U|{3}{G}|Creature - Dinosaur|2|5|Enrage — Whenever Cacophodon is dealt damage, untap target permanent.| @@ -32810,7 +32810,7 @@ Knight of the Stampede|Rivals of Ixalan|138|C|{3}{G}|Creature - Human Knight|2|4 Naturalize|Rivals of Ixalan|139|C|{1}{G}|Instant|||Destroy target artifact or enchantment.| Orazca Frillback|Rivals of Ixalan|140|C|{2}{G}|Creature - Dinosaur|4|2|| Overgrown Armasaur|Rivals of Ixalan|141|C|{3}{G}{G}|Creature - Dinosaur|4|4|Enrage — Whenever Overgrown Armasaur is dealt damage, create a 1/1 green Saproling creature token.| -Path to Discovery|Rivals of Ixalan|142|R|{3}{G}|Enchantment|||Whenever a creature enters the battlefield under your control, 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 the creature, then put the card back or put it into your graveyard.)| +Path of Discovery|Rivals of Ixalan|142|R|{3}{G}|Enchantment|||Whenever a creature enters the battlefield under your control, 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 the creature, then put the card back or put it into your graveyard.)| Plummet|Rivals of Ixalan|143|C|{1}{G}|Instant|||Destroy target creature with flying.| Polyraptor|Rivals of Ixalan|144|M|{6}{G}{G}|Creature - Dinosaur|5|5|Enrage — Whenever Polyraptor is dealt damage, create a token that is a copy of Polyraptor.| Strength of the Pack|Rivals of Ixalan|145|U|{4}{G}{G}|Sorcery|||Put two +1/+1 counters on each creature you control.| @@ -33858,6 +33858,7 @@ Serra's Guardian|Core Set 2019|284|R|{4}{W}{W}|Creature - Angel|5|5|Flying$Vigil Silverbeak Griffin|Core Set 2019|285|C|{W}{W}|Creature - Griffin|2|2|Flying| Tezzeret, Cruel Machinist|Core Set 2019|286|M|{4}{U}{U}|Legendary Planeswalker - Tezzeret|4|+1: Draw a card.$0: Until your next turn, target artifact you control becomes a 5/5 creature in addition to its other types.$−7: Put any number of cards from your hand onto the battlefield face down. They're 5/5 artifact creatures.| Riddlemaster Sphinx|Core Set 2019|287|R|{4}{U}{U}|Creature - Sphinx|5|5|Flying$When Riddlemaster Sphinx enters the battlefield, you may return target creature an opponent controls to its owner's hand.| +Pendulum of Patterns|Core Set 2019|288|C|{2}|Artifact|||When Pendulum of Patterns enters the battlefield, you gain 3 life.${5}, {T}, Sacrifice Pendulum of Patterns: Draw a card.| Tezzeret's Gatebreaker|Core Set 2019|289|R|{4}|Artifact|||When Tezzeret's Gatebreaker enters the battlefield, look at the top five cards of your library. You may reveal a blue or artifact card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.${5}{U}, {T}, Sacrifice Tezzeret's Gatebreaker: Creatures you control can't be blocked this turn.| Tezzeret's Strider|Core Set 2019|290|U|{3}|Artifact Creature - Golem|3|1|As long as you control a Tezzeret planeswalker, Tezzeret's Strider has menace.| Liliana, the Necromancer|Core Set 2019|291|M|{3}{B}{B}|Legendary Planeswalker - Liliana|4|+1: Target player loses 2 life.$−1: Return target creature card from your graveyard to your hand.$−7: Destroy up to two target creatures. Put up to two creature cards from graveyards onto the battlefield under your control.|