From 6ad23a2f3d73b0ae0f357c739317655b4aa1c95d Mon Sep 17 00:00:00 2001 From: campb <campb@SPLENDOR> Date: Mon, 7 May 2018 17:23:32 -0400 Subject: [PATCH 001/154] Parsing connect arguments and connecting. --- .../src/main/java/mage/client/MageFrame.java | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 4d3d0b2a71..269ef77bdb 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -105,6 +105,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { private static final String GRAY_MODE_ARG = "-gray"; private static final String FILL_SCREEN_ARG = "-fullscreen"; private static final String SKIP_DONE_SYMBOLS = "-skipDoneSymbols"; + private static final String USER_ARG = "-user"; + private static final String PASSWORD_ARG = "-pw"; + private static final String SERVER_ARG = "-server"; + private static final String PORT_ARG = "-port"; private static final String NOT_CONNECTED_TEXT = "<not connected>"; private static MageFrame instance; @@ -123,6 +127,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { private static boolean grayMode = false; private static boolean fullscreenMode = false; private static boolean skipSmallSymbolGenerationForExisting = false; + private static String startUser = null; + private static String startPassword = ""; + private static String startServer = "localhost"; + private static int startPort = -1; private static final Map<UUID, ChatPanelBasic> CHATS = new HashMap<>(); private static final Map<UUID, GamePanel> GAMES = new HashMap<>(); @@ -1186,8 +1194,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { startTime = System.currentTimeMillis(); Thread.setDefaultUncaughtExceptionHandler((t, e) -> LOGGER.fatal(null, e)); + SwingUtilities.invokeLater(() -> { - for (String arg : args) { + for (int i = 0; i < args.length; i++) { + String arg = args[i]; if (arg.startsWith(LITE_MODE_ARG)) { liteMode = true; } @@ -1200,6 +1210,22 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { if (arg.startsWith(SKIP_DONE_SYMBOLS)) { skipSmallSymbolGenerationForExisting = true; } + if (arg.startsWith(USER_ARG)){ + startUser = args[i+1]; + i++; + } + if (arg.startsWith(PASSWORD_ARG)){ + startPassword = args[i+1]; + i++; + } + if (arg.startsWith(SERVER_ARG)){ + startServer = args[i+1]; + i++; + } + if (arg.startsWith(PORT_ARG)){ + startPort = Integer.valueOf(args[i+1]); + i++; + } } if (!liteMode) { final SplashScreen splash = SplashScreen.getSplashScreen(); @@ -1213,6 +1239,25 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { } instance = new MageFrame(); instance.setVisible(true); + if( startUser != null){ + //instance.connectDialog. + Connection startConnection = new Connection(); + startConnection.setUsername(startUser); + startConnection.setHost(startServer); + if (startPort > 0){ + startConnection.setPort(startPort); + }else { + startConnection.setPort(MagePreferences.getServerPortWithDefault(Config.port)); + } + PreferencesDialog.setProxyInformation(startConnection); + startConnection.setPassword(startPassword); + boolean connectSuccess = connect(startConnection); + if (connectSuccess){ + instance.connectDialog.hideDialog(); + } else { + + } + } }); } From 5e6474c06e1f2aa09f3284966c2836ec1ce62f2c Mon Sep 17 00:00:00 2001 From: Blake Curry <blake.curry@gmx.us> Date: Tue, 8 May 2018 13:42:55 -0400 Subject: [PATCH 002/154] Improved command line autoconnect Changed how the command line autoconnect was handled to leverage the existing autoconnect code. --- .../src/main/java/mage/client/MageFrame.java | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 269ef77bdb..59594260f4 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -740,7 +740,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { } public boolean autoConnect() { - boolean autoConnectParamValue = Boolean.parseBoolean(PREFS.get("autoConnect", "false")); + boolean autoConnectParamValue = startUser != null || Boolean.parseBoolean(PREFS.get("autoConnect", "false")); boolean status = false; if (autoConnectParamValue) { status = performConnect(false); @@ -1238,26 +1238,20 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { } } instance = new MageFrame(); - instance.setVisible(true); + if( startUser != null){ - //instance.connectDialog. - Connection startConnection = new Connection(); - startConnection.setUsername(startUser); - startConnection.setHost(startServer); + instance.currentConnection = new Connection(); + instance.currentConnection.setUsername(startUser); + instance.currentConnection.setHost(startServer); if (startPort > 0){ - startConnection.setPort(startPort); + instance.currentConnection.setPort(startPort); }else { - startConnection.setPort(MagePreferences.getServerPortWithDefault(Config.port)); - } - PreferencesDialog.setProxyInformation(startConnection); - startConnection.setPassword(startPassword); - boolean connectSuccess = connect(startConnection); - if (connectSuccess){ - instance.connectDialog.hideDialog(); - } else { - + instance.currentConnection.setPort(MagePreferences.getServerPortWithDefault(Config.port)); } + PreferencesDialog.setProxyInformation(instance.currentConnection); + instance.currentConnection.setPassword(startPassword); } + instance.setVisible(true); }); } From 8ee6c054cd4b2d81144d2d3e11a9169b96bf64ab Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Sun, 20 May 2018 17:25:57 +0200 Subject: [PATCH 003/154] ignore Atom build config and logs --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 3d7e99c65e..84a1b82bba 100644 --- a/.gitignore +++ b/.gitignore @@ -140,3 +140,7 @@ client_secrets.json dependency-reduced-pom.xml mage-bundle /Mage.Client/game-*.json + +# build-tools config and log files when building client/server with Atom +.build-tools.cson +build-output.log From 06392f510c4ab28523aa2b6ef9a0c5669915366f Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Sun, 20 May 2018 18:33:06 +0200 Subject: [PATCH 004/154] refactor code reorder import statemets tableSeats renamed to jTableSeats to follow naming scheme setGUISize called sooner (as it is in PlayersChatPanel.java) --- .../client/dialog/TableWaitingDialog.form | 2 +- .../client/dialog/TableWaitingDialog.java | 57 ++++++++++--------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.form b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.form index be222cd34b..bc3776f1f5 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.form @@ -111,7 +111,7 @@ <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <SubComponents> - <Component class="javax.swing.JTable" name="tableSeats"> + <Component class="javax.swing.JTable" name="jTableSeats"> <Properties> <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> <Connection code="tableWaitModel" type="code"/> diff --git a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java index a6e523cfcc..60eb9d080e 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java @@ -43,13 +43,13 @@ import java.util.concurrent.TimeUnit; import javax.swing.Icon; import javax.swing.SwingWorker; import javax.swing.table.AbstractTableModel; +import org.apache.log4j.Logger; + import mage.client.MageFrame; import mage.client.SessionHandler; import mage.client.chat.ChatPanelBasic; import mage.client.components.MageComponents; import mage.client.components.tray.MageTray; -import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_ORDER; -import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_WIDTH; import mage.client.util.GUISizeHelper; import mage.client.util.audio.AudioManager; import mage.client.util.gui.TableUtil; @@ -58,7 +58,9 @@ import mage.players.PlayerType; import mage.remote.Session; import mage.view.SeatView; import mage.view.TableView; -import org.apache.log4j.Logger; + +import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_ORDER; +import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_WIDTH; /** * @author BetaSteward_at_googlemail.com @@ -66,7 +68,7 @@ import org.apache.log4j.Logger; public class TableWaitingDialog extends MageDialog { private static final Logger LOGGER = Logger.getLogger(TableWaitingDialog.class); - private static final int[] DEFAULT_COLUMS_WIDTH = {20, 50, 100, 100, 100}; + private static final int[] DEFAULT_COLUMNS_WIDTH = {20, 50, 100, 100, 100}; private UUID tableId; private UUID roomId; @@ -89,12 +91,13 @@ public class TableWaitingDialog extends MageDialog { this.setSize(prefWidth, prefHeight); } - chatPanel.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE); - tableSeats.createDefaultColumnsFromModel(); - TableUtil.setColumnWidthAndOrder(tableSeats, DEFAULT_COLUMS_WIDTH, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER); - tableSeats.setDefaultRenderer(Icon.class, new CountryCellRenderer()); setGUISize(); + chatPanel.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE); + jTableSeats.createDefaultColumnsFromModel(); + TableUtil.setColumnWidthAndOrder(jTableSeats, DEFAULT_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER); + jTableSeats.setDefaultRenderer(Icon.class, new CountryCellRenderer()); + MageFrame.getUI().addButton(MageComponents.TABLE_WAITING_START_BUTTON, btnStart); } @@ -104,9 +107,9 @@ public class TableWaitingDialog extends MageDialog { } private void setGUISize() { - tableSeats.getTableHeader().setFont(GUISizeHelper.tableFont); - tableSeats.setFont(GUISizeHelper.tableFont); - tableSeats.setRowHeight(GUISizeHelper.getTableRowHeight()); + jTableSeats.getTableHeader().setFont(GUISizeHelper.tableFont); + jTableSeats.setFont(GUISizeHelper.tableFont); + jTableSeats.setRowHeight(GUISizeHelper.getTableRowHeight()); jSplitPane1.setDividerSize(GUISizeHelper.dividerBarSize); jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(GUISizeHelper.scrollBarSize, 0)); @@ -131,14 +134,14 @@ public class TableWaitingDialog extends MageDialog { closeDialog(); return; } - int row = this.tableSeats.getSelectedRow(); + int row = this.jTableSeats.getSelectedRow(); if (getTitle().equals("Waiting for players")) { this.title = getTitle() + " - " + table.getDeckType() + " / " + table.getGameType(); this.repaint(); } tableWaitModel.loadData(table); - this.tableSeats.repaint(); - this.tableSeats.getSelectionModel().setSelectionInterval(row, row); + this.jTableSeats.repaint(); + this.jTableSeats.getSelectionModel().setSelectionInterval(row, row); } else { closeDialog(); } @@ -177,12 +180,12 @@ public class TableWaitingDialog extends MageDialog { if (updateTask != null) { updateTask.cancel(true); } + this.chatPanel.disconnect(); MageFrame.getUI().removeButton(MageComponents.TABLE_WAITING_START_BUTTON); this.removeDialog(); - TableUtil.saveColumnWidthAndOrderToPrefs(tableSeats, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER); - PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLE_WAITING_WIDTH, Integer.toString(getWidth())); - PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLE_WAITING_HEIGHT, Integer.toString(getHeight())); + TableUtil.saveColumnWidthAndOrderToPrefs(jTableSeats, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER); + PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_WIDTH, Integer.toString(getWidth())); } /** @@ -200,7 +203,7 @@ public class TableWaitingDialog extends MageDialog { btnStart = new javax.swing.JButton(); jSplitPane1 = new javax.swing.JSplitPane(); jScrollPane1 = new javax.swing.JScrollPane(); - tableSeats = new javax.swing.JTable(); + jTableSeats = new javax.swing.JTable(); chatPanel = new mage.client.chat.ChatPanelBasic(); setResizable(true); @@ -226,9 +229,9 @@ public class TableWaitingDialog extends MageDialog { jSplitPane1.setResizeWeight(1.0); jSplitPane1.setToolTipText(""); - tableSeats.setModel(tableWaitModel); - tableSeats.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); - jScrollPane1.setViewportView(tableSeats); + jTableSeats.setModel(tableWaitModel); + jTableSeats.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + jScrollPane1.setViewportView(jTableSeats); jSplitPane1.setLeftComponent(jScrollPane1); jSplitPane1.setRightComponent(chatPanel); @@ -288,19 +291,19 @@ public class TableWaitingDialog extends MageDialog { }//GEN-LAST:event_btnCancelActionPerformed private void btnMoveDownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMoveDownActionPerformed - int row = this.tableSeats.getSelectedRow(); - if (row < this.tableSeats.getRowCount() - 1) { + int row = this.jTableSeats.getSelectedRow(); + if (row < this.jTableSeats.getRowCount() - 1) { SessionHandler.swapSeats(roomId, tableId, row, row + 1); - this.tableSeats.getSelectionModel().setSelectionInterval(row + 1, row + 1); + this.jTableSeats.getSelectionModel().setSelectionInterval(row + 1, row + 1); } }//GEN-LAST:event_btnMoveDownActionPerformed private void btnMoveUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMoveUpActionPerformed - int row = this.tableSeats.getSelectedRow(); + int row = this.jTableSeats.getSelectedRow(); if (row > 0) { SessionHandler.swapSeats(roomId, tableId, row, row - 1); - this.tableSeats.getSelectionModel().setSelectionInterval(row - 1, row - 1); + this.jTableSeats.getSelectionModel().setSelectionInterval(row - 1, row - 1); } }//GEN-LAST:event_btnMoveUpActionPerformed @@ -312,7 +315,7 @@ public class TableWaitingDialog extends MageDialog { private mage.client.chat.ChatPanelBasic chatPanel; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JSplitPane jSplitPane1; - private javax.swing.JTable tableSeats; + private javax.swing.JTable jTableSeats; // End of variables declaration//GEN-END:variables } From a3e433f7bd9feda462e1af36c29b70fb11600d24 Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Sun, 20 May 2018 19:25:31 +0200 Subject: [PATCH 005/154] remove offending line setting width incorrectly (was always 1647) --- .../src/main/java/mage/client/dialog/TableWaitingDialog.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java index 60eb9d080e..c3567f83a4 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java @@ -185,7 +185,6 @@ public class TableWaitingDialog extends MageDialog { MageFrame.getUI().removeButton(MageComponents.TABLE_WAITING_START_BUTTON); this.removeDialog(); TableUtil.saveColumnWidthAndOrderToPrefs(jTableSeats, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER); - PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_WIDTH, Integer.toString(getWidth())); } /** From 0fe129f817dd8a88126ca4e474e7ff4e6c480348 Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Sun, 20 May 2018 20:12:22 +0200 Subject: [PATCH 006/154] remove todo (column wodth and sort order persists through restarts) --- Mage.Client/src/main/java/mage/client/table/TablesPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index f7560511b6..36f1e52002 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -192,7 +192,7 @@ public class TablesPanel extends javax.swing.JPanel { activeTablesSorter.setSortKeys(list); TableUtil.setColumnWidthAndOrder(tableTables, DEFAULT_COLUMNS_WIDTH, - PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH, PreferencesDialog.KEY_TABLES_COLUMNS_ORDER); // TODO: is sort order save and restore after app restart/window open? + PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH, PreferencesDialog.KEY_TABLES_COLUMNS_ORDER); // 2. TABLE COMPLETED completedTablesSorter = new MageTableRowSorter(matchesModel); From d65344158faea76b37d7b8daf10d7d4d0ed8ca1d Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Sun, 20 May 2018 21:07:28 +0200 Subject: [PATCH 007/154] add logging for restoring/saving column width and order (remove later) --- .../src/main/java/mage/client/util/gui/TableUtil.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java b/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java index 7bf6d5b1ae..61f502f18a 100644 --- a/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java +++ b/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java @@ -5,8 +5,10 @@ */ package mage.client.util.gui; +import java.util.Arrays; import javax.swing.JTable; import javax.swing.table.TableColumn; +import org.apache.log4j.Logger; import mage.client.dialog.PreferencesDialog; /** @@ -22,11 +24,15 @@ public final class TableUtil { * @param widthPrefKey * @param orderPrefKey */ + + private static final Logger LOGGER = Logger.getLogger(TableUtil.class); + static public void setColumnWidthAndOrder(JTable table, int[] defaultColumnsWidth, String widthPrefKey, String orderPrefKey) { table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // set the column width from saved value or defaults int[] widths = getIntArrayFromString(PreferencesDialog.getCachedValue(widthPrefKey, null)); + LOGGER.info("loading stored widths: " + Arrays.toString(widths)); int i = 0; for (int width : defaultColumnsWidth) { if (widths != null && widths.length > i) { @@ -43,6 +49,7 @@ public final class TableUtil { // set the column order int[] order = getIntArrayFromString(PreferencesDialog.getCachedValue(orderPrefKey, null)); + LOGGER.info("loading column order: " + Arrays.toString(order)); if (order != null && order.length == table.getColumnCount()) { for (int j = 0; j < table.getColumnCount(); j++) { table.moveColumn(table.convertColumnIndexToView(order[j]), j); @@ -70,6 +77,8 @@ public final class TableUtil { PreferencesDialog.saveValue(widthPrefKey, columnWidthSettings.toString()); PreferencesDialog.saveValue(orderPrefKey, columnOrderSettings.toString()); + LOGGER.info("saving column widths: " + columnWidthSettings.toString()); + LOGGER.info("saving column order: " + columnOrderSettings.toString()); } public static int[] getIntArrayFromString(String stringData) { From f1f2a80f4f72be9650e210db6d469b35b7d94325 Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Sun, 20 May 2018 21:07:28 +0200 Subject: [PATCH 008/154] add logging for restoring/saving column width and order (remove later) --- .../src/main/java/mage/client/util/gui/TableUtil.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java b/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java index 7bf6d5b1ae..61f502f18a 100644 --- a/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java +++ b/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java @@ -5,8 +5,10 @@ */ package mage.client.util.gui; +import java.util.Arrays; import javax.swing.JTable; import javax.swing.table.TableColumn; +import org.apache.log4j.Logger; import mage.client.dialog.PreferencesDialog; /** @@ -22,11 +24,15 @@ public final class TableUtil { * @param widthPrefKey * @param orderPrefKey */ + + private static final Logger LOGGER = Logger.getLogger(TableUtil.class); + static public void setColumnWidthAndOrder(JTable table, int[] defaultColumnsWidth, String widthPrefKey, String orderPrefKey) { table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // set the column width from saved value or defaults int[] widths = getIntArrayFromString(PreferencesDialog.getCachedValue(widthPrefKey, null)); + LOGGER.info("loading stored widths: " + Arrays.toString(widths)); int i = 0; for (int width : defaultColumnsWidth) { if (widths != null && widths.length > i) { @@ -43,6 +49,7 @@ public final class TableUtil { // set the column order int[] order = getIntArrayFromString(PreferencesDialog.getCachedValue(orderPrefKey, null)); + LOGGER.info("loading column order: " + Arrays.toString(order)); if (order != null && order.length == table.getColumnCount()) { for (int j = 0; j < table.getColumnCount(); j++) { table.moveColumn(table.convertColumnIndexToView(order[j]), j); @@ -70,6 +77,8 @@ public final class TableUtil { PreferencesDialog.saveValue(widthPrefKey, columnWidthSettings.toString()); PreferencesDialog.saveValue(orderPrefKey, columnOrderSettings.toString()); + LOGGER.info("saving column widths: " + columnWidthSettings.toString()); + LOGGER.info("saving column order: " + columnOrderSettings.toString()); } public static int[] getIntArrayFromString(String stringData) { From ac799b2036931f16c05eaaf4e9f6e9fd6b598b0c Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 12:15:49 -0400 Subject: [PATCH 009/154] updated Battlebond spoilers --- Utils/mtg-cards-data.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 4ec10c7433..71d4e22fa5 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33358,8 +33358,17 @@ Karplusan Hound|Dominaria|277|U|{3}{R}|Creature - Hound|3|3|Whenever Karplusan H Pyromantic Pilgrim|Dominaria|278|C|{2}{R}|Creature - Human Wizard|3|1|Haste| Timber Gorge|Dominaria|279|C||Land|||Timber Gorge enters the battlefield tapped.${t}: Add {R} or {G}.| Firesong and Sunspeaker|Dominaria|280|R|{4}{R}{W}|Legendary Creature - Minotaur Cleric|4|6|Red instant and sorcery spells you control have lifelink.$Whenever a white instant or sorcery spell causes you to gain life, Firesong and Sunspeaker deals 3 damage to any target.| +Will Kenrith|Battlebond|1|M|{4}{U}{U}|Legendary Planeswalker - Will|4|+2: Until your next turn, up to two target creatures each have base power and toughness 0/3 and lose all abilities.$-2: Target player draws two cards. Until your next turn, instant, sorcery, and planeswalker spells that player casts cost 2 less to cast.$-8: Target player gets an emblem with "Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy."$Partner with Rowan Kenrith$Will Kenrith can be your commander.| +Rowan Kenrith|Battlebond|2|M|{4}{R}{R}|Legendary Planeswalker - Rowan|4|+2: During target player's next turn, each creature that player controls attacks if able.$-2: Rowan Kenrith deals 3 damage to each tapped creature target player controls.$-8: Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy."$Partner with Will Kenrith$Rowan Kenrith can be your commander.| Pir, Imaginative Rascal|Battlebond|11|R|{2}{G}|Legendary Creature - Human|1|1|Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.)$If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead.| Toothy, Imaginary Friend|Battlebond|12|R|{3}{U}|Legendary Creature - Illusion|1|1|Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.)$Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend.$When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it.| +Dwarven Lightsmith|Battlebond|27|C|{5}{C}|Creature - Dwarf Cleric|3|4|Assist (Another player can pay up to {5} of this spell's cost.)$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| +Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| +Soaring Show-Off|Battlebond|40|C|{2}{U}|Creature - Bird Warrior|2|2|Flying$When Soaring Show-Off enters the battlefield, each player draws a card.| +Fan Favorite|Battlebond|46|C|{3}{B}|Creature - Human Rogue|2|2|Assist (Another player can play up to {3} of this spell's cost.)${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| +Charging Binox|Battlebond|66|C|{7}{G}|Creature - Beast|7|5|Assist (Another player can pay up to {7} of this spell's cost.)$Trample| +Pir's Whim|Battlebond|73|R|{3}{G}|Sorcery|||For each player, choose friend or foe. Each friend searches their library for a land card, puts it onto the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment.| +Rushblade Commander|Battlebond|77|U|{B}{R}|Creature - Azra Warrior|2|2|Warrior creatures your team controls have haste.| Bountiful Promenade|Battlebond|81|R||Land|||Bountiful Promenade enters the battlefield tapped unless you have two or more opponents.${T}: Add {G} or {W}.| Luxury Suite|Battlebond|82|R||Land|||Luxury Suite enters the battlefield tapped unless you have two or more opponents.${T}: Add {B} or {R}.| Morphic Pool|Battlebond|83|R||Land|||Morphic Pool enters the battlefield tapped unless you have two or more opponents.${T}: Add {U} or {B}.| From d0a0f2eb64827cd34ad80ba15acb9d93f91a5a9c Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Mon, 21 May 2018 18:17:10 +0200 Subject: [PATCH 010/154] * Corrosive Ooze - Fixed handling of destroying of equipments. --- Mage.Sets/src/mage/cards/c/CorrosiveOoze.java | 183 +++++++++++++++++- Mage.Sets/src/mage/cards/r/ReflectorMage.java | 18 +- 2 files changed, 182 insertions(+), 19 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java b/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java index c3eda26765..7fa4894f67 100644 --- a/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java +++ b/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java @@ -27,19 +27,37 @@ */ package mage.cards.c; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; import mage.abilities.common.BlocksOrBecomesBlockedTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; -import mage.abilities.effects.common.DestroyAllAttachedEquipmentEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Outcome; import mage.constants.SubType; +import mage.constants.TurnPhase; +import mage.constants.WatcherScope; +import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.EquippedPredicate; +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.watchers.Watcher; /** * @@ -62,9 +80,8 @@ public class CorrosiveOoze extends CardImpl { this.toughness = new MageInt(2); // Whenever Corrosive Ooze blocks or becomes blocked by an equipped creature, destroy all Equipment attached to that creature at end of combat. - Effect effect = new CreateDelayedTriggeredAbilityEffect(new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyAllAttachedEquipmentEffect()), true); - effect.setText("destroy all Equipment attached to that creature at end of combat"); - this.addAbility(new BlocksOrBecomesBlockedTriggeredAbility(effect, filter, false)); + Effect effect = new CreateDelayedTriggeredAbilityEffect(new AtTheEndOfCombatDelayedTriggeredAbility(new CorrosiveOozeEffect()), true); + this.addAbility(new BlocksOrBecomesBlockedTriggeredAbility(effect, filter, false), new CorrosiveOozeCombatWatcher()); } public CorrosiveOoze(final CorrosiveOoze card) { @@ -76,3 +93,161 @@ public class CorrosiveOoze extends CardImpl { return new CorrosiveOoze(this); } } + +class CorrosiveOozeEffect extends OneShotEffect { + + public CorrosiveOozeEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "destroy all Equipment attached to that creature at end of combat"; + } + + public CorrosiveOozeEffect(final CorrosiveOozeEffect effect) { + super(effect); + } + + @Override + public CorrosiveOozeEffect copy() { + return new CorrosiveOozeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + CorrosiveOozeCombatWatcher watcher = (CorrosiveOozeCombatWatcher) game.getState().getWatchers().get(CorrosiveOozeCombatWatcher.class.getSimpleName()); + if (controller != null && watcher != null) { + MageObjectReference sourceMor = new MageObjectReference(source.getSourceObject(game), game); + // get equipmentsToDestroy of creatres already left the battlefield + List<Permanent> toDestroy = new ArrayList<>(); + Set<MageObjectReference> toDestroyMor = watcher.getEquipmentsToDestroy(sourceMor); + if (toDestroyMor != null) { + for (MageObjectReference mor : toDestroyMor) { + Permanent attachment = mor.getPermanent(game); + if (attachment != null) { + toDestroy.add(attachment); + } + } + } + // get the related creatures + Set<MageObjectReference> relatedCreatures = watcher.getRelatedBlockedCreatures(sourceMor); + if (relatedCreatures != null) { + for (MageObjectReference relatedCreature : relatedCreatures) { + Permanent permanent = relatedCreature.getPermanent(game); + if (permanent != null) { + for (UUID attachmentId : permanent.getAttachments()) { + Permanent attachment = game.getPermanent(attachmentId); + if (attachment != null && attachment.hasSubtype(SubType.EQUIPMENT, game)) { + toDestroy.add(attachment); + } + } + } + } + } + for (Permanent permanent : toDestroy) { + permanent.destroy(source.getSourceId(), game, false); + } + + return true; + } + return false; + + } +} + +class CorrosiveOozeCombatWatcher extends Watcher { + + public final HashMap<MageObjectReference, HashSet<MageObjectReference>> oozeBlocksOrBlocked = new HashMap<>(); + public final HashMap<MageObjectReference, HashSet<MageObjectReference>> oozeEquipmentsToDestroy = new HashMap<>(); + + public CorrosiveOozeCombatWatcher() { + super(CorrosiveOozeCombatWatcher.class.getSimpleName(), WatcherScope.GAME); + } + + public CorrosiveOozeCombatWatcher(final CorrosiveOozeCombatWatcher watcher) { + super(watcher); + for (Map.Entry<MageObjectReference, HashSet<MageObjectReference>> entry : watcher.oozeBlocksOrBlocked.entrySet()) { + HashSet<MageObjectReference> newSet = new HashSet<>(entry.getValue()); + oozeBlocksOrBlocked.put(entry.getKey(), newSet); + } + for (Map.Entry<MageObjectReference, HashSet<MageObjectReference>> entry : watcher.oozeEquipmentsToDestroy.entrySet()) { + HashSet<MageObjectReference> newSet = new HashSet<>(entry.getValue()); + oozeEquipmentsToDestroy.put(entry.getKey(), newSet); + } + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.BEGIN_COMBAT_STEP_PRE) { + this.oozeBlocksOrBlocked.clear(); + } + if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED) { + Permanent attacker = game.getPermanent(event.getTargetId()); + Permanent blocker = game.getPermanent(event.getSourceId()); + if (attacker != null && attacker.getName().equals("Corrosive Ooze")) { + if (blocker != null && hasAttachedEquipment(game, blocker)) { + MageObjectReference oozeMor = new MageObjectReference(attacker, game); + HashSet<MageObjectReference> relatedCreatures = oozeBlocksOrBlocked.getOrDefault(oozeMor, new HashSet<>()); + relatedCreatures.add(new MageObjectReference(event.getSourceId(), game)); + oozeBlocksOrBlocked.put(oozeMor, relatedCreatures); + } + } + if (blocker != null && blocker.getName().equals("Corrosive Ooze")) { + if (attacker != null && hasAttachedEquipment(game, attacker)) { + MageObjectReference oozeMor = new MageObjectReference(blocker, game); + HashSet<MageObjectReference> relatedCreatures = oozeBlocksOrBlocked.getOrDefault(oozeMor, new HashSet<>()); + relatedCreatures.add(new MageObjectReference(event.getTargetId(), game)); + oozeBlocksOrBlocked.put(oozeMor, relatedCreatures); + } + } + } + if (game.getTurn().getPhaseType().equals(TurnPhase.COMBAT)) { + if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { + if (((ZoneChangeEvent) event).getFromZone().equals(Zone.BATTLEFIELD)) { + // Check if a previous blocked or blocked by creatures is leaving the battlefield + for (Map.Entry<MageObjectReference, HashSet<MageObjectReference>> entry : oozeBlocksOrBlocked.entrySet()) { + for (MageObjectReference mor : entry.getValue()) { + if (mor.refersTo(((ZoneChangeEvent) event).getTarget(), game)) { + // check for equipments and remember + for (UUID attachmentId : ((ZoneChangeEvent) event).getTarget().getAttachments()) { + Permanent attachment = game.getPermanent(attachmentId); + if (attachment != null && attachment.hasSubtype(SubType.EQUIPMENT, game)) { + HashSet<MageObjectReference> toDestroy = oozeEquipmentsToDestroy.getOrDefault(entry.getKey(), new HashSet<>()); + toDestroy.add(new MageObjectReference(attachment, game)); + oozeEquipmentsToDestroy.put(entry.getKey(), toDestroy); + } + } + } + } + } + } + } + } + } + + private boolean hasAttachedEquipment(Game game, Permanent permanent) { + for (UUID attachmentId : permanent.getAttachments()) { + Permanent attachment = game.getPermanent(attachmentId); + if (attachment != null && attachment.hasSubtype(SubType.EQUIPMENT, game)) { + return true; + } + } + return false; + } + + public Set<MageObjectReference> getRelatedBlockedCreatures(MageObjectReference ooze) { + Set<MageObjectReference> relatedCreatures = this.oozeBlocksOrBlocked.get(ooze); + oozeBlocksOrBlocked.remove(ooze); // remove here to get no overlap with creatures leaving meanwhile + return relatedCreatures; + } + + public Set<MageObjectReference> getEquipmentsToDestroy(MageObjectReference ooze) { + Set<MageObjectReference> equipmentsToDestroy = this.oozeEquipmentsToDestroy.get(ooze); + oozeEquipmentsToDestroy.remove(ooze); // remove here to get no overlap with creatures leaving meanwhile + return equipmentsToDestroy; + } + + @Override + public CorrosiveOozeCombatWatcher copy() { + return new CorrosiveOozeCombatWatcher(this); + } + +} diff --git a/Mage.Sets/src/mage/cards/r/ReflectorMage.java b/Mage.Sets/src/mage/cards/r/ReflectorMage.java index 1eadff8017..9046d789fd 100644 --- a/Mage.Sets/src/mage/cards/r/ReflectorMage.java +++ b/Mage.Sets/src/mage/cards/r/ReflectorMage.java @@ -38,10 +38,9 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.PhaseStep; +import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; @@ -50,7 +49,6 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.game.stack.Spell; -import mage.game.turn.Step; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; @@ -67,7 +65,7 @@ public class ReflectorMage extends CardImpl { } public ReflectorMage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); this.power = new MageInt(2); @@ -128,7 +126,7 @@ class ExclusionRitualReplacementEffect extends ContinuousRuleModifyingEffectImpl private final UUID ownerId; ExclusionRitualReplacementEffect(String creatureName, UUID ownerId) { - super(Duration.Custom, Outcome.Detriment); + super(Duration.UntilYourNextTurn, Outcome.Detriment); staticText = "That creature's owner can't cast spells with the same name as that creature until your next turn"; this.creatureName = creatureName; this.ownerId = ownerId; @@ -158,16 +156,6 @@ class ExclusionRitualReplacementEffect extends ContinuousRuleModifyingEffectImpl return false; } - @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()) { - return true; - } - } - return false; - } - @Override public boolean apply(Game game, Ability source) { return false; From eee0f7f4f391e7d5e3a4e37b24ef183285cea301 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 12:37:04 -0400 Subject: [PATCH 011/154] Added Battlebond reprints --- Mage.Sets/src/mage/sets/Battlebond.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index f50f18b3fe..9ba3123e91 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -53,10 +53,21 @@ public class Battlebond extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; + cards.add(new SetCardInfo("Doomed Traveler", 91, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); + cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); + cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); + cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); + cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); + cards.add(new SetCardInfo("Doomed Dissenter", 142, Rarity.COMMON, mage.cards.d.DoomedDissenter.class)); + cards.add(new SetCardInfo("Doubling Season", 195, Rarity.MYTHIC, mage.cards.d.DoublingSeason.class)); + cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); + cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); + cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); + cards.add(new SetCardInfo("Eager Construct", 234, Rarity.COMMON, mage.cards.e.EagerConstruct.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); - cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); - cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); - cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); - cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); + cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); + cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); + cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); + cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); } } From 0f0adaaff369fd8b300a330dbb75093f91e72597 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 12:45:13 -0400 Subject: [PATCH 012/154] updated Battlebond spoiler --- Utils/mtg-cards-data.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 71d4e22fa5..c4d29248e5 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33360,11 +33360,13 @@ Timber Gorge|Dominaria|279|C||Land|||Timber Gorge enters the battlefield tapped. Firesong and Sunspeaker|Dominaria|280|R|{4}{R}{W}|Legendary Creature - Minotaur Cleric|4|6|Red instant and sorcery spells you control have lifelink.$Whenever a white instant or sorcery spell causes you to gain life, Firesong and Sunspeaker deals 3 damage to any target.| Will Kenrith|Battlebond|1|M|{4}{U}{U}|Legendary Planeswalker - Will|4|+2: Until your next turn, up to two target creatures each have base power and toughness 0/3 and lose all abilities.$-2: Target player draws two cards. Until your next turn, instant, sorcery, and planeswalker spells that player casts cost 2 less to cast.$-8: Target player gets an emblem with "Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy."$Partner with Rowan Kenrith$Will Kenrith can be your commander.| Rowan Kenrith|Battlebond|2|M|{4}{R}{R}|Legendary Planeswalker - Rowan|4|+2: During target player's next turn, each creature that player controls attacks if able.$-2: Rowan Kenrith deals 3 damage to each tapped creature target player controls.$-8: Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy."$Partner with Will Kenrith$Rowan Kenrith can be your commander.| +Gorm the Great|Battlebond|8|R|{3}{G}|Legendary Creature - Giant Warrior|2|7|Partner with Virtus the Veiled (When this creature enters the battlefield, target player may put Virtus into their hand from their library, then shuffle.)$Vigilance$Gorm the Great must be blocked if able and Gorm must be blocked by two or more creatures if able.| Pir, Imaginative Rascal|Battlebond|11|R|{2}{G}|Legendary Creature - Human|1|1|Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.)$If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead.| Toothy, Imaginary Friend|Battlebond|12|R|{3}{U}|Legendary Creature - Illusion|1|1|Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.)$Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend.$When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it.| Dwarven Lightsmith|Battlebond|27|C|{5}{C}|Creature - Dwarf Cleric|3|4|Assist (Another player can pay up to {5} of this spell's cost.)$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| Soaring Show-Off|Battlebond|40|C|{2}{U}|Creature - Bird Warrior|2|2|Flying$When Soaring Show-Off enters the battlefield, each player draws a card.| +Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist (Another player can pay up to {6} of this spell's cost)$Exile all nonland permanents.| Fan Favorite|Battlebond|46|C|{3}{B}|Creature - Human Rogue|2|2|Assist (Another player can play up to {3} of this spell's cost.)${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| Charging Binox|Battlebond|66|C|{7}{G}|Creature - Beast|7|5|Assist (Another player can pay up to {7} of this spell's cost.)$Trample| Pir's Whim|Battlebond|73|R|{3}{G}|Sorcery|||For each player, choose friend or foe. Each friend searches their library for a land card, puts it onto the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment.| From 53407b19042cf1103b57ec8f56de773107c33b6e Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 12:45:54 -0400 Subject: [PATCH 013/154] updated Battlebond spoiler --- Utils/mtg-cards-data.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index c4d29248e5..5c3068cf9b 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33360,6 +33360,7 @@ Timber Gorge|Dominaria|279|C||Land|||Timber Gorge enters the battlefield tapped. Firesong and Sunspeaker|Dominaria|280|R|{4}{R}{W}|Legendary Creature - Minotaur Cleric|4|6|Red instant and sorcery spells you control have lifelink.$Whenever a white instant or sorcery spell causes you to gain life, Firesong and Sunspeaker deals 3 damage to any target.| Will Kenrith|Battlebond|1|M|{4}{U}{U}|Legendary Planeswalker - Will|4|+2: Until your next turn, up to two target creatures each have base power and toughness 0/3 and lose all abilities.$-2: Target player draws two cards. Until your next turn, instant, sorcery, and planeswalker spells that player casts cost 2 less to cast.$-8: Target player gets an emblem with "Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy."$Partner with Rowan Kenrith$Will Kenrith can be your commander.| Rowan Kenrith|Battlebond|2|M|{4}{R}{R}|Legendary Planeswalker - Rowan|4|+2: During target player's next turn, each creature that player controls attacks if able.$-2: Rowan Kenrith deals 3 damage to each tapped creature target player controls.$-8: Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy."$Partner with Will Kenrith$Rowan Kenrith can be your commander.| +Virtus the Veiled|Battlebond|7|R|{2}{R}|Legendary Creature - Azra Assassin|1|1|Partner with Gorm the Great (When this creature enters the battlefield, target player may put Gorm into their hand from their library, then shuffle.)$Deathtouch$Whenever Virus the Veiled deals combat damage to a player, that player loses half their life rounded up.| Gorm the Great|Battlebond|8|R|{3}{G}|Legendary Creature - Giant Warrior|2|7|Partner with Virtus the Veiled (When this creature enters the battlefield, target player may put Virtus into their hand from their library, then shuffle.)$Vigilance$Gorm the Great must be blocked if able and Gorm must be blocked by two or more creatures if able.| Pir, Imaginative Rascal|Battlebond|11|R|{2}{G}|Legendary Creature - Human|1|1|Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.)$If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead.| Toothy, Imaginary Friend|Battlebond|12|R|{3}{U}|Legendary Creature - Illusion|1|1|Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.)$Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend.$When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it.| From 59a639def4a18fcd0a85c921a86a288ac4d16bbc Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 13:20:50 -0400 Subject: [PATCH 014/154] Implemented Soaring Show-Off --- .../src/mage/cards/s/SoaringShowOff.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SoaringShowOff.java diff --git a/Mage.Sets/src/mage/cards/s/SoaringShowOff.java b/Mage.Sets/src/mage/cards/s/SoaringShowOff.java new file mode 100644 index 0000000000..203737ed3b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SoaringShowOff.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DrawCardAllEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class SoaringShowOff extends CardImpl { + + public SoaringShowOff(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.BIRD); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Soaring Show-Off enters the battlefield, each player draws a card. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardAllEffect(1))); + } + + public SoaringShowOff(final SoaringShowOff card) { + super(card); + } + + @Override + public SoaringShowOff copy() { + return new SoaringShowOff(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 9ba3123e91..fba911b570 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -68,6 +68,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); + cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); } } From bd96d30b3d7b9b5398e8147988c0aaf8b7c75531 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 15:12:31 -0400 Subject: [PATCH 015/154] Implemented Partners With ability --- .../src/mage/deck/Commander.java | 19 ++- .../src/mage/deck/FreeformCommander.java | 27 +++- .../src/mage/deck/PennyDreadfulCommander.java | 20 ++- .../keyword/PartnersWithAbility.java | 143 ++++++++++++++++++ 4 files changed, 198 insertions(+), 11 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/keyword/PartnersWithAbility.java diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java index c1912a21a0..94c5ed286b 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java @@ -33,6 +33,7 @@ import mage.abilities.Ability; import mage.abilities.common.CanBeYourCommanderAbility; import mage.abilities.costs.mana.ManaCost; import mage.abilities.keyword.PartnerAbility; +import mage.abilities.keyword.PartnersWithAbility; import mage.cards.Card; import mage.cards.ExpansionSet; import mage.cards.Sets; @@ -133,6 +134,10 @@ public class Commander extends Constructed { invalid.put("Commander", "Sideboard must contain only the commander(s)"); valid = false; } else { + Set<String> commanderNames = new HashSet<>(); + for (Card commander : deck.getSideboard()) { + commanderNames.add(commander.getName()); + } for (Card commander : deck.getSideboard()) { if (bannedCommander.contains(commander.getName())) { invalid.put("Commander", "Commander banned (" + commander.getName() + ')'); @@ -144,8 +149,18 @@ public class Commander extends Constructed { valid = false; } if (deck.getSideboard().size() == 2 && !commander.getAbilities().contains(PartnerAbility.getInstance())) { - invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')'); - valid = false; + boolean partnersWith = false; + for (Ability ability : commander.getAbilities()) { + if (ability instanceof PartnersWithAbility + && commanderNames.contains(((PartnersWithAbility) ability).getPartnerName())) { + partnersWith = true; + break; + } + } + if (!partnersWith) { + invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')'); + valid = false; + } } FilterMana commanderColor = commander.getColorIdentity(); if (commanderColor.isWhite()) { diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java index 570be2a80e..32fc877413 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java @@ -28,15 +28,14 @@ package mage.deck; import java.util.*; -import java.util.Map.Entry; -import mage.abilities.common.CanBeYourCommanderAbility; +import mage.abilities.Ability; import mage.abilities.keyword.PartnerAbility; +import mage.abilities.keyword.PartnersWithAbility; 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; /** @@ -90,15 +89,29 @@ public class FreeformCommander extends Constructed { invalid.put("Commander", "Sideboard must contain only the commander(s)"); valid = false; } else { + Set<String> commanderNames = new HashSet<>(); for (Card commander : deck.getSideboard()) { - if (!(commander.isCreature() || - commander.isLegendary())) { + commanderNames.add(commander.getName()); + } + for (Card commander : deck.getSideboard()) { + if (!(commander.isCreature() + || commander.isLegendary())) { invalid.put("Commander", "For Freeform Commander, the commander must be a creature or be legendary. Yours was: " + commander.getName()); valid = false; } if (deck.getSideboard().size() == 2 && !commander.getAbilities().contains(PartnerAbility.getInstance())) { - invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')'); - valid = false; + boolean partnersWith = false; + for (Ability ability : commander.getAbilities()) { + if (ability instanceof PartnersWithAbility + && commanderNames.contains(((PartnersWithAbility) ability).getPartnerName())) { + partnersWith = true; + break; + } + } + if (!partnersWith) { + invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')'); + valid = false; + } } FilterMana commanderColor = commander.getColorIdentity(); if (commanderColor.isWhite()) { diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java index 07bbe63069..0d23661a43 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java @@ -29,8 +29,10 @@ package mage.deck; import java.util.*; import java.util.Map.Entry; +import mage.abilities.Ability; import mage.abilities.common.CanBeYourCommanderAbility; import mage.abilities.keyword.PartnerAbility; +import mage.abilities.keyword.PartnersWithAbility; import mage.cards.Card; import mage.cards.ExpansionSet; import mage.cards.Sets; @@ -98,6 +100,10 @@ public class PennyDreadfulCommander extends Constructed { invalid.put("Commander", "Sideboard must contain only the commander(s)"); valid = false; } else { + Set<String> commanderNames = new HashSet<>(); + for (Card commander : deck.getSideboard()) { + commanderNames.add(commander.getName()); + } for (Card commander : deck.getSideboard()) { if ((!commander.isCreature() || !commander.isLegendary()) && (!commander.isPlaneswalker() || !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) { @@ -105,8 +111,18 @@ public class PennyDreadfulCommander extends Constructed { valid = false; } if (deck.getSideboard().size() == 2 && !commander.getAbilities().contains(PartnerAbility.getInstance())) { - invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')'); - valid = false; + boolean partnersWith = false; + for (Ability ability : commander.getAbilities()) { + if (ability instanceof PartnersWithAbility + && commanderNames.contains(((PartnersWithAbility) ability).getPartnerName())) { + partnersWith = true; + break; + } + } + if (!partnersWith) { + invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')'); + valid = false; + } } FilterMana commanderColor = commander.getColorIdentity(); if (commanderColor.isWhite()) { diff --git a/Mage/src/main/java/mage/abilities/keyword/PartnersWithAbility.java b/Mage/src/main/java/mage/abilities/keyword/PartnersWithAbility.java new file mode 100644 index 0000000000..54eb5984a3 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/PartnersWithAbility.java @@ -0,0 +1,143 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.abilities.keyword; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardsImpl; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class PartnersWithAbility extends EntersBattlefieldTriggeredAbility { + + private final String partnerName; + private final String shortName; + + public PartnersWithAbility(String partnerName) { + super(new PartnersWithSearchEffect(partnerName), false); + this.addTarget(new TargetPlayer()); + this.partnerName = partnerName; + this.shortName = shortenName(partnerName); + } + + public PartnersWithAbility(final PartnersWithAbility ability) { + super(ability); + this.partnerName = ability.partnerName; + this.shortName = ability.shortName; + } + + @Override + public PartnersWithAbility copy() { + return new PartnersWithAbility(this); + } + + @Override + public String getRule() { + return "Partners with" + partnerName + + " <i>(When this creature enters the battlefield, target player may put " + shortName + + " into their hand from their library, then shuffle.)</i>"; + } + + public String getPartnerName() { + return partnerName; + } + + public static String shortenName(String st) { + StringBuilder sb = new StringBuilder(); + for (char s : st.toCharArray()) { + if (s == ' ' || s == ',') { + break; + } else { + sb.append(s); + } + } + return sb.toString(); + } +} + +class PartnersWithSearchEffect extends OneShotEffect { + + private final String partnerName; + + public PartnersWithSearchEffect(String partnerName) { + super(Outcome.Detriment); + this.partnerName = partnerName; + this.staticText = ""; + } + + public PartnersWithSearchEffect(final PartnersWithSearchEffect effect) { + super(effect); + this.partnerName = effect.partnerName; + } + + @Override + public PartnersWithSearchEffect copy() { + return new PartnersWithSearchEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Player player = game.getPlayer(source.getFirstTarget()); + if (player != null) { + FilterCard filter = new FilterCard("card named " + partnerName); + filter.add(new NamePredicate(partnerName)); + TargetCardInLibrary target = new TargetCardInLibrary(filter); + if (player.chooseUse(Outcome.Benefit, "Search your library for a card named" + partnerName + " and put it into your hand?", source, game)) { + player.searchLibrary(target, game); + for (UUID cardId : target.getTargets()) { + Card card = player.getLibrary().getCard(cardId, game); + if (card != null) { + player.revealCards(source, new CardsImpl(card), game); + player.moveCards(card, Zone.HAND, source, game); + } + } + player.shuffleLibrary(source, game); + } + } + // prevent undo + controller.resetStoredBookmark(game); + return true; + } + return false; + } +} From 4d7579479fa311f9c06cb1a977a58fa8218a3a32 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 15:24:10 -0400 Subject: [PATCH 016/154] Implemented Pir, Imaginative Rascal --- .../mage/cards/p/PirImaginativeRascal.java | 128 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 3 +- 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/p/PirImaginativeRascal.java diff --git a/Mage.Sets/src/mage/cards/p/PirImaginativeRascal.java b/Mage.Sets/src/mage/cards/p/PirImaginativeRascal.java new file mode 100644 index 0000000000..d022fcf943 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PirImaginativeRascal.java @@ -0,0 +1,128 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.keyword.PartnersWithAbility; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class PirImaginativeRascal extends CardImpl { + + public PirImaginativeRascal(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.) + this.addAbility(new PartnersWithAbility("Toothy, Imaginary Friend")); + + // If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PirImaginativeRascalEffect())); + } + + public PirImaginativeRascal(final PirImaginativeRascal card) { + super(card); + } + + @Override + public PirImaginativeRascal copy() { + return new PirImaginativeRascal(this); + } +} + +class PirImaginativeRascalEffect extends ReplacementEffectImpl { + + PirImaginativeRascalEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit, false); + staticText = "If one or more counters would be put on a permanent your team controls, " + + "that many plus one of each of those kinds of counters are put on that permanent instead"; + } + + PirImaginativeRascalEffect(final PirImaginativeRascalEffect effect) { + super(effect); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + int amount = event.getAmount(); + if (amount >= 1) { + event.setAmount(amount + 1); + } + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ADD_COUNTERS; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Permanent permanent = game.getPermanent(event.getTargetId()); + Player player = game.getPlayer(source.getControllerId()); + if (permanent == null) { + permanent = game.getPermanentEntering(event.getTargetId()); + } + if (permanent != null && player != null && !player.hasOpponent(permanent.getControllerId(), game)) { + return true; + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public PirImaginativeRascalEffect copy() { + return new PirImaginativeRascalEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index fba911b570..098d8ae382 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -55,6 +55,7 @@ public class Battlebond extends ExpansionSet { this.ratioBoosterMythic = 8; cards.add(new SetCardInfo("Doomed Traveler", 91, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); + cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); @@ -68,7 +69,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); - cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); + cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); } } From 1a3a0d88c0d4d291d3556cae1a46b9845d2028c4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 15:30:14 -0400 Subject: [PATCH 017/154] Implemented Toothy, Imaginary Friend --- .../mage/cards/t/ToothyImaginaryFriend.java | 77 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 78 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/ToothyImaginaryFriend.java diff --git a/Mage.Sets/src/mage/cards/t/ToothyImaginaryFriend.java b/Mage.Sets/src/mage/cards/t/ToothyImaginaryFriend.java new file mode 100644 index 0000000000..d26c078467 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ToothyImaginaryFriend.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.DrawCardControllerTriggeredAbility; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.PartnersWithAbility; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; + +/** + * + * @author TheElk801 + */ +public class ToothyImaginaryFriend extends CardImpl { + + public ToothyImaginaryFriend(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.ILLUSION); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.) + this.addAbility(new PartnersWithAbility("Pir, Imaginative Rascal")); + + // Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend. + this.addAbility(new DrawCardControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), true)); + + // When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it. + this.addAbility(new LeavesBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(new CountersSourceCount(CounterType.P1P1)), false)); + } + + public ToothyImaginaryFriend(final ToothyImaginaryFriend card) { + super(card); + } + + @Override + public ToothyImaginaryFriend copy() { + return new ToothyImaginaryFriend(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 098d8ae382..718125bb2f 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -71,5 +71,6 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); + cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); } } From 636b35ae3971017ac51ce8b3f5d82317d95664c2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 15:53:06 -0400 Subject: [PATCH 018/154] small change to Partner with ability --- .../src/mage/deck/Commander.java | 6 ++--- .../src/mage/deck/FreeformCommander.java | 6 ++--- .../src/mage/deck/PennyDreadfulCommander.java | 6 ++--- .../mage/cards/p/PirImaginativeRascal.java | 4 ++-- .../mage/cards/t/ToothyImaginaryFriend.java | 4 ++-- ...thAbility.java => PartnerWithAbility.java} | 24 ++++++++++++------- 6 files changed, 29 insertions(+), 21 deletions(-) rename Mage/src/main/java/mage/abilities/keyword/{PartnersWithAbility.java => PartnerWithAbility.java} (87%) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java index 94c5ed286b..7fad492607 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java @@ -33,7 +33,7 @@ import mage.abilities.Ability; import mage.abilities.common.CanBeYourCommanderAbility; import mage.abilities.costs.mana.ManaCost; import mage.abilities.keyword.PartnerAbility; -import mage.abilities.keyword.PartnersWithAbility; +import mage.abilities.keyword.PartnerWithAbility; import mage.cards.Card; import mage.cards.ExpansionSet; import mage.cards.Sets; @@ -151,8 +151,8 @@ public class Commander extends Constructed { if (deck.getSideboard().size() == 2 && !commander.getAbilities().contains(PartnerAbility.getInstance())) { boolean partnersWith = false; for (Ability ability : commander.getAbilities()) { - if (ability instanceof PartnersWithAbility - && commanderNames.contains(((PartnersWithAbility) ability).getPartnerName())) { + if (ability instanceof PartnerWithAbility + && commanderNames.contains(((PartnerWithAbility) ability).getPartnerName())) { partnersWith = true; break; } diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java index 32fc877413..970ca92f9f 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/FreeformCommander.java @@ -30,7 +30,7 @@ package mage.deck; import java.util.*; import mage.abilities.Ability; import mage.abilities.keyword.PartnerAbility; -import mage.abilities.keyword.PartnersWithAbility; +import mage.abilities.keyword.PartnerWithAbility; import mage.cards.Card; import mage.cards.ExpansionSet; import mage.cards.Sets; @@ -102,8 +102,8 @@ public class FreeformCommander extends Constructed { if (deck.getSideboard().size() == 2 && !commander.getAbilities().contains(PartnerAbility.getInstance())) { boolean partnersWith = false; for (Ability ability : commander.getAbilities()) { - if (ability instanceof PartnersWithAbility - && commanderNames.contains(((PartnersWithAbility) ability).getPartnerName())) { + if (ability instanceof PartnerWithAbility + && commanderNames.contains(((PartnerWithAbility) ability).getPartnerName())) { partnersWith = true; break; } diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java index 0d23661a43..e09c5f3ee8 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/PennyDreadfulCommander.java @@ -32,7 +32,7 @@ import java.util.Map.Entry; import mage.abilities.Ability; import mage.abilities.common.CanBeYourCommanderAbility; import mage.abilities.keyword.PartnerAbility; -import mage.abilities.keyword.PartnersWithAbility; +import mage.abilities.keyword.PartnerWithAbility; import mage.cards.Card; import mage.cards.ExpansionSet; import mage.cards.Sets; @@ -113,8 +113,8 @@ public class PennyDreadfulCommander extends Constructed { if (deck.getSideboard().size() == 2 && !commander.getAbilities().contains(PartnerAbility.getInstance())) { boolean partnersWith = false; for (Ability ability : commander.getAbilities()) { - if (ability instanceof PartnersWithAbility - && commanderNames.contains(((PartnersWithAbility) ability).getPartnerName())) { + if (ability instanceof PartnerWithAbility + && commanderNames.contains(((PartnerWithAbility) ability).getPartnerName())) { partnersWith = true; break; } diff --git a/Mage.Sets/src/mage/cards/p/PirImaginativeRascal.java b/Mage.Sets/src/mage/cards/p/PirImaginativeRascal.java index d022fcf943..c9fabcc66b 100644 --- a/Mage.Sets/src/mage/cards/p/PirImaginativeRascal.java +++ b/Mage.Sets/src/mage/cards/p/PirImaginativeRascal.java @@ -32,7 +32,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.keyword.PartnersWithAbility; +import mage.abilities.keyword.PartnerWithAbility; import mage.constants.SubType; import mage.constants.SuperType; import mage.cards.CardImpl; @@ -61,7 +61,7 @@ public class PirImaginativeRascal extends CardImpl { this.toughness = new MageInt(1); // Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.) - this.addAbility(new PartnersWithAbility("Toothy, Imaginary Friend")); + this.addAbility(new PartnerWithAbility("Toothy, Imaginary Friend", true)); // If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PirImaginativeRascalEffect())); diff --git a/Mage.Sets/src/mage/cards/t/ToothyImaginaryFriend.java b/Mage.Sets/src/mage/cards/t/ToothyImaginaryFriend.java index d26c078467..d480130b85 100644 --- a/Mage.Sets/src/mage/cards/t/ToothyImaginaryFriend.java +++ b/Mage.Sets/src/mage/cards/t/ToothyImaginaryFriend.java @@ -34,7 +34,7 @@ import mage.abilities.common.LeavesBattlefieldTriggeredAbility; import mage.abilities.dynamicvalue.common.CountersSourceCount; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.PartnersWithAbility; +import mage.abilities.keyword.PartnerWithAbility; import mage.constants.SubType; import mage.constants.SuperType; import mage.cards.CardImpl; @@ -57,7 +57,7 @@ public class ToothyImaginaryFriend extends CardImpl { this.toughness = new MageInt(1); // Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.) - this.addAbility(new PartnersWithAbility("Pir, Imaginative Rascal")); + this.addAbility(new PartnerWithAbility("Pir, Imaginative Rascal", true)); // Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend. this.addAbility(new DrawCardControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), true)); diff --git a/Mage/src/main/java/mage/abilities/keyword/PartnersWithAbility.java b/Mage/src/main/java/mage/abilities/keyword/PartnerWithAbility.java similarity index 87% rename from Mage/src/main/java/mage/abilities/keyword/PartnersWithAbility.java rename to Mage/src/main/java/mage/abilities/keyword/PartnerWithAbility.java index 54eb5984a3..15daf1a2a5 100644 --- a/Mage/src/main/java/mage/abilities/keyword/PartnersWithAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/PartnerWithAbility.java @@ -46,32 +46,40 @@ import mage.target.common.TargetCardInLibrary; * * @author TheElk801 */ -public class PartnersWithAbility extends EntersBattlefieldTriggeredAbility { +public class PartnerWithAbility extends EntersBattlefieldTriggeredAbility { private final String partnerName; private final String shortName; - public PartnersWithAbility(String partnerName) { + public PartnerWithAbility(String partnerName) { + this(partnerName, false); + } + + public PartnerWithAbility(String partnerName, boolean isLegendary) { super(new PartnersWithSearchEffect(partnerName), false); this.addTarget(new TargetPlayer()); this.partnerName = partnerName; - this.shortName = shortenName(partnerName); + if (isLegendary) { + this.shortName = shortenName(partnerName); + } else { + this.shortName = partnerName; + } } - public PartnersWithAbility(final PartnersWithAbility ability) { + public PartnerWithAbility(final PartnerWithAbility ability) { super(ability); this.partnerName = ability.partnerName; this.shortName = ability.shortName; } @Override - public PartnersWithAbility copy() { - return new PartnersWithAbility(this); + public PartnerWithAbility copy() { + return new PartnerWithAbility(this); } @Override public String getRule() { - return "Partners with" + partnerName + return "Partner with " + partnerName + " <i>(When this creature enters the battlefield, target player may put " + shortName + " into their hand from their library, then shuffle.)</i>"; } @@ -122,7 +130,7 @@ class PartnersWithSearchEffect extends OneShotEffect { FilterCard filter = new FilterCard("card named " + partnerName); filter.add(new NamePredicate(partnerName)); TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (player.chooseUse(Outcome.Benefit, "Search your library for a card named" + partnerName + " and put it into your hand?", source, game)) { + if (player.chooseUse(Outcome.Benefit, "Search your library for a card named " + partnerName + " and put it into your hand?", source, game)) { player.searchLibrary(target, game); for (UUID cardId : target.getTargets()) { Card card = player.getLibrary().getCard(cardId, game); From cbdeb95097e87b303aa3d680c12bc3b6c759e50c Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 16:03:16 -0400 Subject: [PATCH 019/154] Updated Battlebond spoiler --- Utils/mtg-cards-data.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 5c3068cf9b..4945c8c6a3 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33364,11 +33364,15 @@ Virtus the Veiled|Battlebond|7|R|{2}{R}|Legendary Creature - Azra Assassin|1|1|P Gorm the Great|Battlebond|8|R|{3}{G}|Legendary Creature - Giant Warrior|2|7|Partner with Virtus the Veiled (When this creature enters the battlefield, target player may put Virtus into their hand from their library, then shuffle.)$Vigilance$Gorm the Great must be blocked if able and Gorm must be blocked by two or more creatures if able.| Pir, Imaginative Rascal|Battlebond|11|R|{2}{G}|Legendary Creature - Human|1|1|Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.)$If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead.| Toothy, Imaginary Friend|Battlebond|12|R|{3}{U}|Legendary Creature - Illusion|1|1|Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.)$Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend.$When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it.| +Soulblade Corrupter|Battlebond|17|U|{4}{B}|Creature - Human Warrior|3|3|Partner with Soulblade Renewer (When this creature enters the battlefield, target player may put Soulblade Renewer into their hand from their library, then shuffle.)$Deathtouch$Whenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn.| +Soulblade Renewer|Battlebond|18|U|{4}{G}|Creature - Elf Warrior|2|2|Partner with Soulblade Corrupter (When this creature enters the battlefield, target player may put Soulblade Corrupter into their hand from their library, then shuffle.)$When Soulblade Renewer enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two target creatures.)| Dwarven Lightsmith|Battlebond|27|C|{5}{C}|Creature - Dwarf Cleric|3|4|Assist (Another player can pay up to {5} of this spell's cost.)$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| +Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist (Another player can pay up to {6} of this spell's cost)$Exile all nonland permanents.| Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| Soaring Show-Off|Battlebond|40|C|{2}{U}|Creature - Bird Warrior|2|2|Flying$When Soaring Show-Off enters the battlefield, each player draws a card.| -Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist (Another player can pay up to {6} of this spell's cost)$Exile all nonland permanents.| +Archfiend of Despair|Battlebond|44|M|{6}{B}{B}|Creature - Demon|6|6|Flying$Your opponents can't gain life.$At the beginning of each end step, each opponent loses life equal to the life that player lost this turn. (Damage causes loss of life.)| Fan Favorite|Battlebond|46|C|{3}{B}|Creature - Human Rogue|2|2|Assist (Another player can play up to {3} of this spell's cost.)${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| +Mindblade Render|Battlebond|49|R|{1}{B}|Creature - Azra Warrior|1|3|Whenever your opponents are dealt combat damage, if any of that damage was dealt by a Warrior, you draw a card and you lose 1 life.| Charging Binox|Battlebond|66|C|{7}{G}|Creature - Beast|7|5|Assist (Another player can pay up to {7} of this spell's cost.)$Trample| Pir's Whim|Battlebond|73|R|{3}{G}|Sorcery|||For each player, choose friend or foe. Each friend searches their library for a land card, puts it onto the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment.| Rushblade Commander|Battlebond|77|U|{B}{R}|Creature - Azra Warrior|2|2|Warrior creatures your team controls have haste.| From 28c66659c08ff455791c1e2410d64b7c73e62d79 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 16:23:44 -0400 Subject: [PATCH 020/154] Implemented Soulblade Renewer --- .../src/mage/cards/s/SoulbladeRenewer.java | 68 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 69 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SoulbladeRenewer.java diff --git a/Mage.Sets/src/mage/cards/s/SoulbladeRenewer.java b/Mage.Sets/src/mage/cards/s/SoulbladeRenewer.java new file mode 100644 index 0000000000..5f0a152104 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SoulbladeRenewer.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.PartnerWithAbility; +import mage.abilities.keyword.SupportAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class SoulbladeRenewer extends CardImpl { + + public SoulbladeRenewer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Partner with Soulblade Corrupter (When this creature enters the battlefield, target player may put Soulblade Corrupter into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Soulblade Corrupter")); + + // When Soulblade Renewer enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two target creatures.) + this.addAbility(new SupportAbility(this, 2)); + } + + public SoulbladeRenewer(final SoulbladeRenewer card) { + super(card); + } + + @Override + public SoulbladeRenewer copy() { + return new SoulbladeRenewer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 718125bb2f..c110239ebb 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -70,6 +70,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); + cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); } From 663a4bb967fc01318ed3ec24e29c93c995585456 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 16:42:22 -0400 Subject: [PATCH 021/154] Implemented Soulblade Corrupter --- .../src/mage/cards/s/SoulbladeCorrupter.java | 120 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 121 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SoulbladeCorrupter.java diff --git a/Mage.Sets/src/mage/cards/s/SoulbladeCorrupter.java b/Mage.Sets/src/mage/cards/s/SoulbladeCorrupter.java new file mode 100644 index 0000000000..69a85513c7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SoulbladeCorrupter.java @@ -0,0 +1,120 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksAllTriggeredAbility; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.PartnerWithAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SetTargetPointer; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.CounterPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class SoulbladeCorrupter extends CardImpl { + + public SoulbladeCorrupter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Partner with Soulblade Renewer (When this creature enters the battlefield, target player may put Soulblade Renewer into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Soulblade Renewer")); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // Whenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn. + this.addAbility(new SoulbladeCorrupterTriggeredAbility()); + } + + public SoulbladeCorrupter(final SoulbladeCorrupter card) { + super(card); + } + + @Override + public SoulbladeCorrupter copy() { + return new SoulbladeCorrupter(this); + } +} + +class SoulbladeCorrupterTriggeredAbility extends AttacksAllTriggeredAbility { + + private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("creature with a +1/+1 counter on it"); + + static { + filter2.add(new CounterPredicate(CounterType.P1P1)); + } + + SoulbladeCorrupterTriggeredAbility() { + super(new GainAbilityTargetEffect( + DeathtouchAbility.getInstance(), + Duration.EndOfTurn + ), false, filter2, SetTargetPointer.PERMANENT, false); + } + + SoulbladeCorrupterTriggeredAbility(final SoulbladeCorrupterTriggeredAbility effect) { + super(effect); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (super.checkTrigger(event, game)) { + Permanent permanent = game.getPermanent(event.getSourceId()); + if (permanent != null) { + Player player = game.getPlayer(permanent.getControllerId()); + return player != null && player.hasOpponent(getControllerId(), game); + } + } + return false; + } + + @Override + public SoulbladeCorrupterTriggeredAbility copy() { + return new SoulbladeCorrupterTriggeredAbility(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index c110239ebb..f37fcd7d18 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -70,6 +70,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); + cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); From 856025e6d6fed638cd1fda4bbc44cc4eb3c5db97 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 16:48:49 -0400 Subject: [PATCH 022/154] updated Battlebond spoiler --- Utils/mtg-cards-data.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 4945c8c6a3..a8dabadfde 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33366,6 +33366,8 @@ Pir, Imaginative Rascal|Battlebond|11|R|{2}{G}|Legendary Creature - Human|1|1|Pa Toothy, Imaginary Friend|Battlebond|12|R|{3}{U}|Legendary Creature - Illusion|1|1|Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.)$Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend.$When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it.| Soulblade Corrupter|Battlebond|17|U|{4}{B}|Creature - Human Warrior|3|3|Partner with Soulblade Renewer (When this creature enters the battlefield, target player may put Soulblade Renewer into their hand from their library, then shuffle.)$Deathtouch$Whenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn.| Soulblade Renewer|Battlebond|18|U|{4}{G}|Creature - Elf Warrior|2|2|Partner with Soulblade Corrupter (When this creature enters the battlefield, target player may put Soulblade Corrupter into their hand from their library, then shuffle.)$When Soulblade Renewer enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two target creatures.)| +Impetuous Protege|Battlebond|19|U|{2}{R}|Creature - Human Warrior|0|4|Partner with Proud Mentor (When this creature enters the battlefield, target player may put Proud Mentor into their hand from their library, then shuffle.)$Whenever Impetuous Protege attacks, it gets +X/+0 until end of turn, where X is the greatest power among tapped creatures your opponents control| +Proud Mentor|Battlebond|20|U|{2}{W}|Creature - Human Warrior|1|1|Partner with Impetuous Protege (When this creature enters the battlefield, target player may put Impetuous Protege into their hand from their library, then shuffle.)${W}, {T}: Tap target creature| Dwarven Lightsmith|Battlebond|27|C|{5}{C}|Creature - Dwarf Cleric|3|4|Assist (Another player can pay up to {5} of this spell's cost.)$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist (Another player can pay up to {6} of this spell's cost)$Exile all nonland permanents.| Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| From 8ff54e86a7f03bf683168fbd14a118c4dca3b107 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 16:55:56 -0400 Subject: [PATCH 023/154] Implemented Proud Mentor --- Mage.Sets/src/mage/cards/p/ProudMentor.java | 78 +++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 2 + 2 files changed, 80 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/ProudMentor.java diff --git a/Mage.Sets/src/mage/cards/p/ProudMentor.java b/Mage.Sets/src/mage/cards/p/ProudMentor.java new file mode 100644 index 0000000000..f4de3f7943 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/ProudMentor.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ColoredManaCost; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ColoredManaSymbol; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class ProudMentor extends CardImpl { + + public ProudMentor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Partner with Impetuous Protege (When this creature enters the battlefield, target player may put Impetuous Protege into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Impetuous Protege")); + + // {W}, {T}: Tap target creature + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new ColoredManaCost(ColoredManaSymbol.W)); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public ProudMentor(final ProudMentor card) { + super(card); + } + + @Override + public ProudMentor copy() { + return new ProudMentor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index f37fcd7d18..3481a68762 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -56,6 +56,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Doomed Traveler", 91, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); + cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); @@ -68,6 +69,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); + cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); From 04dec9b91bb8358de2b34b3d256d49b4f2540cf1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 17:39:51 -0400 Subject: [PATCH 024/154] Implemented Impetuous Protege --- .../src/mage/cards/i/ImpetuousProtege.java | 113 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 2 + 2 files changed, 115 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/ImpetuousProtege.java diff --git a/Mage.Sets/src/mage/cards/i/ImpetuousProtege.java b/Mage.Sets/src/mage/cards/i/ImpetuousProtege.java new file mode 100644 index 0000000000..d78e27708f --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/ImpetuousProtege.java @@ -0,0 +1,113 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class ImpetuousProtege extends CardImpl { + + public ImpetuousProtege(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // Partner with Proud Mentor (When this creature enters the battlefield, target player may put Proud Mentor into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Proud Mentor")); + + // Whenever Impetuous Protege attacks, it gets +X/+0 until end of turn, where X is the greatest power among tapped creatures your opponents control + this.addAbility(new AttacksTriggeredAbility(new ImpetuousProtegeEffect(), false)); + } + + public ImpetuousProtege(final ImpetuousProtege card) { + super(card); + } + + @Override + public ImpetuousProtege copy() { + return new ImpetuousProtege(this); + } +} + +class ImpetuousProtegeEffect extends OneShotEffect { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new TappedPredicate()); + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + ImpetuousProtegeEffect() { + super(Outcome.Benefit); + this.staticText = "it gets +X/+0 until end of turn, where X is the greatest power among tapped creatures your opponents control"; + } + + ImpetuousProtegeEffect(final ImpetuousProtegeEffect effect) { + super(effect); + } + + @Override + public ImpetuousProtegeEffect copy() { + return new ImpetuousProtegeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + int maxPower = 0; + for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + maxPower = Math.max(maxPower, creature.getPower().getValue()); + } + game.addEffect(new BoostSourceEffect(maxPower, 0, Duration.EndOfTurn), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 3481a68762..1f990612a7 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -55,6 +55,7 @@ public class Battlebond extends ExpansionSet { this.ratioBoosterMythic = 8; cards.add(new SetCardInfo("Doomed Traveler", 91, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); + cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); @@ -67,6 +68,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); cards.add(new SetCardInfo("Eager Construct", 234, Rarity.COMMON, mage.cards.e.EagerConstruct.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); + cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); From d645c1a5d80cf1a368c5f1a018b2bf4bd96f7746 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 19:59:17 -0400 Subject: [PATCH 025/154] Implemented Will Kenrith --- Mage.Sets/src/mage/cards/w/WillKenrith.java | 154 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + .../abilities/effects/ContinuousEffect.java | 2 + .../effects/ContinuousEffectImpl.java | 5 + .../abilities/keyword/PartnerWithAbility.java | 17 +- .../src/main/java/mage/constants/SubType.java | 1 + .../command/emblems/WillKenrithEmblem.java | 54 ++++++ 7 files changed, 231 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/w/WillKenrith.java create mode 100644 Mage/src/main/java/mage/game/command/emblems/WillKenrithEmblem.java diff --git a/Mage.Sets/src/mage/cards/w/WillKenrith.java b/Mage.Sets/src/mage/cards/w/WillKenrith.java new file mode 100644 index 0000000000..ce133b91d6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WillKenrith.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.cards.w; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.CanBeYourCommanderAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.abilities.effects.common.GetEmblemTargetPlayerEffect; +import mage.abilities.effects.common.continuous.LoseAllAbilitiesTargetEffect; +import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect; +import mage.abilities.effects.common.cost.SpellsCostReductionAllEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.command.emblems.WillKenrithEmblem; +import mage.target.TargetPlayer; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class WillKenrith extends CardImpl { + + public WillKenrith(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{U}{U}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.WILL); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); + + // +2: Until your next turn, up to two target creatures each have base power and toughness 0/3 and lose all abilities. + Ability ability = new LoyaltyAbility( + new SetPowerToughnessTargetEffect(0, 3, Duration.EndOfTurn) + .setText("until end of turn, up to two target creatures each have base power and toughness 0/3"), + 2 + ); + ability.addEffect(new LoseAllAbilitiesTargetEffect(Duration.EndOfTurn) + .setText("and lose all abilities") + ); + ability.addTarget(new TargetCreaturePermanent(0, 2)); + this.addAbility(ability); + + // -2: Target player draws two cards. Until your next turn, instant, sorcery, and planeswalker spells that player casts cost 2 less to cast. + ability = new LoyaltyAbility(new DrawCardTargetEffect(2), -2); + ability.addEffect(new WillKenrithCostReductionEffect()); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + + // -8: Target player gets an emblem with "Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy." + Effect effect = new GetEmblemTargetPlayerEffect(new WillKenrithEmblem()); + effect.setText( + "Target player gets an emblem with " + + "\"Whenever you cast an instant or sorcery spell, " + + "copy it. You may choose new targets for the copy.\"" + ); + ability = new LoyaltyAbility(effect, -8); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + + // Partner with Rowan Kenrith + this.addAbility(new PartnerWithAbility("Rowan Kenrith", true, false)); + + // Will Kenrith can be your commander. + this.addAbility(CanBeYourCommanderAbility.getInstance()); + } + + public WillKenrith(final WillKenrith card) { + super(card); + } + + @Override + public WillKenrith copy() { + return new WillKenrith(this); + } +} + +class WillKenrithCostReductionEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard(); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY), + new CardTypePredicate(CardType.PLANESWALKER) + )); + } + + WillKenrithCostReductionEffect() { + super(Outcome.Benefit); + this.staticText = "Until your next turn, instant, sorcery, and planeswalker spells that player casts cost {2} less to cast."; + } + + WillKenrithCostReductionEffect(final WillKenrithCostReductionEffect effect) { + super(effect); + } + + @Override + public WillKenrithCostReductionEffect copy() { + return new WillKenrithCostReductionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + FilterCard filter2 = filter.copy(); + filter2.add(new ControllerIdPredicate(source.getFirstTarget())); + ContinuousEffect effect = new SpellsCostReductionAllEffect(filter2, 2); + effect.setDuration(Duration.UntilYourNextTurn); + game.addEffect(effect, source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 1f990612a7..52eba02023 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -78,5 +78,6 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); + cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); } } diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffect.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffect.java index 51df5b855d..04e7fdec34 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffect.java @@ -51,6 +51,8 @@ public interface ContinuousEffect extends Effect { void discard(); + void setDuration(Duration duration); + Duration getDuration(); long getOrder(); diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffectImpl.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffectImpl.java index ac2720a393..eab9194ed5 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffectImpl.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffectImpl.java @@ -112,6 +112,11 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu this.characterDefining = effect.characterDefining; } + @Override + public void setDuration(Duration duration) { + this.duration = duration; + } + @Override public Duration getDuration() { return duration; diff --git a/Mage/src/main/java/mage/abilities/keyword/PartnerWithAbility.java b/Mage/src/main/java/mage/abilities/keyword/PartnerWithAbility.java index 15daf1a2a5..63cbcf4343 100644 --- a/Mage/src/main/java/mage/abilities/keyword/PartnerWithAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/PartnerWithAbility.java @@ -50,15 +50,21 @@ public class PartnerWithAbility extends EntersBattlefieldTriggeredAbility { private final String partnerName; private final String shortName; + private final boolean hasReminderText; public PartnerWithAbility(String partnerName) { this(partnerName, false); } public PartnerWithAbility(String partnerName, boolean isLegendary) { + this(partnerName, isLegendary, true); + } + + public PartnerWithAbility(String partnerName, boolean isLegendary, boolean hasReminderText) { super(new PartnersWithSearchEffect(partnerName), false); this.addTarget(new TargetPlayer()); this.partnerName = partnerName; + this.hasReminderText = hasReminderText; if (isLegendary) { this.shortName = shortenName(partnerName); } else { @@ -70,6 +76,7 @@ public class PartnerWithAbility extends EntersBattlefieldTriggeredAbility { super(ability); this.partnerName = ability.partnerName; this.shortName = ability.shortName; + this.hasReminderText = ability.hasReminderText; } @Override @@ -79,9 +86,13 @@ public class PartnerWithAbility extends EntersBattlefieldTriggeredAbility { @Override public String getRule() { - return "Partner with " + partnerName - + " <i>(When this creature enters the battlefield, target player may put " + shortName - + " into their hand from their library, then shuffle.)</i>"; + if (hasReminderText) { + return "Partner with " + partnerName + + " <i>(When this creature enters the battlefield, target player may put " + shortName + + " into their hand from their library, then shuffle.)</i>"; + } else { + return "Partner with " + partnerName; + } } public String getPartnerName() { diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index 05f7f08e47..7d81951dcc 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -401,6 +401,7 @@ public enum SubType { UGIN("Ugin", SubTypeSet.PlaneswalkerType), VENSER("Venser", SubTypeSet.PlaneswalkerType), VRASKA("Vraska", SubTypeSet.PlaneswalkerType), + WILL("Will", SubTypeSet.PlaneswalkerType), XENAGOS("Xenagos", SubTypeSet.PlaneswalkerType), YANGGU("Yanggu", SubTypeSet.PlaneswalkerType), YANLING("Yanling", SubTypeSet.PlaneswalkerType), diff --git a/Mage/src/main/java/mage/game/command/emblems/WillKenrithEmblem.java b/Mage/src/main/java/mage/game/command/emblems/WillKenrithEmblem.java new file mode 100644 index 0000000000..6d89f2e22c --- /dev/null +++ b/Mage/src/main/java/mage/game/command/emblems/WillKenrithEmblem.java @@ -0,0 +1,54 @@ +/* + * 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.game.command.emblems; + +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.CopyTargetSpellEffect; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.command.Emblem; + +/** + * + * @author spjspj + */ +public class WillKenrithEmblem extends Emblem { + // Target player gets an emblem with "Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy." + + public WillKenrithEmblem() { + this.setName("Emblem Will Kenrith"); + this.getAbilities().add(new SpellCastControllerTriggeredAbility( + Zone.COMMAND, + new CopyTargetSpellEffect(true) + .setText("copy that spell. You may choose new targets for the copy"), + StaticFilters.FILTER_INSTANT_OR_SORCERY_SPELL, + false, + true + )); + } +} From 8b15be9bf07ad6901eb4924861e66dec106e5ef2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 20:37:17 -0400 Subject: [PATCH 026/154] Implemented Rowan Kenrith --- Mage.Sets/src/mage/cards/r/RowanKenrith.java | 182 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 2 + .../src/main/java/mage/constants/SubType.java | 1 + .../command/emblems/RowanKenrithEmblem.java | 124 ++++++++++++ .../command/emblems/WillKenrithEmblem.java | 2 +- 5 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/r/RowanKenrith.java create mode 100644 Mage/src/main/java/mage/game/command/emblems/RowanKenrithEmblem.java diff --git a/Mage.Sets/src/mage/cards/r/RowanKenrith.java b/Mage.Sets/src/mage/cards/r/RowanKenrith.java new file mode 100644 index 0000000000..769bbe4f47 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RowanKenrith.java @@ -0,0 +1,182 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.CanBeYourCommanderAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.RequirementEffect; +import mage.abilities.effects.common.DamageAllEffect; +import mage.abilities.effects.common.GetEmblemTargetPlayerEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TurnPhase; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.game.Game; +import mage.game.command.emblems.RowanKenrithEmblem; +import mage.game.permanent.Permanent; +import mage.target.TargetPlayer; + +/** + * + * @author TheElk801 + */ +public class RowanKenrith extends CardImpl { + + public RowanKenrith(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{R}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.ROWAN); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); + + // +2: During target player's next turn, each creature that player controls attacks if able. + LoyaltyAbility ability = new LoyaltyAbility(new RowanKenrithAttackEffect(), 2); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + + // -2: Rowan Kenrith deals 3 damage to each tapped creature target player controls. + ability = new LoyaltyAbility(new RowanKenrithDamageEffect(), -2); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + + // -8: Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy." + Effect effect = new GetEmblemTargetPlayerEffect(new RowanKenrithEmblem()); + effect.setText( + "Target player gets an emblem with " + + "\"Whenever you activate an ability that isn't a mana ability, " + + "copy it. You may choose new targets for the copy.\"" + ); + ability = new LoyaltyAbility(effect, -8); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + + // Partner with Will Kenrith + this.addAbility(new PartnerWithAbility("Will Kenrith", true, false)); + + // Rowan Kenrith can be your commander. + this.addAbility(CanBeYourCommanderAbility.getInstance()); + } + + public RowanKenrith(final RowanKenrith card) { + super(card); + } + + @Override + public RowanKenrith copy() { + return new RowanKenrith(this); + } +} + +class RowanKenrithAttackEffect extends RequirementEffect { + + protected MageObjectReference creatingPermanent; + + public RowanKenrithAttackEffect() { + super(Duration.Custom); + staticText = "During target player's next turn, creatures that player controls attack if able"; + } + + public RowanKenrithAttackEffect(final RowanKenrithAttackEffect effect) { + super(effect); + this.creatingPermanent = effect.creatingPermanent; + } + + @Override + public RowanKenrithAttackEffect copy() { + return new RowanKenrithAttackEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + creatingPermanent = new MageObjectReference(source.getSourceId(), game); + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return permanent.getControllerId().equals(source.getFirstTarget()); + } + + @Override + public boolean isInactive(Ability source, Game game) { + return (startingTurn != game.getTurnNum() + && (game.getPhase().getType() == TurnPhase.END + && game.getActivePlayerId().equals(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; + } + + @Override + public boolean mustAttack(Game game) { + return true; + } + + @Override + public boolean mustBlock(Game game) { + return false; + } +} + +class RowanKenrithDamageEffect extends OneShotEffect { + + RowanKenrithDamageEffect() { + super(Outcome.Benefit); + this.staticText = "{this} deals 3 damage to each tapped creature target player controls"; + } + + RowanKenrithDamageEffect(final RowanKenrithDamageEffect effect) { + super(effect); + } + + @Override + public RowanKenrithDamageEffect copy() { + return new RowanKenrithDamageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(new TappedPredicate()); + filter.add(new ControllerIdPredicate(source.getControllerId())); + return new DamageAllEffect(3, filter).apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 52eba02023..bb8326fbd0 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -58,6 +58,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); + cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); @@ -72,6 +73,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); + cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index 7d81951dcc..9e9a23c048 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -389,6 +389,7 @@ public enum SubType { NIXILIS("Nixilis", SubTypeSet.PlaneswalkerType), OBI_WAN("Obi-Wan", SubTypeSet.PlaneswalkerType, true), // Star Wars RAL("Ral", SubTypeSet.PlaneswalkerType), + ROWAN("Rowan", SubTypeSet.PlaneswalkerType), SAHEELI("Saheeli", SubTypeSet.PlaneswalkerType), SAMUT("Samut", SubTypeSet.PlaneswalkerType), SARKHAN("Sarkhan", SubTypeSet.PlaneswalkerType), diff --git a/Mage/src/main/java/mage/game/command/emblems/RowanKenrithEmblem.java b/Mage/src/main/java/mage/game/command/emblems/RowanKenrithEmblem.java new file mode 100644 index 0000000000..292542dd2b --- /dev/null +++ b/Mage/src/main/java/mage/game/command/emblems/RowanKenrithEmblem.java @@ -0,0 +1,124 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ..AS IS.. AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.game.command.emblems; + +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.mana.ManaAbility; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.command.Emblem; +import mage.game.events.GameEvent; +import mage.game.stack.StackAbility; +import mage.game.stack.StackObject; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class RowanKenrithEmblem extends Emblem { + // Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy." + + public RowanKenrithEmblem() { + this.setName("Emblem Rowan Kenrith"); + this.getAbilities().add(new RowanKenrithEmblemTriggeredAbility()); + } +} + +class RowanKenrithEmblemTriggeredAbility extends TriggeredAbilityImpl { + + public RowanKenrithEmblemTriggeredAbility() { + super(Zone.COMMAND, new RowanKenrithEmblemCopyEffect(), false); + } + + public RowanKenrithEmblemTriggeredAbility(final RowanKenrithEmblemTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ACTIVATED_ABILITY; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getPlayerId().equals(this.getControllerId())) { + StackObject ability = game.getStack().getStackObject(event.getTargetId()); + if (ability != null && !(ability instanceof ManaAbility)) { + this.getEffects().get(0).setTargetPointer(new FixedTarget(ability.getId())); + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy."; + } + + @Override + public RowanKenrithEmblemTriggeredAbility copy() { + return new RowanKenrithEmblemTriggeredAbility(this); + } +} + +class RowanKenrithEmblemCopyEffect extends OneShotEffect { + + public RowanKenrithEmblemCopyEffect() { + super(Outcome.Copy); + this.staticText = "copy it. You may choose new targets for the copy."; + } + + public RowanKenrithEmblemCopyEffect(final RowanKenrithEmblemCopyEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(targetPointer.getFirst(game, source)); + if (stackAbility != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + stackAbility.createCopyOnStack(game, source, source.getControllerId(), true); + return true; + } + } + return false; + + } + + @Override + public RowanKenrithEmblemCopyEffect copy() { + return new RowanKenrithEmblemCopyEffect(this); + } +} diff --git a/Mage/src/main/java/mage/game/command/emblems/WillKenrithEmblem.java b/Mage/src/main/java/mage/game/command/emblems/WillKenrithEmblem.java index 6d89f2e22c..25fa741b91 100644 --- a/Mage/src/main/java/mage/game/command/emblems/WillKenrithEmblem.java +++ b/Mage/src/main/java/mage/game/command/emblems/WillKenrithEmblem.java @@ -35,7 +35,7 @@ import mage.game.command.Emblem; /** * - * @author spjspj + * @author TheElk801 */ public class WillKenrithEmblem extends Emblem { // Target player gets an emblem with "Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy." From f29c7440cdc24e3535817c2c859a43ebe31baf7c Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 21:43:06 -0400 Subject: [PATCH 027/154] Reordered Battlebond cards --- Mage.Sets/src/mage/sets/Battlebond.java | 35 +++++++++++-------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index bb8326fbd0..e7d65ed89b 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -53,33 +53,30 @@ public class Battlebond extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; - cards.add(new SetCardInfo("Doomed Traveler", 91, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); - cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); - cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); - cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); - cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); - cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); - cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); - cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); + cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); + cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); + cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); cards.add(new SetCardInfo("Doomed Dissenter", 142, Rarity.COMMON, mage.cards.d.DoomedDissenter.class)); + cards.add(new SetCardInfo("Doomed Traveler", 91, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); cards.add(new SetCardInfo("Doubling Season", 195, Rarity.MYTHIC, mage.cards.d.DoublingSeason.class)); - cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); - cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); - cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); cards.add(new SetCardInfo("Eager Construct", 234, Rarity.COMMON, mage.cards.e.EagerConstruct.class)); - cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); - cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); + cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); + cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); + cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); - cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); - cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); + cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); + cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); + cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); + cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); + cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); - cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); - cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); + cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); + cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); - cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); - cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); + cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); + cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); } } From d00d0be805de5cdb545df1c08bed15732d8a8945 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 21 May 2018 22:37:09 -0400 Subject: [PATCH 028/154] Implemented Archfiend of Despair --- .../src/mage/cards/a/ArchfiendOfDespair.java | 123 ++++++++++++++++++ .../src/mage/cards/e/ErebosGodOfTheDead.java | 45 ++----- Mage.Sets/src/mage/sets/Battlebond.java | 1 + 3 files changed, 134 insertions(+), 35 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/ArchfiendOfDespair.java diff --git a/Mage.Sets/src/mage/cards/a/ArchfiendOfDespair.java b/Mage.Sets/src/mage/cards/a/ArchfiendOfDespair.java new file mode 100644 index 0000000000..a260f97c97 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArchfiendOfDespair.java @@ -0,0 +1,123 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.CantGainLifeAllEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.watchers.common.PlayerLostLifeWatcher; + +/** + * + * @author TheElk801 + */ +public class ArchfiendOfDespair extends CardImpl { + + public ArchfiendOfDespair(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{B}{B}"); + + this.subtype.add(SubType.DEMON); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Your opponents can't gain life. + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + new CantGainLifeAllEffect( + Duration.WhileOnBattlefield, + TargetController.OPPONENT + ) + )); + + // At the beginning of each end step, each opponent loses life equal to the life that player lost this turn. (Damage causes loss of life.) + this.addAbility(new BeginningOfEndStepTriggeredAbility(new ArchfiendOfDespairEffect(), TargetController.ANY, false)); + } + + public ArchfiendOfDespair(final ArchfiendOfDespair card) { + super(card); + } + + @Override + public ArchfiendOfDespair copy() { + return new ArchfiendOfDespair(this); + } +} + +class ArchfiendOfDespairEffect extends OneShotEffect { + + public ArchfiendOfDespairEffect() { + super(Outcome.LoseLife); + this.staticText = "each opponent loses life equal to the life he or she lost this turn"; + } + + public ArchfiendOfDespairEffect(final ArchfiendOfDespairEffect effect) { + super(effect); + } + + @Override + public ArchfiendOfDespairEffect copy() { + return new ArchfiendOfDespairEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get(PlayerLostLifeWatcher.class.getSimpleName()); + if (controller != null && watcher != null) { + for (UUID playerId : game.getOpponents(controller.getId())) { + Player opponent = game.getPlayer(playerId); + if (opponent != null) { + int lifeLost = watcher.getLiveLost(playerId); + if (lifeLost > 0) { + opponent.loseLife(lifeLost, game, false); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/e/ErebosGodOfTheDead.java b/Mage.Sets/src/mage/cards/e/ErebosGodOfTheDead.java index f250f2df16..56efd26e77 100644 --- a/Mage.Sets/src/mage/cards/e/ErebosGodOfTheDead.java +++ b/Mage.Sets/src/mage/cards/e/ErebosGodOfTheDead.java @@ -35,16 +35,14 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.PayLifeCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.DevotionCount; -import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.CantGainLifeAllEffect; import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.game.Game; -import mage.players.Player; /** * @@ -53,7 +51,7 @@ import mage.players.Player; public class ErebosGodOfTheDead extends CardImpl { public ErebosGodOfTheDead(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{3}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{B}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.GOD); @@ -62,13 +60,20 @@ public class ErebosGodOfTheDead extends CardImpl { // Indestructible this.addAbility(IndestructibleAbility.getInstance()); + // As long as your devotion to black is less than five, Erebos isn't a creature. Effect effect = new LoseCreatureTypeSourceEffect(new DevotionCount(ColoredManaSymbol.B), 5); effect.setText("As long as your devotion to black is less than five, Erebos isn't a creature.<i>(Each {B} in the mana costs of permanents you control counts towards your devotion to black.)</i>"); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); // Your opponents can't gain life. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new OpponentsCantGainLifeEffect())); + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + new CantGainLifeAllEffect( + Duration.WhileOnBattlefield, + TargetController.OPPONENT + ) + )); // {1}{B}, Pay 2 life: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}{B}")); @@ -86,33 +91,3 @@ public class ErebosGodOfTheDead extends CardImpl { return new ErebosGodOfTheDead(this); } } - -class OpponentsCantGainLifeEffect extends ContinuousEffectImpl { - - public OpponentsCantGainLifeEffect() { - super(Duration.WhileOnBattlefield, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit); - staticText = "Your opponents can't gain life"; - } - - public OpponentsCantGainLifeEffect(final OpponentsCantGainLifeEffect effect) { - super(effect); - } - - @Override - public OpponentsCantGainLifeEffect copy() { - return new OpponentsCantGainLifeEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - for (UUID playerId: game.getOpponents(source.getControllerId())) { - Player player = game.getPlayer(playerId); - if (player != null) - { - player.setCanGainLife(false); - } - } - return true; - } - -} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index e7d65ed89b..7e97e2076a 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -53,6 +53,7 @@ public class Battlebond extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; + cards.add(new SetCardInfo("Archfiend of Despair", 44, Rarity.MYTHIC, mage.cards.a.ArchfiendOfDespair.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); From 0eb1bc9938ec4d9066a78b762b13ab0e5813010e Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 22 May 2018 09:42:06 -0400 Subject: [PATCH 029/154] added some reprints to Battlebond --- Mage.Sets/src/mage/sets/Battlebond.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 7e97e2076a..9fed284f35 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -53,7 +53,7 @@ public class Battlebond extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; - cards.add(new SetCardInfo("Archfiend of Despair", 44, Rarity.MYTHIC, mage.cards.a.ArchfiendOfDespair.class)); + cards.add(new SetCardInfo("Archfiend of Despair", 44, Rarity.MYTHIC, mage.cards.a.ArchfiendOfDespair.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); @@ -77,7 +77,9 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); + cards.add(new SetCardInfo("True-Name Nemesis", 136, Rarity.MYTHIC, mage.cards.t.TrueNameNemesis.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); + cards.add(new SetCardInfo("Vigor", 215, Rarity.RARE, mage.cards.v.Vigor.class)); cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); } } From 2a7a258f340fc304d7644aed6339c0cc23716158 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 22 May 2018 09:58:36 -0400 Subject: [PATCH 030/154] Added Sower of Temptation to Battlebond --- Mage.Sets/src/mage/sets/Battlebond.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 9fed284f35..5969abd66b 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -76,6 +76,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); + cards.add(new SetCardInfo("Sower of Temptation", 131, Rarity.RARE, mage.cards.s.SowerOfTemptation.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); cards.add(new SetCardInfo("True-Name Nemesis", 136, Rarity.MYTHIC, mage.cards.t.TrueNameNemesis.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); From 725adb1a2549e58323e60464aa56653f260ff35f Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 22 May 2018 10:13:14 -0400 Subject: [PATCH 031/154] Implemented Rushblade Commander --- .../src/mage/cards/r/RushbladeCommander.java | 89 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + .../src/main/java/mage/constants/SubType.java | 1 + 3 files changed, 91 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RushbladeCommander.java diff --git a/Mage.Sets/src/mage/cards/r/RushbladeCommander.java b/Mage.Sets/src/mage/cards/r/RushbladeCommander.java new file mode 100644 index 0000000000..1e9388bc9d --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RushbladeCommander.java @@ -0,0 +1,89 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.abilities.keyword.HasteAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class RushbladeCommander extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Warrior creatures your team controls"); + + static { + filter.add(Predicates.not( + new ControllerPredicate(TargetController.OPPONENT) + )); + filter.add(new SubtypePredicate(SubType.WARRIOR)); + } + + public RushbladeCommander(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{R}"); + + this.subtype.add(SubType.AZRA); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Warrior creatures your team controls have haste. + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + new GainAbilityAllEffect( + HasteAbility.getInstance(), + Duration.WhileOnBattlefield, + filter + ) + )); + } + + public RushbladeCommander(final RushbladeCommander card) { + super(card); + } + + @Override + public RushbladeCommander copy() { + return new RushbladeCommander(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 5969abd66b..345ee04c85 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -71,6 +71,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); + cards.add(new SetCardInfo("Rushblade Commander", 77, Rarity.UNCOMMON, mage.cards.r.RushbladeCommander.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index 9e9a23c048..082b3478e2 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -61,6 +61,7 @@ public enum SubType { AUROCHS("Aurochs", SubTypeSet.CreatureType), AUTOBOT("Autobot", SubTypeSet.CreatureType, true), // H17, Grimlock AVATAR("Avatar", SubTypeSet.CreatureType), + AZRA("Azra", SubTypeSet.CreatureType), // B BADGER("Badger", SubTypeSet.CreatureType), BARBARIAN("Barbarian", SubTypeSet.CreatureType), From 5822a7d94d0f845805ea9f50b2e5763a24d66abb Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Tue, 22 May 2018 20:11:07 +0200 Subject: [PATCH 032/154] refactor divider setting and saving into utility functions refactor setting and saving filters into utility functions --- .../java/mage/client/table/TablesPanel.java | 87 +++++++------------ .../mage/client/util/gui/GuiDisplayUtil.java | 26 ++++++ .../java/mage/client/util/gui/TableUtil.java | 33 +++++-- 3 files changed, 84 insertions(+), 62 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index 36f1e52002..c8ee3e7f1f 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -56,6 +56,11 @@ import mage.client.components.MageComponents; import mage.client.dialog.*; import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_ORDER; import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH; +import static mage.client.dialog.PreferencesDialog.KEY_TABLES_FILTER_SETTINGS; +import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_1; +import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2; +import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3; +import static mage.client.dialog.PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE; import mage.client.util.ButtonColumn; import mage.client.util.GUISizeHelper; import mage.client.util.IgnoreList; @@ -227,8 +232,7 @@ public class TablesPanel extends javax.swing.JPanel { jScrollPaneTablesActive.getViewport().setBackground(new Color(255, 255, 255, 50)); jScrollPaneTablesFinished.getViewport().setBackground(new Color(255, 255, 255, 50)); - restoreSettings(); - + saveActiveFiltersToPrefs(); setGUISize(); Action openTableAction; @@ -343,7 +347,7 @@ public class TablesPanel extends javax.swing.JPanel { } public void cleanUp() { - saveSettings(); + saveGuiSettings(); chatPanelMain.cleanUp(); } @@ -406,66 +410,35 @@ public class TablesPanel extends javax.swing.JPanel { } private void saveDividerLocations() { - // save panel sizes and divider locations. + // save desktop bounds and divider locations Rectangle rec = MageFrame.getDesktop().getBounds(); - String sb = Double.toString(rec.getWidth()) + 'x' + Double.toString(rec.getHeight()); - PreferencesDialog.saveValue(PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE, sb); - PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_1, Integer.toString(this.jSplitPane1.getDividerLocation())); - PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2, Integer.toString(this.jSplitPaneTables.getDividerLocation())); - PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3, Integer.toString(chatPanelMain.getSplitDividerLocation())); + String currentBounds = Double.toString(rec.getWidth()) + 'x' + Double.toString(rec.getHeight()); + PreferencesDialog.saveValue(KEY_MAGE_PANEL_LAST_SIZE, currentBounds); + GuiDisplayUtil.setDividerLocation(KEY_TABLES_DIVIDER_LOCATION_1, this.jSplitPane1.getDividerLocation()); + GuiDisplayUtil.setDividerLocation(KEY_TABLES_DIVIDER_LOCATION_2, this.jSplitPaneTables.getDividerLocation()); + GuiDisplayUtil.setDividerLocation(KEY_TABLES_DIVIDER_LOCATION_3, chatPanelMain.getSplitDividerLocation()); } - private void restoreSettings() { - // filter settings - String formatSettings = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_FILTER_SETTINGS, ""); - int i = 0; - for (JToggleButton component : filterButtons) { - if (formatSettings.length() > i) { - component.setSelected(formatSettings.substring(i, i + 1).equals("x")); - } else { - component.setSelected(true); - } - i++; - } + private void saveActiveFiltersToPrefs() { + TableUtil.setActiveFilters(KEY_TABLES_FILTER_SETTINGS, filterButtons); setTableFilter(); } - private void saveSettings() { - // Filters - StringBuilder formatSettings = new StringBuilder(); - for (JToggleButton component : filterButtons) { - formatSettings.append(component.isSelected() ? "x" : "-"); - } - PreferencesDialog.saveValue(PreferencesDialog.KEY_TABLES_FILTER_SETTINGS, formatSettings.toString()); - + private void saveGuiSettings() { + TableUtil.saveActiveFiltersToPrefs(KEY_TABLES_FILTER_SETTINGS, filterButtons); TableUtil.saveColumnWidthAndOrderToPrefs(tableTables, KEY_TABLES_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_ORDER); } - private void restoreDividerLocations() { - Rectangle rec = MageFrame.getDesktop().getBounds(); - if (rec != null) { - String size = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE, null); - String sb = Double.toString(rec.getWidth()) + 'x' + Double.toString(rec.getHeight()); - // use divider positions only if screen size is the same as it was the time the settings were saved - if (size != null && size.equals(sb)) { - String location = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_1, null); - if (location != null && jSplitPane1 != null) { - jSplitPane1.setDividerLocation(Integer.parseInt(location)); - } - if (this.btnStateFinished.isSelected()) { - this.jSplitPaneTables.setDividerLocation(-1); - } else { - location = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2, null); - if (location != null && jSplitPaneTables != null) { - jSplitPaneTables.setDividerLocation(Integer.parseInt(location)); - } - } - location = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3, null); - if (location != null && chatPanelMain != null) { - chatPanelMain.setSplitDividerLocation(Integer.parseInt(location)); - } - } - } + private void restoreDividers() { + Rectangle currentBounds = MageFrame.getDesktop().getBounds(); + if (currentBounds != null) { + String firstDivider = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_1, null); + String tableDivider = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2, null); + String chatDivider = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3, null); + GuiDisplayUtil.restoreDividerLocations(currentBounds, firstDivider, jSplitPane1); + GuiDisplayUtil.restoreDividerLocations(currentBounds, tableDivider, jSplitPaneTables); + GuiDisplayUtil.restoreDividerLocations(currentBounds, chatDivider, chatPanelMain); + } } public Map<String, JComponent> getUIComponents() { @@ -565,7 +538,7 @@ public class TablesPanel extends javax.swing.JPanel { MageFrame.getUI().addButton(MageComponents.NEW_GAME_BUTTON, btnNewTable); // divider locations have to be set with delay else values set are overwritten with system defaults - Executors.newSingleThreadScheduledExecutor().schedule(() -> restoreDividerLocations(), 300, TimeUnit.MILLISECONDS); + Executors.newSingleThreadScheduledExecutor().schedule(() -> restoreDividers(), 300, TimeUnit.MILLISECONDS); } @@ -1284,7 +1257,7 @@ public class TablesPanel extends javax.swing.JPanel { if (currentMessage >= messages.size()) { currentMessage = 0; } - + URLHandler.RemoveMouseAdapter(jLabelFooterText); URLHandler.handleMessage(messages.get(currentMessage), this.jLabelFooterText); } @@ -1447,7 +1420,7 @@ class TableTableModel extends AbstractTableModel { if (tables[arg0].isTournament()) { return "Show"; } else { - owner = tables[arg0].getControllerName(); + owner = tables[arg0].getControllerName(); if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) { return ""; } diff --git a/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java b/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java index 2702815006..1ad148b0c2 100644 --- a/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java +++ b/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java @@ -4,8 +4,11 @@ import java.awt.*; import java.util.ArrayList; import java.util.Locale; import javax.swing.*; +import mage.client.dialog.PreferencesDialog; +import static mage.client.dialog.PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE; import mage.client.MageFrame; import mage.client.util.GUISizeHelper; +import mage.client.table.*; import mage.constants.*; import mage.view.CardView; import mage.view.CounterView; @@ -26,6 +29,29 @@ public final class GuiDisplayUtil { public ArrayList<String> lines; } + public static void restoreDividerLocations(Rectangle bounds, String lastDividerLocation, JComponent component) { + String currentBounds = Double.toString(bounds.getWidth()) + 'x' + Double.toString(bounds.getHeight()); + String savedBounds = PreferencesDialog.getCachedValue(KEY_MAGE_PANEL_LAST_SIZE, null); + // use divider positions only if screen size is the same as it was the time the settings were saved + if (savedBounds != null && savedBounds.equals(currentBounds)) { + if (lastDividerLocation != null && component != null) { + if (component instanceof JSplitPane) { + JSplitPane jSplitPane = (JSplitPane) component; + jSplitPane.setDividerLocation(Integer.parseInt(lastDividerLocation)); + } + + if (component instanceof PlayersChatPanel) { + PlayersChatPanel playerChatPanel = (PlayersChatPanel) component; + playerChatPanel.setSplitDividerLocation(Integer.parseInt(lastDividerLocation)); + } + } + } + } + + public static void setDividerLocation(String dividerPrefKey, int position) { + PreferencesDialog.saveValue(dividerPrefKey, Integer.toString(position)); + } + public static JXPanel getDescription(CardView card, int width, int height) { JXPanel descriptionPanel = new JXPanel(); diff --git a/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java b/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java index 61f502f18a..fbd66783b8 100644 --- a/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java +++ b/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java @@ -7,6 +7,7 @@ package mage.client.util.gui; import java.util.Arrays; import javax.swing.JTable; +import javax.swing.JToggleButton; import javax.swing.table.TableColumn; import org.apache.log4j.Logger; import mage.client.dialog.PreferencesDialog; @@ -27,7 +28,29 @@ public final class TableUtil { private static final Logger LOGGER = Logger.getLogger(TableUtil.class); - static public void setColumnWidthAndOrder(JTable table, int[] defaultColumnsWidth, String widthPrefKey, String orderPrefKey) { + public static void saveActiveFiltersToPrefs(String filterPrefKey, JToggleButton[] buttons) { + StringBuilder currentFilters = new StringBuilder(); + for (JToggleButton component : buttons) { + currentFilters.append(component.isSelected() ? "x" : "-"); + } + + PreferencesDialog.saveValue(filterPrefKey, currentFilters.toString()); + } + + public static void setActiveFilters(String filterPrefKey, JToggleButton[] buttons) { + String formatSettings = PreferencesDialog.getCachedValue(filterPrefKey, ""); + int i = 0; + for (JToggleButton component : buttons) { + if (formatSettings.length() > i) { + component.setSelected(formatSettings.substring(i, i + 1).equals("x")); + } else { + component.setSelected(true); + } + i++; + } + } + + public static void setColumnWidthAndOrder(JTable table, int[] defaultColumnsWidth, String widthPrefKey, String orderPrefKey) { table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // set the column width from saved value or defaults @@ -58,11 +81,11 @@ public final class TableUtil { } - static public void saveColumnWidthAndOrderToPrefs(JTable table, String widthPrefKey, String orderPrefKey) { - // Column width + public static void saveColumnWidthAndOrderToPrefs(JTable table, String widthPrefKey, String orderPrefKey) { StringBuilder columnWidthSettings = new StringBuilder(); StringBuilder columnOrderSettings = new StringBuilder(); boolean firstValue = true; + for (int i = 0; i < table.getColumnModel().getColumnCount(); i++) { TableColumn column = table.getColumnModel().getColumn(table.convertColumnIndexToView(i)); if (!firstValue) { @@ -74,14 +97,14 @@ public final class TableUtil { columnWidthSettings.append(column.getWidth()); columnOrderSettings.append(table.convertColumnIndexToModel(i)); } + PreferencesDialog.saveValue(widthPrefKey, columnWidthSettings.toString()); PreferencesDialog.saveValue(orderPrefKey, columnOrderSettings.toString()); - LOGGER.info("saving column widths: " + columnWidthSettings.toString()); LOGGER.info("saving column order: " + columnOrderSettings.toString()); } - public static int[] getIntArrayFromString(String stringData) { + private static int[] getIntArrayFromString(String stringData) { int[] intArray = null; if (stringData != null && !stringData.isEmpty()) { String[] items = stringData.split(","); From ebc36c503e93fb159484963291775c2f89818eba Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Tue, 22 May 2018 20:36:05 +0200 Subject: [PATCH 033/154] add restoring tournament table chat divider location refactor getting current bounds into utility function --- .../java/mage/client/dialog/PreferencesDialog.java | 1 + .../java/mage/client/dialog/TableWaitingDialog.java | 10 ++++++++++ .../src/main/java/mage/client/table/TablesPanel.java | 12 +++++------- .../java/mage/client/util/gui/GuiDisplayUtil.java | 6 ++++++ 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java index 71b0668eef..60620c13ab 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java @@ -203,6 +203,7 @@ public class PreferencesDialog extends javax.swing.JDialog { public static final String KEY_TABLES_DIVIDER_LOCATION_1 = "tablePanelDividerLocation1"; public static final String KEY_TABLES_DIVIDER_LOCATION_2 = "tablePanelDividerLocation2"; public static final String KEY_TABLES_DIVIDER_LOCATION_3 = "tablePanelDividerLocation3"; + public static final String KEY_TABLES_DIVIDER_LOCATION_4 = "tablePanelDividerLocation4"; // Positions of deck editor divider bars public static final String KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION = "editorHorizontalDividerLocation"; diff --git a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java index c3567f83a4..33ff704220 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java @@ -34,6 +34,7 @@ package mage.client.dialog; import java.awt.Dimension; +import java.awt.Rectangle; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -54,6 +55,7 @@ import mage.client.util.GUISizeHelper; import mage.client.util.audio.AudioManager; import mage.client.util.gui.TableUtil; import mage.client.util.gui.countryBox.CountryCellRenderer; +import mage.client.util.gui.GuiDisplayUtil; import mage.players.PlayerType; import mage.remote.Session; import mage.view.SeatView; @@ -61,6 +63,7 @@ import mage.view.TableView; import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_ORDER; import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_WIDTH; +import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_4; /** * @author BetaSteward_at_googlemail.com @@ -154,6 +157,9 @@ public class TableWaitingDialog extends MageDialog { this.roomId = roomId; this.tableId = tableId; this.isTournament = isTournament; + + Rectangle currentBounds = MageFrame.getDesktop().getBounds(); + updateTask = new UpdateSeatsTask(SessionHandler.getSession(), roomId, tableId, this); if (SessionHandler.isTableOwner(roomId, tableId)) { this.btnStart.setVisible(true); @@ -171,6 +177,8 @@ public class TableWaitingDialog extends MageDialog { this.setModal(false); this.setLocation(100, 100); this.setVisible(true); + String tournamentChatDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_4, null); + GuiDisplayUtil.restoreDividerLocations(currentBounds, tournamentChatDivider, jSplitPane1); } else { closeDialog(); } @@ -185,6 +193,8 @@ public class TableWaitingDialog extends MageDialog { MageFrame.getUI().removeButton(MageComponents.TABLE_WAITING_START_BUTTON); this.removeDialog(); TableUtil.saveColumnWidthAndOrderToPrefs(jTableSeats, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER); + GuiDisplayUtil.saveCurrentBoundsToPrefs(); + GuiDisplayUtil.setDividerLocation(KEY_TABLES_DIVIDER_LOCATION_4, this.jSplitPane1.getDividerLocation()); } /** diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index c8ee3e7f1f..eacd35acd1 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -410,10 +410,8 @@ public class TablesPanel extends javax.swing.JPanel { } private void saveDividerLocations() { - // save desktop bounds and divider locations - Rectangle rec = MageFrame.getDesktop().getBounds(); - String currentBounds = Double.toString(rec.getWidth()) + 'x' + Double.toString(rec.getHeight()); - PreferencesDialog.saveValue(KEY_MAGE_PANEL_LAST_SIZE, currentBounds); + // save divider locations and divider saveDividerLocations + GuiDisplayUtil.saveCurrentBoundsToPrefs(); GuiDisplayUtil.setDividerLocation(KEY_TABLES_DIVIDER_LOCATION_1, this.jSplitPane1.getDividerLocation()); GuiDisplayUtil.setDividerLocation(KEY_TABLES_DIVIDER_LOCATION_2, this.jSplitPaneTables.getDividerLocation()); GuiDisplayUtil.setDividerLocation(KEY_TABLES_DIVIDER_LOCATION_3, chatPanelMain.getSplitDividerLocation()); @@ -432,9 +430,9 @@ public class TablesPanel extends javax.swing.JPanel { private void restoreDividers() { Rectangle currentBounds = MageFrame.getDesktop().getBounds(); if (currentBounds != null) { - String firstDivider = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_1, null); - String tableDivider = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2, null); - String chatDivider = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3, null); + String firstDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_1, null); + String tableDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_2, null); + String chatDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_3, null); GuiDisplayUtil.restoreDividerLocations(currentBounds, firstDivider, jSplitPane1); GuiDisplayUtil.restoreDividerLocations(currentBounds, tableDivider, jSplitPaneTables); GuiDisplayUtil.restoreDividerLocations(currentBounds, chatDivider, chatPanelMain); diff --git a/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java b/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java index 1ad148b0c2..cd478e47e2 100644 --- a/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java +++ b/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java @@ -48,6 +48,12 @@ public final class GuiDisplayUtil { } } + public static void saveCurrentBoundsToPrefs() { + Rectangle rec = MageFrame.getDesktop().getBounds(); + String currentBounds = Double.toString(rec.getWidth()) + 'x' + Double.toString(rec.getHeight()); + PreferencesDialog.saveValue(KEY_MAGE_PANEL_LAST_SIZE, currentBounds); + } + public static void setDividerLocation(String dividerPrefKey, int position) { PreferencesDialog.saveValue(dividerPrefKey, Integer.toString(position)); } From 32cb438e7cb3a17d643c3a4078b427ccc19fe7f2 Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Tue, 22 May 2018 21:26:17 +0200 Subject: [PATCH 034/154] minor refactor - code ordering and variable reference --- .../mage/client/dialog/TableWaitingDialog.java | 15 +++++++-------- .../main/java/mage/client/table/TablesPanel.java | 3 +-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java index 33ff704220..238d203d79 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java @@ -95,12 +95,10 @@ public class TableWaitingDialog extends MageDialog { } setGUISize(); - - chatPanel.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE); jTableSeats.createDefaultColumnsFromModel(); - TableUtil.setColumnWidthAndOrder(jTableSeats, DEFAULT_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER); jTableSeats.setDefaultRenderer(Icon.class, new CountryCellRenderer()); - + TableUtil.setColumnWidthAndOrder(jTableSeats, DEFAULT_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER); + chatPanel.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE); MageFrame.getUI().addButton(MageComponents.TABLE_WAITING_START_BUTTON, btnStart); } @@ -154,13 +152,14 @@ public class TableWaitingDialog extends MageDialog { } public void showDialog(UUID roomId, UUID tableId, boolean isTournament) { + Rectangle currentBounds = MageFrame.getDesktop().getBounds(); + Optional<UUID> chatId = SessionHandler.getTableChatId(tableId); + updateTask = new UpdateSeatsTask(SessionHandler.getSession(), roomId, tableId, this); + this.roomId = roomId; this.tableId = tableId; this.isTournament = isTournament; - Rectangle currentBounds = MageFrame.getDesktop().getBounds(); - - updateTask = new UpdateSeatsTask(SessionHandler.getSession(), roomId, tableId, this); if (SessionHandler.isTableOwner(roomId, tableId)) { this.btnStart.setVisible(true); this.btnMoveDown.setVisible(true); @@ -170,7 +169,7 @@ public class TableWaitingDialog extends MageDialog { this.btnMoveDown.setVisible(false); this.btnMoveUp.setVisible(false); } - Optional<UUID> chatId = SessionHandler.getTableChatId(tableId); + if (chatId.isPresent()) { this.chatPanel.connect(chatId.get()); updateTask.execute(); diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index eacd35acd1..d9610492a8 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -196,8 +196,7 @@ public class TablesPanel extends javax.swing.JPanel { list.add(new RowSorter.SortKey(TableTableModel.COLUMN_CREATED, SortOrder.DESCENDING)); activeTablesSorter.setSortKeys(list); - TableUtil.setColumnWidthAndOrder(tableTables, DEFAULT_COLUMNS_WIDTH, - PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH, PreferencesDialog.KEY_TABLES_COLUMNS_ORDER); + TableUtil.setColumnWidthAndOrder(tableTables, DEFAULT_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_WIDTH, KEY_TABLES_COLUMNS_ORDER); // 2. TABLE COMPLETED completedTablesSorter = new MageTableRowSorter(matchesModel); From 5c42c54a3a585bcd7b96cf4c33b32b58fd60733e Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 22 May 2018 18:55:33 -0400 Subject: [PATCH 035/154] updated Battlebond spoiler --- Utils/mtg-cards-data.txt | 94 ++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index a8dabadfde..36d5f7185a 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33358,30 +33358,70 @@ Karplusan Hound|Dominaria|277|U|{3}{R}|Creature - Hound|3|3|Whenever Karplusan H Pyromantic Pilgrim|Dominaria|278|C|{2}{R}|Creature - Human Wizard|3|1|Haste| Timber Gorge|Dominaria|279|C||Land|||Timber Gorge enters the battlefield tapped.${t}: Add {R} or {G}.| Firesong and Sunspeaker|Dominaria|280|R|{4}{R}{W}|Legendary Creature - Minotaur Cleric|4|6|Red instant and sorcery spells you control have lifelink.$Whenever a white instant or sorcery spell causes you to gain life, Firesong and Sunspeaker deals 3 damage to any target.| -Will Kenrith|Battlebond|1|M|{4}{U}{U}|Legendary Planeswalker - Will|4|+2: Until your next turn, up to two target creatures each have base power and toughness 0/3 and lose all abilities.$-2: Target player draws two cards. Until your next turn, instant, sorcery, and planeswalker spells that player casts cost 2 less to cast.$-8: Target player gets an emblem with "Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy."$Partner with Rowan Kenrith$Will Kenrith can be your commander.| -Rowan Kenrith|Battlebond|2|M|{4}{R}{R}|Legendary Planeswalker - Rowan|4|+2: During target player's next turn, each creature that player controls attacks if able.$-2: Rowan Kenrith deals 3 damage to each tapped creature target player controls.$-8: Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy."$Partner with Will Kenrith$Rowan Kenrith can be your commander.| -Virtus the Veiled|Battlebond|7|R|{2}{R}|Legendary Creature - Azra Assassin|1|1|Partner with Gorm the Great (When this creature enters the battlefield, target player may put Gorm into their hand from their library, then shuffle.)$Deathtouch$Whenever Virus the Veiled deals combat damage to a player, that player loses half their life rounded up.| -Gorm the Great|Battlebond|8|R|{3}{G}|Legendary Creature - Giant Warrior|2|7|Partner with Virtus the Veiled (When this creature enters the battlefield, target player may put Virtus into their hand from their library, then shuffle.)$Vigilance$Gorm the Great must be blocked if able and Gorm must be blocked by two or more creatures if able.| -Pir, Imaginative Rascal|Battlebond|11|R|{2}{G}|Legendary Creature - Human|1|1|Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.)$If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead.| -Toothy, Imaginary Friend|Battlebond|12|R|{3}{U}|Legendary Creature - Illusion|1|1|Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.)$Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend.$When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it.| -Soulblade Corrupter|Battlebond|17|U|{4}{B}|Creature - Human Warrior|3|3|Partner with Soulblade Renewer (When this creature enters the battlefield, target player may put Soulblade Renewer into their hand from their library, then shuffle.)$Deathtouch$Whenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn.| -Soulblade Renewer|Battlebond|18|U|{4}{G}|Creature - Elf Warrior|2|2|Partner with Soulblade Corrupter (When this creature enters the battlefield, target player may put Soulblade Corrupter into their hand from their library, then shuffle.)$When Soulblade Renewer enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two target creatures.)| -Impetuous Protege|Battlebond|19|U|{2}{R}|Creature - Human Warrior|0|4|Partner with Proud Mentor (When this creature enters the battlefield, target player may put Proud Mentor into their hand from their library, then shuffle.)$Whenever Impetuous Protege attacks, it gets +X/+0 until end of turn, where X is the greatest power among tapped creatures your opponents control| -Proud Mentor|Battlebond|20|U|{2}{W}|Creature - Human Warrior|1|1|Partner with Impetuous Protege (When this creature enters the battlefield, target player may put Impetuous Protege into their hand from their library, then shuffle.)${W}, {T}: Tap target creature| -Dwarven Lightsmith|Battlebond|27|C|{5}{C}|Creature - Dwarf Cleric|3|4|Assist (Another player can pay up to {5} of this spell's cost.)$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| -Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist (Another player can pay up to {6} of this spell's cost)$Exile all nonland permanents.| -Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| -Soaring Show-Off|Battlebond|40|C|{2}{U}|Creature - Bird Warrior|2|2|Flying$When Soaring Show-Off enters the battlefield, each player draws a card.| -Archfiend of Despair|Battlebond|44|M|{6}{B}{B}|Creature - Demon|6|6|Flying$Your opponents can't gain life.$At the beginning of each end step, each opponent loses life equal to the life that player lost this turn. (Damage causes loss of life.)| -Fan Favorite|Battlebond|46|C|{3}{B}|Creature - Human Rogue|2|2|Assist (Another player can play up to {3} of this spell's cost.)${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| -Mindblade Render|Battlebond|49|R|{1}{B}|Creature - Azra Warrior|1|3|Whenever your opponents are dealt combat damage, if any of that damage was dealt by a Warrior, you draw a card and you lose 1 life.| -Charging Binox|Battlebond|66|C|{7}{G}|Creature - Beast|7|5|Assist (Another player can pay up to {7} of this spell's cost.)$Trample| -Pir's Whim|Battlebond|73|R|{3}{G}|Sorcery|||For each player, choose friend or foe. Each friend searches their library for a land card, puts it onto the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment.| -Rushblade Commander|Battlebond|77|U|{B}{R}|Creature - Azra Warrior|2|2|Warrior creatures your team controls have haste.| -Bountiful Promenade|Battlebond|81|R||Land|||Bountiful Promenade enters the battlefield tapped unless you have two or more opponents.${T}: Add {G} or {W}.| -Luxury Suite|Battlebond|82|R||Land|||Luxury Suite enters the battlefield tapped unless you have two or more opponents.${T}: Add {B} or {R}.| -Morphic Pool|Battlebond|83|R||Land|||Morphic Pool enters the battlefield tapped unless you have two or more opponents.${T}: Add {U} or {B}.| -Sea of Clouds|Battlebond|84|R||Land|||Sea of Clouds enters the battlefield tapped unless you have two or more opponents.${T}: Add {U} or {W}.| -Spire Garden|Battlebond|85|R||Land|||Spire Garden enters the battlefield tapped unless you have two or more opponents.${T}: Add {R} or {G}.| -Mu Yanling|Global Series: Jiang Yanggu & Mu Yanling|1|M|{4}{U}{U}|Legendary Planeswalker - Yanling|5|+2: Target creature can't be blocked this turn.$-3: Draw two cards.$-10: Tap all creatures your opponents control. You take an extra turn after this one.| -Jiang Yanggu|Global Series: Jiang Yanggu & Mu Yanling|22|M|{4}{G}|Legendary Planeswalker - Yanggu|4|+1: Target creature gets +2/+2 until end of turn.$-1: If you don't control a creature named Mowu, creature a legendary 3/3 green Hound creature token named Mowu.$-5: Until end of turn, target creature gains trample and gets +X/+X, where X is the number of lands you control.| +Will Kenrith|Battlebond|1|M|Legendary Planeswalker - Will|||+2: Until your next turn, up to two target creatures each have base power and toughness 0/3 and lose all abilities.$-2: Target player draws two cards. Until your next turn, instant, sorcery, and planeswalker spells that player casts cost {2} less to cast.$-8: Target player gets an emblem with "Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy."$Partner with Rowan Kenrith$Will Kenrith can be your commander.| +Rowan Kenrith|Battlebond|2|M|Legendary Planeswalker - Rowan|||+2: During target player's next turn, each creature that player controls attacks if able. $-2: Rowan Kenrith deals 3 damage to each tapped creature target player controls. $-8: Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy."$Partner with Will Kenrith$Rowan Kenrith can be your commander.| +Regna, the Redeemer|Battlebond|3|R|Legendary Creature - Angel|4|4|Partner with Krav, the Unredeemed (When this creature enters the battlefield, target player may put Krav into their hand from their library, then shuffle.)$Flying$At the beginning of each end step, if your team gained life this turn, create two 1/1 white Warrior creature tokens.| +Krav, the Unredeemed|Battlebond|4|R|Legendary Creature - Demon|3|3|Partner with Regna, the Redeemer (When this creature enters the battlefield, target player may put Regna into their hand from their library, then shuffle.)${B}, Sacrifice X creatures: Target player draws X cards and gains X life. Put X +1/+1 counters on Krav, the Unredeemed.| +Virtus the Veiled|Battlebond|7|R|Legendary Creature - Azra Assassin|1|1|Partner with Gorm the Great (When this creature enters the battlefield, target player may put Gorm into their hand from their library, then shuffle.)$Deathtouch$Whenever Virtus the Veiled deals combat damage to a player, that player loses half their life, rounded up.| +Gorm the Great|Battlebond|8|R|Legendary Creature - Giant Warrior|2|7|Partner with Virtus the Veiled (When this creature enters the battlefield, target player may put Virtus into their hand from their library, then shuffle.)$Vigilance$Gorm the Great must be blocked if able, and Gorm must be blocked by two or more creatures if able.| +Pir, Imaginative Rascal|Battlebond|11|R|Legendary Creature - Human|1|1|Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.)$If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead.| +Toothy, Imaginary Friend|Battlebond|12|R|Legendary Creature - Illusion|1|1|Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.)$Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend.$When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it.| +Soulblade Corrupter|Battlebond|17|U|Creature - Human Warrior|3|3|Partner with Soulblade Renewer (When this creature enters the battlefield, target player may put Soulblade Renewer into their hand from their library, then shuffle.)$Deathtouch$Whenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn.| +Soulblade Renewer|Battlebond|18|U|Creature - Elf Warrior|2|2|Partner with Soulblade Corrupter (When this creature enters the battlefield, target player may put Soulblade Corrupter into their hand from their library, then shuffle.)$When Soulblade Renewer enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| +Impetuous Protege|Battlebond|19|U|Creature - Human Warrior|0|4|Partner with Proud Mentor (When this creature enters the battlefield, target player may put Proud Mentor into their hand from their library, then shuffle.)$Whenever Impetuous Protege attacks, it gets +X/+0 until end of turn, where X is the greatest power among tapped creatures your opponents control.| +Proud Mentor|Battlebond|20|U|Creature - Human Warrior|1|1|Partner with Impetuous Protege (When this creature enters the battlefield, target player may put Impetuous Protege into their hand from their library, then shuffle.)${W}, {T}: Tap target creature.| +Arena Rector|Battlebond|23|M|Creature - Human Cleric|1|2|When Arena Rector dies, you may exile it. If you do, search your library for a planeswalker card, put it onto the battlefield, then shuffle your library.| +Dwarven Lightsmith|Battlebond|27|C|Creature - Dwarf Cleric|3|4|Assist (Another player can pay up to {5} of this spell's cost.)$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| +Play of the Game|Battlebond|29|R|Sorcery|||Assist (Another player can pay up to {6} of this spell's cost.)$Exile all nonland permanents.| +Regna's Sanction|Battlebond|30|R|Sorcery|||For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest.| +Game Plan|Battlebond|35|R|Sorcery|||Assist (Another player can pay up to {5} of this spell's cost.)$Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Game Plan.| +Huddle Up|Battlebond|36|C|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| +Saltwater Stalwart|Battlebond|39|C|Creature - Merfolk Warrior|2|4|Whenever Saltwater Stalwart deals damage to an opponent, target player draws a card.| +Soaring Show-Off|Battlebond|40|C|Creature - Bird Warrior|2|2|Flying$When Soaring Show-Off enters the battlefield, each player draws a card.| +Archfiend of Despair|Battlebond|44|M|Creature - Demon|6|6|Flying$Your opponents can't gain life.$At the beginning of each end step, each opponent loses life equal to the life that player lost this turn. (Damage causes loss of life.)| +Fan Favorite|Battlebond|46|C|Creature - Human Rogue|2|2|Assist (Another player can pay up to {3} of this spell's cost.)${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| +Mindblade Render|Battlebond|49|R|Creature - Azra Warrior|1|3|Whenever your opponents are dealt combat damage, if any of that damage was dealt by a Warrior, you draw a card and you lose 1 life.| +Sickle Dancer|Battlebond|50|C|Creature - Human Warrior|3|2|Whenever Sickle Dancer attacks, if your team controls another Warrior, Sickle Dancer gets +1/+1 until end of turn.| +Stunning Reversal|Battlebond|51|M|Instant|||The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1. $Exile Stunning Reversal.| +Thrasher Brute|Battlebond|52|U|Creature - Orc Warrior|4|3|Whenever Thrasher Brute or another Warrior enters the battlefield under your team's control, target opponent loses 1 life and you gain 1 life.| +Virtus's Virtue|Battlebond|54|R|Sorcery|||For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control.| +Stolen Strategy|Battlebond|64|R|Enchantment|||At the beginning of your upkeep, exile the top card of each opponent's library. Until end of turn, you may cast nonland cards from among those exiled cards, and you may spend mana as though it were mana of any color to cast those spells.| +Charging Binox|Battlebond|66|C|Creature - Beast|7|5|Assist (Another player can pay up to {7} of this spell's cost.)$Trample| +The Crowd Goes Wild|Battlebond|68|U|Sorcery|||Assist (Another player can pay up to {X} of this spell's cost. You choose the value of X.)$Support X. (Put a +1/+1 counter on each of up to X target creatures.)$Each creature with a +1/+1 counter on it gains trample until end of turn.| +Generous Sponsor|Battlebond|70|R|Creature - Elf Advisor|1|4|When Generous Sponsor enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)$Whenever you put one or more counters on a creature you don't control, draw a card.| +Jungle Wayfinder|Battlebond|72|C|Creature - Elf Warrior|3|3|When Jungle Wayfinder enters the battlefield, each player may search their library for a basic land card, reveal it, put it into their hand, then shuffle their library.| +Pir's Whim|Battlebond|73|R|Sorcery|||For each player, choose friend or foe. Each friend searches their library for a land card, puts it on the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment they control.| +Rushblade Commander|Battlebond|77|U|Creature - Azra Warrior|2|2|Warriors your team controls have haste.| +Bountiful Promenade|Battlebond|81|R|Land|||Bountiful Promenade enters the battlefield tapped unless you have two or more opponents.${T}: Add {G} or {W}.| +Luxury Suite|Battlebond|82|R|Land|||Luxury Suite enters the battlefield tapped unless you have two or more opponents.${T}: Add {B} or {R}.| +Morphic Pool|Battlebond|83|R|Land|||Morphic Pool enters the battlefield tapped unless you have two or more opponents.${T}: Add {U} or {B}.| +Sea of Clouds|Battlebond|84|R|Land|||Sea of Clouds enters the battlefield tapped unless you have two or more opponents.${T}: Add {W} or {U}.| +Spire Garden|Battlebond|85|R|Land|||Spire Garden enters the battlefield tapped unless you have two or more opponents.${T}: Add {R} or {G}.| +Doomed Traveler|Battlebond|91|C|Creature - Human Soldier|1|1|When Doomed Traveler dies, create a 1/1 white Spirit creature token with flying.| +Expedition Raptor|Battlebond|92|C|Creature - Bird|2|2|Flying$When Expedition Raptor enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| +Land Tax|Battlebond|94|M|Enchantment|||At the beginning of your upkeep, if an opponent controls more lands than you, you may search your library for up to three basic land cards, reveal them, and put them into your hand. If you do, shuffle your library.| +Shoulder to Shoulder|Battlebond|105|C|Sorcery|||Support 2. (Put a +1/+1 counter on each of up to two target creatures.)$Draw a card.| +Swords to Plowshares|Battlebond|110|U|Instant|||Exile target creature. Its controller gains life equal to its power.| +Impulse|Battlebond|119|C|Instant|||Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.| +Kraken Hatchling|Battlebond|121|C|Creature - Kraken|0|4|| +Peregrine Drake|Battlebond|128|U|Creature - Drake|2|3|Flying$When Peregrine Drake enters the battlefield, untap up to five lands.| +Sower of Temptation|Battlebond|131|R|Creature - Faerie Wizard|2|2|Flying$When Sower of Temptation enters the battlefield, gain control of target creature for as long as Sower of Temptation remains on the battlefield.| +Tidespout Tyrant|Battlebond|134|R|Creature - Djinn|5|5|Flying$Whenever you cast a spell, return target permanent to its owner's hand.| +True-Name Nemesis|Battlebond|136|M|Creature - Merfolk Rogue|3|1|As True-Name Nemesis enters the battlefield, choose a player.$True-Name Nemesis has protection from the chosen player. (This creature can't be blocked, targeted, dealt damage, or enchanted by anything controlled by that player.)| +Daggerdrome Imp|Battlebond|140|C|Creature - Imp|1|1|Flying$Lifelink (Damage dealt by this creature also causes you to gain that much life.)| +Diabolic Intent|Battlebond|141|R|Sorcery|||As an additional cost to cast this spell, sacrifice a creature.$Search your library for a card and put that card into your hand. Then shuffle your library.| +Doomed Dissenter|Battlebond|142|C|Creature - Human|1|1|When Doomed Dissenter dies, create a 2/2 black Zombie creature token.| +Boldwyr Intimidator|Battlebond|169|U|Creature - Giant Warrior|5|5|Cowards can't block Warriors.${R}: Target creature becomes a Coward until end of turn.${2}{R}: Target creature becomes a Warrior until end of turn.| +Chain Lightning|Battlebond|171|U|Sorcery|||Chain Lightning deals 3 damage to any target. Then that player or that permanent's controller may pay {R}{R}. If the player does, they may copy this spell and may choose a new target for that copy.| +Doubling Season|Battlebond|195|M|Enchantment|||If an effect would create one or more tokens under your control, it creates twice that many of those tokens instead.$If an effect would put one or more counters on a permanent you control, it puts twice that many of those counters on that permanent instead.| +Fertile Ground|Battlebond|198|C|Enchantment - Aura|||Enchant land$Whenever enchanted land is tapped for mana, its controller adds an additional one mana of any color.| +Veteran Explorer|Battlebond|214|U|Creature - Human Soldier Scout|1|1|When Veteran Explorer dies, each player may search their library for up to two basic land cards and put them onto the battlefield. Then each player who searched their library this way shuffles it.| +Vigor|Battlebond|215|R|Creature - Elemental Incarnation|6|6|Trample$If damage would be dealt to a creature you control other than Vigor, prevent that damage. Put a +1/+1 counter on that creature for each 1 damage prevented this way.$When Vigor is put into a graveyard from anywhere, shuffle it into its owner's library.| +Auger Spree|Battlebond|218|C|Instant|||Target creature gets +4/-4 until end of turn.| +Centaur Healer|Battlebond|219|C|Creature - Centaur Cleric|3|3|When Centaur Healer enters the battlefield, you gain 3 life.| +Eager Construct|Battlebond|234|C|Artifact Creature - Construct|2|2|When Eager Construct enters the battlefield, each player may scry 1. (To scry 1, look at the top card of your library, then you may put that card on the bottom of your library.)| +Plains|Battlebond|250|C|Basic Land - Plains|||({T}: Add {W}.)| +Island|Battlebond|251|C|Basic Land - Island|||({T}: Add {U}.)| +Swamp|Battlebond|252|C|Basic Land - Swamp|||({T}: Add {B}.)| +Mountain|Battlebond|253|C|Basic Land - Mountain|||({T}: Add {R}.)| +Forest|Battlebond|254|C|Basic Land - Forest|||({T}: Add {G}.)| From 02001abda88021dd08e40957387c29440f52811d Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 22 May 2018 19:21:19 -0400 Subject: [PATCH 036/154] added Battlebond reprints --- Mage.Sets/src/mage/sets/Battlebond.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 345ee04c85..46d5cf150e 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -55,23 +55,33 @@ public class Battlebond extends ExpansionSet { this.ratioBoosterMythic = 8; cards.add(new SetCardInfo("Archfiend of Despair", 44, Rarity.MYTHIC, mage.cards.a.ArchfiendOfDespair.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); + cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); + cards.add(new SetCardInfo("Chain Lightning", 171, Rarity.UNCOMMON, mage.cards.c.ChainLightning.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); + cards.add(new SetCardInfo("Diabolic Intent", 141, Rarity.RARE, mage.cards.d.DiabolicIntent.class)); cards.add(new SetCardInfo("Doomed Dissenter", 142, Rarity.COMMON, mage.cards.d.DoomedDissenter.class)); cards.add(new SetCardInfo("Doomed Traveler", 91, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); cards.add(new SetCardInfo("Doubling Season", 195, Rarity.MYTHIC, mage.cards.d.DoublingSeason.class)); cards.add(new SetCardInfo("Eager Construct", 234, Rarity.COMMON, mage.cards.e.EagerConstruct.class)); cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); + cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); + cards.add(new SetCardInfo("Impulse", 119, Rarity.COMMON, mage.cards.i.Impulse.class)); + cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Kraken Hatchling", 121, Rarity.COMMON, mage.cards.k.KrakenHatchling.class)); + cards.add(new SetCardInfo("Land Tax", 94, Rarity.MYTHIC, mage.cards.l.LandTax.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); + cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); + cards.add(new SetCardInfo("Plains", 250, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); - cards.add(new SetCardInfo("Rushblade Commander", 77, Rarity.UNCOMMON, mage.cards.r.RushbladeCommander.class)); + cards.add(new SetCardInfo("Rushblade Commander", 77, Rarity.UNCOMMON, mage.cards.r.RushbladeCommander.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); @@ -79,8 +89,12 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); cards.add(new SetCardInfo("Sower of Temptation", 131, Rarity.RARE, mage.cards.s.SowerOfTemptation.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); - cards.add(new SetCardInfo("True-Name Nemesis", 136, Rarity.MYTHIC, mage.cards.t.TrueNameNemesis.class)); + cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swords to Plowshares", 110, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); + cards.add(new SetCardInfo("Tidespout Tyrant", 134, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); + cards.add(new SetCardInfo("True-Name Nemesis", 136, Rarity.MYTHIC, mage.cards.t.TrueNameNemesis.class)); + cards.add(new SetCardInfo("Veteran Explorer", 214, Rarity.UNCOMMON, mage.cards.v.VeteranExplorer.class)); cards.add(new SetCardInfo("Vigor", 215, Rarity.RARE, mage.cards.v.Vigor.class)); cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); } From 715319f18bfaeff6383d6130216507600f3ca24f Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 22 May 2018 19:49:25 -0400 Subject: [PATCH 037/154] fixed error in Battlebond spoiler generation --- Utils/mtg-cards-data.txt | 134 +++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 36d5f7185a..9ea55c0774 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33358,70 +33358,70 @@ Karplusan Hound|Dominaria|277|U|{3}{R}|Creature - Hound|3|3|Whenever Karplusan H Pyromantic Pilgrim|Dominaria|278|C|{2}{R}|Creature - Human Wizard|3|1|Haste| Timber Gorge|Dominaria|279|C||Land|||Timber Gorge enters the battlefield tapped.${t}: Add {R} or {G}.| Firesong and Sunspeaker|Dominaria|280|R|{4}{R}{W}|Legendary Creature - Minotaur Cleric|4|6|Red instant and sorcery spells you control have lifelink.$Whenever a white instant or sorcery spell causes you to gain life, Firesong and Sunspeaker deals 3 damage to any target.| -Will Kenrith|Battlebond|1|M|Legendary Planeswalker - Will|||+2: Until your next turn, up to two target creatures each have base power and toughness 0/3 and lose all abilities.$-2: Target player draws two cards. Until your next turn, instant, sorcery, and planeswalker spells that player casts cost {2} less to cast.$-8: Target player gets an emblem with "Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy."$Partner with Rowan Kenrith$Will Kenrith can be your commander.| -Rowan Kenrith|Battlebond|2|M|Legendary Planeswalker - Rowan|||+2: During target player's next turn, each creature that player controls attacks if able. $-2: Rowan Kenrith deals 3 damage to each tapped creature target player controls. $-8: Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy."$Partner with Will Kenrith$Rowan Kenrith can be your commander.| -Regna, the Redeemer|Battlebond|3|R|Legendary Creature - Angel|4|4|Partner with Krav, the Unredeemed (When this creature enters the battlefield, target player may put Krav into their hand from their library, then shuffle.)$Flying$At the beginning of each end step, if your team gained life this turn, create two 1/1 white Warrior creature tokens.| -Krav, the Unredeemed|Battlebond|4|R|Legendary Creature - Demon|3|3|Partner with Regna, the Redeemer (When this creature enters the battlefield, target player may put Regna into their hand from their library, then shuffle.)${B}, Sacrifice X creatures: Target player draws X cards and gains X life. Put X +1/+1 counters on Krav, the Unredeemed.| -Virtus the Veiled|Battlebond|7|R|Legendary Creature - Azra Assassin|1|1|Partner with Gorm the Great (When this creature enters the battlefield, target player may put Gorm into their hand from their library, then shuffle.)$Deathtouch$Whenever Virtus the Veiled deals combat damage to a player, that player loses half their life, rounded up.| -Gorm the Great|Battlebond|8|R|Legendary Creature - Giant Warrior|2|7|Partner with Virtus the Veiled (When this creature enters the battlefield, target player may put Virtus into their hand from their library, then shuffle.)$Vigilance$Gorm the Great must be blocked if able, and Gorm must be blocked by two or more creatures if able.| -Pir, Imaginative Rascal|Battlebond|11|R|Legendary Creature - Human|1|1|Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.)$If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead.| -Toothy, Imaginary Friend|Battlebond|12|R|Legendary Creature - Illusion|1|1|Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.)$Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend.$When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it.| -Soulblade Corrupter|Battlebond|17|U|Creature - Human Warrior|3|3|Partner with Soulblade Renewer (When this creature enters the battlefield, target player may put Soulblade Renewer into their hand from their library, then shuffle.)$Deathtouch$Whenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn.| -Soulblade Renewer|Battlebond|18|U|Creature - Elf Warrior|2|2|Partner with Soulblade Corrupter (When this creature enters the battlefield, target player may put Soulblade Corrupter into their hand from their library, then shuffle.)$When Soulblade Renewer enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| -Impetuous Protege|Battlebond|19|U|Creature - Human Warrior|0|4|Partner with Proud Mentor (When this creature enters the battlefield, target player may put Proud Mentor into their hand from their library, then shuffle.)$Whenever Impetuous Protege attacks, it gets +X/+0 until end of turn, where X is the greatest power among tapped creatures your opponents control.| -Proud Mentor|Battlebond|20|U|Creature - Human Warrior|1|1|Partner with Impetuous Protege (When this creature enters the battlefield, target player may put Impetuous Protege into their hand from their library, then shuffle.)${W}, {T}: Tap target creature.| -Arena Rector|Battlebond|23|M|Creature - Human Cleric|1|2|When Arena Rector dies, you may exile it. If you do, search your library for a planeswalker card, put it onto the battlefield, then shuffle your library.| -Dwarven Lightsmith|Battlebond|27|C|Creature - Dwarf Cleric|3|4|Assist (Another player can pay up to {5} of this spell's cost.)$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| -Play of the Game|Battlebond|29|R|Sorcery|||Assist (Another player can pay up to {6} of this spell's cost.)$Exile all nonland permanents.| -Regna's Sanction|Battlebond|30|R|Sorcery|||For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest.| -Game Plan|Battlebond|35|R|Sorcery|||Assist (Another player can pay up to {5} of this spell's cost.)$Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Game Plan.| -Huddle Up|Battlebond|36|C|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| -Saltwater Stalwart|Battlebond|39|C|Creature - Merfolk Warrior|2|4|Whenever Saltwater Stalwart deals damage to an opponent, target player draws a card.| -Soaring Show-Off|Battlebond|40|C|Creature - Bird Warrior|2|2|Flying$When Soaring Show-Off enters the battlefield, each player draws a card.| -Archfiend of Despair|Battlebond|44|M|Creature - Demon|6|6|Flying$Your opponents can't gain life.$At the beginning of each end step, each opponent loses life equal to the life that player lost this turn. (Damage causes loss of life.)| -Fan Favorite|Battlebond|46|C|Creature - Human Rogue|2|2|Assist (Another player can pay up to {3} of this spell's cost.)${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| -Mindblade Render|Battlebond|49|R|Creature - Azra Warrior|1|3|Whenever your opponents are dealt combat damage, if any of that damage was dealt by a Warrior, you draw a card and you lose 1 life.| -Sickle Dancer|Battlebond|50|C|Creature - Human Warrior|3|2|Whenever Sickle Dancer attacks, if your team controls another Warrior, Sickle Dancer gets +1/+1 until end of turn.| -Stunning Reversal|Battlebond|51|M|Instant|||The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1. $Exile Stunning Reversal.| -Thrasher Brute|Battlebond|52|U|Creature - Orc Warrior|4|3|Whenever Thrasher Brute or another Warrior enters the battlefield under your team's control, target opponent loses 1 life and you gain 1 life.| -Virtus's Virtue|Battlebond|54|R|Sorcery|||For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control.| -Stolen Strategy|Battlebond|64|R|Enchantment|||At the beginning of your upkeep, exile the top card of each opponent's library. Until end of turn, you may cast nonland cards from among those exiled cards, and you may spend mana as though it were mana of any color to cast those spells.| -Charging Binox|Battlebond|66|C|Creature - Beast|7|5|Assist (Another player can pay up to {7} of this spell's cost.)$Trample| -The Crowd Goes Wild|Battlebond|68|U|Sorcery|||Assist (Another player can pay up to {X} of this spell's cost. You choose the value of X.)$Support X. (Put a +1/+1 counter on each of up to X target creatures.)$Each creature with a +1/+1 counter on it gains trample until end of turn.| -Generous Sponsor|Battlebond|70|R|Creature - Elf Advisor|1|4|When Generous Sponsor enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)$Whenever you put one or more counters on a creature you don't control, draw a card.| -Jungle Wayfinder|Battlebond|72|C|Creature - Elf Warrior|3|3|When Jungle Wayfinder enters the battlefield, each player may search their library for a basic land card, reveal it, put it into their hand, then shuffle their library.| -Pir's Whim|Battlebond|73|R|Sorcery|||For each player, choose friend or foe. Each friend searches their library for a land card, puts it on the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment they control.| -Rushblade Commander|Battlebond|77|U|Creature - Azra Warrior|2|2|Warriors your team controls have haste.| -Bountiful Promenade|Battlebond|81|R|Land|||Bountiful Promenade enters the battlefield tapped unless you have two or more opponents.${T}: Add {G} or {W}.| -Luxury Suite|Battlebond|82|R|Land|||Luxury Suite enters the battlefield tapped unless you have two or more opponents.${T}: Add {B} or {R}.| -Morphic Pool|Battlebond|83|R|Land|||Morphic Pool enters the battlefield tapped unless you have two or more opponents.${T}: Add {U} or {B}.| -Sea of Clouds|Battlebond|84|R|Land|||Sea of Clouds enters the battlefield tapped unless you have two or more opponents.${T}: Add {W} or {U}.| -Spire Garden|Battlebond|85|R|Land|||Spire Garden enters the battlefield tapped unless you have two or more opponents.${T}: Add {R} or {G}.| -Doomed Traveler|Battlebond|91|C|Creature - Human Soldier|1|1|When Doomed Traveler dies, create a 1/1 white Spirit creature token with flying.| -Expedition Raptor|Battlebond|92|C|Creature - Bird|2|2|Flying$When Expedition Raptor enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| -Land Tax|Battlebond|94|M|Enchantment|||At the beginning of your upkeep, if an opponent controls more lands than you, you may search your library for up to three basic land cards, reveal them, and put them into your hand. If you do, shuffle your library.| -Shoulder to Shoulder|Battlebond|105|C|Sorcery|||Support 2. (Put a +1/+1 counter on each of up to two target creatures.)$Draw a card.| -Swords to Plowshares|Battlebond|110|U|Instant|||Exile target creature. Its controller gains life equal to its power.| -Impulse|Battlebond|119|C|Instant|||Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.| -Kraken Hatchling|Battlebond|121|C|Creature - Kraken|0|4|| -Peregrine Drake|Battlebond|128|U|Creature - Drake|2|3|Flying$When Peregrine Drake enters the battlefield, untap up to five lands.| -Sower of Temptation|Battlebond|131|R|Creature - Faerie Wizard|2|2|Flying$When Sower of Temptation enters the battlefield, gain control of target creature for as long as Sower of Temptation remains on the battlefield.| -Tidespout Tyrant|Battlebond|134|R|Creature - Djinn|5|5|Flying$Whenever you cast a spell, return target permanent to its owner's hand.| -True-Name Nemesis|Battlebond|136|M|Creature - Merfolk Rogue|3|1|As True-Name Nemesis enters the battlefield, choose a player.$True-Name Nemesis has protection from the chosen player. (This creature can't be blocked, targeted, dealt damage, or enchanted by anything controlled by that player.)| -Daggerdrome Imp|Battlebond|140|C|Creature - Imp|1|1|Flying$Lifelink (Damage dealt by this creature also causes you to gain that much life.)| -Diabolic Intent|Battlebond|141|R|Sorcery|||As an additional cost to cast this spell, sacrifice a creature.$Search your library for a card and put that card into your hand. Then shuffle your library.| -Doomed Dissenter|Battlebond|142|C|Creature - Human|1|1|When Doomed Dissenter dies, create a 2/2 black Zombie creature token.| -Boldwyr Intimidator|Battlebond|169|U|Creature - Giant Warrior|5|5|Cowards can't block Warriors.${R}: Target creature becomes a Coward until end of turn.${2}{R}: Target creature becomes a Warrior until end of turn.| -Chain Lightning|Battlebond|171|U|Sorcery|||Chain Lightning deals 3 damage to any target. Then that player or that permanent's controller may pay {R}{R}. If the player does, they may copy this spell and may choose a new target for that copy.| -Doubling Season|Battlebond|195|M|Enchantment|||If an effect would create one or more tokens under your control, it creates twice that many of those tokens instead.$If an effect would put one or more counters on a permanent you control, it puts twice that many of those counters on that permanent instead.| -Fertile Ground|Battlebond|198|C|Enchantment - Aura|||Enchant land$Whenever enchanted land is tapped for mana, its controller adds an additional one mana of any color.| -Veteran Explorer|Battlebond|214|U|Creature - Human Soldier Scout|1|1|When Veteran Explorer dies, each player may search their library for up to two basic land cards and put them onto the battlefield. Then each player who searched their library this way shuffles it.| -Vigor|Battlebond|215|R|Creature - Elemental Incarnation|6|6|Trample$If damage would be dealt to a creature you control other than Vigor, prevent that damage. Put a +1/+1 counter on that creature for each 1 damage prevented this way.$When Vigor is put into a graveyard from anywhere, shuffle it into its owner's library.| -Auger Spree|Battlebond|218|C|Instant|||Target creature gets +4/-4 until end of turn.| -Centaur Healer|Battlebond|219|C|Creature - Centaur Cleric|3|3|When Centaur Healer enters the battlefield, you gain 3 life.| -Eager Construct|Battlebond|234|C|Artifact Creature - Construct|2|2|When Eager Construct enters the battlefield, each player may scry 1. (To scry 1, look at the top card of your library, then you may put that card on the bottom of your library.)| -Plains|Battlebond|250|C|Basic Land - Plains|||({T}: Add {W}.)| -Island|Battlebond|251|C|Basic Land - Island|||({T}: Add {U}.)| -Swamp|Battlebond|252|C|Basic Land - Swamp|||({T}: Add {B}.)| -Mountain|Battlebond|253|C|Basic Land - Mountain|||({T}: Add {R}.)| -Forest|Battlebond|254|C|Basic Land - Forest|||({T}: Add {G}.)| +Will Kenrith|Battlebond|1|M|{4}{U}{U}|Legendary Planeswalker - Will|||+2: Until your next turn, up to two target creatures each have base power and toughness 0/3 and lose all abilities.$-2: Target player draws two cards. Until your next turn, instant, sorcery, and planeswalker spells that player casts cost {2} less to cast.$-8: Target player gets an emblem with "Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy."$Partner with Rowan Kenrith$Will Kenrith can be your commander.| +Rowan Kenrith|Battlebond|2|M|{4}{R}{R}|Legendary Planeswalker - Rowan|||+2: During target player's next turn, each creature that player controls attacks if able. $-2: Rowan Kenrith deals 3 damage to each tapped creature target player controls. $-8: Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy."$Partner with Will Kenrith$Rowan Kenrith can be your commander.| +Regna, the Redeemer|Battlebond|3|R|{5}{W}|Legendary Creature - Angel|4|4|Partner with Krav, the Unredeemed (When this creature enters the battlefield, target player may put Krav into their hand from their library, then shuffle.)$Flying$At the beginning of each end step, if your team gained life this turn, create two 1/1 white Warrior creature tokens.| +Krav, the Unredeemed|Battlebond|4|R|{4}{B}|Legendary Creature - Demon|3|3|Partner with Regna, the Redeemer (When this creature enters the battlefield, target player may put Regna into their hand from their library, then shuffle.)${B}, Sacrifice X creatures: Target player draws X cards and gains X life. Put X +1/+1 counters on Krav, the Unredeemed.| +Virtus the Veiled|Battlebond|7|R|{2}{B}|Legendary Creature - Azra Assassin|1|1|Partner with Gorm the Great (When this creature enters the battlefield, target player may put Gorm into their hand from their library, then shuffle.)$Deathtouch$Whenever Virtus the Veiled deals combat damage to a player, that player loses half their life, rounded up.| +Gorm the Great|Battlebond|8|R|{3}{G}|Legendary Creature - Giant Warrior|2|7|Partner with Virtus the Veiled (When this creature enters the battlefield, target player may put Virtus into their hand from their library, then shuffle.)$Vigilance$Gorm the Great must be blocked if able, and Gorm must be blocked by two or more creatures if able.| +Pir, Imaginative Rascal|Battlebond|11|R|{2}{G}|Legendary Creature - Human|1|1|Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.)$If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead.| +Toothy, Imaginary Friend|Battlebond|12|R|{3}{U}|Legendary Creature - Illusion|1|1|Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.)$Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend.$When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it.| +Soulblade Corrupter|Battlebond|17|U|{4}{B}|Creature - Human Warrior|3|3|Partner with Soulblade Renewer (When this creature enters the battlefield, target player may put Soulblade Renewer into their hand from their library, then shuffle.)$Deathtouch$Whenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn.| +Soulblade Renewer|Battlebond|18|U|{4}{G}|Creature - Elf Warrior|2|2|Partner with Soulblade Corrupter (When this creature enters the battlefield, target player may put Soulblade Corrupter into their hand from their library, then shuffle.)$When Soulblade Renewer enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| +Impetuous Protege|Battlebond|19|U|{2}{R}|Creature - Human Warrior|0|4|Partner with Proud Mentor (When this creature enters the battlefield, target player may put Proud Mentor into their hand from their library, then shuffle.)$Whenever Impetuous Protege attacks, it gets +X/+0 until end of turn, where X is the greatest power among tapped creatures your opponents control.| +Proud Mentor|Battlebond|20|U|{2}{W}|Creature - Human Warrior|1|1|Partner with Impetuous Protege (When this creature enters the battlefield, target player may put Impetuous Protege into their hand from their library, then shuffle.)${W}, {T}: Tap target creature.| +Arena Rector|Battlebond|23|M|{3}{W}|Creature - Human Cleric|1|2|When Arena Rector dies, you may exile it. If you do, search your library for a planeswalker card, put it onto the battlefield, then shuffle your library.| +Dwarven Lightsmith|Battlebond|27|C|{5}{W}|Creature - Dwarf Cleric|3|4|Assist (Another player can pay up to {5} of this spell's cost.)$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| +Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist (Another player can pay up to {6} of this spell's cost.)$Exile all nonland permanents.| +Regna's Sanction|Battlebond|30|R|{3}{W}|Sorcery|||For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest.| +Game Plan|Battlebond|35|R|{5}{U}|Sorcery|||Assist (Another player can pay up to {5} of this spell's cost.)$Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Game Plan.| +Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| +Saltwater Stalwart|Battlebond|39|C|{3}{U}|Creature - Merfolk Warrior|2|4|Whenever Saltwater Stalwart deals damage to an opponent, target player draws a card.| +Soaring Show-Off|Battlebond|40|C|{2}{U}|Creature - Bird Warrior|2|2|Flying$When Soaring Show-Off enters the battlefield, each player draws a card.| +Archfiend of Despair|Battlebond|44|M|{6}{B}{B}|Creature - Demon|6|6|Flying$Your opponents can't gain life.$At the beginning of each end step, each opponent loses life equal to the life that player lost this turn. (Damage causes loss of life.)| +Fan Favorite|Battlebond|46|C|{3}{B}|Creature - Human Rogue|2|2|Assist (Another player can pay up to {3} of this spell's cost.)${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| +Mindblade Render|Battlebond|49|R|{1}{B}|Creature - Azra Warrior|1|3|Whenever your opponents are dealt combat damage, if any of that damage was dealt by a Warrior, you draw a card and you lose 1 life.| +Sickle Dancer|Battlebond|50|C|{2}{B}|Creature - Human Warrior|3|2|Whenever Sickle Dancer attacks, if your team controls another Warrior, Sickle Dancer gets +1/+1 until end of turn.| +Stunning Reversal|Battlebond|51|M|{3}{B}|Instant|||The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1. $Exile Stunning Reversal.| +Thrasher Brute|Battlebond|52|U|{3}{B}|Creature - Orc Warrior|4|3|Whenever Thrasher Brute or another Warrior enters the battlefield under your team's control, target opponent loses 1 life and you gain 1 life.| +Virtus's Virtue|Battlebond|54|R|{2}{B}|Sorcery|||For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control.| +Stolen Strategy|Battlebond|64|R|{4}{R}|Enchantment|||At the beginning of your upkeep, exile the top card of each opponent's library. Until end of turn, you may cast nonland cards from among those exiled cards, and you may spend mana as though it were mana of any color to cast those spells.| +Charging Binox|Battlebond|66|C|{7}{G}|Creature - Beast|7|5|Assist (Another player can pay up to {7} of this spell's cost.)$Trample| +The Crowd Goes Wild|Battlebond|68|U|{X}{G}|Sorcery|||Assist (Another player can pay up to {X} of this spell's cost. You choose the value of X.)$Support X. (Put a +1/+1 counter on each of up to X target creatures.)$Each creature with a +1/+1 counter on it gains trample until end of turn.| +Generous Sponsor|Battlebond|70|R|{2}{G}|Creature - Elf Advisor|1|4|When Generous Sponsor enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)$Whenever you put one or more counters on a creature you don't control, draw a card.| +Jungle Wayfinder|Battlebond|72|C|{2}{G}|Creature - Elf Warrior|3|3|When Jungle Wayfinder enters the battlefield, each player may search their library for a basic land card, reveal it, put it into their hand, then shuffle their library.| +Pir's Whim|Battlebond|73|R|{3}{G}|Sorcery|||For each player, choose friend or foe. Each friend searches their library for a land card, puts it on the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment they control.| +Rushblade Commander|Battlebond|77|U|{B}{R}|Creature - Azra Warrior|2|2|Warriors your team controls have haste.| +Bountiful Promenade|Battlebond|81|R||Land|||Bountiful Promenade enters the battlefield tapped unless you have two or more opponents.${T}: Add {G} or {W}.| +Luxury Suite|Battlebond|82|R||Land|||Luxury Suite enters the battlefield tapped unless you have two or more opponents.${T}: Add {B} or {R}.| +Morphic Pool|Battlebond|83|R||Land|||Morphic Pool enters the battlefield tapped unless you have two or more opponents.${T}: Add {U} or {B}.| +Sea of Clouds|Battlebond|84|R||Land|||Sea of Clouds enters the battlefield tapped unless you have two or more opponents.${T}: Add {W} or {U}.| +Spire Garden|Battlebond|85|R||Land|||Spire Garden enters the battlefield tapped unless you have two or more opponents.${T}: Add {R} or {G}.| +Doomed Traveler|Battlebond|91|C|{W}|Creature - Human Soldier|1|1|When Doomed Traveler dies, create a 1/1 white Spirit creature token with flying.| +Expedition Raptor|Battlebond|92|C|{3}{W}{W}|Creature - Bird|2|2|Flying$When Expedition Raptor enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| +Land Tax|Battlebond|94|M|{W}|Enchantment|||At the beginning of your upkeep, if an opponent controls more lands than you, you may search your library for up to three basic land cards, reveal them, and put them into your hand. If you do, shuffle your library.| +Shoulder to Shoulder|Battlebond|105|C|{2}{W}|Sorcery|||Support 2. (Put a +1/+1 counter on each of up to two target creatures.)$Draw a card.| +Swords to Plowshares|Battlebond|110|U|{W}|Instant|||Exile target creature. Its controller gains life equal to its power.| +Impulse|Battlebond|119|C|{1}{U}|Instant|||Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.| +Kraken Hatchling|Battlebond|121|C|{U}|Creature - Kraken|0|4|| +Peregrine Drake|Battlebond|128|U|{4}{U}|Creature - Drake|2|3|Flying$When Peregrine Drake enters the battlefield, untap up to five lands.| +Sower of Temptation|Battlebond|131|R|{2}{U}{U}|Creature - Faerie Wizard|2|2|Flying$When Sower of Temptation enters the battlefield, gain control of target creature for as long as Sower of Temptation remains on the battlefield.| +Tidespout Tyrant|Battlebond|134|R|{5}{U}{U}{U}|Creature - Djinn|5|5|Flying$Whenever you cast a spell, return target permanent to its owner's hand.| +True-Name Nemesis|Battlebond|136|M|{1}{U}{U}|Creature - Merfolk Rogue|3|1|As True-Name Nemesis enters the battlefield, choose a player.$True-Name Nemesis has protection from the chosen player. (This creature can't be blocked, targeted, dealt damage, or enchanted by anything controlled by that player.)| +Daggerdrome Imp|Battlebond|140|C|{1}{B}|Creature - Imp|1|1|Flying$Lifelink (Damage dealt by this creature also causes you to gain that much life.)| +Diabolic Intent|Battlebond|141|R|{1}{B}|Sorcery|||As an additional cost to cast this spell, sacrifice a creature.$Search your library for a card and put that card into your hand. Then shuffle your library.| +Doomed Dissenter|Battlebond|142|C|{1}{B}|Creature - Human|1|1|When Doomed Dissenter dies, create a 2/2 black Zombie creature token.| +Boldwyr Intimidator|Battlebond|169|U|{5}{R}{R}|Creature - Giant Warrior|5|5|Cowards can't block Warriors.${R}: Target creature becomes a Coward until end of turn.${2}{R}: Target creature becomes a Warrior until end of turn.| +Chain Lightning|Battlebond|171|U|{R}|Sorcery|||Chain Lightning deals 3 damage to any target. Then that player or that permanent's controller may pay {R}{R}. If the player does, they may copy this spell and may choose a new target for that copy.| +Doubling Season|Battlebond|195|M|{4}{G}|Enchantment|||If an effect would create one or more tokens under your control, it creates twice that many of those tokens instead.$If an effect would put one or more counters on a permanent you control, it puts twice that many of those counters on that permanent instead.| +Fertile Ground|Battlebond|198|C|{1}{G}|Enchantment - Aura|||Enchant land$Whenever enchanted land is tapped for mana, its controller adds an additional one mana of any color.| +Veteran Explorer|Battlebond|214|U|{G}|Creature - Human Soldier Scout|1|1|When Veteran Explorer dies, each player may search their library for up to two basic land cards and put them onto the battlefield. Then each player who searched their library this way shuffles it.| +Vigor|Battlebond|215|R|{3}{G}{G}{G}|Creature - Elemental Incarnation|6|6|Trample$If damage would be dealt to a creature you control other than Vigor, prevent that damage. Put a +1/+1 counter on that creature for each 1 damage prevented this way.$When Vigor is put into a graveyard from anywhere, shuffle it into its owner's library.| +Auger Spree|Battlebond|218|C|{1}{B}{R}|Instant|||Target creature gets +4/-4 until end of turn.| +Centaur Healer|Battlebond|219|C|{1}{G}{W}|Creature - Centaur Cleric|3|3|When Centaur Healer enters the battlefield, you gain 3 life.| +Eager Construct|Battlebond|234|C|{2}|Artifact Creature - Construct|2|2|When Eager Construct enters the battlefield, each player may scry 1. (To scry 1, look at the top card of your library, then you may put that card on the bottom of your library.)| +Plains|Battlebond|250|C||Basic Land - Plains|||({T}: Add {W}.)| +Island|Battlebond|251|C||Basic Land - Island|||({T}: Add {U}.)| +Swamp|Battlebond|252|C||Basic Land - Swamp|||({T}: Add {B}.)| +Mountain|Battlebond|253|C||Basic Land - Mountain|||({T}: Add {R}.)| +Forest|Battlebond|254|C||Basic Land - Forest|||({T}: Add {G}.)| From 244da69ede87de4589f50e9d53174ef93cbc1689 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 22 May 2018 19:52:02 -0400 Subject: [PATCH 038/154] Implemented Arena Rector --- Mage.Sets/src/mage/cards/a/AcademyRector.java | 11 +-- Mage.Sets/src/mage/cards/a/ArenaRector.java | 75 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 3 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/ArenaRector.java diff --git a/Mage.Sets/src/mage/cards/a/AcademyRector.java b/Mage.Sets/src/mage/cards/a/AcademyRector.java index a88b967c00..0b3ec6ab31 100644 --- a/Mage.Sets/src/mage/cards/a/AcademyRector.java +++ b/Mage.Sets/src/mage/cards/a/AcademyRector.java @@ -55,11 +55,12 @@ public class AcademyRector extends CardImpl { this.toughness = new MageInt(2); // When Academy Rector dies, you may exile it. If you do, search your library for an enchantment card, put that card onto the battlefield, then shuffle your library. - this.addAbility(new DiesTriggeredAbility(new DoIfCostPaid( - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterEnchantmentCard())), - new ExileSourceFromGraveCost(), - "Exile to search enchantment?"), - false + this.addAbility(new DiesTriggeredAbility( + new DoIfCostPaid( + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterEnchantmentCard())), + new ExileSourceFromGraveCost(), + "Exile to search for an enchantment?" + ), false )); } diff --git a/Mage.Sets/src/mage/cards/a/ArenaRector.java b/Mage.Sets/src/mage/cards/a/ArenaRector.java new file mode 100644 index 0000000000..63b5ab78fd --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArenaRector.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.costs.common.ExileSourceFromGraveCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterPlaneswalkerCard; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class ArenaRector extends CardImpl { + + public ArenaRector(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // When Arena Rector dies, you may exile it. If you do, search your library for a planeswalker card, put it onto the battlefield, then shuffle your library. + this.addAbility(new DiesTriggeredAbility( + new DoIfCostPaid( + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterPlaneswalkerCard())), + new ExileSourceFromGraveCost(), + "Exile to search for a planeswalker?" + ), false + )); + } + + public ArenaRector(final ArenaRector card) { + super(card); + } + + @Override + public ArenaRector copy() { + return new ArenaRector(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 46d5cf150e..ce69883498 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -54,6 +54,7 @@ public class Battlebond extends ExpansionSet { this.numBoosterRare = 1; this.ratioBoosterMythic = 8; cards.add(new SetCardInfo("Archfiend of Despair", 44, Rarity.MYTHIC, mage.cards.a.ArchfiendOfDespair.class)); + cards.add(new SetCardInfo("Arena Rector", 23, Rarity.MYTHIC, mage.cards.a.ArenaRector.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); From 252cfc479eafe03d0ab42f2c376ab912d268a4da Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 22 May 2018 22:01:00 -0400 Subject: [PATCH 039/154] Implemented Regna, the Redeemer --- .../src/mage/cards/r/RegnaTheRedeemer.java | 118 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 119 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RegnaTheRedeemer.java diff --git a/Mage.Sets/src/mage/cards/r/RegnaTheRedeemer.java b/Mage.Sets/src/mage/cards/r/RegnaTheRedeemer.java new file mode 100644 index 0000000000..a280153e1a --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RegnaTheRedeemer.java @@ -0,0 +1,118 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.condition.IntCompareCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.PartnerWithAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.TargetController; +import mage.game.Game; +import mage.game.permanent.token.WarriorToken; +import mage.players.Player; +import mage.watchers.common.PlayerGainedLifeWatcher; + +/** + * + * @author TheElk801 + */ +public class RegnaTheRedeemer extends CardImpl { + + public RegnaTheRedeemer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.ANGEL); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Partner with Krav, the Unredeemed (When this creature enters the battlefield, target player may put Krav into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Krav, the Unredeemed", true)); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // At the beginning of each end step, if your team gained life this turn, create two 1/1 white Warrior creature tokens. + this.addAbility(new ConditionalTriggeredAbility( + new BeginningOfEndStepTriggeredAbility( + new CreateTokenEffect(new WarriorToken(), 2), + TargetController.ANY, + false + ), + new RegnaTheRedeemerCondition(), + "At the beginning of each end step, " + + "if your team gained life this turn, " + + "create two 1/1 white Warrior creature tokens" + ), new PlayerGainedLifeWatcher()); + } + + public RegnaTheRedeemer(final RegnaTheRedeemer card) { + super(card); + } + + @Override + public RegnaTheRedeemer copy() { + return new RegnaTheRedeemer(this); + } +} + +class RegnaTheRedeemerCondition extends IntCompareCondition { + + public RegnaTheRedeemerCondition() { + super(ComparisonType.MORE_THAN, 0); + } + + @Override + protected int getInputValue(Game game, Ability source) { + int gainedLife = 0; + PlayerGainedLifeWatcher watcher = (PlayerGainedLifeWatcher) game.getState().getWatchers().get(PlayerGainedLifeWatcher.class.getSimpleName()); + if (watcher != null) { + for (UUID playerId : game.getPlayerList()) { + Player player = game.getPlayer(playerId); + if (!player.hasOpponent(source.getControllerId(), game)) { + gainedLife = watcher.getLiveGained(playerId); + if (gainedLife > 0) { + break; + } + } + } + } + return gainedLife; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index ce69883498..f488d1431c 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -81,6 +81,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); cards.add(new SetCardInfo("Plains", 250, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); + cards.add(new SetCardInfo("Regna, the Redeemer", 3, Rarity.RARE, mage.cards.r.RegnaTheRedeemer.class)); cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); cards.add(new SetCardInfo("Rushblade Commander", 77, Rarity.UNCOMMON, mage.cards.r.RushbladeCommander.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); From 94f14c31c4954da68ca586480d18d65418fd7c44 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 22 May 2018 22:19:54 -0400 Subject: [PATCH 040/154] Implemented Krav, the Unredeemed --- .../src/mage/cards/k/KravTheUnredeemed.java | 111 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 112 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KravTheUnredeemed.java diff --git a/Mage.Sets/src/mage/cards/k/KravTheUnredeemed.java b/Mage.Sets/src/mage/cards/k/KravTheUnredeemed.java new file mode 100644 index 0000000000..7ceaa19436 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KravTheUnredeemed.java @@ -0,0 +1,111 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.k; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeXTargetCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.GetXValue; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.abilities.effects.common.GainLifeTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.target.TargetPlayer; + +/** + * + * @author TheElk801 + */ +public class KravTheUnredeemed extends CardImpl { + + public KravTheUnredeemed(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.DEMON); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Partner with Regna, the Redeemer (When this creature enters the battlefield, target player may put Regna into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Regna, the Redeemer", true)); + + // {B}, Sacrifice X creatures: Target player draws X cards and gains X life. Put X +1/+1 counters on Krav, the Unredeemed. + Ability ability = new SimpleActivatedAbility(new KravTheUnredeemedEffect(), new ManaCostsImpl("{B}")); + ability.addTarget(new TargetPlayer()); + ability.addCost(new SacrificeXTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE)); + this.addAbility(ability); + } + + public KravTheUnredeemed(final KravTheUnredeemed card) { + super(card); + } + + @Override + public KravTheUnredeemed copy() { + return new KravTheUnredeemed(this); + } +} + +class KravTheUnredeemedEffect extends OneShotEffect { + + KravTheUnredeemedEffect() { + super(Outcome.Benefit); + this.staticText = "Target player draws X cards and gains X life. Put X +1/+1 counters on {this}"; + } + + KravTheUnredeemedEffect(final KravTheUnredeemedEffect effect) { + super(effect); + } + + @Override + public KravTheUnredeemedEffect copy() { + return new KravTheUnredeemedEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + int xValue = new GetXValue().calculate(game, source, this); + new DrawCardTargetEffect(xValue).apply(game, source); + new GainLifeTargetEffect(xValue).apply(game, source); + new AddCountersSourceEffect(CounterType.P1P1.createInstance(xValue)).apply(game, source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index f488d1431c..484b03a913 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -73,6 +73,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Impulse", 119, Rarity.COMMON, mage.cards.i.Impulse.class)); cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kraken Hatchling", 121, Rarity.COMMON, mage.cards.k.KrakenHatchling.class)); + cards.add(new SetCardInfo("Krav, the Unredeemed", 4, Rarity.RARE, mage.cards.k.KravTheUnredeemed.class)); cards.add(new SetCardInfo("Land Tax", 94, Rarity.MYTHIC, mage.cards.l.LandTax.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); From 130bbe5d96bc73f3b96deed22f62c3e72c26000a Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Tue, 22 May 2018 22:38:21 -0400 Subject: [PATCH 041/154] Implemented Saltwater Stalwart --- .../src/mage/cards/s/SaltwaterStalwart.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SaltwaterStalwart.java diff --git a/Mage.Sets/src/mage/cards/s/SaltwaterStalwart.java b/Mage.Sets/src/mage/cards/s/SaltwaterStalwart.java new file mode 100644 index 0000000000..c036645812 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SaltwaterStalwart.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetPlayer; + +/** + * + * @author TheElk801 + */ +public class SaltwaterStalwart extends CardImpl { + + public SaltwaterStalwart(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Whenever Saltwater Stalwart deals damage to an opponent, target player draws a card. + Ability ability = new DealsDamageToOpponentTriggeredAbility(new DrawCardTargetEffect(1)); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + } + + public SaltwaterStalwart(final SaltwaterStalwart card) { + super(card); + } + + @Override + public SaltwaterStalwart copy() { + return new SaltwaterStalwart(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 484b03a913..e5275783b5 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -85,6 +85,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Regna, the Redeemer", 3, Rarity.RARE, mage.cards.r.RegnaTheRedeemer.class)); cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); cards.add(new SetCardInfo("Rushblade Commander", 77, Rarity.UNCOMMON, mage.cards.r.RushbladeCommander.class)); + cards.add(new SetCardInfo("Saltwater Stalwart", 39, Rarity.COMMON, mage.cards.s.SaltwaterStalwart.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); From 42b539c41f351612255119741005ac354814a108 Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Wed, 23 May 2018 16:49:48 +0200 Subject: [PATCH 042/154] renamed utility functions for clarity --- .../java/mage/client/dialog/TableWaitingDialog.java | 5 +++-- .../src/main/java/mage/client/table/TablesPanel.java | 10 +++++----- .../main/java/mage/client/util/gui/GuiDisplayUtil.java | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java index 238d203d79..cc9e0e5fe8 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java @@ -154,6 +154,7 @@ public class TableWaitingDialog extends MageDialog { public void showDialog(UUID roomId, UUID tableId, boolean isTournament) { Rectangle currentBounds = MageFrame.getDesktop().getBounds(); Optional<UUID> chatId = SessionHandler.getTableChatId(tableId); + String tournamentChatDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_4, null); updateTask = new UpdateSeatsTask(SessionHandler.getSession(), roomId, tableId, this); this.roomId = roomId; @@ -176,7 +177,7 @@ public class TableWaitingDialog extends MageDialog { this.setModal(false); this.setLocation(100, 100); this.setVisible(true); - String tournamentChatDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_4, null); + GuiDisplayUtil.restoreDividerLocations(currentBounds, tournamentChatDivider, jSplitPane1); } else { closeDialog(); @@ -193,7 +194,7 @@ public class TableWaitingDialog extends MageDialog { this.removeDialog(); TableUtil.saveColumnWidthAndOrderToPrefs(jTableSeats, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER); GuiDisplayUtil.saveCurrentBoundsToPrefs(); - GuiDisplayUtil.setDividerLocation(KEY_TABLES_DIVIDER_LOCATION_4, this.jSplitPane1.getDividerLocation()); + GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_4, this.jSplitPane1.getDividerLocation()); } /** diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index d9610492a8..31b1868657 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -231,7 +231,7 @@ public class TablesPanel extends javax.swing.JPanel { jScrollPaneTablesActive.getViewport().setBackground(new Color(255, 255, 255, 50)); jScrollPaneTablesFinished.getViewport().setBackground(new Color(255, 255, 255, 50)); - saveActiveFiltersToPrefs(); + restoreFilters(); setGUISize(); Action openTableAction; @@ -411,12 +411,12 @@ public class TablesPanel extends javax.swing.JPanel { private void saveDividerLocations() { // save divider locations and divider saveDividerLocations GuiDisplayUtil.saveCurrentBoundsToPrefs(); - GuiDisplayUtil.setDividerLocation(KEY_TABLES_DIVIDER_LOCATION_1, this.jSplitPane1.getDividerLocation()); - GuiDisplayUtil.setDividerLocation(KEY_TABLES_DIVIDER_LOCATION_2, this.jSplitPaneTables.getDividerLocation()); - GuiDisplayUtil.setDividerLocation(KEY_TABLES_DIVIDER_LOCATION_3, chatPanelMain.getSplitDividerLocation()); + GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_1, this.jSplitPane1.getDividerLocation()); + GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_2, this.jSplitPaneTables.getDividerLocation()); + GuiDisplayUtil.saveDividerLocationToPrefs(KEY_TABLES_DIVIDER_LOCATION_3, chatPanelMain.getSplitDividerLocation()); } - private void saveActiveFiltersToPrefs() { + private void restoreFilters() { TableUtil.setActiveFilters(KEY_TABLES_FILTER_SETTINGS, filterButtons); setTableFilter(); } diff --git a/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java b/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java index cd478e47e2..2261c9e2a7 100644 --- a/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java +++ b/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java @@ -54,7 +54,7 @@ public final class GuiDisplayUtil { PreferencesDialog.saveValue(KEY_MAGE_PANEL_LAST_SIZE, currentBounds); } - public static void setDividerLocation(String dividerPrefKey, int position) { + public static void saveDividerLocationToPrefs(String dividerPrefKey, int position) { PreferencesDialog.saveValue(dividerPrefKey, Integer.toString(position)); } From efa0cfdae9bcc89a517c695a48df5c691b8fe265 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 11:12:21 -0400 Subject: [PATCH 043/154] Implemented Virtus the Veiled --- .../src/mage/cards/v/VirtusTheVeiled.java | 75 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 76 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VirtusTheVeiled.java diff --git a/Mage.Sets/src/mage/cards/v/VirtusTheVeiled.java b/Mage.Sets/src/mage/cards/v/VirtusTheVeiled.java new file mode 100644 index 0000000000..65d21fe242 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VirtusTheVeiled.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; +import mage.abilities.effects.common.LoseHalfLifeTargetEffect; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.PartnerWithAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class VirtusTheVeiled extends CardImpl { + + public VirtusTheVeiled(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.AZRA); + this.subtype.add(SubType.ASSASSIN); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Partner with Gorm the Great (When this creature enters the battlefield, target player may put Gorm into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Gorm the Great", true)); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // Whenever Virtus the Veiled deals combat damage to a player, that player loses half their life, rounded up. + this.addAbility(new DealsDamageToOpponentTriggeredAbility(new LoseHalfLifeTargetEffect(), false, true, true)); + } + + public VirtusTheVeiled(final VirtusTheVeiled card) { + super(card); + } + + @Override + public VirtusTheVeiled copy() { + return new VirtusTheVeiled(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index e5275783b5..336ece37c5 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -100,6 +100,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("True-Name Nemesis", 136, Rarity.MYTHIC, mage.cards.t.TrueNameNemesis.class)); cards.add(new SetCardInfo("Veteran Explorer", 214, Rarity.UNCOMMON, mage.cards.v.VeteranExplorer.class)); cards.add(new SetCardInfo("Vigor", 215, Rarity.RARE, mage.cards.v.Vigor.class)); + cards.add(new SetCardInfo("Virtus the Veiled", 7, Rarity.RARE, mage.cards.v.VirtusTheVeiled.class)); cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); } } From 544563ae8b57067d6506445a008981fa97b25e14 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 11:57:49 -0400 Subject: [PATCH 044/154] Implemented Pir's Whim Also added an object for choosing friend or foe --- Mage.Sets/src/mage/cards/p/PirsWhim.java | 115 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + .../mage/choices/ChooseFriendsAndFoes.java | 51 ++++++++ 3 files changed, 167 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PirsWhim.java create mode 100644 Mage/src/main/java/mage/choices/ChooseFriendsAndFoes.java diff --git a/Mage.Sets/src/mage/cards/p/PirsWhim.java b/Mage.Sets/src/mage/cards/p/PirsWhim.java new file mode 100644 index 0000000000..825aab6115 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PirsWhim.java @@ -0,0 +1,115 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; +import mage.choices.ChooseFriendsAndFoes; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class PirsWhim extends CardImpl { + + public PirsWhim(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}"); + + // For each player, choose friend or foe. Each friend searches their library for a land card, puts it on the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment they control. + this.getSpellAbility().addEffect(new PirsWhimEffect()); + } + + public PirsWhim(final PirsWhim card) { + super(card); + } + + @Override + public PirsWhim copy() { + return new PirsWhim(this); + } +} + +class PirsWhimEffect extends OneShotEffect { + + PirsWhimEffect() { + super(Outcome.Benefit); + this.staticText = "For each player, choose friend or foe. " + + "Each friend searches their library for a land card, " + + "puts it onto the battlefield tapped, then shuffles their library. " + + "Each foe sacrifices an artifact or enchantment they control."; + } + + PirsWhimEffect(final PirsWhimEffect effect) { + super(effect); + } + + @Override + public PirsWhimEffect copy() { + return new PirsWhimEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getSourceId()); + ChooseFriendsAndFoes choice = new ChooseFriendsAndFoes(); + if (!choice.chooseFriendOrFoe(controller, source, game)) { + return false; + } + for (Player player : choice.getFriends()) { + if (player != null) { + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_LAND); + if (player.searchLibrary(target, game)) { + player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, true, null); + player.shuffleLibrary(source, game); + } + } + } + for (Player player : choice.getFoes()) { + if (player != null) { + Effect effect = new SacrificeEffect(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT, 1, ""); + effect.setTargetPointer(new FixedTarget(player.getId(), game)); + effect.apply(game, source); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 336ece37c5..50f3002f97 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -79,6 +79,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); + cards.add(new SetCardInfo("Pir's Whim", 73, Rarity.RARE, mage.cards.p.PirsWhim.class)); cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); cards.add(new SetCardInfo("Plains", 250, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); diff --git a/Mage/src/main/java/mage/choices/ChooseFriendsAndFoes.java b/Mage/src/main/java/mage/choices/ChooseFriendsAndFoes.java new file mode 100644 index 0000000000..6ab7e4891d --- /dev/null +++ b/Mage/src/main/java/mage/choices/ChooseFriendsAndFoes.java @@ -0,0 +1,51 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.choices; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class ChooseFriendsAndFoes { + + private List<Player> friends = new ArrayList<>(); + private List<Player> foes = new ArrayList<>(); + + public boolean chooseFriendOrFoe(Player playerChoosing, Ability source, Game game) { + if (playerChoosing == null) { + return false; + } + friends.clear(); + foes.clear(); + for (UUID playerId : game.getState().getPlayersInRange(playerChoosing.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + if (playerChoosing.chooseUse(Outcome.Vote, "Is " + player.getName() + " friend or foe?", null, "Friend", "Foe", source, game)) { + friends.add(player); + } else { + foes.add(player); + } + } + } + return true; + } + + public List<Player> getFriends() { + return friends; + } + + public List<Player> getFoes() { + return foes; + } +} From 49fd99a45bffbc13d9948d4c40d282d8f28a872d Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Wed, 23 May 2018 18:00:25 +0200 Subject: [PATCH 045/154] fix columns being resized due to auto creation flag --- .../src/main/java/mage/client/dialog/TableWaitingDialog.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java index cc9e0e5fe8..7a1d1b1fa5 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java @@ -96,6 +96,7 @@ public class TableWaitingDialog extends MageDialog { setGUISize(); jTableSeats.createDefaultColumnsFromModel(); + jTableSeats.setAutoCreateColumnsFromModel(false); jTableSeats.setDefaultRenderer(Icon.class, new CountryCellRenderer()); TableUtil.setColumnWidthAndOrder(jTableSeats, DEFAULT_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_WIDTH, KEY_TABLE_WAITING_COLUMNS_ORDER); chatPanel.useExtendedView(ChatPanelBasic.VIEW_MODE.NONE); From 47e1405587e152937e2907e0a0e55884de5c4816 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 12:39:49 -0400 Subject: [PATCH 046/154] Implemented Sickle Dancer --- Mage.Sets/src/mage/cards/s/SickleDancer.java | 84 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 85 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SickleDancer.java diff --git a/Mage.Sets/src/mage/cards/s/SickleDancer.java b/Mage.Sets/src/mage/cards/s/SickleDancer.java new file mode 100644 index 0000000000..86690e99b6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SickleDancer.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class SickleDancer extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.WARRIOR, "Warrior creature"); + + static { + filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); + filter.add(new AnotherPredicate()); + } + + public SickleDancer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Whenever Sickle Dancer attacks, if your team controls another Warrior, Sickle Dancer gets +1/+1 until end of turn. + this.addAbility(new ConditionalTriggeredAbility( + new AttacksTriggeredAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn), false), + new PermanentsOnTheBattlefieldCondition(filter), + "Whenever {this} attacks, if your team controls another Warrior, {this} gets +1/+1 until end of turn." + )); + } + + public SickleDancer(final SickleDancer card) { + super(card); + } + + @Override + public SickleDancer copy() { + return new SickleDancer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 50f3002f97..09aa39c836 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -89,6 +89,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Saltwater Stalwart", 39, Rarity.COMMON, mage.cards.s.SaltwaterStalwart.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); + cards.add(new SetCardInfo("Sickle Dancer", 50, Rarity.COMMON, mage.cards.s.SickleDancer.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); From 9da01a1270105839bd892c028caa38a0246ed7f6 Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Wed, 23 May 2018 18:50:12 +0200 Subject: [PATCH 047/154] remove logging --- Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java b/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java index fbd66783b8..f762afb2f4 100644 --- a/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java +++ b/Mage.Client/src/main/java/mage/client/util/gui/TableUtil.java @@ -55,7 +55,6 @@ public final class TableUtil { // set the column width from saved value or defaults int[] widths = getIntArrayFromString(PreferencesDialog.getCachedValue(widthPrefKey, null)); - LOGGER.info("loading stored widths: " + Arrays.toString(widths)); int i = 0; for (int width : defaultColumnsWidth) { if (widths != null && widths.length > i) { @@ -72,7 +71,6 @@ public final class TableUtil { // set the column order int[] order = getIntArrayFromString(PreferencesDialog.getCachedValue(orderPrefKey, null)); - LOGGER.info("loading column order: " + Arrays.toString(order)); if (order != null && order.length == table.getColumnCount()) { for (int j = 0; j < table.getColumnCount(); j++) { table.moveColumn(table.convertColumnIndexToView(order[j]), j); @@ -100,8 +98,6 @@ public final class TableUtil { PreferencesDialog.saveValue(widthPrefKey, columnWidthSettings.toString()); PreferencesDialog.saveValue(orderPrefKey, columnOrderSettings.toString()); - LOGGER.info("saving column widths: " + columnWidthSettings.toString()); - LOGGER.info("saving column order: " + columnOrderSettings.toString()); } private static int[] getIntArrayFromString(String stringData) { From 60e5d67ea94b36f46a9c4c2c6da5bc87ce588c54 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 12:57:34 -0400 Subject: [PATCH 048/154] Implemented Thrasher Brute --- Mage.Sets/src/mage/cards/t/ThrasherBrute.java | 119 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 120 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/ThrasherBrute.java diff --git a/Mage.Sets/src/mage/cards/t/ThrasherBrute.java b/Mage.Sets/src/mage/cards/t/ThrasherBrute.java new file mode 100644 index 0000000000..12383777bc --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThrasherBrute.java @@ -0,0 +1,119 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class ThrasherBrute extends CardImpl { + + private static final ThrasherBruteFilter filter = new ThrasherBruteFilter(); + + public ThrasherBrute(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.ORC); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Whenever Thrasher Brute or another Warrior enters the battlefield under your team's control, target opponent loses 1 life and you gain 1 life. + Ability ability = new EntersBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, + new LoseLifeTargetEffect(1), + filter, + false, + "Whenever {this} or another Warrior enters the battlefield under your team's control, " + + "target opponent loses 1 life and you gain 1 life." + ); + ability.addEffect(new GainLifeEffect(1)); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public ThrasherBrute(final ThrasherBrute card) { + super(card); + } + + @Override + public ThrasherBrute copy() { + return new ThrasherBrute(this); + } +} + +class ThrasherBruteFilter extends FilterPermanent { + + ThrasherBruteFilter() { + super(); + this.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); + } + + ThrasherBruteFilter(final ThrasherBruteFilter effect) { + super(effect); + } + + @Override + public ThrasherBruteFilter copy() { + return new ThrasherBruteFilter(this); + } + + @Override + public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) { + if (super.match(permanent, sourceId, playerId, game)) { + if (sourceId.equals(permanent.getId())) { + return true; + } else { + if (permanent.hasSubtype(SubType.WARRIOR, game)) { + return true; + } + } + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 09aa39c836..472e8aec10 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -97,6 +97,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swords to Plowshares", 110, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); + cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); cards.add(new SetCardInfo("Tidespout Tyrant", 134, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); cards.add(new SetCardInfo("True-Name Nemesis", 136, Rarity.MYTHIC, mage.cards.t.TrueNameNemesis.class)); From f3cdad97e7ef9f8147f29edb18a2ab47ea98b6c2 Mon Sep 17 00:00:00 2001 From: GrayedFox <che.fisher@gmail.com> Date: Wed, 23 May 2018 19:06:01 +0200 Subject: [PATCH 049/154] add default width for History (also fixes stored width not being used) --- .../src/main/java/mage/client/dialog/TableWaitingDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java index 7a1d1b1fa5..db61cf981d 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java @@ -71,7 +71,7 @@ import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_4 public class TableWaitingDialog extends MageDialog { private static final Logger LOGGER = Logger.getLogger(TableWaitingDialog.class); - private static final int[] DEFAULT_COLUMNS_WIDTH = {20, 50, 100, 100, 100}; + private static final int[] DEFAULT_COLUMNS_WIDTH = {20, 50, 100, 100, 100, 100}; private UUID tableId; private UUID roomId; From e3a7a7d317c3358f4abb684ab17c6f2bbf6bb58e Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 13:17:32 -0400 Subject: [PATCH 050/154] Implemented Stunning Reversal --- .../src/mage/cards/s/StunningReversal.java | 114 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 115 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/StunningReversal.java diff --git a/Mage.Sets/src/mage/cards/s/StunningReversal.java b/Mage.Sets/src/mage/cards/s/StunningReversal.java new file mode 100644 index 0000000000..1e03ed5757 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StunningReversal.java @@ -0,0 +1,114 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.ExileSpellEffect; +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; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class StunningReversal extends CardImpl { + + public StunningReversal(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{B}"); + + // The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1. + this.getSpellAbility().addEffect(new StunningReversalEffect()); + + // Exile Stunning Reversal. + this.getSpellAbility().addEffect(ExileSpellEffect.getInstance()); + } + + public StunningReversal(final StunningReversal card) { + super(card); + } + + @Override + public StunningReversal copy() { + return new StunningReversal(this); + } +} + +class StunningReversalEffect extends ReplacementEffectImpl { + + public StunningReversalEffect() { + super(Duration.EndOfTurn, Outcome.Benefit); + staticText = "The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1. "; + } + + public StunningReversalEffect(final StunningReversalEffect effect) { + super(effect); + } + + @Override + public StunningReversalEffect copy() { + return new StunningReversalEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player player = game.getPlayer(event.getPlayerId()); + if (player != null) { + player.drawCards(7, game); + player.setLife(1, game, source); + this.discard(); + } + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.LOSES; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getPlayerId().equals(source.getControllerId())) { + return true; + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 472e8aec10..4205297ecc 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -95,6 +95,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); cards.add(new SetCardInfo("Sower of Temptation", 131, Rarity.RARE, mage.cards.s.SowerOfTemptation.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); + cards.add(new SetCardInfo("Stunning Reversal", 51, Rarity.MYTHIC, mage.cards.s.StunningReversal.class)); cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swords to Plowshares", 110, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); From 1cf57154cf89eff96aef2697e8240c1837b5f150 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 13:40:43 -0400 Subject: [PATCH 051/154] Implemented Mindblade Render --- .../src/mage/cards/m/MindbladeRender.java | 126 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 127 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MindbladeRender.java diff --git a/Mage.Sets/src/mage/cards/m/MindbladeRender.java b/Mage.Sets/src/mage/cards/m/MindbladeRender.java new file mode 100644 index 0000000000..d7f7041092 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MindbladeRender.java @@ -0,0 +1,126 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +import mage.constants.SubType; +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.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class MindbladeRender extends CardImpl { + + public MindbladeRender(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add(SubType.AZRA); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Whenever your opponents are dealt combat damage, if any of that damage was dealt by a Warrior, you draw a card and you lose 1 life. + this.addAbility(new MindbladeRenderTriggeredAbility()); + } + + public MindbladeRender(final MindbladeRender card) { + super(card); + } + + @Override + public MindbladeRender copy() { + return new MindbladeRender(this); + } +} + +class MindbladeRenderTriggeredAbility extends TriggeredAbilityImpl { + + private boolean usedForCombatDamageStep; + + MindbladeRenderTriggeredAbility() { + super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1)); + this.addEffect(new LoseLifeSourceControllerEffect(1)); + this.usedForCombatDamageStep = false; + } + + MindbladeRenderTriggeredAbility(final MindbladeRenderTriggeredAbility effect) { + super(effect); + this.usedForCombatDamageStep = effect.usedForCombatDamageStep; + } + + @Override + public MindbladeRenderTriggeredAbility copy() { + return new MindbladeRenderTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PLAYER || event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Player controller = game.getPlayer(getControllerId()); + if (controller == null) { + return false; + } + Permanent damager = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (damager == null) { + return false; + } + if (event.getType() == GameEvent.EventType.DAMAGE_PLAYER + && event.getFlag() + && 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; + } + + @Override + public String getRule() { + return "Whenever your opponents are dealt combat damage, if any of that damage was dealt by a Warrior, you draw a card and you lose 1 life."; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 4205297ecc..751a6c227f 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -76,6 +76,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Krav, the Unredeemed", 4, Rarity.RARE, mage.cards.k.KravTheUnredeemed.class)); cards.add(new SetCardInfo("Land Tax", 94, Rarity.MYTHIC, mage.cards.l.LandTax.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); + cards.add(new SetCardInfo("Mindblade Render", 49, Rarity.RARE, mage.cards.m.MindbladeRender.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); From 064ab419e40919a89cc2e03c1ea1536dede75f02 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 13:42:36 -0400 Subject: [PATCH 052/154] Updated Battlebond spoiler --- Utils/mtg-cards-data.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 9ea55c0774..a8e97194dd 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33376,8 +33376,10 @@ Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist (Another player can Regna's Sanction|Battlebond|30|R|{3}{W}|Sorcery|||For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest.| Game Plan|Battlebond|35|R|{5}{U}|Sorcery|||Assist (Another player can pay up to {5} of this spell's cost.)$Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Game Plan.| Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| +Out of Bounds|Battlebond|38|C|{3}{U}|Instant|||Assist (Another player can pay up to {3} of this spell's cost.)$Counter target spell.| Saltwater Stalwart|Battlebond|39|C|{3}{U}|Creature - Merfolk Warrior|2|4|Whenever Saltwater Stalwart deals damage to an opponent, target player draws a card.| Soaring Show-Off|Battlebond|40|C|{2}{U}|Creature - Bird Warrior|2|2|Flying$When Soaring Show-Off enters the battlefield, each player draws a card.| +Spellseeker|Battlebond|41|R|{2}{U}|Creature - Human Wizard|1|1|When Spellseeker enters the battlefield, you may search your library for an instant or sorcery card with converted mana cost 2 or less, reveal it, put it into your hand, then shuffle your library.| Archfiend of Despair|Battlebond|44|M|{6}{B}{B}|Creature - Demon|6|6|Flying$Your opponents can't gain life.$At the beginning of each end step, each opponent loses life equal to the life that player lost this turn. (Damage causes loss of life.)| Fan Favorite|Battlebond|46|C|{3}{B}|Creature - Human Rogue|2|2|Assist (Another player can pay up to {3} of this spell's cost.)${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| Mindblade Render|Battlebond|49|R|{1}{B}|Creature - Azra Warrior|1|3|Whenever your opponents are dealt combat damage, if any of that damage was dealt by a Warrior, you draw a card and you lose 1 life.| @@ -33385,12 +33387,16 @@ Sickle Dancer|Battlebond|50|C|{2}{B}|Creature - Human Warrior|3|2|Whenever Sickl Stunning Reversal|Battlebond|51|M|{3}{B}|Instant|||The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1. $Exile Stunning Reversal.| Thrasher Brute|Battlebond|52|U|{3}{B}|Creature - Orc Warrior|4|3|Whenever Thrasher Brute or another Warrior enters the battlefield under your team's control, target opponent loses 1 life and you gain 1 life.| Virtus's Virtue|Battlebond|54|R|{2}{B}|Sorcery|||For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control.| +Lava-Field Overlord|Battlebond|60|U|{7}{R}{R}|Creature - Dragon|5|4|Assist (Another player can pay up to {7} of this spell's cost.)$Flying$When Lava-Field Overlord enters the battlefield, it deals 4 damage to target creature an opponent controls.| +Stadium Vendors|Battlebond|63|C|{3}{R}|Creature - Goblin|3|3|When Stadium Vendors enters the battlefield, choose a player. That player adds two mana of any one color they choose.| Stolen Strategy|Battlebond|64|R|{4}{R}|Enchantment|||At the beginning of your upkeep, exile the top card of each opponent's library. Until end of turn, you may cast nonland cards from among those exiled cards, and you may spend mana as though it were mana of any color to cast those spells.| +Bramble Sovereign|Battlebond|65|M|{2}{G}{G}|Creature - Dryad|4|4|Whenever another nontoken creature enters the battlefield, you may pay {1}{G}. If you do, that creature's controller creates a token that's a copy of that creature.| Charging Binox|Battlebond|66|C|{7}{G}|Creature - Beast|7|5|Assist (Another player can pay up to {7} of this spell's cost.)$Trample| The Crowd Goes Wild|Battlebond|68|U|{X}{G}|Sorcery|||Assist (Another player can pay up to {X} of this spell's cost. You choose the value of X.)$Support X. (Put a +1/+1 counter on each of up to X target creatures.)$Each creature with a +1/+1 counter on it gains trample until end of turn.| Generous Sponsor|Battlebond|70|R|{2}{G}|Creature - Elf Advisor|1|4|When Generous Sponsor enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)$Whenever you put one or more counters on a creature you don't control, draw a card.| Jungle Wayfinder|Battlebond|72|C|{2}{G}|Creature - Elf Warrior|3|3|When Jungle Wayfinder enters the battlefield, each player may search their library for a basic land card, reveal it, put it into their hand, then shuffle their library.| Pir's Whim|Battlebond|73|R|{3}{G}|Sorcery|||For each player, choose friend or foe. Each friend searches their library for a land card, puts it on the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment they control.| +Last One Standing|Battlebond|76|R|{1}{B}{R}|Sorcery|||Choose a creature at random, then destroy the rest.| Rushblade Commander|Battlebond|77|U|{B}{R}|Creature - Azra Warrior|2|2|Warriors your team controls have haste.| Bountiful Promenade|Battlebond|81|R||Land|||Bountiful Promenade enters the battlefield tapped unless you have two or more opponents.${T}: Add {G} or {W}.| Luxury Suite|Battlebond|82|R||Land|||Luxury Suite enters the battlefield tapped unless you have two or more opponents.${T}: Add {B} or {R}.| @@ -33399,6 +33405,7 @@ Sea of Clouds|Battlebond|84|R||Land|||Sea of Clouds enters the battlefield tappe Spire Garden|Battlebond|85|R||Land|||Spire Garden enters the battlefield tapped unless you have two or more opponents.${T}: Add {R} or {G}.| Doomed Traveler|Battlebond|91|C|{W}|Creature - Human Soldier|1|1|When Doomed Traveler dies, create a 1/1 white Spirit creature token with flying.| Expedition Raptor|Battlebond|92|C|{3}{W}{W}|Creature - Bird|2|2|Flying$When Expedition Raptor enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| +Kor Spiritdancer|Battlebond|93|R|{1}{W}|Creature - Kor Wizard|0|2|Kor Spiritdancer gets +2/+2 for each Aura attached to it.$Whenever you cast an Aura spell, you may draw a card.| Land Tax|Battlebond|94|M|{W}|Enchantment|||At the beginning of your upkeep, if an opponent controls more lands than you, you may search your library for up to three basic land cards, reveal them, and put them into your hand. If you do, shuffle your library.| Shoulder to Shoulder|Battlebond|105|C|{2}{W}|Sorcery|||Support 2. (Put a +1/+1 counter on each of up to two target creatures.)$Draw a card.| Swords to Plowshares|Battlebond|110|U|{W}|Instant|||Exile target creature. Its controller gains life equal to its power.| @@ -33411,10 +33418,13 @@ True-Name Nemesis|Battlebond|136|M|{1}{U}{U}|Creature - Merfolk Rogue|3|1|As Tru Daggerdrome Imp|Battlebond|140|C|{1}{B}|Creature - Imp|1|1|Flying$Lifelink (Damage dealt by this creature also causes you to gain that much life.)| Diabolic Intent|Battlebond|141|R|{1}{B}|Sorcery|||As an additional cost to cast this spell, sacrifice a creature.$Search your library for a card and put that card into your hand. Then shuffle your library.| Doomed Dissenter|Battlebond|142|C|{1}{B}|Creature - Human|1|1|When Doomed Dissenter dies, create a 2/2 black Zombie creature token.| +Nirkana Revenant|Battlebond|150|M|{4}{B}{B}|Creature - Vampire Shade|4|4|Whenever you tap a Swamp for mana, add an additional {B}.${B}: Nirkana Revenant gets +1/+1 until end of turn.| Boldwyr Intimidator|Battlebond|169|U|{5}{R}{R}|Creature - Giant Warrior|5|5|Cowards can't block Warriors.${R}: Target creature becomes a Coward until end of turn.${2}{R}: Target creature becomes a Warrior until end of turn.| Chain Lightning|Battlebond|171|U|{R}|Sorcery|||Chain Lightning deals 3 damage to any target. Then that player or that permanent's controller may pay {R}{R}. If the player does, they may copy this spell and may choose a new target for that copy.| Doubling Season|Battlebond|195|M|{4}{G}|Enchantment|||If an effect would create one or more tokens under your control, it creates twice that many of those tokens instead.$If an effect would put one or more counters on a permanent you control, it puts twice that many of those counters on that permanent instead.| Fertile Ground|Battlebond|198|C|{1}{G}|Enchantment - Aura|||Enchant land$Whenever enchanted land is tapped for mana, its controller adds an additional one mana of any color.| +Greater Good|Battlebond|201|R|{2}{G}{G}|Enchantment|||Sacrifice a creature: Draw cards equal to the sacrificed creature's power, then discard three cards.| +Seedborn Muse|Battlebond|212|R|{3}{G}{G}|Creature - Spirit|2|4|Untap all permanents you control during each other player's untap step.| Veteran Explorer|Battlebond|214|U|{G}|Creature - Human Soldier Scout|1|1|When Veteran Explorer dies, each player may search their library for up to two basic land cards and put them onto the battlefield. Then each player who searched their library this way shuffles it.| Vigor|Battlebond|215|R|{3}{G}{G}{G}|Creature - Elemental Incarnation|6|6|Trample$If damage would be dealt to a creature you control other than Vigor, prevent that damage. Put a +1/+1 counter on that creature for each 1 damage prevented this way.$When Vigor is put into a graveyard from anywhere, shuffle it into its owner's library.| Auger Spree|Battlebond|218|C|{1}{B}{R}|Instant|||Target creature gets +4/-4 until end of turn.| From 0c478c3a1dc029f068b2ea89e6fdf11e254ced5b Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 13:45:54 -0400 Subject: [PATCH 053/154] Added Battlebond reprints --- Mage.Sets/src/mage/sets/Battlebond.java | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 751a6c227f..491b4e7cdc 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -54,7 +54,7 @@ public class Battlebond extends ExpansionSet { this.numBoosterRare = 1; this.ratioBoosterMythic = 8; cards.add(new SetCardInfo("Archfiend of Despair", 44, Rarity.MYTHIC, mage.cards.a.ArchfiendOfDespair.class)); - cards.add(new SetCardInfo("Arena Rector", 23, Rarity.MYTHIC, mage.cards.a.ArenaRector.class)); + cards.add(new SetCardInfo("Arena Rector", 23, Rarity.MYTHIC, mage.cards.a.ArenaRector.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); @@ -69,43 +69,47 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Greater Good", 201, Rarity.RARE, mage.cards.g.GreaterGood.class)); cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Impulse", 119, Rarity.COMMON, mage.cards.i.Impulse.class)); cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Kor Spiritdancer", 93, Rarity.RARE, mage.cards.k.KorSpiritdancer.class)); cards.add(new SetCardInfo("Kraken Hatchling", 121, Rarity.COMMON, mage.cards.k.KrakenHatchling.class)); - cards.add(new SetCardInfo("Krav, the Unredeemed", 4, Rarity.RARE, mage.cards.k.KravTheUnredeemed.class)); + cards.add(new SetCardInfo("Krav, the Unredeemed", 4, Rarity.RARE, mage.cards.k.KravTheUnredeemed.class)); cards.add(new SetCardInfo("Land Tax", 94, Rarity.MYTHIC, mage.cards.l.LandTax.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); - cards.add(new SetCardInfo("Mindblade Render", 49, Rarity.RARE, mage.cards.m.MindbladeRender.class)); + cards.add(new SetCardInfo("Mindblade Render", 49, Rarity.RARE, mage.cards.m.MindbladeRender.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Nirkana Revenant", 150, Rarity.MYTHIC, mage.cards.n.NirkanaRevenant.class)); cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); - cards.add(new SetCardInfo("Pir's Whim", 73, Rarity.RARE, mage.cards.p.PirsWhim.class)); + cards.add(new SetCardInfo("Pir's Whim", 73, Rarity.RARE, mage.cards.p.PirsWhim.class)); cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); cards.add(new SetCardInfo("Plains", 250, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); - cards.add(new SetCardInfo("Regna, the Redeemer", 3, Rarity.RARE, mage.cards.r.RegnaTheRedeemer.class)); + cards.add(new SetCardInfo("Regna, the Redeemer", 3, Rarity.RARE, mage.cards.r.RegnaTheRedeemer.class)); cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); cards.add(new SetCardInfo("Rushblade Commander", 77, Rarity.UNCOMMON, mage.cards.r.RushbladeCommander.class)); - cards.add(new SetCardInfo("Saltwater Stalwart", 39, Rarity.COMMON, mage.cards.s.SaltwaterStalwart.class)); + cards.add(new SetCardInfo("Saltwater Stalwart", 39, Rarity.COMMON, mage.cards.s.SaltwaterStalwart.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); + cards.add(new SetCardInfo("Seedborn Muse", 212, Rarity.RARE, mage.cards.s.SeedbornMuse.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); - cards.add(new SetCardInfo("Sickle Dancer", 50, Rarity.COMMON, mage.cards.s.SickleDancer.class)); + cards.add(new SetCardInfo("Sickle Dancer", 50, Rarity.COMMON, mage.cards.s.SickleDancer.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); cards.add(new SetCardInfo("Sower of Temptation", 131, Rarity.RARE, mage.cards.s.SowerOfTemptation.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); - cards.add(new SetCardInfo("Stunning Reversal", 51, Rarity.MYTHIC, mage.cards.s.StunningReversal.class)); + cards.add(new SetCardInfo("Stunning Reversal", 51, Rarity.MYTHIC, mage.cards.s.StunningReversal.class)); cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swords to Plowshares", 110, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); - cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); + cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); cards.add(new SetCardInfo("Tidespout Tyrant", 134, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); cards.add(new SetCardInfo("True-Name Nemesis", 136, Rarity.MYTHIC, mage.cards.t.TrueNameNemesis.class)); cards.add(new SetCardInfo("Veteran Explorer", 214, Rarity.UNCOMMON, mage.cards.v.VeteranExplorer.class)); cards.add(new SetCardInfo("Vigor", 215, Rarity.RARE, mage.cards.v.Vigor.class)); - cards.add(new SetCardInfo("Virtus the Veiled", 7, Rarity.RARE, mage.cards.v.VirtusTheVeiled.class)); + cards.add(new SetCardInfo("Virtus the Veiled", 7, Rarity.RARE, mage.cards.v.VirtusTheVeiled.class)); cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); } } From cd04e8968806e4cac85e5f592c83c095f7ca0197 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 13:51:48 -0400 Subject: [PATCH 054/154] Implemented Spellseeker --- Mage.Sets/src/mage/cards/s/Spellseeker.java | 78 +++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 79 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/Spellseeker.java diff --git a/Mage.Sets/src/mage/cards/s/Spellseeker.java b/Mage.Sets/src/mage/cards/s/Spellseeker.java new file mode 100644 index 0000000000..15efb2e2ee --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Spellseeker.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.filter.common.FilterInstantOrSorceryCard; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class Spellseeker extends CardImpl { + + private static final FilterInstantOrSorceryCard filter = new FilterInstantOrSorceryCard("an instant or sorcery card with converted mana cost 2 or less"); + + static { + filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 3)); + } + + public Spellseeker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // When Spellseeker enters the battlefield, you may search your library for an instant or sorcery card with converted mana cost 2 or less, reveal it, put it into your hand, then shuffle your library. + this.addAbility(new EntersBattlefieldTriggeredAbility( + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, filter), true, true), + true + )); + } + + public Spellseeker(final Spellseeker card) { + super(card); + } + + @Override + public Spellseeker copy() { + return new Spellseeker(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 491b4e7cdc..fbff3057fb 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -99,6 +99,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); cards.add(new SetCardInfo("Sower of Temptation", 131, Rarity.RARE, mage.cards.s.SowerOfTemptation.class)); + cards.add(new SetCardInfo("Spellseeker", 41, Rarity.RARE, mage.cards.s.Spellseeker.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); cards.add(new SetCardInfo("Stunning Reversal", 51, Rarity.MYTHIC, mage.cards.s.StunningReversal.class)); cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); From a4a4cf7bd56916bc51b2b61894d03cf665481849 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 14:09:37 -0400 Subject: [PATCH 055/154] Implemented Last One Standing --- .../src/mage/cards/l/LastOneStanding.java | 97 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + Mage/src/main/java/mage/util/RandomUtil.java | 6 +- 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/l/LastOneStanding.java diff --git a/Mage.Sets/src/mage/cards/l/LastOneStanding.java b/Mage.Sets/src/mage/cards/l/LastOneStanding.java new file mode 100644 index 0000000000..877c902cb0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LastOneStanding.java @@ -0,0 +1,97 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.l; + +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +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.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.util.RandomUtil; + +/** + * + * @author TheElk801 + */ +public class LastOneStanding extends CardImpl { + + public LastOneStanding(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}{R}"); + + // Choose a creature at random, then destroy the rest. + this.getSpellAbility().addEffect(new LastOneStandingEffect()); + } + + public LastOneStanding(final LastOneStanding card) { + super(card); + } + + @Override + public LastOneStanding copy() { + return new LastOneStanding(this); + } +} + +class LastOneStandingEffect extends OneShotEffect { + + LastOneStandingEffect() { + super(Outcome.Benefit); + this.staticText = "Choose a creature at random, then destroy the rest."; + } + + LastOneStandingEffect(final LastOneStandingEffect effect) { + super(effect); + } + + @Override + public LastOneStandingEffect copy() { + return new LastOneStandingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + List<Permanent> creatureList = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game); + if (creatureList.size() < 2) { + return true; + } + int toSave = RandomUtil.nextInt(creatureList.size()); + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(Predicates.not(new PermanentIdPredicate(creatureList.get(toSave).getId()))); + return new DestroyAllEffect(filter).apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index fbff3057fb..b6cecdc678 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -77,6 +77,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Kraken Hatchling", 121, Rarity.COMMON, mage.cards.k.KrakenHatchling.class)); cards.add(new SetCardInfo("Krav, the Unredeemed", 4, Rarity.RARE, mage.cards.k.KravTheUnredeemed.class)); cards.add(new SetCardInfo("Land Tax", 94, Rarity.MYTHIC, mage.cards.l.LandTax.class)); + cards.add(new SetCardInfo("Last One Standing", 76, Rarity.RARE, mage.cards.l.LastOneStanding.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Mindblade Render", 49, Rarity.RARE, mage.cards.m.MindbladeRender.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); diff --git a/Mage/src/main/java/mage/util/RandomUtil.java b/Mage/src/main/java/mage/util/RandomUtil.java index 4447e1f64e..aa08d60938 100644 --- a/Mage/src/main/java/mage/util/RandomUtil.java +++ b/Mage/src/main/java/mage/util/RandomUtil.java @@ -8,8 +8,12 @@ import java.util.concurrent.ThreadLocalRandom; */ public final class RandomUtil { + private RandomUtil() { + } - public static Random getRandom() {return ThreadLocalRandom.current();} + public static Random getRandom() { + return ThreadLocalRandom.current(); + } public static int nextInt() { return ThreadLocalRandom.current().nextInt(); From 37abac1f71ba805c274f20691367a4f31824d264 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 15:25:24 -0400 Subject: [PATCH 056/154] Updated Battlebond Spoiler --- Utils/mtg-cards-data.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index a8e97194dd..0a2a41d537 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33364,8 +33364,12 @@ Regna, the Redeemer|Battlebond|3|R|{5}{W}|Legendary Creature - Angel|4|4|Partner Krav, the Unredeemed|Battlebond|4|R|{4}{B}|Legendary Creature - Demon|3|3|Partner with Regna, the Redeemer (When this creature enters the battlefield, target player may put Regna into their hand from their library, then shuffle.)${B}, Sacrifice X creatures: Target player draws X cards and gains X life. Put X +1/+1 counters on Krav, the Unredeemed.| Virtus the Veiled|Battlebond|7|R|{2}{B}|Legendary Creature - Azra Assassin|1|1|Partner with Gorm the Great (When this creature enters the battlefield, target player may put Gorm into their hand from their library, then shuffle.)$Deathtouch$Whenever Virtus the Veiled deals combat damage to a player, that player loses half their life, rounded up.| Gorm the Great|Battlebond|8|R|{3}{G}|Legendary Creature - Giant Warrior|2|7|Partner with Virtus the Veiled (When this creature enters the battlefield, target player may put Virtus into their hand from their library, then shuffle.)$Vigilance$Gorm the Great must be blocked if able, and Gorm must be blocked by two or more creatures if able.| +Khorvath Brightflame|Battlebond|9|R|{5}{R}|Legendart Creature - Dragon|3|4|Partner with Sylvia Brightspear (When this creature enters the battlefield, target player may put Sylvia into their hand from their library, then shuffle.)$Flying, haste$Knights your team controls have flying and haste.| +Sylvia Brightspear|Battlebond|10|R|{2}{W}|Legendary Creature - Human Knight|2|2|Partner with Khorvath Brightflame (When this creature enters the battlefield, target player may put Khorvath into their hand from their library, then shuffle.)$Double strike$Dragons your team controls have double strike.| Pir, Imaginative Rascal|Battlebond|11|R|{2}{G}|Legendary Creature - Human|1|1|Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.)$If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead.| Toothy, Imaginary Friend|Battlebond|12|R|{3}{U}|Legendary Creature - Illusion|1|1|Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.)$Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend.$When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it.| +Chakram Retriever|Battlebond|15|U|{4}{U}|Creature - Elemental Hound|2|4|Partner with Chakram Slinger (When this creature enters the battlefield, target player may put Chakram Slinger into their hand from their library, then shuffle.)$Whenever you cast a spell during your turn, untap target creature.| +Chakram Slinger|Battlebond|16|U|{4}{R}|Creature - Human Warrior|2|4|Partner with Chakram Retriever (When this creature enters the battlefield, target player may put Chakram Retriever into their hand from their library, then shuffle.)${R}, {T}: Chakram Slinger deals 2 damage to target player or planeswalker.| Soulblade Corrupter|Battlebond|17|U|{4}{B}|Creature - Human Warrior|3|3|Partner with Soulblade Renewer (When this creature enters the battlefield, target player may put Soulblade Renewer into their hand from their library, then shuffle.)$Deathtouch$Whenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn.| Soulblade Renewer|Battlebond|18|U|{4}{G}|Creature - Elf Warrior|2|2|Partner with Soulblade Corrupter (When this creature enters the battlefield, target player may put Soulblade Corrupter into their hand from their library, then shuffle.)$When Soulblade Renewer enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| Impetuous Protege|Battlebond|19|U|{2}{R}|Creature - Human Warrior|0|4|Partner with Proud Mentor (When this creature enters the battlefield, target player may put Proud Mentor into their hand from their library, then shuffle.)$Whenever Impetuous Protege attacks, it gets +X/+0 until end of turn, where X is the greatest power among tapped creatures your opponents control.| @@ -33374,6 +33378,7 @@ Arena Rector|Battlebond|23|M|{3}{W}|Creature - Human Cleric|1|2|When Arena Recto Dwarven Lightsmith|Battlebond|27|C|{5}{W}|Creature - Dwarf Cleric|3|4|Assist (Another player can pay up to {5} of this spell's cost.)$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist (Another player can pay up to {6} of this spell's cost.)$Exile all nonland permanents.| Regna's Sanction|Battlebond|30|R|{3}{W}|Sorcery|||For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest.| +Together Forever|Battlebond|32|R|{W}{W}|Enchantment|||When Together Forever enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)${1}: Choose target creature with a counter on it. When that creature dies this turn, return that card to its owner's hand.| Game Plan|Battlebond|35|R|{5}{U}|Sorcery|||Assist (Another player can pay up to {5} of this spell's cost.)$Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Game Plan.| Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| Out of Bounds|Battlebond|38|C|{3}{U}|Instant|||Assist (Another player can pay up to {3} of this spell's cost.)$Counter target spell.| @@ -33382,18 +33387,21 @@ Soaring Show-Off|Battlebond|40|C|{2}{U}|Creature - Bird Warrior|2|2|Flying$When Spellseeker|Battlebond|41|R|{2}{U}|Creature - Human Wizard|1|1|When Spellseeker enters the battlefield, you may search your library for an instant or sorcery card with converted mana cost 2 or less, reveal it, put it into your hand, then shuffle your library.| Archfiend of Despair|Battlebond|44|M|{6}{B}{B}|Creature - Demon|6|6|Flying$Your opponents can't gain life.$At the beginning of each end step, each opponent loses life equal to the life that player lost this turn. (Damage causes loss of life.)| Fan Favorite|Battlebond|46|C|{3}{B}|Creature - Human Rogue|2|2|Assist (Another player can pay up to {3} of this spell's cost.)${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| +Gang Up|Battlebond|47|U|{X}{B}|Instant|||Assist (Another player can pay up to {X} of this spell's cost. You choose the value of X.)$Destroy target creature with power X or less.| +Inner Demon|Battlebond|48|U|{2}{B}{B}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +2/+2, has flying, and is a Demon in addition to its other types.$When Inner Demon enters the battlefield, all non-Demon creatures get -2/-2 until end of turn.| Mindblade Render|Battlebond|49|R|{1}{B}|Creature - Azra Warrior|1|3|Whenever your opponents are dealt combat damage, if any of that damage was dealt by a Warrior, you draw a card and you lose 1 life.| Sickle Dancer|Battlebond|50|C|{2}{B}|Creature - Human Warrior|3|2|Whenever Sickle Dancer attacks, if your team controls another Warrior, Sickle Dancer gets +1/+1 until end of turn.| Stunning Reversal|Battlebond|51|M|{3}{B}|Instant|||The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1. $Exile Stunning Reversal.| Thrasher Brute|Battlebond|52|U|{3}{B}|Creature - Orc Warrior|4|3|Whenever Thrasher Brute or another Warrior enters the battlefield under your team's control, target opponent loses 1 life and you gain 1 life.| -Virtus's Virtue|Battlebond|54|R|{2}{B}|Sorcery|||For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control.| +Virtus's Maneuver|Battlebond|54|R|{2}{B}|Sorcery|||For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control.| +Cheering Fanatic|Battlebond|58|U|{1}{R}|Creature - Goblin|2|2|Whenever Cheering Fanatic attacks, choose a card name. Spells with the chosen name cost {1} less to cast this turn.| Lava-Field Overlord|Battlebond|60|U|{7}{R}{R}|Creature - Dragon|5|4|Assist (Another player can pay up to {7} of this spell's cost.)$Flying$When Lava-Field Overlord enters the battlefield, it deals 4 damage to target creature an opponent controls.| Stadium Vendors|Battlebond|63|C|{3}{R}|Creature - Goblin|3|3|When Stadium Vendors enters the battlefield, choose a player. That player adds two mana of any one color they choose.| Stolen Strategy|Battlebond|64|R|{4}{R}|Enchantment|||At the beginning of your upkeep, exile the top card of each opponent's library. Until end of turn, you may cast nonland cards from among those exiled cards, and you may spend mana as though it were mana of any color to cast those spells.| Bramble Sovereign|Battlebond|65|M|{2}{G}{G}|Creature - Dryad|4|4|Whenever another nontoken creature enters the battlefield, you may pay {1}{G}. If you do, that creature's controller creates a token that's a copy of that creature.| Charging Binox|Battlebond|66|C|{7}{G}|Creature - Beast|7|5|Assist (Another player can pay up to {7} of this spell's cost.)$Trample| The Crowd Goes Wild|Battlebond|68|U|{X}{G}|Sorcery|||Assist (Another player can pay up to {X} of this spell's cost. You choose the value of X.)$Support X. (Put a +1/+1 counter on each of up to X target creatures.)$Each creature with a +1/+1 counter on it gains trample until end of turn.| -Generous Sponsor|Battlebond|70|R|{2}{G}|Creature - Elf Advisor|1|4|When Generous Sponsor enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)$Whenever you put one or more counters on a creature you don't control, draw a card.| +Generous Patron|Battlebond|70|R|{2}{G}|Creature - Elf Advisor|1|4|When Generous Patron enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)$Whenever you put one or more counters on a creature you don't control, draw a card.| Jungle Wayfinder|Battlebond|72|C|{2}{G}|Creature - Elf Warrior|3|3|When Jungle Wayfinder enters the battlefield, each player may search their library for a basic land card, reveal it, put it into their hand, then shuffle their library.| Pir's Whim|Battlebond|73|R|{3}{G}|Sorcery|||For each player, choose friend or foe. Each friend searches their library for a land card, puts it on the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment they control.| Last One Standing|Battlebond|76|R|{1}{B}{R}|Sorcery|||Choose a creature at random, then destroy the rest.| From dd2de70601bdd256f96f88f7f7f9f95a1eb1adbb Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 15:48:25 -0400 Subject: [PATCH 057/154] Implemented Chakram Slinger --- .../src/mage/cards/c/ChakramSlinger.java | 76 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 77 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ChakramSlinger.java diff --git a/Mage.Sets/src/mage/cards/c/ChakramSlinger.java b/Mage.Sets/src/mage/cards/c/ChakramSlinger.java new file mode 100644 index 0000000000..f9a7154c8d --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChakramSlinger.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetPlayerOrPlaneswalker; + +/** + * + * @author TheElk801 + */ +public class ChakramSlinger extends CardImpl { + + public ChakramSlinger(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Partner with Chakram Retriever (When this creature enters the battlefield, target player may put Chakram Retriever into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Chakram Retriever")); + + // {R}, {T}: Chakram Slinger deals 2 damage to target player or planeswalker. + Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(2), new ManaCostsImpl("{R}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetPlayerOrPlaneswalker()); + this.addAbility(ability); + } + + public ChakramSlinger(final ChakramSlinger card) { + super(card); + } + + @Override + public ChakramSlinger copy() { + return new ChakramSlinger(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index b6cecdc678..e0ebad4501 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -60,6 +60,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); cards.add(new SetCardInfo("Chain Lightning", 171, Rarity.UNCOMMON, mage.cards.c.ChainLightning.class)); + cards.add(new SetCardInfo("Chakram Slinger", 16, Rarity.UNCOMMON, mage.cards.c.ChakramSlinger.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); cards.add(new SetCardInfo("Diabolic Intent", 141, Rarity.RARE, mage.cards.d.DiabolicIntent.class)); cards.add(new SetCardInfo("Doomed Dissenter", 142, Rarity.COMMON, mage.cards.d.DoomedDissenter.class)); From da121f63214386385e892bb1324d8a5679542c37 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 15:55:45 -0400 Subject: [PATCH 058/154] Implemented Chakram Retriever --- .../src/mage/cards/c/ChakramRetriever.java | 78 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 79 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/ChakramRetriever.java diff --git a/Mage.Sets/src/mage/cards/c/ChakramRetriever.java b/Mage.Sets/src/mage/cards/c/ChakramRetriever.java new file mode 100644 index 0000000000..4d0c17f885 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChakramRetriever.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.condition.common.MyTurnCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class ChakramRetriever extends CardImpl { + + public ChakramRetriever(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.HOUND); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Partner with Chakram Slinger (When this creature enters the battlefield, target player may put Chakram Slinger into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Chakram Slinger")); + + // Whenever you cast a spell during your turn, untap target creature. + Ability ability = new ConditionalTriggeredAbility( + new SpellCastControllerTriggeredAbility(new UntapTargetEffect(), false), + MyTurnCondition.instance, + "Whenever you cast a spell during your turn, untap target creature." + ); + ability.addTarget(new TargetCreaturePermanent()); + } + + public ChakramRetriever(final ChakramRetriever card) { + super(card); + } + + @Override + public ChakramRetriever copy() { + return new ChakramRetriever(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index e0ebad4501..ac6242d2de 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -60,6 +60,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); cards.add(new SetCardInfo("Chain Lightning", 171, Rarity.UNCOMMON, mage.cards.c.ChainLightning.class)); + cards.add(new SetCardInfo("Chakram Retriever", 15, Rarity.UNCOMMON, mage.cards.c.ChakramRetriever.class)); cards.add(new SetCardInfo("Chakram Slinger", 16, Rarity.UNCOMMON, mage.cards.c.ChakramSlinger.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); cards.add(new SetCardInfo("Diabolic Intent", 141, Rarity.RARE, mage.cards.d.DiabolicIntent.class)); From fa3ccf8bb512983d9b2f67f7ac71208052e6b9db Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 16:46:36 -0400 Subject: [PATCH 059/154] Updated Battleborn spoiler --- Utils/mtg-cards-data.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 0a2a41d537..26ef71cea0 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33364,7 +33364,7 @@ Regna, the Redeemer|Battlebond|3|R|{5}{W}|Legendary Creature - Angel|4|4|Partner Krav, the Unredeemed|Battlebond|4|R|{4}{B}|Legendary Creature - Demon|3|3|Partner with Regna, the Redeemer (When this creature enters the battlefield, target player may put Regna into their hand from their library, then shuffle.)${B}, Sacrifice X creatures: Target player draws X cards and gains X life. Put X +1/+1 counters on Krav, the Unredeemed.| Virtus the Veiled|Battlebond|7|R|{2}{B}|Legendary Creature - Azra Assassin|1|1|Partner with Gorm the Great (When this creature enters the battlefield, target player may put Gorm into their hand from their library, then shuffle.)$Deathtouch$Whenever Virtus the Veiled deals combat damage to a player, that player loses half their life, rounded up.| Gorm the Great|Battlebond|8|R|{3}{G}|Legendary Creature - Giant Warrior|2|7|Partner with Virtus the Veiled (When this creature enters the battlefield, target player may put Virtus into their hand from their library, then shuffle.)$Vigilance$Gorm the Great must be blocked if able, and Gorm must be blocked by two or more creatures if able.| -Khorvath Brightflame|Battlebond|9|R|{5}{R}|Legendart Creature - Dragon|3|4|Partner with Sylvia Brightspear (When this creature enters the battlefield, target player may put Sylvia into their hand from their library, then shuffle.)$Flying, haste$Knights your team controls have flying and haste.| +Khorvath Brightflame|Battlebond|9|R|{5}{R}|Legendary Creature - Dragon|3|4|Partner with Sylvia Brightspear (When this creature enters the battlefield, target player may put Sylvia into their hand from their library, then shuffle.)$Flying, haste$Knights your team controls have flying and haste.| Sylvia Brightspear|Battlebond|10|R|{2}{W}|Legendary Creature - Human Knight|2|2|Partner with Khorvath Brightflame (When this creature enters the battlefield, target player may put Khorvath into their hand from their library, then shuffle.)$Double strike$Dragons your team controls have double strike.| Pir, Imaginative Rascal|Battlebond|11|R|{2}{G}|Legendary Creature - Human|1|1|Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.)$If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead.| Toothy, Imaginary Friend|Battlebond|12|R|{3}{U}|Legendary Creature - Illusion|1|1|Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.)$Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend.$When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it.| @@ -33374,8 +33374,11 @@ Soulblade Corrupter|Battlebond|17|U|{4}{B}|Creature - Human Warrior|3|3|Partner Soulblade Renewer|Battlebond|18|U|{4}{G}|Creature - Elf Warrior|2|2|Partner with Soulblade Corrupter (When this creature enters the battlefield, target player may put Soulblade Corrupter into their hand from their library, then shuffle.)$When Soulblade Renewer enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| Impetuous Protege|Battlebond|19|U|{2}{R}|Creature - Human Warrior|0|4|Partner with Proud Mentor (When this creature enters the battlefield, target player may put Proud Mentor into their hand from their library, then shuffle.)$Whenever Impetuous Protege attacks, it gets +X/+0 until end of turn, where X is the greatest power among tapped creatures your opponents control.| Proud Mentor|Battlebond|20|U|{2}{W}|Creature - Human Warrior|1|1|Partner with Impetuous Protege (When this creature enters the battlefield, target player may put Impetuous Protege into their hand from their library, then shuffle.)${W}, {T}: Tap target creature.| +Ley Weaver|Battlebond|21|U|{3}{G}|Creature - Human Druid|2|2|Partner with Lore Weaver (When this creature enters the battlefield, target player may put Lore Weaver into their hand from their library, then shuffle.)${T}: Untap two target lands.| +Lore Weaver|Battlebond|22|U|{3}{U}|Creature - Human Wizard|2|2|Partner with Ley Weaver (When this creature enters the battlefield, target player may put Ley Weaver into their hand from their library, then shuffle.)${5}{U}{U}: Target player draws two cards.| Arena Rector|Battlebond|23|M|{3}{W}|Creature - Human Cleric|1|2|When Arena Rector dies, you may exile it. If you do, search your library for a planeswalker card, put it onto the battlefield, then shuffle your library.| Dwarven Lightsmith|Battlebond|27|C|{5}{W}|Creature - Dwarf Cleric|3|4|Assist (Another player can pay up to {5} of this spell's cost.)$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| +Jubilant Mascot|Battlebond|28|U|{2}{W}|Creature - Homunculus|1|1|At the beginning of combat on your turn, you may pay {3}{W}. If you do, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist (Another player can pay up to {6} of this spell's cost.)$Exile all nonland permanents.| Regna's Sanction|Battlebond|30|R|{3}{W}|Sorcery|||For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest.| Together Forever|Battlebond|32|R|{W}{W}|Enchantment|||When Together Forever enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)${1}: Choose target creature with a counter on it. When that creature dies this turn, return that card to its owner's hand.| From 299a107a540f81a9db7f4d55823933fe5b1817db Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 16:51:14 -0400 Subject: [PATCH 060/154] Implemented Ley Weaver --- Mage.Sets/src/mage/cards/l/LeyWeaver.java | 74 +++++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 75 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LeyWeaver.java diff --git a/Mage.Sets/src/mage/cards/l/LeyWeaver.java b/Mage.Sets/src/mage/cards/l/LeyWeaver.java new file mode 100644 index 0000000000..84890f3f98 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LeyWeaver.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author TheElk801 + */ +public class LeyWeaver extends CardImpl { + + public LeyWeaver(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.DRUID); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Partner with Lore Weaver (When this creature enters the battlefield, target player may put Lore Weaver into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Lore Weaver")); + + // {T}: Untap two target lands. + Ability ability = new SimpleActivatedAbility(new UntapTargetEffect(), new TapSourceCost()); + ability.addTarget(new TargetLandPermanent(2)); + this.addAbility(ability); + } + + public LeyWeaver(final LeyWeaver card) { + super(card); + } + + @Override + public LeyWeaver copy() { + return new LeyWeaver(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index ac6242d2de..596e41a49a 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -80,6 +80,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Krav, the Unredeemed", 4, Rarity.RARE, mage.cards.k.KravTheUnredeemed.class)); cards.add(new SetCardInfo("Land Tax", 94, Rarity.MYTHIC, mage.cards.l.LandTax.class)); cards.add(new SetCardInfo("Last One Standing", 76, Rarity.RARE, mage.cards.l.LastOneStanding.class)); + cards.add(new SetCardInfo("Ley Weaver", 21, Rarity.UNCOMMON, mage.cards.l.LeyWeaver.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Mindblade Render", 49, Rarity.RARE, mage.cards.m.MindbladeRender.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); From 4939937554d7b10d08a451d41061524669f54094 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 16:53:53 -0400 Subject: [PATCH 061/154] Implemented Lore Weaver --- Mage.Sets/src/mage/cards/l/LoreWeaver.java | 73 ++++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 74 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LoreWeaver.java diff --git a/Mage.Sets/src/mage/cards/l/LoreWeaver.java b/Mage.Sets/src/mage/cards/l/LoreWeaver.java new file mode 100644 index 0000000000..1e74242463 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LoreWeaver.java @@ -0,0 +1,73 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetPlayer; + +/** + * + * @author TheElk801 + */ +public class LoreWeaver extends CardImpl { + + public LoreWeaver(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Partner with Ley Weaver (When this creature enters the battlefield, target player may put Ley Weaver into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Ley Weaver")); + + // {5}{U}{U}: Target player draws two cards. + Ability ability = new SimpleActivatedAbility(new DrawCardTargetEffect(2), new ManaCostsImpl("{5}{U}{U}")); + ability.addTarget(new TargetPlayer()); + } + + public LoreWeaver(final LoreWeaver card) { + super(card); + } + + @Override + public LoreWeaver copy() { + return new LoreWeaver(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 596e41a49a..3ca8578545 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -81,6 +81,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Land Tax", 94, Rarity.MYTHIC, mage.cards.l.LandTax.class)); cards.add(new SetCardInfo("Last One Standing", 76, Rarity.RARE, mage.cards.l.LastOneStanding.class)); cards.add(new SetCardInfo("Ley Weaver", 21, Rarity.UNCOMMON, mage.cards.l.LeyWeaver.class)); + cards.add(new SetCardInfo("Lore Weaver", 22, Rarity.UNCOMMON, mage.cards.l.LoreWeaver.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Mindblade Render", 49, Rarity.RARE, mage.cards.m.MindbladeRender.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); From 49727333672ea9c0707bd03f5a9387df90618d77 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 17:01:01 -0400 Subject: [PATCH 062/154] Implemented Khorvath Brightflame --- .../src/mage/cards/k/KhorvathBrightflame.java | 93 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 94 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KhorvathBrightflame.java diff --git a/Mage.Sets/src/mage/cards/k/KhorvathBrightflame.java b/Mage.Sets/src/mage/cards/k/KhorvathBrightflame.java new file mode 100644 index 0000000000..62fba0471d --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KhorvathBrightflame.java @@ -0,0 +1,93 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.k; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.PartnerWithAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class KhorvathBrightflame extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent(SubType.KNIGHT, "Knights your team controls"); + + static { + filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); + } + + public KhorvathBrightflame(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.DRAGON); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Partner with Sylvia Brightspear (When this creature enters the battlefield, target player may put Sylvia into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Sylvia Brightspear", true)); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // Knights your team controls have flying and haste. + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filter)); + ability.addEffect(new GainAbilityAllEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter).setText("and haste")); + this.addAbility(ability); + } + + public KhorvathBrightflame(final KhorvathBrightflame card) { + super(card); + } + + @Override + public KhorvathBrightflame copy() { + return new KhorvathBrightflame(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 3ca8578545..78f8baa121 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -75,6 +75,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Impulse", 119, Rarity.COMMON, mage.cards.i.Impulse.class)); cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Khorvath Brightflame", 9, Rarity.RARE, mage.cards.k.KhorvathBrightflame.class)); cards.add(new SetCardInfo("Kor Spiritdancer", 93, Rarity.RARE, mage.cards.k.KorSpiritdancer.class)); cards.add(new SetCardInfo("Kraken Hatchling", 121, Rarity.COMMON, mage.cards.k.KrakenHatchling.class)); cards.add(new SetCardInfo("Krav, the Unredeemed", 4, Rarity.RARE, mage.cards.k.KravTheUnredeemed.class)); From 7e05f3d670a58327e70d58a597ebebe74c8c9091 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 17:03:58 -0400 Subject: [PATCH 063/154] Implemented Sylvia Brightspear --- .../src/mage/cards/s/SylviaBrightspear.java | 87 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 88 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SylviaBrightspear.java diff --git a/Mage.Sets/src/mage/cards/s/SylviaBrightspear.java b/Mage.Sets/src/mage/cards/s/SylviaBrightspear.java new file mode 100644 index 0000000000..6a456de6b6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SylviaBrightspear.java @@ -0,0 +1,87 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.PartnerWithAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class SylviaBrightspear extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent(SubType.DRAGON, "Dragons your team controls"); + + static { + filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); + } + + public SylviaBrightspear(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Partner with Khorvath Brightflame (When this creature enters the battlefield, target player may put Khorvath into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Khorvath Brightflame", true)); + + // Double strike + this.addAbility(DoubleStrikeAbility.getInstance()); + + // Dragons your team controls have double strike. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield, filter))); + } + + public SylviaBrightspear(final SylviaBrightspear card) { + super(card); + } + + @Override + public SylviaBrightspear copy() { + return new SylviaBrightspear(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 78f8baa121..4cdfe54596 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -110,6 +110,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Stunning Reversal", 51, Rarity.MYTHIC, mage.cards.s.StunningReversal.class)); cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swords to Plowshares", 110, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); + cards.add(new SetCardInfo("Sylvia Brightspear", 10, Rarity.RARE, mage.cards.s.SylviaBrightspear.class)); cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); cards.add(new SetCardInfo("Tidespout Tyrant", 134, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); From 02df4c7f9e56ae06605257950288e646c2db7037 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 17:12:15 -0400 Subject: [PATCH 064/154] Implemented Inner Demon --- Mage.Sets/src/mage/cards/i/InnerDemon.java | 102 +++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 103 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/InnerDemon.java diff --git a/Mage.Sets/src/mage/cards/i/InnerDemon.java b/Mage.Sets/src/mage/cards/i/InnerDemon.java new file mode 100644 index 0000000000..7472846ffc --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InnerDemon.java @@ -0,0 +1,102 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.AddCardSubtypeAttachedEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author TheElk801 + */ +public class InnerDemon extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("all non-Demon creatures"); + + static { + filter.add(Predicates.not(new SubtypePredicate(SubType.DEMON))); + } + + public InnerDemon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{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); + + // Enchanted creature gets +2/+2, has flying, and is a Demon in addition to its other types. + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield)); + Effect effect = new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA); + effect.setText(", has flying"); + ability.addEffect(effect); + effect = new AddCardSubtypeAttachedEffect(SubType.DEMON, Duration.WhileOnBattlefield, AttachmentType.AURA); + effect.setText(", and is an Demon in addition to its other types"); + ability.addEffect(effect); + this.addAbility(ability); + + // When Inner Demon enters the battlefield, all non-Demon creatures get -2/-2 until end of turn. + this.addAbility(new EntersBattlefieldTriggeredAbility(new BoostAllEffect(-2, -2, Duration.EndOfTurn, filter, false))); + } + + public InnerDemon(final InnerDemon card) { + super(card); + } + + @Override + public InnerDemon copy() { + return new InnerDemon(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 4cdfe54596..590c2f2aa8 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -74,6 +74,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Greater Good", 201, Rarity.RARE, mage.cards.g.GreaterGood.class)); cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Impulse", 119, Rarity.COMMON, mage.cards.i.Impulse.class)); + cards.add(new SetCardInfo("Inner Demon", 48, Rarity.UNCOMMON, mage.cards.i.InnerDemon.class)); cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Khorvath Brightflame", 9, Rarity.RARE, mage.cards.k.KhorvathBrightflame.class)); cards.add(new SetCardInfo("Kor Spiritdancer", 93, Rarity.RARE, mage.cards.k.KorSpiritdancer.class)); From 0c6d35ce5936d12b8506f5e2f3a2639e0983fdd2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 17:32:23 -0400 Subject: [PATCH 065/154] Implemented Bramble Sovereign --- .../src/mage/cards/b/BrambleSovereign.java | 116 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 117 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BrambleSovereign.java diff --git a/Mage.Sets/src/mage/cards/b/BrambleSovereign.java b/Mage.Sets/src/mage/cards/b/BrambleSovereign.java new file mode 100644 index 0000000000..d4ef316237 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BrambleSovereign.java @@ -0,0 +1,116 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SetTargetPointer; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class BrambleSovereign extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creature"); + + static { + filter.add(Predicates.not(new TokenPredicate())); + } + + public BrambleSovereign(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + + this.subtype.add(SubType.DRYAD); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Whenever another nontoken creature enters the battlefield, you may pay {1}{G}. If you do, that creature's controller creates a token that's a copy of that creature. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, + new DoIfCostPaid(new BrambleSovereignEffect(), new ManaCostsImpl("{1}{G}")), + filter, false, SetTargetPointer.PERMANENT, + "Whenever a nontoken creature enters the battlefield, you may pay {1}{G}. " + + "If you do, that creature's controller creates a token that's a copy of that creature." + )); + } + + public BrambleSovereign(final BrambleSovereign card) { + super(card); + } + + @Override + public BrambleSovereign copy() { + return new BrambleSovereign(this); + } +} + +class BrambleSovereignEffect extends OneShotEffect { + + BrambleSovereignEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "its controller creates a token that's a copy of that creature"; + } + + BrambleSovereignEffect(final BrambleSovereignEffect effect) { + super(effect); + } + + @Override + public BrambleSovereignEffect copy() { + return new BrambleSovereignEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source)); + if (permanent != null) { + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(permanent.getControllerId()); + effect.setTargetPointer(targetPointer); + effect.apply(game, source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 590c2f2aa8..8d5b3d67b4 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -58,6 +58,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); + cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); cards.add(new SetCardInfo("Chain Lightning", 171, Rarity.UNCOMMON, mage.cards.c.ChainLightning.class)); cards.add(new SetCardInfo("Chakram Retriever", 15, Rarity.UNCOMMON, mage.cards.c.ChakramRetriever.class)); From dbf19c27ef14e03c1a208a9b7b371feb6b596eec Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 17:46:43 -0400 Subject: [PATCH 066/154] Implemented Jubilant Mascot --- .../src/mage/cards/j/JubilantMascot.java | 85 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 86 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/j/JubilantMascot.java diff --git a/Mage.Sets/src/mage/cards/j/JubilantMascot.java b/Mage.Sets/src/mage/cards/j/JubilantMascot.java new file mode 100644 index 0000000000..0b6184973f --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JubilantMascot.java @@ -0,0 +1,85 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.j; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class JubilantMascot extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other target creatures"); + + static { + filter.add(new AnotherPredicate()); + } + + public JubilantMascot(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.HOMUNCULUS); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // At the beginning of combat on your turn, you may pay {3}{W}. If you do, support 2. (Put a +1/+1 counter on each of up to two other target creatures.) + Ability ability = new BeginningOfCombatTriggeredAbility( + new DoIfCostPaid( + new AddCountersTargetEffect(CounterType.P1P1.createInstance()) + .setText("support 2"), + new ManaCostsImpl("{3}{W}") + ), TargetController.YOU, false); + ability.addTarget(new TargetCreaturePermanent(0, 2, filter, false)); + this.addAbility(ability); + } + + public JubilantMascot(final JubilantMascot card) { + super(card); + } + + @Override + public JubilantMascot copy() { + return new JubilantMascot(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 8d5b3d67b4..4873b8522e 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -77,6 +77,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Impulse", 119, Rarity.COMMON, mage.cards.i.Impulse.class)); cards.add(new SetCardInfo("Inner Demon", 48, Rarity.UNCOMMON, mage.cards.i.InnerDemon.class)); cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jubilant Mascot", 28, Rarity.UNCOMMON, mage.cards.j.JubilantMascot.class)); cards.add(new SetCardInfo("Khorvath Brightflame", 9, Rarity.RARE, mage.cards.k.KhorvathBrightflame.class)); cards.add(new SetCardInfo("Kor Spiritdancer", 93, Rarity.RARE, mage.cards.k.KorSpiritdancer.class)); cards.add(new SetCardInfo("Kraken Hatchling", 121, Rarity.COMMON, mage.cards.k.KrakenHatchling.class)); From 38eb1dc579e6532d6246ceeb2a23d233410df3ff Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 19:36:53 -0400 Subject: [PATCH 067/154] Implemented Cheering Fanatic --- .../src/mage/cards/c/CheeringFanatic.java | 103 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 104 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CheeringFanatic.java diff --git a/Mage.Sets/src/mage/cards/c/CheeringFanatic.java b/Mage.Sets/src/mage/cards/c/CheeringFanatic.java new file mode 100644 index 0000000000..da78460670 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CheeringFanatic.java @@ -0,0 +1,103 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.NameACardEffect; +import mage.abilities.effects.common.NameACardEffect.TypeOfName; +import mage.abilities.effects.common.cost.SpellsCostReductionAllEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.game.Game; + +/** + * + * @author TheElk801 + */ +public class CheeringFanatic extends CardImpl { + + public CheeringFanatic(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.GOBLIN); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Cheering Fanatic attacks, choose a card name. Spells with the chosen name cost {1} less to cast this turn. + this.addAbility(new AttacksTriggeredAbility(new CheeringFanaticEffect(), false)); + } + + public CheeringFanatic(final CheeringFanatic card) { + super(card); + } + + @Override + public CheeringFanatic copy() { + return new CheeringFanatic(this); + } +} + +class CheeringFanaticEffect extends OneShotEffect { + + CheeringFanaticEffect() { + super(Outcome.Benefit); + this.staticText = "choose a card name. Spells with the chosen name cost {1} less to cast this turn"; + } + + CheeringFanaticEffect(final CheeringFanaticEffect effect) { + super(effect); + } + + @Override + public CheeringFanaticEffect copy() { + return new CheeringFanaticEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + new NameACardEffect(TypeOfName.ALL).apply(game, source); + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY); + FilterCard filter = new FilterCard(); + filter.add(new NamePredicate(cardName)); + ContinuousEffect effect = new SpellsCostReductionAllEffect(filter, 1); + effect.setDuration(Duration.EndOfTurn); + game.addEffect(effect, source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 4873b8522e..1ebe45a15d 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -63,6 +63,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Chain Lightning", 171, Rarity.UNCOMMON, mage.cards.c.ChainLightning.class)); cards.add(new SetCardInfo("Chakram Retriever", 15, Rarity.UNCOMMON, mage.cards.c.ChakramRetriever.class)); cards.add(new SetCardInfo("Chakram Slinger", 16, Rarity.UNCOMMON, mage.cards.c.ChakramSlinger.class)); + cards.add(new SetCardInfo("Cheering Fanatic", 58, Rarity.UNCOMMON, mage.cards.c.CheeringFanatic.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); cards.add(new SetCardInfo("Diabolic Intent", 141, Rarity.RARE, mage.cards.d.DiabolicIntent.class)); cards.add(new SetCardInfo("Doomed Dissenter", 142, Rarity.COMMON, mage.cards.d.DoomedDissenter.class)); From 44fd9f76aecb6328807f4e9a2606f466474b8cba Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 19:40:27 -0400 Subject: [PATCH 068/154] Updated Battlebond spoiler --- Utils/mtg-cards-data.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 26ef71cea0..c6123caf73 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33362,6 +33362,8 @@ Will Kenrith|Battlebond|1|M|{4}{U}{U}|Legendary Planeswalker - Will|||+2: Until Rowan Kenrith|Battlebond|2|M|{4}{R}{R}|Legendary Planeswalker - Rowan|||+2: During target player's next turn, each creature that player controls attacks if able. $-2: Rowan Kenrith deals 3 damage to each tapped creature target player controls. $-8: Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy."$Partner with Will Kenrith$Rowan Kenrith can be your commander.| Regna, the Redeemer|Battlebond|3|R|{5}{W}|Legendary Creature - Angel|4|4|Partner with Krav, the Unredeemed (When this creature enters the battlefield, target player may put Krav into their hand from their library, then shuffle.)$Flying$At the beginning of each end step, if your team gained life this turn, create two 1/1 white Warrior creature tokens.| Krav, the Unredeemed|Battlebond|4|R|{4}{B}|Legendary Creature - Demon|3|3|Partner with Regna, the Redeemer (When this creature enters the battlefield, target player may put Regna into their hand from their library, then shuffle.)${B}, Sacrifice X creatures: Target player draws X cards and gains X life. Put X +1/+1 counters on Krav, the Unredeemed.| +Zndrsplt, Eye of Wisdom|Battlebond|5|R|{4}{U}|Legendary Creature - Homunculus|1|4|Partner with Okaun, Eye of Chaos (When this creature enters the battlefield, target player may put Okaun into their hand from their library, then shuffle.)$At the beginning of combat on your turn, flip a coin until you lose a flip.$Whenever a player wins a coin flip, draw a card.| +Okaun, Eye of Chaos|Battlebond|6|R|{4}{R}|Legendary Creature - Cyclops Berserker|3|3|Partner with Zndrsplt, Eye of Wisdom (When this creature enters the battlefield, target player may put Zndrsplt into their hand from their library, then shuffle.)$At the beginning of combat on your turn, flip a coin until you lose a flip.$Whenever a player wins a coin flip, double Okaun's power and toughness until end of turn.| Virtus the Veiled|Battlebond|7|R|{2}{B}|Legendary Creature - Azra Assassin|1|1|Partner with Gorm the Great (When this creature enters the battlefield, target player may put Gorm into their hand from their library, then shuffle.)$Deathtouch$Whenever Virtus the Veiled deals combat damage to a player, that player loses half their life, rounded up.| Gorm the Great|Battlebond|8|R|{3}{G}|Legendary Creature - Giant Warrior|2|7|Partner with Virtus the Veiled (When this creature enters the battlefield, target player may put Virtus into their hand from their library, then shuffle.)$Vigilance$Gorm the Great must be blocked if able, and Gorm must be blocked by two or more creatures if able.| Khorvath Brightflame|Battlebond|9|R|{5}{R}|Legendary Creature - Dragon|3|4|Partner with Sylvia Brightspear (When this creature enters the battlefield, target player may put Sylvia into their hand from their library, then shuffle.)$Flying, haste$Knights your team controls have flying and haste.| @@ -33381,6 +33383,7 @@ Dwarven Lightsmith|Battlebond|27|C|{5}{W}|Creature - Dwarf Cleric|3|4|Assist (An Jubilant Mascot|Battlebond|28|U|{2}{W}|Creature - Homunculus|1|1|At the beginning of combat on your turn, you may pay {3}{W}. If you do, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist (Another player can pay up to {6} of this spell's cost.)$Exile all nonland permanents.| Regna's Sanction|Battlebond|30|R|{3}{W}|Sorcery|||For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest.| +Skystreamer|Battlebond|31|C|{4}{W}|Creature - Griffin|3|2|Assist (Another player can pay up to {4} of this spell's cost.)$Flying$When Skystreamer enters the battlefield, target player gains 4 life.| Together Forever|Battlebond|32|R|{W}{W}|Enchantment|||When Together Forever enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)${1}: Choose target creature with a counter on it. When that creature dies this turn, return that card to its owner's hand.| Game Plan|Battlebond|35|R|{5}{U}|Sorcery|||Assist (Another player can pay up to {5} of this spell's cost.)$Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Game Plan.| Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| @@ -33435,7 +33438,9 @@ Chain Lightning|Battlebond|171|U|{R}|Sorcery|||Chain Lightning deals 3 damage to Doubling Season|Battlebond|195|M|{4}{G}|Enchantment|||If an effect would create one or more tokens under your control, it creates twice that many of those tokens instead.$If an effect would put one or more counters on a permanent you control, it puts twice that many of those counters on that permanent instead.| Fertile Ground|Battlebond|198|C|{1}{G}|Enchantment - Aura|||Enchant land$Whenever enchanted land is tapped for mana, its controller adds an additional one mana of any color.| Greater Good|Battlebond|201|R|{2}{G}{G}|Enchantment|||Sacrifice a creature: Draw cards equal to the sacrificed creature's power, then discard three cards.| +Magus of the Candelabra|Battlebond|206|R|{G}|Creature - Human Wizard|1|2|{X}, {T}: Untap X target lands.| Seedborn Muse|Battlebond|212|R|{3}{G}{G}|Creature - Spirit|2|4|Untap all permanents you control during each other player's untap step.| +Skyshroud Claim|Battlebond|213|C|{3}{G}|Sorcery|||Search your library for up to two Forest cards and put them onto the battlefield. Then shuffle your library.| Veteran Explorer|Battlebond|214|U|{G}|Creature - Human Soldier Scout|1|1|When Veteran Explorer dies, each player may search their library for up to two basic land cards and put them onto the battlefield. Then each player who searched their library this way shuffles it.| Vigor|Battlebond|215|R|{3}{G}{G}{G}|Creature - Elemental Incarnation|6|6|Trample$If damage would be dealt to a creature you control other than Vigor, prevent that damage. Put a +1/+1 counter on that creature for each 1 damage prevented this way.$When Vigor is put into a graveyard from anywhere, shuffle it into its owner's library.| Auger Spree|Battlebond|218|C|{1}{B}{R}|Instant|||Target creature gets +4/-4 until end of turn.| From 5b635f5b60abb0608d568c8b30819d91bea246d0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 19:42:37 -0400 Subject: [PATCH 069/154] Added more Battlebond reprints --- Mage.Sets/src/mage/sets/Battlebond.java | 26 +++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 1ebe45a15d..77f00b9ccd 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -58,12 +58,12 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); - cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); + cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); cards.add(new SetCardInfo("Chain Lightning", 171, Rarity.UNCOMMON, mage.cards.c.ChainLightning.class)); - cards.add(new SetCardInfo("Chakram Retriever", 15, Rarity.UNCOMMON, mage.cards.c.ChakramRetriever.class)); - cards.add(new SetCardInfo("Chakram Slinger", 16, Rarity.UNCOMMON, mage.cards.c.ChakramSlinger.class)); - cards.add(new SetCardInfo("Cheering Fanatic", 58, Rarity.UNCOMMON, mage.cards.c.CheeringFanatic.class)); + cards.add(new SetCardInfo("Chakram Retriever", 15, Rarity.UNCOMMON, mage.cards.c.ChakramRetriever.class)); + cards.add(new SetCardInfo("Chakram Slinger", 16, Rarity.UNCOMMON, mage.cards.c.ChakramSlinger.class)); + cards.add(new SetCardInfo("Cheering Fanatic", 58, Rarity.UNCOMMON, mage.cards.c.CheeringFanatic.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); cards.add(new SetCardInfo("Diabolic Intent", 141, Rarity.RARE, mage.cards.d.DiabolicIntent.class)); cards.add(new SetCardInfo("Doomed Dissenter", 142, Rarity.COMMON, mage.cards.d.DoomedDissenter.class)); @@ -76,18 +76,19 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Greater Good", 201, Rarity.RARE, mage.cards.g.GreaterGood.class)); cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Impulse", 119, Rarity.COMMON, mage.cards.i.Impulse.class)); - cards.add(new SetCardInfo("Inner Demon", 48, Rarity.UNCOMMON, mage.cards.i.InnerDemon.class)); + cards.add(new SetCardInfo("Inner Demon", 48, Rarity.UNCOMMON, mage.cards.i.InnerDemon.class)); cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Jubilant Mascot", 28, Rarity.UNCOMMON, mage.cards.j.JubilantMascot.class)); - cards.add(new SetCardInfo("Khorvath Brightflame", 9, Rarity.RARE, mage.cards.k.KhorvathBrightflame.class)); + cards.add(new SetCardInfo("Jubilant Mascot", 28, Rarity.UNCOMMON, mage.cards.j.JubilantMascot.class)); + cards.add(new SetCardInfo("Khorvath Brightflame", 9, Rarity.RARE, mage.cards.k.KhorvathBrightflame.class)); cards.add(new SetCardInfo("Kor Spiritdancer", 93, Rarity.RARE, mage.cards.k.KorSpiritdancer.class)); cards.add(new SetCardInfo("Kraken Hatchling", 121, Rarity.COMMON, mage.cards.k.KrakenHatchling.class)); cards.add(new SetCardInfo("Krav, the Unredeemed", 4, Rarity.RARE, mage.cards.k.KravTheUnredeemed.class)); cards.add(new SetCardInfo("Land Tax", 94, Rarity.MYTHIC, mage.cards.l.LandTax.class)); - cards.add(new SetCardInfo("Last One Standing", 76, Rarity.RARE, mage.cards.l.LastOneStanding.class)); - cards.add(new SetCardInfo("Ley Weaver", 21, Rarity.UNCOMMON, mage.cards.l.LeyWeaver.class)); - cards.add(new SetCardInfo("Lore Weaver", 22, Rarity.UNCOMMON, mage.cards.l.LoreWeaver.class)); + cards.add(new SetCardInfo("Last One Standing", 76, Rarity.RARE, mage.cards.l.LastOneStanding.class)); + cards.add(new SetCardInfo("Ley Weaver", 21, Rarity.UNCOMMON, mage.cards.l.LeyWeaver.class)); + cards.add(new SetCardInfo("Lore Weaver", 22, Rarity.UNCOMMON, mage.cards.l.LoreWeaver.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); + cards.add(new SetCardInfo("Magus of the Candelabra", 206, Rarity.RARE, mage.cards.m.MagusOfTheCandelabra.class)); cards.add(new SetCardInfo("Mindblade Render", 49, Rarity.RARE, mage.cards.m.MindbladeRender.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); @@ -105,16 +106,17 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Seedborn Muse", 212, Rarity.RARE, mage.cards.s.SeedbornMuse.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); cards.add(new SetCardInfo("Sickle Dancer", 50, Rarity.COMMON, mage.cards.s.SickleDancer.class)); + cards.add(new SetCardInfo("Skyshroud Claim", 213, Rarity.COMMON, mage.cards.s.SkyshroudClaim.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); cards.add(new SetCardInfo("Sower of Temptation", 131, Rarity.RARE, mage.cards.s.SowerOfTemptation.class)); - cards.add(new SetCardInfo("Spellseeker", 41, Rarity.RARE, mage.cards.s.Spellseeker.class)); + cards.add(new SetCardInfo("Spellseeker", 41, Rarity.RARE, mage.cards.s.Spellseeker.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); cards.add(new SetCardInfo("Stunning Reversal", 51, Rarity.MYTHIC, mage.cards.s.StunningReversal.class)); cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swords to Plowshares", 110, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); - cards.add(new SetCardInfo("Sylvia Brightspear", 10, Rarity.RARE, mage.cards.s.SylviaBrightspear.class)); + cards.add(new SetCardInfo("Sylvia Brightspear", 10, Rarity.RARE, mage.cards.s.SylviaBrightspear.class)); cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); cards.add(new SetCardInfo("Tidespout Tyrant", 134, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); From 162d061e066b2cf60b14b3c87dfc75aa4b4f35f3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 20:17:39 -0400 Subject: [PATCH 070/154] Implemented Zndrsplt, Eye of Wisdom --- .../src/mage/cards/z/ZndrspltEyeOfWisdom.java | 76 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + .../common/WinsCoinFlipTriggeredAbility.java | 70 +++++++++++++++++ .../effects/common/FlipUntilLoseEffect.java | 68 +++++++++++++++++ 4 files changed, 215 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/z/ZndrspltEyeOfWisdom.java create mode 100644 Mage/src/main/java/mage/abilities/common/WinsCoinFlipTriggeredAbility.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/FlipUntilLoseEffect.java diff --git a/Mage.Sets/src/mage/cards/z/ZndrspltEyeOfWisdom.java b/Mage.Sets/src/mage/cards/z/ZndrspltEyeOfWisdom.java new file mode 100644 index 0000000000..c5279b5d94 --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZndrspltEyeOfWisdom.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.z; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.common.WinsCoinFlipTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.FlipUntilLoseEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; + +/** + * + * @author TheElk801 + */ +public class ZndrspltEyeOfWisdom extends CardImpl { + + public ZndrspltEyeOfWisdom(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HOMUNCULUS); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // Partner with Okaun, Eye of Chaos (When this creature enters the battlefield, target player may put Okaun into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Okaun, Eye of Chaos", true)); + + // At the beginning of combat on your turn, flip a coin until you lose a flip. + this.addAbility(new BeginningOfCombatTriggeredAbility(new FlipUntilLoseEffect(), TargetController.YOU, false)); + + // Whenever a player wins a coin flip, draw a card. + this.addAbility(new WinsCoinFlipTriggeredAbility(new DrawCardSourceControllerEffect(1))); + } + + public ZndrspltEyeOfWisdom(final ZndrspltEyeOfWisdom card) { + super(card); + } + + @Override + public ZndrspltEyeOfWisdom copy() { + return new ZndrspltEyeOfWisdom(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 77f00b9ccd..60126b1de2 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -125,5 +125,6 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Vigor", 215, Rarity.RARE, mage.cards.v.Vigor.class)); cards.add(new SetCardInfo("Virtus the Veiled", 7, Rarity.RARE, mage.cards.v.VirtusTheVeiled.class)); cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); + cards.add(new SetCardInfo("Zndrsplt, Eye of Wisdom", 5, Rarity.RARE, mage.cards.z.ZndrspltEyeOfWisdom.class)); } } diff --git a/Mage/src/main/java/mage/abilities/common/WinsCoinFlipTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/WinsCoinFlipTriggeredAbility.java new file mode 100644 index 0000000000..1d049cfb73 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/WinsCoinFlipTriggeredAbility.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.abilities.common; + +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author TheElk801 + */ +public class WinsCoinFlipTriggeredAbility extends TriggeredAbilityImpl { + + public WinsCoinFlipTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect, false); + } + + public WinsCoinFlipTriggeredAbility(final WinsCoinFlipTriggeredAbility ability) { + super(ability); + } + + @Override + public WinsCoinFlipTriggeredAbility copy() { + return new WinsCoinFlipTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.COIN_FLIPPED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return event.getFlag(); + } + + @Override + public String getRule() { + return "Whenever a player wins a coin flip," + super.getRule(); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/FlipUntilLoseEffect.java b/Mage/src/main/java/mage/abilities/effects/common/FlipUntilLoseEffect.java new file mode 100644 index 0000000000..f4a65a3b0e --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/FlipUntilLoseEffect.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class FlipUntilLoseEffect extends OneShotEffect { + + public FlipUntilLoseEffect() { + super(Outcome.Benefit); + this.staticText = "flip a coin until you lose a flip"; + } + + public FlipUntilLoseEffect(final FlipUntilLoseEffect effect) { + super(effect); + } + + @Override + public FlipUntilLoseEffect copy() { + return new FlipUntilLoseEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + while (true) { + if (!player.flipCoin(game)) { + return true; + } + } + } +} From 578b75dd43b449a6522dba3ebbddd483743de995 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 20:27:21 -0400 Subject: [PATCH 071/154] Implemented Okaun, Eye of Chaos --- .../src/mage/cards/o/OkaunEyeOfChaos.java | 90 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 91 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java diff --git a/Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java b/Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java new file mode 100644 index 0000000000..35ce845d90 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java @@ -0,0 +1,90 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.o; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.common.WinsCoinFlipTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.SourcePermanentPowerCount; +import mage.abilities.dynamicvalue.common.SourcePermanentToughnessValue; +import mage.abilities.effects.common.FlipUntilLoseEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; + +/** + * + * @author TheElk801 + */ +public class OkaunEyeOfChaos extends CardImpl { + + public OkaunEyeOfChaos(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.CYCLOPS); + this.subtype.add(SubType.BERSERKER); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Partner with Zndrsplt, Eye of Wisdom (When this creature enters the battlefield, target player may put Zndrsplt into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Zndrsplt, Eye of Wisdom", true)); + + // At the beginning of combat on your turn, flip a coin until you lose a flip. + this.addAbility(new BeginningOfCombatTriggeredAbility(new FlipUntilLoseEffect(), TargetController.YOU, false)); + + // Whenever a player wins a coin flip, double Okaun's power and toughness until end of turn. + DynamicValue sourcePower = new SourcePermanentPowerCount(); + DynamicValue sourceToughness = new SourcePermanentToughnessValue(); + this.addAbility(new WinsCoinFlipTriggeredAbility( + new BoostSourceEffect( + sourcePower, + sourceToughness, + Duration.EndOfTurn, + true + ).setText("double {this}'s power until end of turn") + )); + } + + public OkaunEyeOfChaos(final OkaunEyeOfChaos card) { + super(card); + } + + @Override + public OkaunEyeOfChaos copy() { + return new OkaunEyeOfChaos(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 60126b1de2..8a0f12ae79 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -93,6 +93,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nirkana Revenant", 150, Rarity.MYTHIC, mage.cards.n.NirkanaRevenant.class)); + cards.add(new SetCardInfo("Okaun, Eye of Chaos", 6, Rarity.RARE, mage.cards.o.OkaunEyeOfChaos.class)); cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); cards.add(new SetCardInfo("Pir's Whim", 73, Rarity.RARE, mage.cards.p.PirsWhim.class)); cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); From 0d1bff7bc7ad9310b580cf364738fea9887d8bed Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 21:59:58 -0400 Subject: [PATCH 072/154] Implemented Jungle Wayfinder --- .../src/mage/cards/j/JungleWayfinder.java | 119 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 120 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/j/JungleWayfinder.java diff --git a/Mage.Sets/src/mage/cards/j/JungleWayfinder.java b/Mage.Sets/src/mage/cards/j/JungleWayfinder.java new file mode 100644 index 0000000000..76e3d659ef --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JungleWayfinder.java @@ -0,0 +1,119 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.j; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.constants.SubType; +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.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class JungleWayfinder extends CardImpl { + + public JungleWayfinder(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When Jungle Wayfinder enters the battlefield, each player may search their library for a basic land card, reveal it, put it into their hand, then shuffle their library. + this.addAbility(new EntersBattlefieldTriggeredAbility(new JungleWayfinderEffect(), false)); + } + + public JungleWayfinder(final JungleWayfinder card) { + super(card); + } + + @Override + public JungleWayfinder copy() { + return new JungleWayfinder(this); + } +} + +class JungleWayfinderEffect extends OneShotEffect { + + public JungleWayfinderEffect() { + super(Outcome.Benefit); + this.staticText = "each player may search their library for a basic land card, reveal it, put it into their hand, then shuffle their library"; + } + + public JungleWayfinderEffect(final JungleWayfinderEffect effect) { + super(effect); + } + + @Override + public JungleWayfinderEffect copy() { + return new JungleWayfinderEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD); + if (player.chooseUse(Outcome.Benefit, "Search your library for a card to put into your hand?", source, game)) { + player.searchLibrary(target, game); + for (UUID cardId : target.getTargets()) { + Card card = player.getLibrary().getCard(cardId, game); + if (card != null) { + player.revealCards(source, new CardsImpl(card), game); + player.moveCards(card, Zone.HAND, source, game); + } + } + player.shuffleLibrary(source, game); + } + } + } + // prevent undo + controller.resetStoredBookmark(game); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 8a0f12ae79..1c85519686 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -79,6 +79,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Inner Demon", 48, Rarity.UNCOMMON, mage.cards.i.InnerDemon.class)); cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jubilant Mascot", 28, Rarity.UNCOMMON, mage.cards.j.JubilantMascot.class)); + cards.add(new SetCardInfo("Jungle Wayfinder", 72, Rarity.COMMON, mage.cards.j.JungleWayfinder.class)); cards.add(new SetCardInfo("Khorvath Brightflame", 9, Rarity.RARE, mage.cards.k.KhorvathBrightflame.class)); cards.add(new SetCardInfo("Kor Spiritdancer", 93, Rarity.RARE, mage.cards.k.KorSpiritdancer.class)); cards.add(new SetCardInfo("Kraken Hatchling", 121, Rarity.COMMON, mage.cards.k.KrakenHatchling.class)); From 704bc1a22dc10b0ab1b8f5c21bf87be4917772a6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Wed, 23 May 2018 22:41:05 -0400 Subject: [PATCH 073/154] Implemented Generous Patron --- .../src/mage/cards/g/GenerousPatron.java | 109 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 110 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GenerousPatron.java diff --git a/Mage.Sets/src/mage/cards/g/GenerousPatron.java b/Mage.Sets/src/mage/cards/g/GenerousPatron.java new file mode 100644 index 0000000000..2dddc5cf97 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GenerousPatron.java @@ -0,0 +1,109 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.SupportAbility; +import mage.constants.SubType; +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.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class GenerousPatron extends CardImpl { + + public GenerousPatron(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.ADVISOR); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // When Generous Patron enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.) + this.addAbility(new SupportAbility(this, 2)); + + // Whenever you put one or more counters on a creature you don't control, draw a card. + this.addAbility(new GenerousPatronTriggeredAbility()); + } + + public GenerousPatron(final GenerousPatron card) { + super(card); + } + + @Override + public GenerousPatron copy() { + return new GenerousPatron(this); + } +} + +class GenerousPatronTriggeredAbility extends TriggeredAbilityImpl { + + public GenerousPatronTriggeredAbility() { + super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), false); + } + + public GenerousPatronTriggeredAbility(GenerousPatronTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.COUNTERS_ADDED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); + return event.getPlayerId().equals(this.getControllerId()) + && permanent != null + && permanent.isCreature() + && !permanent.getControllerId().equals(getControllerId()) + && event.getAmount() > 0; + } + + @Override + public GenerousPatronTriggeredAbility copy() { + return new GenerousPatronTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever you put one or more counters on a creature you don't control, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 1c85519686..9340d1e921 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -73,6 +73,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Generous Patron", 70, Rarity.RARE, mage.cards.g.GenerousPatron.class)); cards.add(new SetCardInfo("Greater Good", 201, Rarity.RARE, mage.cards.g.GreaterGood.class)); cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Impulse", 119, Rarity.COMMON, mage.cards.i.Impulse.class)); From e8e68529834e2d2ceb6005aebbec88d7d1c38a3c Mon Sep 17 00:00:00 2001 From: emerald000 <emerald000@hotmail.com> Date: Thu, 24 May 2018 00:38:37 -0400 Subject: [PATCH 074/154] [BBD] Implemented Assist ability and a card using it (Charging Binox). --- Mage.Sets/src/mage/cards/c/ChargingBinox.java | 66 ++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 9 +- .../mage/abilities/keyword/AssistAbility.java | 158 ++++++++++++++++++ Utils/keywords.txt | 1 + 4 files changed, 230 insertions(+), 4 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/c/ChargingBinox.java create mode 100644 Mage/src/main/java/mage/abilities/keyword/AssistAbility.java diff --git a/Mage.Sets/src/mage/cards/c/ChargingBinox.java b/Mage.Sets/src/mage/cards/c/ChargingBinox.java new file mode 100644 index 0000000000..521b9d6cf8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChargingBinox.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.AssistAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * + * @author emerald000 + */ +public class ChargingBinox extends CardImpl { + + public ChargingBinox(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{7}{G}"); + + this.subtype.add(SubType.BEAST); + this.power = new MageInt(7); + this.toughness = new MageInt(5); + + // Assist (Another player can pay up to {7} of this spell's cost.) + this.addAbility(new AssistAbility()); + // Trample + this.addAbility(TrampleAbility.getInstance()); + } + + public ChargingBinox(final ChargingBinox card) { + super(card); + } + + @Override + public ChargingBinox copy() { + return new ChargingBinox(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 9340d1e921..a2b149ea24 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -63,6 +63,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Chain Lightning", 171, Rarity.UNCOMMON, mage.cards.c.ChainLightning.class)); cards.add(new SetCardInfo("Chakram Retriever", 15, Rarity.UNCOMMON, mage.cards.c.ChakramRetriever.class)); cards.add(new SetCardInfo("Chakram Slinger", 16, Rarity.UNCOMMON, mage.cards.c.ChakramSlinger.class)); + cards.add(new SetCardInfo("Charging Binox", 66, Rarity.COMMON, mage.cards.c.ChargingBinox.class)); cards.add(new SetCardInfo("Cheering Fanatic", 58, Rarity.UNCOMMON, mage.cards.c.CheeringFanatic.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); cards.add(new SetCardInfo("Diabolic Intent", 141, Rarity.RARE, mage.cards.d.DiabolicIntent.class)); @@ -73,14 +74,14 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Generous Patron", 70, Rarity.RARE, mage.cards.g.GenerousPatron.class)); + cards.add(new SetCardInfo("Generous Patron", 70, Rarity.RARE, mage.cards.g.GenerousPatron.class)); cards.add(new SetCardInfo("Greater Good", 201, Rarity.RARE, mage.cards.g.GreaterGood.class)); cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Impulse", 119, Rarity.COMMON, mage.cards.i.Impulse.class)); cards.add(new SetCardInfo("Inner Demon", 48, Rarity.UNCOMMON, mage.cards.i.InnerDemon.class)); cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jubilant Mascot", 28, Rarity.UNCOMMON, mage.cards.j.JubilantMascot.class)); - cards.add(new SetCardInfo("Jungle Wayfinder", 72, Rarity.COMMON, mage.cards.j.JungleWayfinder.class)); + cards.add(new SetCardInfo("Jungle Wayfinder", 72, Rarity.COMMON, mage.cards.j.JungleWayfinder.class)); cards.add(new SetCardInfo("Khorvath Brightflame", 9, Rarity.RARE, mage.cards.k.KhorvathBrightflame.class)); cards.add(new SetCardInfo("Kor Spiritdancer", 93, Rarity.RARE, mage.cards.k.KorSpiritdancer.class)); cards.add(new SetCardInfo("Kraken Hatchling", 121, Rarity.COMMON, mage.cards.k.KrakenHatchling.class)); @@ -95,7 +96,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nirkana Revenant", 150, Rarity.MYTHIC, mage.cards.n.NirkanaRevenant.class)); - cards.add(new SetCardInfo("Okaun, Eye of Chaos", 6, Rarity.RARE, mage.cards.o.OkaunEyeOfChaos.class)); + cards.add(new SetCardInfo("Okaun, Eye of Chaos", 6, Rarity.RARE, mage.cards.o.OkaunEyeOfChaos.class)); cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); cards.add(new SetCardInfo("Pir's Whim", 73, Rarity.RARE, mage.cards.p.PirsWhim.class)); cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); @@ -128,6 +129,6 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Vigor", 215, Rarity.RARE, mage.cards.v.Vigor.class)); cards.add(new SetCardInfo("Virtus the Veiled", 7, Rarity.RARE, mage.cards.v.VirtusTheVeiled.class)); cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); - cards.add(new SetCardInfo("Zndrsplt, Eye of Wisdom", 5, Rarity.RARE, mage.cards.z.ZndrspltEyeOfWisdom.class)); + cards.add(new SetCardInfo("Zndrsplt, Eye of Wisdom", 5, Rarity.RARE, mage.cards.z.ZndrspltEyeOfWisdom.class)); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/AssistAbility.java b/Mage/src/main/java/mage/abilities/keyword/AssistAbility.java new file mode 100644 index 0000000000..f56fd58e58 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/AssistAbility.java @@ -0,0 +1,158 @@ +/* + * 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.keyword; + +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.SpecialAction; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.mana.AlternateManaPaymentAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.mana.ManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.constants.AbilityType; +import mage.constants.ManaType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPlayer; +import mage.filter.predicate.other.PlayerPredicate; +import mage.game.Game; +import mage.players.ManaPool; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPlayer; + +/* + * @author emerald000 + */ +public class AssistAbility extends SimpleStaticAbility implements AlternateManaPaymentAbility { + + private static final FilterPlayer filter = new FilterPlayer("another player"); + static { + filter.add(new PlayerPredicate(TargetController.NOT_YOU)); + } + + public AssistAbility() { + super(Zone.STACK, null); + this.setRuleAtTheTop(true); + } + + public AssistAbility(final AssistAbility ability) { + super(ability); + } + + @Override + public AssistAbility copy() { + return new AssistAbility(this); + } + + @Override + public void addSpecialAction(Ability source, Game game, ManaCost unpaid) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null + && source.getAbilityType() == AbilityType.SPELL + && unpaid.getMana().getGeneric() >= 1 + && game.getState().getValue(source.getSourceId().toString() + game.getState().getZoneChangeCounter(source.getSourceId())) == null) { + SpecialAction specialAction = new AssistSpecialAction(unpaid); + specialAction.setControllerId(source.getControllerId()); + specialAction.setSourceId(source.getSourceId()); + Target target = new TargetPlayer(1, 1, true, filter); + specialAction.addTarget(target); + if (specialAction.canActivate(source.getControllerId(), game)) { + game.getState().getSpecialActions().add(specialAction); + } + } + } + + @Override + public String getRule() { + return "Assist <i>(Another player can help pay the generic mana of this spell's cost.)</i>"; + } +} + +class AssistSpecialAction extends SpecialAction { + + AssistSpecialAction(ManaCost unpaid) { + super(Zone.ALL, true); + setRuleVisible(false); + this.addEffect(new AssistEffect(unpaid)); + } + + AssistSpecialAction(final AssistSpecialAction ability) { + super(ability); + } + + @Override + public AssistSpecialAction copy() { + return new AssistSpecialAction(this); + } +} + +class AssistEffect extends OneShotEffect { + + private final ManaCost unpaid; + + AssistEffect(ManaCost unpaid) { + super(Outcome.Benefit); + this.unpaid = unpaid; + this.staticText = "Assist <i>(Another player can help pay the generic mana of this spell's cost.)</i>"; + } + + AssistEffect(final AssistEffect effect) { + super(effect); + this.unpaid = effect.unpaid; + } + + @Override + public AssistEffect copy() { + return new AssistEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); + if (controller != null && targetPlayer != null) { + int amountToPay = targetPlayer.announceXMana(0, unpaid.getMana().getGeneric(), "How much mana to pay?", game, source); + if (amountToPay > 0) { + Cost cost = new GenericManaCost(amountToPay); + if (cost.pay(source, game, source.getSourceId(), targetPlayer.getId(), false)) { + ManaPool manaPool = controller.getManaPool(); + manaPool.addMana(Mana.ColorlessMana(amountToPay), game, source); + manaPool.unlockManaType(ManaType.COLORLESS); + game.informPlayers(targetPlayer.getLogName() + " paid " + amountToPay + " mana."); + game.getState().setValue(source.getSourceId().toString() + game.getState().getZoneChangeCounter(source.getSourceId()), true); + } + } + return true; + } + return false; + } +} diff --git a/Utils/keywords.txt b/Utils/keywords.txt index f78722fbbb..b8cd2428a2 100644 --- a/Utils/keywords.txt +++ b/Utils/keywords.txt @@ -1,6 +1,7 @@ Afflict|number| Annihilator|number| Ascend|new| +Assist|instance| Basic landcycling|cost| Battle cry|new| Bestow|card, manaString| From acae557fb018ee4b12c38da5726449c5c18a7f36 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 08:09:04 -0400 Subject: [PATCH 075/154] Updated Battlebond Spoiler --- Utils/mtg-cards-data.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index c6123caf73..983d57589c 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33370,6 +33370,8 @@ Khorvath Brightflame|Battlebond|9|R|{5}{R}|Legendary Creature - Dragon|3|4|Partn Sylvia Brightspear|Battlebond|10|R|{2}{W}|Legendary Creature - Human Knight|2|2|Partner with Khorvath Brightflame (When this creature enters the battlefield, target player may put Khorvath into their hand from their library, then shuffle.)$Double strike$Dragons your team controls have double strike.| Pir, Imaginative Rascal|Battlebond|11|R|{2}{G}|Legendary Creature - Human|1|1|Partner with Toothy, Imaginary Friend (When this creature enters the battlefield, target player may put Toothy into their hand from their library, then shuffle.)$If one or more counters would be put on a permanent your team controls, that many plus one of each of those kinds of counters are put on that permanent instead.| Toothy, Imaginary Friend|Battlebond|12|R|{3}{U}|Legendary Creature - Illusion|1|1|Partner with Pir, Imaginative Rascal (When this creature enters the battlefield, target player may put Pir into their hand from their library, then shuffle.)$Whenever you draw a card, put a +1/+1 counter on Toothy, Imaginary Friend.$When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it.| +Blaring Recruiter|Battlebond|13|U|{3}{W}|Creature - Elf Warrior|2|2|Partner with Blaring Captain (When this creature enters the battlefield, target player may put Blaring Captain into their hand from their library, then shuffle.)${2}{W}: Create a 1/1 white Warrior creature token.| +Blaring Captain|Battlebond|14|U|{3}{B}|Creature - Azra Warrior|2|2|Partner with Blaring Recruiter (When this creature enters the battlefield, target player may put Blaring Recruiter into their hand from their library, then shuffle.)$Whenever Blaring Captain attacks, attacking Warriors get +1/+1 until end of turn.| Chakram Retriever|Battlebond|15|U|{4}{U}|Creature - Elemental Hound|2|4|Partner with Chakram Slinger (When this creature enters the battlefield, target player may put Chakram Slinger into their hand from their library, then shuffle.)$Whenever you cast a spell during your turn, untap target creature.| Chakram Slinger|Battlebond|16|U|{4}{R}|Creature - Human Warrior|2|4|Partner with Chakram Retriever (When this creature enters the battlefield, target player may put Chakram Retriever into their hand from their library, then shuffle.)${R}, {T}: Chakram Slinger deals 2 damage to target player or planeswalker.| Soulblade Corrupter|Battlebond|17|U|{4}{B}|Creature - Human Warrior|3|3|Partner with Soulblade Renewer (When this creature enters the battlefield, target player may put Soulblade Renewer into their hand from their library, then shuffle.)$Deathtouch$Whenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn.| @@ -33385,6 +33387,7 @@ Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist (Another player can Regna's Sanction|Battlebond|30|R|{3}{W}|Sorcery|||For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest.| Skystreamer|Battlebond|31|C|{4}{W}|Creature - Griffin|3|2|Assist (Another player can pay up to {4} of this spell's cost.)$Flying$When Skystreamer enters the battlefield, target player gains 4 life.| Together Forever|Battlebond|32|R|{W}{W}|Enchantment|||When Together Forever enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)${1}: Choose target creature with a counter on it. When that creature dies this turn, return that card to its owner's hand.| +Fumble|Battlebond|34|U|{1}{U}|Instant|||Return target creature to its owner's hand. Gain control of all Auras and Equipment that were attached to it, then attach them to another creature.| Game Plan|Battlebond|35|R|{5}{U}|Sorcery|||Assist (Another player can pay up to {5} of this spell's cost.)$Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Game Plan.| Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| Out of Bounds|Battlebond|38|C|{3}{U}|Instant|||Assist (Another player can pay up to {3} of this spell's cost.)$Counter target spell.| @@ -33401,6 +33404,7 @@ Stunning Reversal|Battlebond|51|M|{3}{B}|Instant|||The next time you would lose Thrasher Brute|Battlebond|52|U|{3}{B}|Creature - Orc Warrior|4|3|Whenever Thrasher Brute or another Warrior enters the battlefield under your team's control, target opponent loses 1 life and you gain 1 life.| Virtus's Maneuver|Battlebond|54|R|{2}{B}|Sorcery|||For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control.| Cheering Fanatic|Battlebond|58|U|{1}{R}|Creature - Goblin|2|2|Whenever Cheering Fanatic attacks, choose a card name. Spells with the chosen name cost {1} less to cast this turn.| +Khorvath's Fury|Battlebond|59|R|{4}{R}|Sorcery|||For each player, choose friend or foe. Each friend discards all cards from their hand, then draws that many cards plus one. Khorvath's Fury deals damage to each foe equal to the number of cards in their hand.| Lava-Field Overlord|Battlebond|60|U|{7}{R}{R}|Creature - Dragon|5|4|Assist (Another player can pay up to {7} of this spell's cost.)$Flying$When Lava-Field Overlord enters the battlefield, it deals 4 damage to target creature an opponent controls.| Stadium Vendors|Battlebond|63|C|{3}{R}|Creature - Goblin|3|3|When Stadium Vendors enters the battlefield, choose a player. That player adds two mana of any one color they choose.| Stolen Strategy|Battlebond|64|R|{4}{R}|Enchantment|||At the beginning of your upkeep, exile the top card of each opponent's library. Until end of turn, you may cast nonland cards from among those exiled cards, and you may spend mana as though it were mana of any color to cast those spells.| @@ -33408,15 +33412,18 @@ Bramble Sovereign|Battlebond|65|M|{2}{G}{G}|Creature - Dryad|4|4|Whenever anothe Charging Binox|Battlebond|66|C|{7}{G}|Creature - Beast|7|5|Assist (Another player can pay up to {7} of this spell's cost.)$Trample| The Crowd Goes Wild|Battlebond|68|U|{X}{G}|Sorcery|||Assist (Another player can pay up to {X} of this spell's cost. You choose the value of X.)$Support X. (Put a +1/+1 counter on each of up to X target creatures.)$Each creature with a +1/+1 counter on it gains trample until end of turn.| Generous Patron|Battlebond|70|R|{2}{G}|Creature - Elf Advisor|1|4|When Generous Patron enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)$Whenever you put one or more counters on a creature you don't control, draw a card.| +Grothama, All-Devouring|Battlebond|71|M|{3}{G}{G}|Legendary Creature - Wurm|10|8|Other creatures have "Whenever this creature attacks, you may have it fight Grothama, All-Devouring."$When Grothama leaves the battlefield, each player draws cards equal to the amount of damage dealt to Grothama this turn by sources they controlled.| Jungle Wayfinder|Battlebond|72|C|{2}{G}|Creature - Elf Warrior|3|3|When Jungle Wayfinder enters the battlefield, each player may search their library for a basic land card, reveal it, put it into their hand, then shuffle their library.| Pir's Whim|Battlebond|73|R|{3}{G}|Sorcery|||For each player, choose friend or foe. Each friend searches their library for a land card, puts it on the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment they control.| Last One Standing|Battlebond|76|R|{1}{B}{R}|Sorcery|||Choose a creature at random, then destroy the rest.| Rushblade Commander|Battlebond|77|U|{B}{R}|Creature - Azra Warrior|2|2|Warriors your team controls have haste.| +Sentinel Tower|Battlebond|79|R|{4}|Artifact|||Whenever an instant or sorcery spell is cast during your turn, Sentinel Tower deals 1 damage to any target equal to 1 plus the number of instant and sorcery spells cast before that spell this turn.| Bountiful Promenade|Battlebond|81|R||Land|||Bountiful Promenade enters the battlefield tapped unless you have two or more opponents.${T}: Add {G} or {W}.| Luxury Suite|Battlebond|82|R||Land|||Luxury Suite enters the battlefield tapped unless you have two or more opponents.${T}: Add {B} or {R}.| Morphic Pool|Battlebond|83|R||Land|||Morphic Pool enters the battlefield tapped unless you have two or more opponents.${T}: Add {U} or {B}.| Sea of Clouds|Battlebond|84|R||Land|||Sea of Clouds enters the battlefield tapped unless you have two or more opponents.${T}: Add {W} or {U}.| Spire Garden|Battlebond|85|R||Land|||Spire Garden enters the battlefield tapped unless you have two or more opponents.${T}: Add {R} or {G}.| +Angelic Chorus|Battlebond|87|R|{3}{W}{W}|Enchantment|||Whenever a creature enters the battlefield under your control, you gain life equal to its toughness.| Doomed Traveler|Battlebond|91|C|{W}|Creature - Human Soldier|1|1|When Doomed Traveler dies, create a 1/1 white Spirit creature token with flying.| Expedition Raptor|Battlebond|92|C|{3}{W}{W}|Creature - Bird|2|2|Flying$When Expedition Raptor enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| Kor Spiritdancer|Battlebond|93|R|{1}{W}|Creature - Kor Wizard|0|2|Kor Spiritdancer gets +2/+2 for each Aura attached to it.$Whenever you cast an Aura spell, you may draw a card.| @@ -33427,6 +33434,7 @@ Impulse|Battlebond|119|C|{1}{U}|Instant|||Look at the top four cards of your lib Kraken Hatchling|Battlebond|121|C|{U}|Creature - Kraken|0|4|| Peregrine Drake|Battlebond|128|U|{4}{U}|Creature - Drake|2|3|Flying$When Peregrine Drake enters the battlefield, untap up to five lands.| Sower of Temptation|Battlebond|131|R|{2}{U}{U}|Creature - Faerie Wizard|2|2|Flying$When Sower of Temptation enters the battlefield, gain control of target creature for as long as Sower of Temptation remains on the battlefield.| +Spell Snare|Battlebond|132|U|{U}|Instant|||Counter target spell with converted mana cost 2.| Tidespout Tyrant|Battlebond|134|R|{5}{U}{U}{U}|Creature - Djinn|5|5|Flying$Whenever you cast a spell, return target permanent to its owner's hand.| True-Name Nemesis|Battlebond|136|M|{1}{U}{U}|Creature - Merfolk Rogue|3|1|As True-Name Nemesis enters the battlefield, choose a player.$True-Name Nemesis has protection from the chosen player. (This creature can't be blocked, targeted, dealt damage, or enchanted by anything controlled by that player.)| Daggerdrome Imp|Battlebond|140|C|{1}{B}|Creature - Imp|1|1|Flying$Lifelink (Damage dealt by this creature also causes you to gain that much life.)| @@ -33435,6 +33443,7 @@ Doomed Dissenter|Battlebond|142|C|{1}{B}|Creature - Human|1|1|When Doomed Dissen Nirkana Revenant|Battlebond|150|M|{4}{B}{B}|Creature - Vampire Shade|4|4|Whenever you tap a Swamp for mana, add an additional {B}.${B}: Nirkana Revenant gets +1/+1 until end of turn.| Boldwyr Intimidator|Battlebond|169|U|{5}{R}{R}|Creature - Giant Warrior|5|5|Cowards can't block Warriors.${R}: Target creature becomes a Coward until end of turn.${2}{R}: Target creature becomes a Warrior until end of turn.| Chain Lightning|Battlebond|171|U|{R}|Sorcery|||Chain Lightning deals 3 damage to any target. Then that player or that permanent's controller may pay {R}{R}. If the player does, they may copy this spell and may choose a new target for that copy.| +Beast Within|Battlebond|190|U|{2}{G}|Instant|||Destroy target permanent. Its controller creates a 3/3 green Beast creature token.| Doubling Season|Battlebond|195|M|{4}{G}|Enchantment|||If an effect would create one or more tokens under your control, it creates twice that many of those tokens instead.$If an effect would put one or more counters on a permanent you control, it puts twice that many of those counters on that permanent instead.| Fertile Ground|Battlebond|198|C|{1}{G}|Enchantment - Aura|||Enchant land$Whenever enchanted land is tapped for mana, its controller adds an additional one mana of any color.| Greater Good|Battlebond|201|R|{2}{G}{G}|Enchantment|||Sacrifice a creature: Draw cards equal to the sacrificed creature's power, then discard three cards.| From ccce50cf66afbcbff14042409d9535a4529428aa Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 08:10:17 -0400 Subject: [PATCH 076/154] added Battlebond reprints --- Mage.Sets/src/mage/sets/Battlebond.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index a2b149ea24..4ad3843851 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -53,9 +53,11 @@ public class Battlebond extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; + cards.add(new SetCardInfo("Angelic Chorus", 87, Rarity.RARE, mage.cards.a.AngelicChorus.class)); cards.add(new SetCardInfo("Archfiend of Despair", 44, Rarity.MYTHIC, mage.cards.a.ArchfiendOfDespair.class)); cards.add(new SetCardInfo("Arena Rector", 23, Rarity.MYTHIC, mage.cards.a.ArenaRector.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); + cards.add(new SetCardInfo("Beast Within", 190, Rarity.UNCOMMON, mage.cards.b.BeastWithin.class)); cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); @@ -115,6 +117,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); cards.add(new SetCardInfo("Sower of Temptation", 131, Rarity.RARE, mage.cards.s.SowerOfTemptation.class)); + cards.add(new SetCardInfo("Spell Snare", 132, Rarity.UNCOMMON, mage.cards.s.SpellSnare.class)); cards.add(new SetCardInfo("Spellseeker", 41, Rarity.RARE, mage.cards.s.Spellseeker.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); cards.add(new SetCardInfo("Stunning Reversal", 51, Rarity.MYTHIC, mage.cards.s.StunningReversal.class)); From d56f5c530972587a11ffe5a51c3db942cdfa2fed Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 08:30:36 -0400 Subject: [PATCH 077/154] A few small changes for the Assist implementation --- Utils/keywords.txt | 2 +- Utils/mtg-cards-data.txt | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Utils/keywords.txt b/Utils/keywords.txt index b8cd2428a2..437cc37021 100644 --- a/Utils/keywords.txt +++ b/Utils/keywords.txt @@ -1,7 +1,7 @@ Afflict|number| Annihilator|number| Ascend|new| -Assist|instance| +Assist|new| Basic landcycling|cost| Battle cry|new| Bestow|card, manaString| diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 983d57589c..538c353d5b 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33381,22 +33381,22 @@ Proud Mentor|Battlebond|20|U|{2}{W}|Creature - Human Warrior|1|1|Partner with Im Ley Weaver|Battlebond|21|U|{3}{G}|Creature - Human Druid|2|2|Partner with Lore Weaver (When this creature enters the battlefield, target player may put Lore Weaver into their hand from their library, then shuffle.)${T}: Untap two target lands.| Lore Weaver|Battlebond|22|U|{3}{U}|Creature - Human Wizard|2|2|Partner with Ley Weaver (When this creature enters the battlefield, target player may put Ley Weaver into their hand from their library, then shuffle.)${5}{U}{U}: Target player draws two cards.| Arena Rector|Battlebond|23|M|{3}{W}|Creature - Human Cleric|1|2|When Arena Rector dies, you may exile it. If you do, search your library for a planeswalker card, put it onto the battlefield, then shuffle your library.| -Dwarven Lightsmith|Battlebond|27|C|{5}{W}|Creature - Dwarf Cleric|3|4|Assist (Another player can pay up to {5} of this spell's cost.)$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| +Dwarven Lightsmith|Battlebond|27|C|{5}{W}|Creature - Dwarf Cleric|3|4|Assist$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| Jubilant Mascot|Battlebond|28|U|{2}{W}|Creature - Homunculus|1|1|At the beginning of combat on your turn, you may pay {3}{W}. If you do, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| -Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist (Another player can pay up to {6} of this spell's cost.)$Exile all nonland permanents.| +Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist$Exile all nonland permanents.| Regna's Sanction|Battlebond|30|R|{3}{W}|Sorcery|||For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest.| -Skystreamer|Battlebond|31|C|{4}{W}|Creature - Griffin|3|2|Assist (Another player can pay up to {4} of this spell's cost.)$Flying$When Skystreamer enters the battlefield, target player gains 4 life.| +Skystreamer|Battlebond|31|C|{4}{W}|Creature - Griffin|3|2|Assist$Flying$When Skystreamer enters the battlefield, target player gains 4 life.| Together Forever|Battlebond|32|R|{W}{W}|Enchantment|||When Together Forever enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)${1}: Choose target creature with a counter on it. When that creature dies this turn, return that card to its owner's hand.| Fumble|Battlebond|34|U|{1}{U}|Instant|||Return target creature to its owner's hand. Gain control of all Auras and Equipment that were attached to it, then attach them to another creature.| -Game Plan|Battlebond|35|R|{5}{U}|Sorcery|||Assist (Another player can pay up to {5} of this spell's cost.)$Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Game Plan.| -Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist (Another player can pay up to {2} of this spell's cost.)$Two target players each draw a card.| -Out of Bounds|Battlebond|38|C|{3}{U}|Instant|||Assist (Another player can pay up to {3} of this spell's cost.)$Counter target spell.| +Game Plan|Battlebond|35|R|{5}{U}|Sorcery|||Assist$Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Game Plan.| +Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist$Two target players each draw a card.| +Out of Bounds|Battlebond|38|C|{3}{U}|Instant|||Assist$Counter target spell.| Saltwater Stalwart|Battlebond|39|C|{3}{U}|Creature - Merfolk Warrior|2|4|Whenever Saltwater Stalwart deals damage to an opponent, target player draws a card.| Soaring Show-Off|Battlebond|40|C|{2}{U}|Creature - Bird Warrior|2|2|Flying$When Soaring Show-Off enters the battlefield, each player draws a card.| Spellseeker|Battlebond|41|R|{2}{U}|Creature - Human Wizard|1|1|When Spellseeker enters the battlefield, you may search your library for an instant or sorcery card with converted mana cost 2 or less, reveal it, put it into your hand, then shuffle your library.| Archfiend of Despair|Battlebond|44|M|{6}{B}{B}|Creature - Demon|6|6|Flying$Your opponents can't gain life.$At the beginning of each end step, each opponent loses life equal to the life that player lost this turn. (Damage causes loss of life.)| -Fan Favorite|Battlebond|46|C|{3}{B}|Creature - Human Rogue|2|2|Assist (Another player can pay up to {3} of this spell's cost.)${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| -Gang Up|Battlebond|47|U|{X}{B}|Instant|||Assist (Another player can pay up to {X} of this spell's cost. You choose the value of X.)$Destroy target creature with power X or less.| +Fan Favorite|Battlebond|46|C|{3}{B}|Creature - Human Rogue|2|2|Assist${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| +Gang Up|Battlebond|47|U|{X}{B}|Instant|||Assist$Destroy target creature with power X or less.| Inner Demon|Battlebond|48|U|{2}{B}{B}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +2/+2, has flying, and is a Demon in addition to its other types.$When Inner Demon enters the battlefield, all non-Demon creatures get -2/-2 until end of turn.| Mindblade Render|Battlebond|49|R|{1}{B}|Creature - Azra Warrior|1|3|Whenever your opponents are dealt combat damage, if any of that damage was dealt by a Warrior, you draw a card and you lose 1 life.| Sickle Dancer|Battlebond|50|C|{2}{B}|Creature - Human Warrior|3|2|Whenever Sickle Dancer attacks, if your team controls another Warrior, Sickle Dancer gets +1/+1 until end of turn.| @@ -33405,12 +33405,12 @@ Thrasher Brute|Battlebond|52|U|{3}{B}|Creature - Orc Warrior|4|3|Whenever Thrash Virtus's Maneuver|Battlebond|54|R|{2}{B}|Sorcery|||For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control.| Cheering Fanatic|Battlebond|58|U|{1}{R}|Creature - Goblin|2|2|Whenever Cheering Fanatic attacks, choose a card name. Spells with the chosen name cost {1} less to cast this turn.| Khorvath's Fury|Battlebond|59|R|{4}{R}|Sorcery|||For each player, choose friend or foe. Each friend discards all cards from their hand, then draws that many cards plus one. Khorvath's Fury deals damage to each foe equal to the number of cards in their hand.| -Lava-Field Overlord|Battlebond|60|U|{7}{R}{R}|Creature - Dragon|5|4|Assist (Another player can pay up to {7} of this spell's cost.)$Flying$When Lava-Field Overlord enters the battlefield, it deals 4 damage to target creature an opponent controls.| +Lava-Field Overlord|Battlebond|60|U|{7}{R}{R}|Creature - Dragon|5|4|Assist$Flying$When Lava-Field Overlord enters the battlefield, it deals 4 damage to target creature an opponent controls.| Stadium Vendors|Battlebond|63|C|{3}{R}|Creature - Goblin|3|3|When Stadium Vendors enters the battlefield, choose a player. That player adds two mana of any one color they choose.| Stolen Strategy|Battlebond|64|R|{4}{R}|Enchantment|||At the beginning of your upkeep, exile the top card of each opponent's library. Until end of turn, you may cast nonland cards from among those exiled cards, and you may spend mana as though it were mana of any color to cast those spells.| Bramble Sovereign|Battlebond|65|M|{2}{G}{G}|Creature - Dryad|4|4|Whenever another nontoken creature enters the battlefield, you may pay {1}{G}. If you do, that creature's controller creates a token that's a copy of that creature.| -Charging Binox|Battlebond|66|C|{7}{G}|Creature - Beast|7|5|Assist (Another player can pay up to {7} of this spell's cost.)$Trample| -The Crowd Goes Wild|Battlebond|68|U|{X}{G}|Sorcery|||Assist (Another player can pay up to {X} of this spell's cost. You choose the value of X.)$Support X. (Put a +1/+1 counter on each of up to X target creatures.)$Each creature with a +1/+1 counter on it gains trample until end of turn.| +Charging Binox|Battlebond|66|C|{7}{G}|Creature - Beast|7|5|Assist$Trample| +The Crowd Goes Wild|Battlebond|68|U|{X}{G}|Sorcery|||Assist$Each creature with a +1/+1 counter on it gains trample until end of turn.| Generous Patron|Battlebond|70|R|{2}{G}|Creature - Elf Advisor|1|4|When Generous Patron enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)$Whenever you put one or more counters on a creature you don't control, draw a card.| Grothama, All-Devouring|Battlebond|71|M|{3}{G}{G}|Legendary Creature - Wurm|10|8|Other creatures have "Whenever this creature attacks, you may have it fight Grothama, All-Devouring."$When Grothama leaves the battlefield, each player draws cards equal to the amount of damage dealt to Grothama this turn by sources they controlled.| Jungle Wayfinder|Battlebond|72|C|{2}{G}|Creature - Elf Warrior|3|3|When Jungle Wayfinder enters the battlefield, each player may search their library for a basic land card, reveal it, put it into their hand, then shuffle their library.| From f4ba06f908ec38a10fd75660f4adcc3edf7120ea Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 11:20:30 -0400 Subject: [PATCH 078/154] Implemented Blaring Captain --- .../src/mage/cards/b/BlaringCaptain.java | 78 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 79 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BlaringCaptain.java diff --git a/Mage.Sets/src/mage/cards/b/BlaringCaptain.java b/Mage.Sets/src/mage/cards/b/BlaringCaptain.java new file mode 100644 index 0000000000..d4fac2282f --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BlaringCaptain.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AttackingPredicate; + +/** + * + * @author TheElk801 + */ +public class BlaringCaptain extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.WARRIOR, "attacking Warriors"); + + static { + filter.add(new AttackingPredicate()); + } + + public BlaringCaptain(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.AZRA); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Partner with Blaring Recruiter (When this creature enters the battlefield, target player may put Blaring Recruiter into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Blaring Recruiter")); + + // Whenever Blaring Captain attacks, attacking Warriors get +1/+1 until end of turn. + this.addAbility(new AttacksTriggeredAbility(new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false), false)); + } + + public BlaringCaptain(final BlaringCaptain card) { + super(card); + } + + @Override + public BlaringCaptain copy() { + return new BlaringCaptain(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 4ad3843851..ee62fe2287 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -58,6 +58,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Arena Rector", 23, Rarity.MYTHIC, mage.cards.a.ArenaRector.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); cards.add(new SetCardInfo("Beast Within", 190, Rarity.UNCOMMON, mage.cards.b.BeastWithin.class)); + cards.add(new SetCardInfo("Blaring Captain", 14, Rarity.UNCOMMON, mage.cards.b.BlaringCaptain.class)); cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); From 65d39c8f1b0668d24f612b5dc053e57a17d1f371 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 11:23:29 -0400 Subject: [PATCH 079/154] Implemented Blaring Recruiter --- .../src/mage/cards/b/BlaringRecruiter.java | 71 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 72 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BlaringRecruiter.java diff --git a/Mage.Sets/src/mage/cards/b/BlaringRecruiter.java b/Mage.Sets/src/mage/cards/b/BlaringRecruiter.java new file mode 100644 index 0000000000..bc3e0a34b5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BlaringRecruiter.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.PartnerWithAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.WarriorToken; + +/** + * + * @author TheElk801 + */ +public class BlaringRecruiter extends CardImpl { + + public BlaringRecruiter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Partner with Blaring Captain (When this creature enters the battlefield, target player may put Blaring Captain into their hand from their library, then shuffle.) + this.addAbility(new PartnerWithAbility("Blaring Captain")); + + // {2}{W}: Create a 1/1 white Warrior creature token. + this.addAbility(new SimpleActivatedAbility(new CreateTokenEffect(new WarriorToken()), new ManaCostsImpl("{2}{W}"))); + } + + public BlaringRecruiter(final BlaringRecruiter card) { + super(card); + } + + @Override + public BlaringRecruiter copy() { + return new BlaringRecruiter(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index ee62fe2287..9c46f56fe9 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -59,6 +59,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); cards.add(new SetCardInfo("Beast Within", 190, Rarity.UNCOMMON, mage.cards.b.BeastWithin.class)); cards.add(new SetCardInfo("Blaring Captain", 14, Rarity.UNCOMMON, mage.cards.b.BlaringCaptain.class)); + cards.add(new SetCardInfo("Blaring Recruiter", 13, Rarity.UNCOMMON, mage.cards.b.BlaringRecruiter.class)); cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); From d829c7458c48e11d15d2d94f9aa2b486bf72c845 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 11:28:57 -0400 Subject: [PATCH 080/154] Implemented Skystreamer --- Mage.Sets/src/mage/cards/s/Skystreamer.java | 76 +++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 77 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/Skystreamer.java diff --git a/Mage.Sets/src/mage/cards/s/Skystreamer.java b/Mage.Sets/src/mage/cards/s/Skystreamer.java new file mode 100644 index 0000000000..9c65c2411d --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Skystreamer.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.GainLifeTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.AssistAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetPlayer; + +/** + * + * @author TheElk801 + */ +public class Skystreamer extends CardImpl { + + public Skystreamer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); + + this.subtype.add(SubType.GRIFFIN); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Assist + this.addAbility(new AssistAbility()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Skystreamer enters the battlefield, target player gains 4 life. + Ability ability = new EntersBattlefieldTriggeredAbility(new GainLifeTargetEffect(4), false); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + } + + public Skystreamer(final Skystreamer card) { + super(card); + } + + @Override + public Skystreamer copy() { + return new Skystreamer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 9c46f56fe9..6105a5c224 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -115,6 +115,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); cards.add(new SetCardInfo("Sickle Dancer", 50, Rarity.COMMON, mage.cards.s.SickleDancer.class)); cards.add(new SetCardInfo("Skyshroud Claim", 213, Rarity.COMMON, mage.cards.s.SkyshroudClaim.class)); + cards.add(new SetCardInfo("Skystreamer", 31, Rarity.COMMON, mage.cards.s.Skystreamer.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); From 65a1efa6c0a083bee0a85954802b183c5a053e3b Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 11:29:43 -0400 Subject: [PATCH 081/154] Implemented Out of Bounds --- Mage.Sets/src/mage/cards/o/OutOfBounds.java | 63 +++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 64 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/OutOfBounds.java diff --git a/Mage.Sets/src/mage/cards/o/OutOfBounds.java b/Mage.Sets/src/mage/cards/o/OutOfBounds.java new file mode 100644 index 0000000000..7cf5b0adeb --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OutOfBounds.java @@ -0,0 +1,63 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.o; + +import java.util.UUID; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.abilities.keyword.AssistAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetSpell; + +/** + * + * @author TheElk801 + */ +public class OutOfBounds extends CardImpl { + + public OutOfBounds(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}"); + + // Assist + this.addAbility(new AssistAbility()); + + // Counter target spell. + this.getSpellAbility().addEffect(new CounterTargetEffect()); + this.getSpellAbility().addTarget(new TargetSpell()); + } + + public OutOfBounds(final OutOfBounds card) { + super(card); + } + + @Override + public OutOfBounds copy() { + return new OutOfBounds(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 6105a5c224..9278132871 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -101,6 +101,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nirkana Revenant", 150, Rarity.MYTHIC, mage.cards.n.NirkanaRevenant.class)); cards.add(new SetCardInfo("Okaun, Eye of Chaos", 6, Rarity.RARE, mage.cards.o.OkaunEyeOfChaos.class)); + cards.add(new SetCardInfo("Out of Bounds", 38, Rarity.COMMON, mage.cards.o.OutOfBounds.class)); cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); cards.add(new SetCardInfo("Pir's Whim", 73, Rarity.RARE, mage.cards.p.PirsWhim.class)); cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); From 728a881f069b9173b3045486ba38c0f946dddf23 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 11:34:31 -0400 Subject: [PATCH 082/154] Implemented Play of the Game --- Mage.Sets/src/mage/cards/p/PerilousVault.java | 48 +++----------- Mage.Sets/src/mage/cards/p/PlayOfTheGame.java | 62 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + .../main/java/mage/filter/StaticFilters.java | 6 ++ 4 files changed, 77 insertions(+), 40 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/p/PlayOfTheGame.java diff --git a/Mage.Sets/src/mage/cards/p/PerilousVault.java b/Mage.Sets/src/mage/cards/p/PerilousVault.java index 22b7457e15..b34e9e7e28 100644 --- a/Mage.Sets/src/mage/cards/p/PerilousVault.java +++ b/Mage.Sets/src/mage/cards/p/PerilousVault.java @@ -33,17 +33,12 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.ExileSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterNonlandPermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; +import mage.filter.StaticFilters; /** * @@ -52,10 +47,14 @@ import mage.players.Player; public class PerilousVault extends CardImpl { public PerilousVault(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); // {5}, {T}, Exile Perilous Vault: Exile all nonland permanents. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PerilousVaultEffect(), new GenericManaCost(5)); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new ExileAllEffect(StaticFilters.FILTER_PERMANENTS_NON_LAND), + new GenericManaCost(5) + ); ability.addCost(new TapSourceCost()); ability.addCost(new ExileSourceCost()); this.addAbility(ability); @@ -70,34 +69,3 @@ public class PerilousVault extends CardImpl { return new PerilousVault(this); } } - -class PerilousVaultEffect extends OneShotEffect { - - private static final FilterPermanent filter = new FilterNonlandPermanent(); - - PerilousVaultEffect() { - super(Outcome.Exile); - this.staticText = "Exile all nonland permanents"; - } - - PerilousVaultEffect(final PerilousVaultEffect effect) { - super(effect); - } - - @Override - public PerilousVaultEffect copy() { - return new PerilousVaultEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { - controller.moveCardToExileWithInfo(permanent, null, "", source.getSourceId(), game, Zone.HAND, true); - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/p/PlayOfTheGame.java b/Mage.Sets/src/mage/cards/p/PlayOfTheGame.java new file mode 100644 index 0000000000..bc8648e68a --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PlayOfTheGame.java @@ -0,0 +1,62 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.abilities.effects.common.ExileAllEffect; +import mage.abilities.keyword.AssistAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; + +/** + * + * @author TheElk801 + */ +public class PlayOfTheGame extends CardImpl { + + public PlayOfTheGame(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{W}{W}"); + + // Assist + this.addAbility(new AssistAbility()); + + // Exile all nonland permanents. + this.getSpellAbility().addEffect(new ExileAllEffect(StaticFilters.FILTER_PERMANENTS_NON_LAND)); + } + + public PlayOfTheGame(final PlayOfTheGame card) { + super(card); + } + + @Override + public PlayOfTheGame copy() { + return new PlayOfTheGame(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 9278132871..b739ed03d7 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -106,6 +106,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Pir's Whim", 73, Rarity.RARE, mage.cards.p.PirsWhim.class)); cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); cards.add(new SetCardInfo("Plains", 250, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Play of the Game", 29, Rarity.RARE, mage.cards.p.PlayOfTheGame.class)); cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); cards.add(new SetCardInfo("Regna, the Redeemer", 3, Rarity.RARE, mage.cards.r.RegnaTheRedeemer.class)); cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 7ef7ed806b..e540945a42 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -357,6 +357,12 @@ public final class StaticFilters { FILTER_PERMANENT_NON_LAND.setLockedFilter(true); } + public static final FilterPermanent FILTER_PERMANENTS_NON_LAND = new FilterNonlandPermanent("nonland permanents"); + + static { + FILTER_PERMANENTS_NON_LAND.setLockedFilter(true); + } + public static final FilterCreatureSpell FILTER_SPELL_A_CREATURE = new FilterCreatureSpell("a creature spell"); static { From 0c742fa2b0d7ddd545620ef6ecae7549ba37c7a4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 11:37:44 -0400 Subject: [PATCH 083/154] Implemented Dwarven Lightsmith --- .../src/mage/cards/d/DwarvenLightsmith.java | 80 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 81 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DwarvenLightsmith.java diff --git a/Mage.Sets/src/mage/cards/d/DwarvenLightsmith.java b/Mage.Sets/src/mage/cards/d/DwarvenLightsmith.java new file mode 100644 index 0000000000..49b5f81b0d --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DwarvenLightsmith.java @@ -0,0 +1,80 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.constants.SubType; +import mage.abilities.keyword.AssistAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class DwarvenLightsmith extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures your team controls"); + + static { + filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); + } + + public DwarvenLightsmith(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); + + this.subtype.add(SubType.DWARF); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Assist + this.addAbility(new AssistAbility()); + + // When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn. + this.addAbility(new EntersBattlefieldTriggeredAbility(new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false))); + } + + public DwarvenLightsmith(final DwarvenLightsmith card) { + super(card); + } + + @Override + public DwarvenLightsmith copy() { + return new DwarvenLightsmith(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index b739ed03d7..051c840f1f 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -74,6 +74,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Doomed Dissenter", 142, Rarity.COMMON, mage.cards.d.DoomedDissenter.class)); cards.add(new SetCardInfo("Doomed Traveler", 91, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); cards.add(new SetCardInfo("Doubling Season", 195, Rarity.MYTHIC, mage.cards.d.DoublingSeason.class)); + cards.add(new SetCardInfo("Dwarven Lightsmith", 27, Rarity.COMMON, mage.cards.d.DwarvenLightsmith.class)); cards.add(new SetCardInfo("Eager Construct", 234, Rarity.COMMON, mage.cards.e.EagerConstruct.class)); cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); From 1dfe0d8d0a6c25e5a56ddeb2f0a492b4b1c89354 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 11:42:00 -0400 Subject: [PATCH 084/154] Implemented Fan Favorite --- Mage.Sets/src/mage/cards/f/FanFavorite.java | 76 +++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 77 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FanFavorite.java diff --git a/Mage.Sets/src/mage/cards/f/FanFavorite.java b/Mage.Sets/src/mage/cards/f/FanFavorite.java new file mode 100644 index 0000000000..d45b13cb12 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FanFavorite.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.ActivatedAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.constants.SubType; +import mage.abilities.keyword.AssistAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; + +/** + * + * @author TheElk801 + */ +public class FanFavorite extends CardImpl { + + public FanFavorite(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Assist + this.addAbility(new AssistAbility()); + + // {2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability. + ActivatedAbility ability = new SimpleActivatedAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn), new GenericManaCost(2)); + ability.setMayActivate(TargetController.ANY); + ability.addEffect(new InfoEffect("Any player may activate this ability")); + } + + public FanFavorite(final FanFavorite card) { + super(card); + } + + @Override + public FanFavorite copy() { + return new FanFavorite(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 051c840f1f..b2919be68f 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -77,6 +77,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Dwarven Lightsmith", 27, Rarity.COMMON, mage.cards.d.DwarvenLightsmith.class)); cards.add(new SetCardInfo("Eager Construct", 234, Rarity.COMMON, mage.cards.e.EagerConstruct.class)); cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); + cards.add(new SetCardInfo("Fan Favorite", 46, Rarity.COMMON, mage.cards.f.FanFavorite.class)); cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Generous Patron", 70, Rarity.RARE, mage.cards.g.GenerousPatron.class)); From 8fb03574e60ec7e6c909bc09f20dcc7fedc0da2a Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 11:55:00 -0400 Subject: [PATCH 085/154] Implemented Game Plan, added new class for Timetwister effects --- Mage.Sets/src/mage/cards/c/CommitMemory.java | 35 +--------- Mage.Sets/src/mage/cards/d/DaysUndoing.java | 44 +----------- Mage.Sets/src/mage/cards/g/GamePlan.java | 68 +++++++++++++++++++ .../mage/cards/j/JaceTheLivingGuildpact.java | 55 ++------------- Mage.Sets/src/mage/cards/m/MineMineMine.java | 43 ++---------- .../src/mage/cards/t/TemporalCascade.java | 53 +++------------ Mage.Sets/src/mage/cards/t/TimeReversal.java | 43 +----------- Mage.Sets/src/mage/cards/t/Timetwister.java | 42 +----------- Mage.Sets/src/mage/sets/Battlebond.java | 1 + .../common/ShuffleHandGraveyardAllEffect.java | 45 ++++++++++++ 10 files changed, 145 insertions(+), 284 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/g/GamePlan.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/ShuffleHandGraveyardAllEffect.java diff --git a/Mage.Sets/src/mage/cards/c/CommitMemory.java b/Mage.Sets/src/mage/cards/c/CommitMemory.java index 88a3bfed1d..756f2dacc5 100644 --- a/Mage.Sets/src/mage/cards/c/CommitMemory.java +++ b/Mage.Sets/src/mage/cards/c/CommitMemory.java @@ -32,6 +32,7 @@ import mage.abilities.Ability; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardAllEffect; +import mage.abilities.effects.common.ShuffleHandGraveyardAllEffect; import mage.abilities.keyword.AftermathAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -39,7 +40,6 @@ import mage.cards.SplitCard; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SpellAbilityType; -import mage.constants.Zone; import mage.filter.common.FilterNonlandPermanent; import mage.filter.common.FilterSpellOrPermanent; import mage.game.Game; @@ -72,7 +72,7 @@ public class CommitMemory extends SplitCard { // Aftermath // Each player shuffles their hand and graveyard into their library, then draws seven cards. ((CardImpl) (getRightHalfCard())).addAbility(new AftermathAbility().setRuleAtTheTop(true)); - getRightHalfCard().getSpellAbility().addEffect(new MemoryEffect()); + getRightHalfCard().getSpellAbility().addEffect(new ShuffleHandGraveyardAllEffect()); Effect effect = new DrawCardAllEffect(7); effect.setText(", then draws seven cards"); getRightHalfCard().getSpellAbility().addEffect(effect); @@ -120,34 +120,3 @@ class CommitEffect extends OneShotEffect { return false; } } - -class MemoryEffect extends OneShotEffect { - - public MemoryEffect() { - super(Outcome.Neutral); - staticText = "Each player shuffles their hand and graveyard into their library"; - } - - public MemoryEffect(final MemoryEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - player.moveCards(player.getHand(), Zone.LIBRARY, source, game); - player.moveCards(player.getGraveyard(), Zone.LIBRARY, source, game); - player.shuffleLibrary(source, game); - } - } - return true; - } - - @Override - public MemoryEffect copy() { - return new MemoryEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/d/DaysUndoing.java b/Mage.Sets/src/mage/cards/d/DaysUndoing.java index b43324d297..380c7a8a72 100644 --- a/Mage.Sets/src/mage/cards/d/DaysUndoing.java +++ b/Mage.Sets/src/mage/cards/d/DaysUndoing.java @@ -28,20 +28,15 @@ package mage.cards.d; import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.condition.common.MyTurnCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardAllEffect; import mage.abilities.effects.common.EndTurnEffect; +import mage.abilities.effects.common.ShuffleHandGraveyardAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.game.Game; -import mage.players.Player; /** * @@ -50,10 +45,10 @@ import mage.players.Player; public class DaysUndoing extends CardImpl { public DaysUndoing(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}"); // Each player shuffles their hand and graveyard into their library, then draws seven cards. If it's your turn, end the turn. - this.getSpellAbility().addEffect(new DaysUndoingEffect()); + this.getSpellAbility().addEffect(new ShuffleHandGraveyardAllEffect()); Effect effect = new DrawCardAllEffect(7); effect.setText(", then draws seven cards"); this.getSpellAbility().addEffect(effect); @@ -69,36 +64,3 @@ public class DaysUndoing extends CardImpl { return new DaysUndoing(this); } } - -class DaysUndoingEffect extends OneShotEffect { - - public DaysUndoingEffect() { - super(Outcome.Neutral); - staticText = "Each player shuffles their hand and graveyard into their library"; - } - - public DaysUndoingEffect(final DaysUndoingEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - player.moveCards(player.getHand(), Zone.LIBRARY, source, game); - player.moveCards(player.getGraveyard(), Zone.LIBRARY, source, game); - player.shuffleLibrary(source, game); - - } - } - return true; - } - - @Override - public DaysUndoingEffect copy() { - return new DaysUndoingEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/g/GamePlan.java b/Mage.Sets/src/mage/cards/g/GamePlan.java new file mode 100644 index 0000000000..e7932168a8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GamePlan.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DrawCardAllEffect; +import mage.abilities.effects.common.ExileSpellEffect; +import mage.abilities.effects.common.ShuffleHandGraveyardAllEffect; +import mage.abilities.keyword.AssistAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class GamePlan extends CardImpl { + + public GamePlan(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{U}"); + + // Assist + this.addAbility(new AssistAbility()); + + // Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Game Plan. + this.getSpellAbility().addEffect(new ShuffleHandGraveyardAllEffect()); + Effect effect = new DrawCardAllEffect(7); + effect.setText(", then draws seven cards"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addEffect(ExileSpellEffect.getInstance()); + } + + public GamePlan(final GamePlan card) { + super(card); + } + + @Override + public GamePlan copy() { + return new GamePlan(this); + } +} diff --git a/Mage.Sets/src/mage/cards/j/JaceTheLivingGuildpact.java b/Mage.Sets/src/mage/cards/j/JaceTheLivingGuildpact.java index 03a62fd8bf..07bbedf7b0 100644 --- a/Mage.Sets/src/mage/cards/j/JaceTheLivingGuildpact.java +++ b/Mage.Sets/src/mage/cards/j/JaceTheLivingGuildpact.java @@ -28,28 +28,24 @@ package mage.cards.j; import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.cards.Card; +import mage.abilities.effects.common.ShuffleHandGraveyardAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Outcome; import mage.constants.SuperType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.FilterPermanent; import mage.filter.common.FilterNonlandPermanent; import mage.filter.predicate.permanent.AnotherPredicate; -import mage.game.Game; -import mage.players.Player; import mage.target.TargetPermanent; /** @@ -65,7 +61,7 @@ public class JaceTheLivingGuildpact extends CardImpl { } public JaceTheLivingGuildpact(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{2}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{U}{U}"); this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.JACE); @@ -83,7 +79,8 @@ public class JaceTheLivingGuildpact extends CardImpl { this.addAbility(ability); // -8: Each player shuffles their hand and graveyard into their library. You draw seven cards. - this.addAbility(new LoyaltyAbility(new JaceTheLivingGuildpactEffect(), -8)); + ability = new LoyaltyAbility(new ShuffleHandGraveyardAllEffect(), -8); + ability.addEffect(new DrawCardSourceControllerEffect(7).setText("You draw seven cards")); } @@ -96,45 +93,3 @@ public class JaceTheLivingGuildpact extends CardImpl { return new JaceTheLivingGuildpact(this); } } - -class JaceTheLivingGuildpactEffect extends OneShotEffect { - - public JaceTheLivingGuildpactEffect() { - super(Outcome.Neutral); - staticText = "Each player shuffles their hand and graveyard into their library. You draw seven cards"; - } - - public JaceTheLivingGuildpactEffect(final JaceTheLivingGuildpactEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - for (Card card : player.getHand().getCards(game)) { - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } - for (Card card : player.getGraveyard().getCards(game)) { - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } - player.shuffleLibrary(source, game); - } - } - controller.drawCards(7, game); - return true; - - } - return false; - - } - - @Override - public JaceTheLivingGuildpactEffect copy() { - return new JaceTheLivingGuildpactEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/m/MineMineMine.java b/Mage.Sets/src/mage/cards/m/MineMineMine.java index e5b7648e21..c364c2989d 100644 --- a/Mage.Sets/src/mage/cards/m/MineMineMine.java +++ b/Mage.Sets/src/mage/cards/m/MineMineMine.java @@ -34,6 +34,7 @@ import mage.abilities.common.LeavesBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.ShuffleHandGraveyardAllEffect; import mage.abilities.effects.common.continuous.CantCastMoreThanOneSpellEffect; import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect; import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect.HandSizeModification; @@ -56,22 +57,22 @@ import mage.players.Player; public class MineMineMine extends CardImpl { public MineMineMine(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}{G}"); // When Mine, Mine, Mine enters the battlefield, each player puts his or her library into his or her hand. this.addAbility(new EntersBattlefieldTriggeredAbility(new MineMineMineDrawEffect())); // Players have no maximum hand size and don't lose the game for drawing from an empty library. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MaximumHandSizeControllerEffect(Integer.MAX_VALUE, Duration.WhileOnBattlefield, HandSizeModification.SET, TargetController.ANY) - .setText("Players have no maximum hand size and don't lose the game for drawing from an empty library"))); + .setText("Players have no maximum hand size and don't lose the game for drawing from an empty library"))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MineMineMineDontLoseEffect())); // Each player can't cast more than one spell each turn. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantCastMoreThanOneSpellEffect(TargetController.ANY))); - + // When Mine, Mine, Mine leaves the battlefield, each player shuffles his or her hand and graveyard into his or her library. - this.addAbility(new LeavesBattlefieldTriggeredAbility(new MineMineMineShuffleEffect(), false)); + this.addAbility(new LeavesBattlefieldTriggeredAbility(new ShuffleHandGraveyardAllEffect(), false)); } public MineMineMine(final MineMineMine card) { @@ -133,7 +134,7 @@ class MineMineMineDontLoseEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { return true; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.DRAW_CARD; @@ -148,33 +149,3 @@ class MineMineMineDontLoseEffect extends ReplacementEffectImpl { return false; } } - -class MineMineMineShuffleEffect extends OneShotEffect { - - public MineMineMineShuffleEffect() { - super(Outcome.Neutral); - staticText = "each player shuffles his or her hand and graveyard into his or her library"; - } - - public MineMineMineShuffleEffect(final MineMineMineShuffleEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - player.moveCards(player.getHand(), Zone.LIBRARY, source, game); - player.moveCards(player.getGraveyard(), Zone.LIBRARY, source, game); - player.shuffleLibrary(source, game); - } - } - return true; - } - - @Override - public MineMineMineShuffleEffect copy() { - return new MineMineMineShuffleEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TemporalCascade.java b/Mage.Sets/src/mage/cards/t/TemporalCascade.java index e85e24176c..13f55fde6e 100644 --- a/Mage.Sets/src/mage/cards/t/TemporalCascade.java +++ b/Mage.Sets/src/mage/cards/t/TemporalCascade.java @@ -31,13 +31,12 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ShuffleHandGraveyardAllEffect; import mage.abilities.keyword.EntwineAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -48,16 +47,16 @@ import mage.players.Player; public class TemporalCascade extends CardImpl { public TemporalCascade(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{U}{U}"); // Choose one - Each player shuffles their hand and graveyard into their library; - this.getSpellAbility().addEffect(new TemporalCascadeShuffleEffect()); - + this.getSpellAbility().addEffect(new ShuffleHandGraveyardAllEffect()); + // or each player draws seven cards. Mode mode = new Mode(); mode.getEffects().add(new TemporalCascadeDrawEffect()); this.getSpellAbility().getModes().addMode(mode); - + // Entwine {2} this.addAbility(new EntwineAbility("{2}")); } @@ -72,42 +71,6 @@ public class TemporalCascade extends CardImpl { } } -class TemporalCascadeShuffleEffect extends OneShotEffect { - - public TemporalCascadeShuffleEffect() { - super(Outcome.Neutral); - staticText = "Each player shuffles their hand and graveyard into their library"; - } - - public TemporalCascadeShuffleEffect(final TemporalCascadeShuffleEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player sourcePlayer = game.getPlayer(source.getControllerId()); - for (UUID playerId: game.getState().getPlayersInRange(sourcePlayer.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - for (Card card: player.getHand().getCards(game)) { - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } - for (Card card: player.getGraveyard().getCards(game)) { - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } - player.shuffleLibrary(source, game); - - } - } - return true; - } - - @Override - public TemporalCascadeShuffleEffect copy() { - return new TemporalCascadeShuffleEffect(this); - } -} - class TemporalCascadeDrawEffect extends OneShotEffect { public TemporalCascadeDrawEffect() { @@ -123,11 +86,11 @@ class TemporalCascadeDrawEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player sourcePlayer = game.getPlayer(source.getControllerId()); game.getState().handleSimultaneousEvent(game); // needed here so state based triggered effects - for (UUID playerId: game.getState().getPlayersInRange(sourcePlayer.getId(), game)) { + for (UUID playerId : game.getState().getPlayersInRange(sourcePlayer.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { player.drawCards(7, game); - } + } } return true; } @@ -136,4 +99,4 @@ class TemporalCascadeDrawEffect extends OneShotEffect { public TemporalCascadeDrawEffect copy() { return new TemporalCascadeDrawEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/t/TimeReversal.java b/Mage.Sets/src/mage/cards/t/TimeReversal.java index 50c7b8dda6..8890323d35 100644 --- a/Mage.Sets/src/mage/cards/t/TimeReversal.java +++ b/Mage.Sets/src/mage/cards/t/TimeReversal.java @@ -28,18 +28,13 @@ package mage.cards.t; import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardAllEffect; import mage.abilities.effects.common.ExileSpellEffect; +import mage.abilities.effects.common.ShuffleHandGraveyardAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.game.Game; -import mage.players.Player; /** * @@ -48,10 +43,10 @@ import mage.players.Player; public class TimeReversal extends CardImpl { public TimeReversal(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}{U}"); // Each player shuffles their hand and graveyard into their library, then draws seven cards - this.getSpellAbility().addEffect(new TimeReversalEffect()); + this.getSpellAbility().addEffect(new ShuffleHandGraveyardAllEffect()); Effect effect = new DrawCardAllEffect(7); effect.setText(", then draws seven cards"); this.getSpellAbility().addEffect(effect); @@ -67,35 +62,3 @@ public class TimeReversal extends CardImpl { return new TimeReversal(this); } } - -class TimeReversalEffect extends OneShotEffect { - - public TimeReversalEffect() { - super(Outcome.Neutral); - staticText = "Each player shuffles their hand and graveyard into their library, then draws seven cards"; - } - - public TimeReversalEffect(final TimeReversalEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - player.moveCards(player.getHand(), Zone.LIBRARY, source, game); - player.moveCards(player.getGraveyard(), Zone.LIBRARY, source, game); - player.shuffleLibrary(source, game); - } - } - return true; - } - - @Override - public TimeReversalEffect copy() { - return new TimeReversalEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/t/Timetwister.java b/Mage.Sets/src/mage/cards/t/Timetwister.java index 7f5243640a..e7cee27584 100644 --- a/Mage.Sets/src/mage/cards/t/Timetwister.java +++ b/Mage.Sets/src/mage/cards/t/Timetwister.java @@ -28,17 +28,12 @@ package mage.cards.t; import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardAllEffect; +import mage.abilities.effects.common.ShuffleHandGraveyardAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.game.Game; -import mage.players.Player; /** * @@ -47,10 +42,10 @@ import mage.players.Player; public class Timetwister extends CardImpl { public Timetwister(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}"); // Each player shuffles their hand and graveyard into their library, then draws seven cards. - this.getSpellAbility().addEffect(new TimetwisterEffect()); + this.getSpellAbility().addEffect(new ShuffleHandGraveyardAllEffect()); Effect effect = new DrawCardAllEffect(7); effect.setText(", then draws seven cards"); this.getSpellAbility().addEffect(effect); @@ -66,34 +61,3 @@ public class Timetwister extends CardImpl { return new Timetwister(this); } } - -class TimetwisterEffect extends OneShotEffect { - - public TimetwisterEffect() { - super(Outcome.Neutral); - staticText = "Each player shuffles their hand and graveyard into their library"; - } - - public TimetwisterEffect(final TimetwisterEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - player.moveCards(player.getHand(), Zone.LIBRARY, source, game); - player.moveCards(player.getGraveyard(), Zone.LIBRARY, source, game); - player.shuffleLibrary(source, game); - } - } - return true; - } - - @Override - public TimetwisterEffect copy() { - return new TimetwisterEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index b2919be68f..826413e1f5 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -80,6 +80,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Fan Favorite", 46, Rarity.COMMON, mage.cards.f.FanFavorite.class)); cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Game Plan", 35, Rarity.RARE, mage.cards.g.GamePlan.class)); cards.add(new SetCardInfo("Generous Patron", 70, Rarity.RARE, mage.cards.g.GenerousPatron.class)); cards.add(new SetCardInfo("Greater Good", 201, Rarity.RARE, mage.cards.g.GreaterGood.class)); cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/ShuffleHandGraveyardAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ShuffleHandGraveyardAllEffect.java new file mode 100644 index 0000000000..e764cc9216 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/ShuffleHandGraveyardAllEffect.java @@ -0,0 +1,45 @@ +package mage.abilities.effects.common; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class ShuffleHandGraveyardAllEffect extends OneShotEffect { + + public ShuffleHandGraveyardAllEffect() { + super(Outcome.Neutral); + staticText = "each player shuffles their hand and graveyard into their library"; + } + + public ShuffleHandGraveyardAllEffect(final ShuffleHandGraveyardAllEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + player.moveCards(player.getHand(), Zone.LIBRARY, source, game); + player.moveCards(player.getGraveyard(), Zone.LIBRARY, source, game); + player.shuffleLibrary(source, game); + } + } + return true; + } + + @Override + public ShuffleHandGraveyardAllEffect copy() { + return new ShuffleHandGraveyardAllEffect(this); + } + +} From c472750dec8a8c7204cb435b6dade1e9054438a3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 11:57:44 -0400 Subject: [PATCH 086/154] Implemented Lava-Field Overlord --- .../src/mage/cards/l/LavaFieldOverlord.java | 77 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 78 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LavaFieldOverlord.java diff --git a/Mage.Sets/src/mage/cards/l/LavaFieldOverlord.java b/Mage.Sets/src/mage/cards/l/LavaFieldOverlord.java new file mode 100644 index 0000000000..a5f1728fe6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LavaFieldOverlord.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.AssistAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class LavaFieldOverlord extends CardImpl { + + public LavaFieldOverlord(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{7}{R}{R}"); + + this.subtype.add(SubType.DRAGON); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // Assist + this.addAbility(new AssistAbility()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Lava-Field Overlord enters the battlefield, it deals 4 damage to target creature an opponent controls. + Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(4), false); + ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)); + this.addAbility(ability); + } + + public LavaFieldOverlord(final LavaFieldOverlord card) { + super(card); + } + + @Override + public LavaFieldOverlord copy() { + return new LavaFieldOverlord(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 826413e1f5..2df7a873e4 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -95,6 +95,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Krav, the Unredeemed", 4, Rarity.RARE, mage.cards.k.KravTheUnredeemed.class)); cards.add(new SetCardInfo("Land Tax", 94, Rarity.MYTHIC, mage.cards.l.LandTax.class)); cards.add(new SetCardInfo("Last One Standing", 76, Rarity.RARE, mage.cards.l.LastOneStanding.class)); + cards.add(new SetCardInfo("Lava-Field Overlord", 60, Rarity.UNCOMMON, mage.cards.l.LavaFieldOverlord.class)); cards.add(new SetCardInfo("Ley Weaver", 21, Rarity.UNCOMMON, mage.cards.l.LeyWeaver.class)); cards.add(new SetCardInfo("Lore Weaver", 22, Rarity.UNCOMMON, mage.cards.l.LoreWeaver.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); From a485291d066fa46a8605abf51758e977834bc973 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 11:59:59 -0400 Subject: [PATCH 087/154] Implemented Gang Up --- Mage.Sets/src/mage/cards/g/GangUp.java | 80 +++++++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 81 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GangUp.java diff --git a/Mage.Sets/src/mage/cards/g/GangUp.java b/Mage.Sets/src/mage/cards/g/GangUp.java new file mode 100644 index 0000000000..df6e9c37ea --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GangUp.java @@ -0,0 +1,80 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.AssistAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.game.Game; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class GangUp extends CardImpl { + + public GangUp(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{B}"); + + // Assist + this.addAbility(new AssistAbility()); + + // Destroy target creature with power X or less. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature with power X or less"))); + } + + public GangUp(final GangUp card) { + super(card); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if (ability instanceof SpellAbility) { + int xValue = ability.getManaCostsToPay().getX(); + ability.getTargets().clear(); + FilterCreaturePermanent filter = new FilterCreaturePermanent(new StringBuilder("creature with power ").append(xValue).append(" or less").toString()); + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, xValue + 1)); + ability.addTarget(new TargetCreaturePermanent(filter)); + } + } + + @Override + public GangUp copy() { + return new GangUp(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 2df7a873e4..63ad0ae7e0 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -81,6 +81,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Game Plan", 35, Rarity.RARE, mage.cards.g.GamePlan.class)); + cards.add(new SetCardInfo("Gang Up", 47, Rarity.UNCOMMON, mage.cards.g.GangUp.class)); cards.add(new SetCardInfo("Generous Patron", 70, Rarity.RARE, mage.cards.g.GenerousPatron.class)); cards.add(new SetCardInfo("Greater Good", 201, Rarity.RARE, mage.cards.g.GreaterGood.class)); cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); From 6140ec0719bbf8764c310b1a49ae9bb397445664 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 12:08:14 -0400 Subject: [PATCH 088/154] Implemented The Crowd Goes Wild --- .../src/mage/cards/t/TheCrowdGoesWild.java | 92 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 93 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java diff --git a/Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java b/Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java new file mode 100644 index 0000000000..ca3588b58a --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java @@ -0,0 +1,92 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.AssistAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.CounterPredicate; +import mage.game.Game; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class TheCrowdGoesWild extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with a +1/+1 counter on it"); + + static { + filter.add(new CounterPredicate(CounterType.P1P1)); + } + + public TheCrowdGoesWild(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{G}"); + + // Assist + this.addAbility(new AssistAbility()); + + // Support X (Put a +1/+1 counter on each of up to X target creatures.) + this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance()) + .setText("Support X <i>(Put a +1/+1 counter on each of up to X target creatures.)</i>") + ); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + // Each creature with a +1/+1 counter on it gains trample until end of turn. + this.getSpellAbility().addEffect(new GainAbilityAllEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, filter)); + } + + public TheCrowdGoesWild(final TheCrowdGoesWild card) { + super(card); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if (ability instanceof SpellAbility) { + ability.getTargets().clear(); + int xValue = ability.getManaCostsToPay().getX(); + ability.addTarget(new TargetCreaturePermanent(0, xValue)); + } + } + + @Override + public TheCrowdGoesWild copy() { + return new TheCrowdGoesWild(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 63ad0ae7e0..4f9952f65c 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -134,6 +134,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swords to Plowshares", 110, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); cards.add(new SetCardInfo("Sylvia Brightspear", 10, Rarity.RARE, mage.cards.s.SylviaBrightspear.class)); + cards.add(new SetCardInfo("The Crowd Goes Wild", 68, Rarity.UNCOMMON, mage.cards.t.TheCrowdGoesWild.class)); cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); cards.add(new SetCardInfo("Tidespout Tyrant", 134, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); From e153f0febaf70e83b521902c3e908cebfb80fc79 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 12:23:09 -0400 Subject: [PATCH 089/154] Implemented Huddle Up --- Mage.Sets/src/mage/cards/h/HuddleUp.java | 63 ++++++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 64 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HuddleUp.java diff --git a/Mage.Sets/src/mage/cards/h/HuddleUp.java b/Mage.Sets/src/mage/cards/h/HuddleUp.java new file mode 100644 index 0000000000..d2098c1cef --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HuddleUp.java @@ -0,0 +1,63 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.h; + +import java.util.UUID; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.abilities.keyword.AssistAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetPlayer; + +/** + * + * @author TheElk801 + */ +public class HuddleUp extends CardImpl { + + public HuddleUp(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}"); + + // Assist + this.addAbility(new AssistAbility()); + + // Two target players each draw a card. + this.getSpellAbility().addEffect(new DrawCardTargetEffect(1)); + this.getSpellAbility().addTarget(new TargetPlayer(2)); + } + + public HuddleUp(final HuddleUp card) { + super(card); + } + + @Override + public HuddleUp copy() { + return new HuddleUp(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 4f9952f65c..a36ebf7933 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -84,6 +84,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Gang Up", 47, Rarity.UNCOMMON, mage.cards.g.GangUp.class)); cards.add(new SetCardInfo("Generous Patron", 70, Rarity.RARE, mage.cards.g.GenerousPatron.class)); cards.add(new SetCardInfo("Greater Good", 201, Rarity.RARE, mage.cards.g.GreaterGood.class)); + cards.add(new SetCardInfo("Huddle Up", 36, Rarity.COMMON, mage.cards.h.HuddleUp.class)); cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Impulse", 119, Rarity.COMMON, mage.cards.i.Impulse.class)); cards.add(new SetCardInfo("Inner Demon", 48, Rarity.UNCOMMON, mage.cards.i.InnerDemon.class)); From 02d5df5f7fceee28af0a0ef1982779d5b4f94bfd Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 14:13:23 -0400 Subject: [PATCH 090/154] Updated Battlebond spoiler --- Utils/mtg-cards-data.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 538c353d5b..b0310e2753 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33381,12 +33381,14 @@ Proud Mentor|Battlebond|20|U|{2}{W}|Creature - Human Warrior|1|1|Partner with Im Ley Weaver|Battlebond|21|U|{3}{G}|Creature - Human Druid|2|2|Partner with Lore Weaver (When this creature enters the battlefield, target player may put Lore Weaver into their hand from their library, then shuffle.)${T}: Untap two target lands.| Lore Weaver|Battlebond|22|U|{3}{U}|Creature - Human Wizard|2|2|Partner with Ley Weaver (When this creature enters the battlefield, target player may put Ley Weaver into their hand from their library, then shuffle.)${5}{U}{U}: Target player draws two cards.| Arena Rector|Battlebond|23|M|{3}{W}|Creature - Human Cleric|1|2|When Arena Rector dies, you may exile it. If you do, search your library for a planeswalker card, put it onto the battlefield, then shuffle your library.| +Brightling|Battlebond|25|M|{1}{W}{W}|Creature - Shapeshifter|3|3|{W}: Brightling gains vigilance until end of turn.${W}: Brightling gains lifelink until end of turn.${W}: Return Brightling to its owner's hand.${1}: Brightling gets +1/-1 or -1/+1 until end of turn.| Dwarven Lightsmith|Battlebond|27|C|{5}{W}|Creature - Dwarf Cleric|3|4|Assist$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| Jubilant Mascot|Battlebond|28|U|{2}{W}|Creature - Homunculus|1|1|At the beginning of combat on your turn, you may pay {3}{W}. If you do, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist$Exile all nonland permanents.| Regna's Sanction|Battlebond|30|R|{3}{W}|Sorcery|||For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest.| Skystreamer|Battlebond|31|C|{4}{W}|Creature - Griffin|3|2|Assist$Flying$When Skystreamer enters the battlefield, target player gains 4 life.| Together Forever|Battlebond|32|R|{W}{W}|Enchantment|||When Together Forever enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)${1}: Choose target creature with a counter on it. When that creature dies this turn, return that card to its owner's hand.| +Arcane Artisan|Battlebond|33|M|{2}{U}|Creature - Human Wizard|0|3|{2}{U}, {T}: Target player draws a card, then exiles a card from their hand. If a creature card is exiled this way, that player creates a token that's a copy of that card.$When Arcane Artisan leaves the battlefield, exile all tokens created with it at the beginning of the next end step.| Fumble|Battlebond|34|U|{1}{U}|Instant|||Return target creature to its owner's hand. Gain control of all Auras and Equipment that were attached to it, then attach them to another creature.| Game Plan|Battlebond|35|R|{5}{U}|Sorcery|||Assist$Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Game Plan.| Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist$Two target players each draw a card.| @@ -33403,6 +33405,7 @@ Sickle Dancer|Battlebond|50|C|{2}{B}|Creature - Human Warrior|3|2|Whenever Sickl Stunning Reversal|Battlebond|51|M|{3}{B}|Instant|||The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1. $Exile Stunning Reversal.| Thrasher Brute|Battlebond|52|U|{3}{B}|Creature - Orc Warrior|4|3|Whenever Thrasher Brute or another Warrior enters the battlefield under your team's control, target opponent loses 1 life and you gain 1 life.| Virtus's Maneuver|Battlebond|54|R|{2}{B}|Sorcery|||For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control.| +Bonus Round|Battlebond|56|R|{1}{R}{R}|Sorcery|||Until end of turn, whenever a player casts an instant or sorcery spell, that player copies it and may choose new targets for the copy.| Cheering Fanatic|Battlebond|58|U|{1}{R}|Creature - Goblin|2|2|Whenever Cheering Fanatic attacks, choose a card name. Spells with the chosen name cost {1} less to cast this turn.| Khorvath's Fury|Battlebond|59|R|{4}{R}|Sorcery|||For each player, choose friend or foe. Each friend discards all cards from their hand, then draws that many cards plus one. Khorvath's Fury deals damage to each foe equal to the number of cards in their hand.| Lava-Field Overlord|Battlebond|60|U|{7}{R}{R}|Creature - Dragon|5|4|Assist$Flying$When Lava-Field Overlord enters the battlefield, it deals 4 damage to target creature an opponent controls.| @@ -33415,9 +33418,11 @@ Generous Patron|Battlebond|70|R|{2}{G}|Creature - Elf Advisor|1|4|When Generous Grothama, All-Devouring|Battlebond|71|M|{3}{G}{G}|Legendary Creature - Wurm|10|8|Other creatures have "Whenever this creature attacks, you may have it fight Grothama, All-Devouring."$When Grothama leaves the battlefield, each player draws cards equal to the amount of damage dealt to Grothama this turn by sources they controlled.| Jungle Wayfinder|Battlebond|72|C|{2}{G}|Creature - Elf Warrior|3|3|When Jungle Wayfinder enters the battlefield, each player may search their library for a basic land card, reveal it, put it into their hand, then shuffle their library.| Pir's Whim|Battlebond|73|R|{3}{G}|Sorcery|||For each player, choose friend or foe. Each friend searches their library for a land card, puts it on the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment they control.| +Archon of Valor's Reach|Battlebond|74|R|{4}{W}{G}|Creature - Archon|5|6|Flying, vigilance, trample$As Archon of Valor's Reach enters the battlefield, choose artifact, enchantment, instant, sorcery, or planeswalker.$Players can't cast spells of the chosen type.| Last One Standing|Battlebond|76|R|{1}{B}{R}|Sorcery|||Choose a creature at random, then destroy the rest.| Rushblade Commander|Battlebond|77|U|{B}{R}|Creature - Azra Warrior|2|2|Warriors your team controls have haste.| Sentinel Tower|Battlebond|79|R|{4}|Artifact|||Whenever an instant or sorcery spell is cast during your turn, Sentinel Tower deals 1 damage to any target equal to 1 plus the number of instant and sorcery spells cast before that spell this turn.| +Victory Chimes|Battlebond|80|R|{3}|Artifact|||Untap Victory Chimes during each other player's untap step.${T}: A player of your choice adds {C}.| Bountiful Promenade|Battlebond|81|R||Land|||Bountiful Promenade enters the battlefield tapped unless you have two or more opponents.${T}: Add {G} or {W}.| Luxury Suite|Battlebond|82|R||Land|||Luxury Suite enters the battlefield tapped unless you have two or more opponents.${T}: Add {B} or {R}.| Morphic Pool|Battlebond|83|R||Land|||Morphic Pool enters the battlefield tapped unless you have two or more opponents.${T}: Add {U} or {B}.| @@ -33428,6 +33433,7 @@ Doomed Traveler|Battlebond|91|C|{W}|Creature - Human Soldier|1|1|When Doomed Tra Expedition Raptor|Battlebond|92|C|{3}{W}{W}|Creature - Bird|2|2|Flying$When Expedition Raptor enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| Kor Spiritdancer|Battlebond|93|R|{1}{W}|Creature - Kor Wizard|0|2|Kor Spiritdancer gets +2/+2 for each Aura attached to it.$Whenever you cast an Aura spell, you may draw a card.| Land Tax|Battlebond|94|M|{W}|Enchantment|||At the beginning of your upkeep, if an opponent controls more lands than you, you may search your library for up to three basic land cards, reveal them, and put them into your hand. If you do, shuffle your library.| +Mangara of Corondor|Battlebond|98|R|{1}{W}{W}|Legendary Creature - Human Wizard|1|1|{T}: Exile Mangara of Corondor and target permanent.| Shoulder to Shoulder|Battlebond|105|C|{2}{W}|Sorcery|||Support 2. (Put a +1/+1 counter on each of up to two target creatures.)$Draw a card.| Swords to Plowshares|Battlebond|110|U|{W}|Instant|||Exile target creature. Its controller gains life equal to its power.| Impulse|Battlebond|119|C|{1}{U}|Instant|||Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.| @@ -33448,6 +33454,7 @@ Doubling Season|Battlebond|195|M|{4}{G}|Enchantment|||If an effect would create Fertile Ground|Battlebond|198|C|{1}{G}|Enchantment - Aura|||Enchant land$Whenever enchanted land is tapped for mana, its controller adds an additional one mana of any color.| Greater Good|Battlebond|201|R|{2}{G}{G}|Enchantment|||Sacrifice a creature: Draw cards equal to the sacrificed creature's power, then discard three cards.| Magus of the Candelabra|Battlebond|206|R|{G}|Creature - Human Wizard|1|2|{X}, {T}: Untap X target lands.| +Saddleback Lagac|Battlebond|211|C|{3}{G}|Creature - Lizard|3|1|When Saddleback Lagac enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| Seedborn Muse|Battlebond|212|R|{3}{G}{G}|Creature - Spirit|2|4|Untap all permanents you control during each other player's untap step.| Skyshroud Claim|Battlebond|213|C|{3}{G}|Sorcery|||Search your library for up to two Forest cards and put them onto the battlefield. Then shuffle your library.| Veteran Explorer|Battlebond|214|U|{G}|Creature - Human Soldier Scout|1|1|When Veteran Explorer dies, each player may search their library for up to two basic land cards and put them onto the battlefield. Then each player who searched their library this way shuffles it.| From c24bcf76c01f5dbbe335e70c538231a9eb8c60d1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 14:14:42 -0400 Subject: [PATCH 091/154] Added Battlebond reprints --- Mage.Sets/src/mage/sets/Battlebond.java | 26 +++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index a36ebf7933..d52b4b0ec7 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -58,8 +58,8 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Arena Rector", 23, Rarity.MYTHIC, mage.cards.a.ArenaRector.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); cards.add(new SetCardInfo("Beast Within", 190, Rarity.UNCOMMON, mage.cards.b.BeastWithin.class)); - cards.add(new SetCardInfo("Blaring Captain", 14, Rarity.UNCOMMON, mage.cards.b.BlaringCaptain.class)); - cards.add(new SetCardInfo("Blaring Recruiter", 13, Rarity.UNCOMMON, mage.cards.b.BlaringRecruiter.class)); + cards.add(new SetCardInfo("Blaring Captain", 14, Rarity.UNCOMMON, mage.cards.b.BlaringCaptain.class)); + cards.add(new SetCardInfo("Blaring Recruiter", 13, Rarity.UNCOMMON, mage.cards.b.BlaringRecruiter.class)); cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); @@ -74,17 +74,17 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Doomed Dissenter", 142, Rarity.COMMON, mage.cards.d.DoomedDissenter.class)); cards.add(new SetCardInfo("Doomed Traveler", 91, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); cards.add(new SetCardInfo("Doubling Season", 195, Rarity.MYTHIC, mage.cards.d.DoublingSeason.class)); - cards.add(new SetCardInfo("Dwarven Lightsmith", 27, Rarity.COMMON, mage.cards.d.DwarvenLightsmith.class)); + cards.add(new SetCardInfo("Dwarven Lightsmith", 27, Rarity.COMMON, mage.cards.d.DwarvenLightsmith.class)); cards.add(new SetCardInfo("Eager Construct", 234, Rarity.COMMON, mage.cards.e.EagerConstruct.class)); cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); - cards.add(new SetCardInfo("Fan Favorite", 46, Rarity.COMMON, mage.cards.f.FanFavorite.class)); + cards.add(new SetCardInfo("Fan Favorite", 46, Rarity.COMMON, mage.cards.f.FanFavorite.class)); cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Game Plan", 35, Rarity.RARE, mage.cards.g.GamePlan.class)); - cards.add(new SetCardInfo("Gang Up", 47, Rarity.UNCOMMON, mage.cards.g.GangUp.class)); + cards.add(new SetCardInfo("Game Plan", 35, Rarity.RARE, mage.cards.g.GamePlan.class)); + cards.add(new SetCardInfo("Gang Up", 47, Rarity.UNCOMMON, mage.cards.g.GangUp.class)); cards.add(new SetCardInfo("Generous Patron", 70, Rarity.RARE, mage.cards.g.GenerousPatron.class)); cards.add(new SetCardInfo("Greater Good", 201, Rarity.RARE, mage.cards.g.GreaterGood.class)); - cards.add(new SetCardInfo("Huddle Up", 36, Rarity.COMMON, mage.cards.h.HuddleUp.class)); + cards.add(new SetCardInfo("Huddle Up", 36, Rarity.COMMON, mage.cards.h.HuddleUp.class)); cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Impulse", 119, Rarity.COMMON, mage.cards.i.Impulse.class)); cards.add(new SetCardInfo("Inner Demon", 48, Rarity.UNCOMMON, mage.cards.i.InnerDemon.class)); @@ -97,33 +97,35 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Krav, the Unredeemed", 4, Rarity.RARE, mage.cards.k.KravTheUnredeemed.class)); cards.add(new SetCardInfo("Land Tax", 94, Rarity.MYTHIC, mage.cards.l.LandTax.class)); cards.add(new SetCardInfo("Last One Standing", 76, Rarity.RARE, mage.cards.l.LastOneStanding.class)); - cards.add(new SetCardInfo("Lava-Field Overlord", 60, Rarity.UNCOMMON, mage.cards.l.LavaFieldOverlord.class)); + cards.add(new SetCardInfo("Lava-Field Overlord", 60, Rarity.UNCOMMON, mage.cards.l.LavaFieldOverlord.class)); cards.add(new SetCardInfo("Ley Weaver", 21, Rarity.UNCOMMON, mage.cards.l.LeyWeaver.class)); cards.add(new SetCardInfo("Lore Weaver", 22, Rarity.UNCOMMON, mage.cards.l.LoreWeaver.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Magus of the Candelabra", 206, Rarity.RARE, mage.cards.m.MagusOfTheCandelabra.class)); + cards.add(new SetCardInfo("Mangara of Corondor", 98, Rarity.RARE, mage.cards.m.MangaraOfCorondor.class)); cards.add(new SetCardInfo("Mindblade Render", 49, Rarity.RARE, mage.cards.m.MindbladeRender.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nirkana Revenant", 150, Rarity.MYTHIC, mage.cards.n.NirkanaRevenant.class)); cards.add(new SetCardInfo("Okaun, Eye of Chaos", 6, Rarity.RARE, mage.cards.o.OkaunEyeOfChaos.class)); - cards.add(new SetCardInfo("Out of Bounds", 38, Rarity.COMMON, mage.cards.o.OutOfBounds.class)); + cards.add(new SetCardInfo("Out of Bounds", 38, Rarity.COMMON, mage.cards.o.OutOfBounds.class)); cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); cards.add(new SetCardInfo("Pir's Whim", 73, Rarity.RARE, mage.cards.p.PirsWhim.class)); cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); cards.add(new SetCardInfo("Plains", 250, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Play of the Game", 29, Rarity.RARE, mage.cards.p.PlayOfTheGame.class)); + cards.add(new SetCardInfo("Play of the Game", 29, Rarity.RARE, mage.cards.p.PlayOfTheGame.class)); cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); cards.add(new SetCardInfo("Regna, the Redeemer", 3, Rarity.RARE, mage.cards.r.RegnaTheRedeemer.class)); cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); cards.add(new SetCardInfo("Rushblade Commander", 77, Rarity.UNCOMMON, mage.cards.r.RushbladeCommander.class)); + cards.add(new SetCardInfo("Saddleback Lagac", 211, Rarity.COMMON, mage.cards.s.SaddlebackLagac.class)); cards.add(new SetCardInfo("Saltwater Stalwart", 39, Rarity.COMMON, mage.cards.s.SaltwaterStalwart.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Seedborn Muse", 212, Rarity.RARE, mage.cards.s.SeedbornMuse.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); cards.add(new SetCardInfo("Sickle Dancer", 50, Rarity.COMMON, mage.cards.s.SickleDancer.class)); cards.add(new SetCardInfo("Skyshroud Claim", 213, Rarity.COMMON, mage.cards.s.SkyshroudClaim.class)); - cards.add(new SetCardInfo("Skystreamer", 31, Rarity.COMMON, mage.cards.s.Skystreamer.class)); + cards.add(new SetCardInfo("Skystreamer", 31, Rarity.COMMON, mage.cards.s.Skystreamer.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); @@ -135,7 +137,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swords to Plowshares", 110, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); cards.add(new SetCardInfo("Sylvia Brightspear", 10, Rarity.RARE, mage.cards.s.SylviaBrightspear.class)); - cards.add(new SetCardInfo("The Crowd Goes Wild", 68, Rarity.UNCOMMON, mage.cards.t.TheCrowdGoesWild.class)); + cards.add(new SetCardInfo("The Crowd Goes Wild", 68, Rarity.UNCOMMON, mage.cards.t.TheCrowdGoesWild.class)); cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); cards.add(new SetCardInfo("Tidespout Tyrant", 134, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); From c8c598cad82df0c31d9c8d42350da16638868251 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 14:29:44 -0400 Subject: [PATCH 092/154] Implemented Brightling --- Mage.Sets/src/mage/cards/b/Brightling.java | 138 +++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 139 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/Brightling.java diff --git a/Mage.Sets/src/mage/cards/b/Brightling.java b/Mage.Sets/src/mage/cards/b/Brightling.java new file mode 100644 index 0000000000..812dd97c18 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/Brightling.java @@ -0,0 +1,138 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ColoredManaCost; +import mage.abilities.costs.mana.ColorlessManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ColoredManaSymbol; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class Brightling extends CardImpl { + + public Brightling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}"); + + this.subtype.add(SubType.SHAPESHIFTER); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // {W}: Brightling gains vigilance until end of turn. + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new GainAbilitySourceEffect( + VigilanceAbility.getInstance(), + Duration.EndOfTurn + ), + new ColoredManaCost(ColoredManaSymbol.W) + )); + + // {W}: Brightling gains lifelink until end of turn. + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new GainAbilitySourceEffect( + LifelinkAbility.getInstance(), + Duration.EndOfTurn + ), + new ColoredManaCost(ColoredManaSymbol.W) + )); + + // {W}: Return Brightling to its owner's hand. + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new ReturnToHandSourceEffect(true), + new ColoredManaCost(ColoredManaSymbol.W) + )); + + // {1}: Brightling gets +1/-1 or -1/+1 until end of turn. + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new BrightlingEffect(), + new ColorlessManaCost(1) + )); + } + + public Brightling(final Brightling card) { + super(card); + } + + @Override + public Brightling copy() { + return new Brightling(this); + } +} + +class BrightlingEffect extends OneShotEffect { + + BrightlingEffect() { + super(Outcome.BoostCreature); + this.staticText = "{this} gets +1/-1 or -1/+1 until end of turn"; + } + + BrightlingEffect(final BrightlingEffect effect) { + super(effect); + } + + @Override + public BrightlingEffect copy() { + return new BrightlingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (player == null || permanent == null) { + return false; + } + int boost = (player.chooseUse(outcome, "Give +1/-1 or -1/+1?", null, "+1/-1", "-1/+1", source, game) ? 1 : -1); + return new BoostSourceEffect(boost, -1 * boost, Duration.EndOfTurn).apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index d52b4b0ec7..12c5ffa697 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -63,6 +63,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); + cards.add(new SetCardInfo("Brightling", 25, Rarity.MYTHIC, mage.cards.b.Brightling.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); cards.add(new SetCardInfo("Chain Lightning", 171, Rarity.UNCOMMON, mage.cards.c.ChainLightning.class)); cards.add(new SetCardInfo("Chakram Retriever", 15, Rarity.UNCOMMON, mage.cards.c.ChakramRetriever.class)); From bf01736033de9b3204c4f619b71980f1156f98cd Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 14:57:38 -0400 Subject: [PATCH 093/154] Updated Battlebond spoiler --- Utils/mtg-cards-data.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index b0310e2753..f8c6358ee1 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33396,6 +33396,7 @@ Out of Bounds|Battlebond|38|C|{3}{U}|Instant|||Assist$Counter target spell.| Saltwater Stalwart|Battlebond|39|C|{3}{U}|Creature - Merfolk Warrior|2|4|Whenever Saltwater Stalwart deals damage to an opponent, target player draws a card.| Soaring Show-Off|Battlebond|40|C|{2}{U}|Creature - Bird Warrior|2|2|Flying$When Soaring Show-Off enters the battlefield, each player draws a card.| Spellseeker|Battlebond|41|R|{2}{U}|Creature - Human Wizard|1|1|When Spellseeker enters the battlefield, you may search your library for an instant or sorcery card with converted mana cost 2 or less, reveal it, put it into your hand, then shuffle your library.| +Zndrsplt's Judgment|Battlebond|43|R|{4}{U}|Sorcery|||For each player, choose friend or foe. Each friend creates a token that's a copy of a creature they control. Each foe returns a creature they control to its owner's hand.| Archfiend of Despair|Battlebond|44|M|{6}{B}{B}|Creature - Demon|6|6|Flying$Your opponents can't gain life.$At the beginning of each end step, each opponent loses life equal to the life that player lost this turn. (Damage causes loss of life.)| Fan Favorite|Battlebond|46|C|{3}{B}|Creature - Human Rogue|2|2|Assist${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| Gang Up|Battlebond|47|U|{X}{B}|Instant|||Assist$Destroy target creature with power X or less.| @@ -33409,10 +33410,12 @@ Bonus Round|Battlebond|56|R|{1}{R}{R}|Sorcery|||Until end of turn, whenever a pl Cheering Fanatic|Battlebond|58|U|{1}{R}|Creature - Goblin|2|2|Whenever Cheering Fanatic attacks, choose a card name. Spells with the chosen name cost {1} less to cast this turn.| Khorvath's Fury|Battlebond|59|R|{4}{R}|Sorcery|||For each player, choose friend or foe. Each friend discards all cards from their hand, then draws that many cards plus one. Khorvath's Fury deals damage to each foe equal to the number of cards in their hand.| Lava-Field Overlord|Battlebond|60|U|{7}{R}{R}|Creature - Dragon|5|4|Assist$Flying$When Lava-Field Overlord enters the battlefield, it deals 4 damage to target creature an opponent controls.| +Najeela, the Blade-Blossom|Battlebond|62|M|{2}{R}|Legendary Creature - Human Warrior|3|2|Whenever a Warrior attacks, you may have its controller create a 1/1 white Warrior creature token that's tapped and attacking.${W}{U}{B}{R}{G}: Untap all attacking creatures. They gain trample, lifelink, and haste until end of turn. After this phase, there is an additional combat phase. Activate this ability only during combat.| Stadium Vendors|Battlebond|63|C|{3}{R}|Creature - Goblin|3|3|When Stadium Vendors enters the battlefield, choose a player. That player adds two mana of any one color they choose.| Stolen Strategy|Battlebond|64|R|{4}{R}|Enchantment|||At the beginning of your upkeep, exile the top card of each opponent's library. Until end of turn, you may cast nonland cards from among those exiled cards, and you may spend mana as though it were mana of any color to cast those spells.| Bramble Sovereign|Battlebond|65|M|{2}{G}{G}|Creature - Dryad|4|4|Whenever another nontoken creature enters the battlefield, you may pay {1}{G}. If you do, that creature's controller creates a token that's a copy of that creature.| Charging Binox|Battlebond|66|C|{7}{G}|Creature - Beast|7|5|Assist$Trample| +Combo Attack|Battlebond|67|C|{2}{G}|Sorcery|||Two target creatures your team controls each deal damage equal to their power to target creature.| The Crowd Goes Wild|Battlebond|68|U|{X}{G}|Sorcery|||Assist$Each creature with a +1/+1 counter on it gains trample until end of turn.| Generous Patron|Battlebond|70|R|{2}{G}|Creature - Elf Advisor|1|4|When Generous Patron enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)$Whenever you put one or more counters on a creature you don't control, draw a card.| Grothama, All-Devouring|Battlebond|71|M|{3}{G}{G}|Legendary Creature - Wurm|10|8|Other creatures have "Whenever this creature attacks, you may have it fight Grothama, All-Devouring."$When Grothama leaves the battlefield, each player draws cards equal to the amount of damage dealt to Grothama this turn by sources they controlled.| @@ -33436,8 +33439,10 @@ Land Tax|Battlebond|94|M|{W}|Enchantment|||At the beginning of your upkeep, if a Mangara of Corondor|Battlebond|98|R|{1}{W}{W}|Legendary Creature - Human Wizard|1|1|{T}: Exile Mangara of Corondor and target permanent.| Shoulder to Shoulder|Battlebond|105|C|{2}{W}|Sorcery|||Support 2. (Put a +1/+1 counter on each of up to two target creatures.)$Draw a card.| Swords to Plowshares|Battlebond|110|U|{W}|Instant|||Exile target creature. Its controller gains life equal to its power.| +Tandem Tactics|Battlebond|112|C|{1}{W}|Instant|||Up to two target creatures each get +1/+2 until end of turn. You gain 2 life.| Impulse|Battlebond|119|C|{1}{U}|Instant|||Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.| Kraken Hatchling|Battlebond|121|C|{U}|Creature - Kraken|0|4|| +Mystic Confluence|Battlebond|122|R|{3}{U}{U}|Instant|||Choose three. You may choose the same mode more than once.$• Counter target spell unless its controller pays {3}.$• Return target creature to its owner's hand.$• Draw a card.| Peregrine Drake|Battlebond|128|U|{4}{U}|Creature - Drake|2|3|Flying$When Peregrine Drake enters the battlefield, untap up to five lands.| Sower of Temptation|Battlebond|131|R|{2}{U}{U}|Creature - Faerie Wizard|2|2|Flying$When Sower of Temptation enters the battlefield, gain control of target creature for as long as Sower of Temptation remains on the battlefield.| Spell Snare|Battlebond|132|U|{U}|Instant|||Counter target spell with converted mana cost 2.| From c2699f6419c46c1f579ddbabd0556e635626f8a6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 14:58:28 -0400 Subject: [PATCH 094/154] Added Battlebond reprints --- Mage.Sets/src/mage/sets/Battlebond.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 12c5ffa697..55cba10f29 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -63,7 +63,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); - cards.add(new SetCardInfo("Brightling", 25, Rarity.MYTHIC, mage.cards.b.Brightling.class)); + cards.add(new SetCardInfo("Brightling", 25, Rarity.MYTHIC, mage.cards.b.Brightling.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); cards.add(new SetCardInfo("Chain Lightning", 171, Rarity.UNCOMMON, mage.cards.c.ChainLightning.class)); cards.add(new SetCardInfo("Chakram Retriever", 15, Rarity.UNCOMMON, mage.cards.c.ChakramRetriever.class)); @@ -107,6 +107,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Mindblade Render", 49, Rarity.RARE, mage.cards.m.MindbladeRender.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mystic Confluence", 122, Rarity.RARE, mage.cards.m.MysticConfluence.class)); cards.add(new SetCardInfo("Nirkana Revenant", 150, Rarity.MYTHIC, mage.cards.n.NirkanaRevenant.class)); cards.add(new SetCardInfo("Okaun, Eye of Chaos", 6, Rarity.RARE, mage.cards.o.OkaunEyeOfChaos.class)); cards.add(new SetCardInfo("Out of Bounds", 38, Rarity.COMMON, mage.cards.o.OutOfBounds.class)); @@ -138,6 +139,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swords to Plowshares", 110, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); cards.add(new SetCardInfo("Sylvia Brightspear", 10, Rarity.RARE, mage.cards.s.SylviaBrightspear.class)); + cards.add(new SetCardInfo("Tandem Tactics", 112, Rarity.COMMON, mage.cards.t.TandemTactics.class)); cards.add(new SetCardInfo("The Crowd Goes Wild", 68, Rarity.UNCOMMON, mage.cards.t.TheCrowdGoesWild.class)); cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); cards.add(new SetCardInfo("Tidespout Tyrant", 134, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); From a2d0e8d623c6c5e57f6bfdc8d15e7d0e134b2c5f Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 15:23:49 -0400 Subject: [PATCH 095/154] Implemented Najeela, the Blade-Blossom --- .../mage/cards/n/NajeelaTheBladeBlossom.java | 115 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 116 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java diff --git a/Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java b/Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java new file mode 100644 index 0000000000..4ab86bad7e --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java @@ -0,0 +1,115 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.n; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksAllTriggeredAbility; +import mage.abilities.condition.common.IsPhaseCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.common.AdditionalCombatPhaseEffect; +import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.effects.common.UntapAllEffect; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SetTargetPointer; +import mage.constants.TurnPhase; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.permanent.token.WarriorToken; + +/** + * + * @author TheElk801 + */ +public class NajeelaTheBladeBlossom extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.WARRIOR, "a Warrior"); + + public NajeelaTheBladeBlossom(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Whenever a Warrior attacks, you may have its controller create a 1/1 white Warrior creature token that's tapped and attacking. + this.addAbility(new AttacksAllTriggeredAbility( + new CreateTokenTargetEffect(new WarriorToken(), new StaticValue(1), true, true), + true, filter, SetTargetPointer.PLAYER, false, true + )); + + // {W}{U}{B}{R}{G}: Untap all attacking creatures. They gain trample, lifelink, and haste until end of turn. After this phase, there is an additional combat phase. Activate this ability only during combat. + Ability ability = new ConditionalActivatedAbility( + Zone.BATTLEFIELD, + new UntapAllEffect(StaticFilters.FILTER_ATTACKING_CREATURES), + new ManaCostsImpl("{W}{U}{B}{R}{G}"), + new IsPhaseCondition(TurnPhase.COMBAT) + ); + ability.addEffect(new GainAbilityAllEffect( + TrampleAbility.getInstance(), + Duration.EndOfTurn, + StaticFilters.FILTER_ATTACKING_CREATURES + ).setText("They gain trample,")); + ability.addEffect(new GainAbilityAllEffect( + LifelinkAbility.getInstance(), + Duration.EndOfTurn, + StaticFilters.FILTER_ATTACKING_CREATURES + ).setText("lifelink,")); + ability.addEffect(new GainAbilityAllEffect( + HasteAbility.getInstance(), + Duration.EndOfTurn, + StaticFilters.FILTER_ATTACKING_CREATURES + ).setText("and haste until end of turn.")); + ability.addEffect(new AdditionalCombatPhaseEffect()); + this.addAbility(ability); + } + + public NajeelaTheBladeBlossom(final NajeelaTheBladeBlossom card) { + super(card); + } + + @Override + public NajeelaTheBladeBlossom copy() { + return new NajeelaTheBladeBlossom(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 55cba10f29..de7fd868ff 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -108,6 +108,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mystic Confluence", 122, Rarity.RARE, mage.cards.m.MysticConfluence.class)); + cards.add(new SetCardInfo("Najeela, the Blade-Blossom", 62, Rarity.MYTHIC, mage.cards.n.NajeelaTheBladeBlossom.class)); cards.add(new SetCardInfo("Nirkana Revenant", 150, Rarity.MYTHIC, mage.cards.n.NirkanaRevenant.class)); cards.add(new SetCardInfo("Okaun, Eye of Chaos", 6, Rarity.RARE, mage.cards.o.OkaunEyeOfChaos.class)); cards.add(new SetCardInfo("Out of Bounds", 38, Rarity.COMMON, mage.cards.o.OutOfBounds.class)); From 9d8df8a22e382d2855d4db5f123cb7be29973088 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 16:05:10 -0400 Subject: [PATCH 096/154] Updated Battleborn spoiler --- Utils/mtg-cards-data.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index f8c6358ee1..7a30b56e05 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33396,8 +33396,10 @@ Out of Bounds|Battlebond|38|C|{3}{U}|Instant|||Assist$Counter target spell.| Saltwater Stalwart|Battlebond|39|C|{3}{U}|Creature - Merfolk Warrior|2|4|Whenever Saltwater Stalwart deals damage to an opponent, target player draws a card.| Soaring Show-Off|Battlebond|40|C|{2}{U}|Creature - Bird Warrior|2|2|Flying$When Soaring Show-Off enters the battlefield, each player draws a card.| Spellseeker|Battlebond|41|R|{2}{U}|Creature - Human Wizard|1|1|When Spellseeker enters the battlefield, you may search your library for an instant or sorcery card with converted mana cost 2 or less, reveal it, put it into your hand, then shuffle your library.| +Spellweaver Duo|Battlebond|42|C|{6}{U}|Creature - Human Wizard|4|4|Assist$When Spellweaver Duo enters the battlefield, you may return target tapped creature to its owner's hand.| Zndrsplt's Judgment|Battlebond|43|R|{4}{U}|Sorcery|||For each player, choose friend or foe. Each friend creates a token that's a copy of a creature they control. Each foe returns a creature they control to its owner's hand.| Archfiend of Despair|Battlebond|44|M|{6}{B}{B}|Creature - Demon|6|6|Flying$Your opponents can't gain life.$At the beginning of each end step, each opponent loses life equal to the life that player lost this turn. (Damage causes loss of life.)| +Bloodborn Scoundrels|Battlebond|45|C|{5}{B}|Creature - Vampire Rogue|4|4|Assist$When Bloodborn Scoundrels enters the battlefield, target opponent loses 2 life and you gain 2 life.| Fan Favorite|Battlebond|46|C|{3}{B}|Creature - Human Rogue|2|2|Assist${2}: Fan Favorite gets +1/+1 until end of turn. Any player may activate this ability.| Gang Up|Battlebond|47|U|{X}{B}|Instant|||Assist$Destroy target creature with power X or less.| Inner Demon|Battlebond|48|U|{2}{B}{B}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +2/+2, has flying, and is a Demon in addition to its other types.$When Inner Demon enters the battlefield, all non-Demon creatures get -2/-2 until end of turn.| @@ -33405,6 +33407,7 @@ Mindblade Render|Battlebond|49|R|{1}{B}|Creature - Azra Warrior|1|3|Whenever you Sickle Dancer|Battlebond|50|C|{2}{B}|Creature - Human Warrior|3|2|Whenever Sickle Dancer attacks, if your team controls another Warrior, Sickle Dancer gets +1/+1 until end of turn.| Stunning Reversal|Battlebond|51|M|{3}{B}|Instant|||The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1. $Exile Stunning Reversal.| Thrasher Brute|Battlebond|52|U|{3}{B}|Creature - Orc Warrior|4|3|Whenever Thrasher Brute or another Warrior enters the battlefield under your team's control, target opponent loses 1 life and you gain 1 life.| +Thrilling Encore|Battlebond|53|R|{4}{B}|Instant|||Put onto the battlefield under your control all creature cards in all graveyards that were put there from the battlefield this turn.| Virtus's Maneuver|Battlebond|54|R|{2}{B}|Sorcery|||For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control.| Bonus Round|Battlebond|56|R|{1}{R}{R}|Sorcery|||Until end of turn, whenever a player casts an instant or sorcery spell, that player copies it and may choose new targets for the copy.| Cheering Fanatic|Battlebond|58|U|{1}{R}|Creature - Goblin|2|2|Whenever Cheering Fanatic attacks, choose a card name. Spells with the chosen name cost {1} less to cast this turn.| @@ -33422,6 +33425,7 @@ Grothama, All-Devouring|Battlebond|71|M|{3}{G}{G}|Legendary Creature - Wurm|10|8 Jungle Wayfinder|Battlebond|72|C|{2}{G}|Creature - Elf Warrior|3|3|When Jungle Wayfinder enters the battlefield, each player may search their library for a basic land card, reveal it, put it into their hand, then shuffle their library.| Pir's Whim|Battlebond|73|R|{3}{G}|Sorcery|||For each player, choose friend or foe. Each friend searches their library for a land card, puts it on the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment they control.| Archon of Valor's Reach|Battlebond|74|R|{4}{W}{G}|Creature - Archon|5|6|Flying, vigilance, trample$As Archon of Valor's Reach enters the battlefield, choose artifact, enchantment, instant, sorcery, or planeswalker.$Players can't cast spells of the chosen type.| +Azra Oddsmaker|Battlebond|75|U|{1}{B}{R}|Creature - Azra Warrior|3|3|At the beginning of combat on your turn, you may discard a card. If you do, choose a creature. Whenever that creature deals combat damage to a player this turn, you draw two cards.| Last One Standing|Battlebond|76|R|{1}{B}{R}|Sorcery|||Choose a creature at random, then destroy the rest.| Rushblade Commander|Battlebond|77|U|{B}{R}|Creature - Azra Warrior|2|2|Warriors your team controls have haste.| Sentinel Tower|Battlebond|79|R|{4}|Artifact|||Whenever an instant or sorcery spell is cast during your turn, Sentinel Tower deals 1 damage to any target equal to 1 plus the number of instant and sorcery spells cast before that spell this turn.| @@ -33467,6 +33471,7 @@ Vigor|Battlebond|215|R|{3}{G}{G}{G}|Creature - Elemental Incarnation|6|6|Trample Auger Spree|Battlebond|218|C|{1}{B}{R}|Instant|||Target creature gets +4/-4 until end of turn.| Centaur Healer|Battlebond|219|C|{1}{G}{W}|Creature - Centaur Cleric|3|3|When Centaur Healer enters the battlefield, you gain 3 life.| Eager Construct|Battlebond|234|C|{2}|Artifact Creature - Construct|2|2|When Eager Construct enters the battlefield, each player may scry 1. (To scry 1, look at the top card of your library, then you may put that card on the bottom of your library.)| +Mind's Eye|Battlebond|240|R|{5}|Artifact|||Whenever an opponent draws a card, you may pay {1}. If you do, draw a card.| Plains|Battlebond|250|C||Basic Land - Plains|||({T}: Add {W}.)| Island|Battlebond|251|C||Basic Land - Island|||({T}: Add {U}.)| Swamp|Battlebond|252|C||Basic Land - Swamp|||({T}: Add {B}.)| From 65dd48d70ad2272d1331965067d74a922b308cd6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 16:06:06 -0400 Subject: [PATCH 097/154] Added Mind's Eye to Battlebond --- Mage.Sets/src/mage/sets/Battlebond.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index de7fd868ff..c654250e43 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -104,11 +104,12 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); cards.add(new SetCardInfo("Magus of the Candelabra", 206, Rarity.RARE, mage.cards.m.MagusOfTheCandelabra.class)); cards.add(new SetCardInfo("Mangara of Corondor", 98, Rarity.RARE, mage.cards.m.MangaraOfCorondor.class)); + cards.add(new SetCardInfo("Mind's Eye", 240, Rarity.RARE, mage.cards.m.MindsEye.class)); cards.add(new SetCardInfo("Mindblade Render", 49, Rarity.RARE, mage.cards.m.MindbladeRender.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mystic Confluence", 122, Rarity.RARE, mage.cards.m.MysticConfluence.class)); - cards.add(new SetCardInfo("Najeela, the Blade-Blossom", 62, Rarity.MYTHIC, mage.cards.n.NajeelaTheBladeBlossom.class)); + cards.add(new SetCardInfo("Najeela, the Blade-Blossom", 62, Rarity.MYTHIC, mage.cards.n.NajeelaTheBladeBlossom.class)); cards.add(new SetCardInfo("Nirkana Revenant", 150, Rarity.MYTHIC, mage.cards.n.NirkanaRevenant.class)); cards.add(new SetCardInfo("Okaun, Eye of Chaos", 6, Rarity.RARE, mage.cards.o.OkaunEyeOfChaos.class)); cards.add(new SetCardInfo("Out of Bounds", 38, Rarity.COMMON, mage.cards.o.OutOfBounds.class)); From abc29bdbbd5463e6512aa2f27523d3bf50a91970 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 16:11:12 -0400 Subject: [PATCH 098/154] Implemented Spellweaver Duo --- .../src/mage/cards/s/SelectForInspection.java | 10 ++- .../src/mage/cards/s/SpellweaverDuo.java | 81 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/s/SpellweaverDuo.java diff --git a/Mage.Sets/src/mage/cards/s/SelectForInspection.java b/Mage.Sets/src/mage/cards/s/SelectForInspection.java index 7269649ff1..96ce546897 100644 --- a/Mage.Sets/src/mage/cards/s/SelectForInspection.java +++ b/Mage.Sets/src/mage/cards/s/SelectForInspection.java @@ -43,13 +43,17 @@ import mage.target.common.TargetCreaturePermanent; */ public class SelectForInspection extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("tapped creature"); + + static { + filter.add(new TappedPredicate()); + } + public SelectForInspection(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}"); // Return target tapped creature to its owner's hand. Scry 1. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); - FilterCreaturePermanent filter = new FilterCreaturePermanent("tapped creature"); - filter.add(new TappedPredicate()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); this.getSpellAbility().addEffect(new ScryEffect(1)); diff --git a/Mage.Sets/src/mage/cards/s/SpellweaverDuo.java b/Mage.Sets/src/mage/cards/s/SpellweaverDuo.java new file mode 100644 index 0000000000..fd8f9cc19e --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpellweaverDuo.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.AssistAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class SpellweaverDuo extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("tapped creature"); + + static { + filter.add(new TappedPredicate()); + } + + public SpellweaverDuo(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Assist + this.addAbility(new AssistAbility()); + + // When Spellweaver Duo enters the battlefield, you may return target tapped creature to its owner's hand. + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), true); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public SpellweaverDuo(final SpellweaverDuo card) { + super(card); + } + + @Override + public SpellweaverDuo copy() { + return new SpellweaverDuo(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index c654250e43..674a829177 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -136,6 +136,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Sower of Temptation", 131, Rarity.RARE, mage.cards.s.SowerOfTemptation.class)); cards.add(new SetCardInfo("Spell Snare", 132, Rarity.UNCOMMON, mage.cards.s.SpellSnare.class)); cards.add(new SetCardInfo("Spellseeker", 41, Rarity.RARE, mage.cards.s.Spellseeker.class)); + cards.add(new SetCardInfo("Spellweaver Duo", 42, Rarity.COMMON, mage.cards.s.SpellweaverDuo.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); cards.add(new SetCardInfo("Stunning Reversal", 51, Rarity.MYTHIC, mage.cards.s.StunningReversal.class)); cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); From 6e3011dff29c5fc081ac0db138e19fd694f101f3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 16:14:24 -0400 Subject: [PATCH 099/154] Implemented Bloodborn Scoundrels --- .../src/mage/cards/b/BloodbornScoundrels.java | 76 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 77 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BloodbornScoundrels.java diff --git a/Mage.Sets/src/mage/cards/b/BloodbornScoundrels.java b/Mage.Sets/src/mage/cards/b/BloodbornScoundrels.java new file mode 100644 index 0000000000..5c3da1c828 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BloodbornScoundrels.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.AssistAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class BloodbornScoundrels extends CardImpl { + + public BloodbornScoundrels(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Assist + this.addAbility(new AssistAbility()); + + // When Bloodborn Scoundrels enters the battlefield, target opponent loses 2 life and you gain 2 life. + Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(2)); + ability.addEffect(new GainLifeEffect(2).setText("and you gain 2 life")); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public BloodbornScoundrels(final BloodbornScoundrels card) { + super(card); + } + + @Override + public BloodbornScoundrels copy() { + return new BloodbornScoundrels(this); + } +} +// greetings, good hunter diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 674a829177..aed37432be 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -60,6 +60,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Beast Within", 190, Rarity.UNCOMMON, mage.cards.b.BeastWithin.class)); cards.add(new SetCardInfo("Blaring Captain", 14, Rarity.UNCOMMON, mage.cards.b.BlaringCaptain.class)); cards.add(new SetCardInfo("Blaring Recruiter", 13, Rarity.UNCOMMON, mage.cards.b.BlaringRecruiter.class)); + cards.add(new SetCardInfo("Bloodborn Scoundrels", 45, Rarity.COMMON, mage.cards.b.BloodbornScoundrels.class)); cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); From 2587df2e676b43124f6eb425fa4fd6c7428736b3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Thu, 24 May 2018 17:47:00 -0400 Subject: [PATCH 100/154] Implemented Sentinel Tower --- Mage.Sets/src/mage/cards/s/SentinelTower.java | 163 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 164 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SentinelTower.java diff --git a/Mage.Sets/src/mage/cards/s/SentinelTower.java b/Mage.Sets/src/mage/cards/s/SentinelTower.java new file mode 100644 index 0000000000..5cebd23e60 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SentinelTower.java @@ -0,0 +1,163 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.MageObject; +import mage.MageObjectReference; +import mage.abilities.common.SpellCastAllTriggeredAbility; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.WatcherScope; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.common.TargetAnyTarget; +import mage.watchers.Watcher; + +/** + * + * @author TheElk801 + */ +public class SentinelTower extends CardImpl { + + public SentinelTower(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + + // Whenever an instant or sorcery spell is cast during your turn, Sentinel Tower deals damage to any target equal to 1 plus the number of instant and sorcery spells cast before that spell this turn. + this.addAbility(new SentinelTowerTriggeredAbility(), new SentinelTowerWatcher()); + } + + public SentinelTower(final SentinelTower card) { + super(card); + } + + @Override + public SentinelTower copy() { + return new SentinelTower(this); + } +} + +class SentinelTowerTriggeredAbility extends SpellCastAllTriggeredAbility { + + SentinelTowerTriggeredAbility() { + super(new DamageTargetEffect(0), StaticFilters.FILTER_INSTANT_OR_SORCERY_SPELL, false); + this.addTarget(new TargetAnyTarget()); + } + + SentinelTowerTriggeredAbility(final SentinelTowerTriggeredAbility effect) { + super(effect); + } + + @Override + public SentinelTowerTriggeredAbility copy() { + return new SentinelTowerTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (game.getActivePlayerId().equals(getControllerId()) + && super.checkTrigger(event, game)) { + SentinelTowerWatcher watcher = (SentinelTowerWatcher) game.getState().getWatchers().get(SentinelTowerWatcher.class.getSimpleName()); + if (watcher == null) { + return false; + } + List<MageObjectReference> spellsCast = watcher.getSpellsThisTurn(); + MageObject object = game.getObject(event.getTargetId()); + if (object == null || spellsCast == null) { + return false; + } + int damageToDeal = 0; + for (MageObjectReference mor : spellsCast) { + damageToDeal++; + if (mor.refersTo(object, game)) { + break; + } + } + for (Effect effect : this.getEffects()) { + if (effect instanceof DamageTargetEffect) { + ((DamageTargetEffect) effect).setAmount(new StaticValue(damageToDeal)); + return true; + } + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever an instant or sorcery spell is cast during your turn, " + + "{this} deals damage to any target equal to 1 " + + "plus the number of instant and sorcery spells cast before that spell this turn."; + } +} + +class SentinelTowerWatcher extends Watcher { + + private final List<MageObjectReference> spellsThisTurn; + + SentinelTowerWatcher() { + super(SentinelTowerWatcher.class.getSimpleName(), WatcherScope.GAME); + this.spellsThisTurn = new ArrayList<>(); + } + + SentinelTowerWatcher(final SentinelTowerWatcher effect) { + super(effect); + this.spellsThisTurn = effect.spellsThisTurn; + } + + @Override + public SentinelTowerWatcher copy() { + return new SentinelTowerWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.SPELL_CAST) { + MageObject object = game.getObject(event.getTargetId()); + if (object != null && (object.isInstant() || object.isSorcery())) { + spellsThisTurn.add(new MageObjectReference(object, game)); + } + } + } + + @Override + public void reset() { + spellsThisTurn.clear(); + } + + public List<MageObjectReference> getSpellsThisTurn() { + return spellsThisTurn; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index aed37432be..22ac926697 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -127,6 +127,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Saltwater Stalwart", 39, Rarity.COMMON, mage.cards.s.SaltwaterStalwart.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Seedborn Muse", 212, Rarity.RARE, mage.cards.s.SeedbornMuse.class)); + cards.add(new SetCardInfo("Sentinel Tower", 79, Rarity.RARE, mage.cards.s.SentinelTower.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); cards.add(new SetCardInfo("Sickle Dancer", 50, Rarity.COMMON, mage.cards.s.SickleDancer.class)); cards.add(new SetCardInfo("Skyshroud Claim", 213, Rarity.COMMON, mage.cards.s.SkyshroudClaim.class)); From dc94477c75d4da856e0bebffff8c4682198c0cb5 Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Thu, 24 May 2018 23:50:08 +0200 Subject: [PATCH 101/154] * Fixed Najeela. --- Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java b/Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java index 4ab86bad7e..fad884b31a 100644 --- a/Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java +++ b/Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java @@ -36,19 +36,19 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalActivatedAbility; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.AdditionalCombatPhaseEffect; -import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.UntapAllEffect; import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.TrampleAbility; -import mage.constants.SubType; -import mage.constants.SuperType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SetTargetPointer; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.constants.TurnPhase; import mage.constants.Zone; import mage.filter.StaticFilters; @@ -74,7 +74,8 @@ public class NajeelaTheBladeBlossom extends CardImpl { // Whenever a Warrior attacks, you may have its controller create a 1/1 white Warrior creature token that's tapped and attacking. this.addAbility(new AttacksAllTriggeredAbility( - new CreateTokenTargetEffect(new WarriorToken(), new StaticValue(1), true, true), + new CreateTokenEffect(new WarriorToken(), new StaticValue(1), true, true) + .setText("you may have its controller create a 1/1 white Warrior creature token that's tapped and attacking"), true, filter, SetTargetPointer.PLAYER, false, true )); From b0468de571d2f4dac2679f1f4de42d2b7c600222 Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Fri, 25 May 2018 00:25:30 +0200 Subject: [PATCH 102/154] * Fixed Najeela. --- Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java b/Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java index fad884b31a..8bf283f653 100644 --- a/Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java +++ b/Mage.Sets/src/mage/cards/n/NajeelaTheBladeBlossom.java @@ -36,7 +36,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalActivatedAbility; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.AdditionalCombatPhaseEffect; -import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.CreateTokenTargetEffect; import mage.abilities.effects.common.UntapAllEffect; import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.abilities.keyword.HasteAbility; @@ -74,7 +74,7 @@ public class NajeelaTheBladeBlossom extends CardImpl { // Whenever a Warrior attacks, you may have its controller create a 1/1 white Warrior creature token that's tapped and attacking. this.addAbility(new AttacksAllTriggeredAbility( - new CreateTokenEffect(new WarriorToken(), new StaticValue(1), true, true) + new CreateTokenTargetEffect(new WarriorToken(), new StaticValue(1), true, true) .setText("you may have its controller create a 1/1 white Warrior creature token that's tapped and attacking"), true, filter, SetTargetPointer.PLAYER, false, true )); From 038fe5e5fcf2a9b7907f52504a53c83a79280346 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 09:32:22 -0400 Subject: [PATCH 103/154] Implemented Azra Oddsmaker --- Mage.Sets/src/mage/cards/a/AzraOddsmaker.java | 167 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + .../MageObjectReferencePredicate.java | 56 ++++++ 3 files changed, 224 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AzraOddsmaker.java create mode 100644 Mage/src/main/java/mage/filter/predicate/mageobject/MageObjectReferencePredicate.java diff --git a/Mage.Sets/src/mage/cards/a/AzraOddsmaker.java b/Mage.Sets/src/mage/cards/a/AzraOddsmaker.java new file mode 100644 index 0000000000..f3f3b5901d --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AzraOddsmaker.java @@ -0,0 +1,167 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.MageObjectReferencePredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class AzraOddsmaker extends CardImpl { + + public AzraOddsmaker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}"); + + this.subtype.add(SubType.AZRA); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // At the beginning of combat on your turn, you may discard a card. If you do, choose a creature. Whenever that creature deals combat damage to a player this turn, you draw two cards. + this.addAbility(new BeginningOfCombatTriggeredAbility(new AzraOddsmakerEffect(), TargetController.YOU, true)); + } + + public AzraOddsmaker(final AzraOddsmaker card) { + super(card); + } + + @Override + public AzraOddsmaker copy() { + return new AzraOddsmaker(this); + } +} + +class AzraOddsmakerEffect extends OneShotEffect { + + AzraOddsmakerEffect() { + super(Outcome.Benefit); + this.staticText = "discard a card. If you do, choose a creature. Whenever that creature deals combat damage to a player this turn, you draw two cards"; + } + + AzraOddsmakerEffect(final AzraOddsmakerEffect effect) { + super(effect); + } + + @Override + public AzraOddsmakerEffect copy() { + return new AzraOddsmakerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Cost cost = new DiscardCardCost(); + Permanent permanent = null; + if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game) + && cost.pay(source, game, source.getSourceId(), source.getControllerId(), true)) { + TargetCreaturePermanent target = new TargetCreaturePermanent(); + target.setNotTarget(true); + if (player.choose(Outcome.DrawCard, target, source.getSourceId(), game)) { + permanent = game.getPermanent(target.getFirstTarget()); + } + } + if (permanent == null) { + return false; + } + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(new MageObjectReferencePredicate(new MageObjectReference(permanent, game))); + game.addDelayedTriggeredAbility(new AzraOddsmakerDelayedTriggeredAbility(filter, permanent.getName()), source); + return true; + } +} + +class AzraOddsmakerDelayedTriggeredAbility extends DelayedTriggeredAbility { + + private final FilterCreaturePermanent filter; + private final String creatureName; + + AzraOddsmakerDelayedTriggeredAbility(FilterCreaturePermanent filter, String creatureName) { + super(new DrawCardSourceControllerEffect(2), Duration.EndOfTurn, false); + this.filter = filter; + this.creatureName = creatureName; + } + + AzraOddsmakerDelayedTriggeredAbility(final AzraOddsmakerDelayedTriggeredAbility ability) { + super(ability); + this.filter = ability.filter; + this.creatureName = ability.creatureName; + } + + @Override + public AzraOddsmakerDelayedTriggeredAbility copy() { + return new AzraOddsmakerDelayedTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getFlag()) { + Permanent permanent = game.getPermanent(event.getSourceId()); + if (permanent != null && filter.match(permanent, game)) { + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever " + creatureName + " deals damage to a player this turn, you draw two cards"; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 22ac926697..2a0ee02b0a 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -57,6 +57,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Archfiend of Despair", 44, Rarity.MYTHIC, mage.cards.a.ArchfiendOfDespair.class)); cards.add(new SetCardInfo("Arena Rector", 23, Rarity.MYTHIC, mage.cards.a.ArenaRector.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); + cards.add(new SetCardInfo("Azra Oddsmaker", 75, Rarity.UNCOMMON, mage.cards.a.AzraOddsmaker.class)); cards.add(new SetCardInfo("Beast Within", 190, Rarity.UNCOMMON, mage.cards.b.BeastWithin.class)); cards.add(new SetCardInfo("Blaring Captain", 14, Rarity.UNCOMMON, mage.cards.b.BlaringCaptain.class)); cards.add(new SetCardInfo("Blaring Recruiter", 13, Rarity.UNCOMMON, mage.cards.b.BlaringRecruiter.class)); diff --git a/Mage/src/main/java/mage/filter/predicate/mageobject/MageObjectReferencePredicate.java b/Mage/src/main/java/mage/filter/predicate/mageobject/MageObjectReferencePredicate.java new file mode 100644 index 0000000000..31f6132b61 --- /dev/null +++ b/Mage/src/main/java/mage/filter/predicate/mageobject/MageObjectReferencePredicate.java @@ -0,0 +1,56 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.filter.predicate.mageobject; + +import mage.MageObject; +import mage.MageObjectReference; +import mage.filter.predicate.Predicate; +import mage.game.Game; + +/** + * + * @author TheElk801 + */ +public class MageObjectReferencePredicate implements Predicate<MageObject> { + + private final MageObjectReference mor; + + public MageObjectReferencePredicate(MageObjectReference mor) { + this.mor = mor; + } + + @Override + public boolean apply(MageObject input, Game game) { + return mor.refersTo(input, game); + } + + @Override + public String toString() { + return "MageObjectReference(" + mor.toString() + ')'; + } +} From 3f3c4ce602926e40ef09b3289f06cbe0aff89a11 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 14:17:43 -0400 Subject: [PATCH 104/154] Added Battlebond full spoiler --- Utils/mtg-cards-data.txt | 139 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 2 deletions(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 7a30b56e05..b08e61acd4 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -33381,7 +33381,9 @@ Proud Mentor|Battlebond|20|U|{2}{W}|Creature - Human Warrior|1|1|Partner with Im Ley Weaver|Battlebond|21|U|{3}{G}|Creature - Human Druid|2|2|Partner with Lore Weaver (When this creature enters the battlefield, target player may put Lore Weaver into their hand from their library, then shuffle.)${T}: Untap two target lands.| Lore Weaver|Battlebond|22|U|{3}{U}|Creature - Human Wizard|2|2|Partner with Ley Weaver (When this creature enters the battlefield, target player may put Ley Weaver into their hand from their library, then shuffle.)${5}{U}{U}: Target player draws two cards.| Arena Rector|Battlebond|23|M|{3}{W}|Creature - Human Cleric|1|2|When Arena Rector dies, you may exile it. If you do, search your library for a planeswalker card, put it onto the battlefield, then shuffle your library.| +Aurora Champion|Battlebond|24|C|{2}{W}|Creature - Elf Warrior|3|2|Whenever Aurora Champion attacks, if you team controls another Warrior, tap target creature.| Brightling|Battlebond|25|M|{1}{W}{W}|Creature - Shapeshifter|3|3|{W}: Brightling gains vigilance until end of turn.${W}: Brightling gains lifelink until end of turn.${W}: Return Brightling to its owner's hand.${1}: Brightling gets +1/-1 or -1/+1 until end of turn.| +Bring Down|Battlebond|26|U|{3}{W}|Sorcery|||Assist$Destroy target creature with power 4 or greater.| Dwarven Lightsmith|Battlebond|27|C|{5}{W}|Creature - Dwarf Cleric|3|4|Assist$When Dwarven Lightsmith enters the battlefield, creatures your team controls get +1/+1 until end of turn.| Jubilant Mascot|Battlebond|28|U|{2}{W}|Creature - Homunculus|1|1|At the beginning of combat on your turn, you may pay {3}{W}. If you do, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| Play of the Game|Battlebond|29|R|{6}{W}{W}|Sorcery|||Assist$Exile all nonland permanents.| @@ -33392,7 +33394,8 @@ Arcane Artisan|Battlebond|33|M|{2}{U}|Creature - Human Wizard|0|3|{2}{U}, {T}: T Fumble|Battlebond|34|U|{1}{U}|Instant|||Return target creature to its owner's hand. Gain control of all Auras and Equipment that were attached to it, then attach them to another creature.| Game Plan|Battlebond|35|R|{5}{U}|Sorcery|||Assist$Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Game Plan.| Huddle Up|Battlebond|36|C|{2}{U}|Sorcery|||Assist$Two target players each draw a card.| -Out of Bounds|Battlebond|38|C|{3}{U}|Instant|||Assist$Counter target spell.| +Nimbus Champion|Battlebond|37|U|{5}{U}|Creature - Avatar Warrior|4|4|Flying$Whenever Nimbus Champion attacks, you may return target creature to its owner's hand if that creature's power is less than or equal to the number of Warriors you control.| +Out of Bounds|Battlebond|38|U|{3}{U}|Instant|||Assist$Counter target spell.| Saltwater Stalwart|Battlebond|39|C|{3}{U}|Creature - Merfolk Warrior|2|4|Whenever Saltwater Stalwart deals damage to an opponent, target player draws a card.| Soaring Show-Off|Battlebond|40|C|{2}{U}|Creature - Bird Warrior|2|2|Flying$When Soaring Show-Off enters the battlefield, each player draws a card.| Spellseeker|Battlebond|41|R|{2}{U}|Creature - Human Wizard|1|1|When Spellseeker enters the battlefield, you may search your library for an instant or sorcery card with converted mana cost 2 or less, reveal it, put it into your hand, then shuffle your library.| @@ -33409,10 +33412,13 @@ Stunning Reversal|Battlebond|51|M|{3}{B}|Instant|||The next time you would lose Thrasher Brute|Battlebond|52|U|{3}{B}|Creature - Orc Warrior|4|3|Whenever Thrasher Brute or another Warrior enters the battlefield under your team's control, target opponent loses 1 life and you gain 1 life.| Thrilling Encore|Battlebond|53|R|{4}{B}|Instant|||Put onto the battlefield under your control all creature cards in all graveyards that were put there from the battlefield this turn.| Virtus's Maneuver|Battlebond|54|R|{2}{B}|Sorcery|||For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control.| +Azra Bladeseeker|Battlebond|55|C|{2}{R}|Creature - Azra Warrior|3|2|When Azra Bladeseeker enters the battlefield, each player on your team may discard a card, then each player who discarded a card this way draws a card.| Bonus Round|Battlebond|56|R|{1}{R}{R}|Sorcery|||Until end of turn, whenever a player casts an instant or sorcery spell, that player copies it and may choose new targets for the copy.| +Bull-Rush Bruiser|Battlebond|57|C|{3}{R}|Creature - Minotaur Warrior|4|3|Whenever Bull-Rush Bruiser attacks, if your team controls another Warrior, Bull-Rush Bruiser gains first strike until end of turn.| Cheering Fanatic|Battlebond|58|U|{1}{R}|Creature - Goblin|2|2|Whenever Cheering Fanatic attacks, choose a card name. Spells with the chosen name cost {1} less to cast this turn.| Khorvath's Fury|Battlebond|59|R|{4}{R}|Sorcery|||For each player, choose friend or foe. Each friend discards all cards from their hand, then draws that many cards plus one. Khorvath's Fury deals damage to each foe equal to the number of cards in their hand.| Lava-Field Overlord|Battlebond|60|U|{7}{R}{R}|Creature - Dragon|5|4|Assist$Flying$When Lava-Field Overlord enters the battlefield, it deals 4 damage to target creature an opponent controls.| +Magma Hellion|Battlebond|61|C|{6}{R}|Creature - Hellion|5|4|Assist$Trample, haste| Najeela, the Blade-Blossom|Battlebond|62|M|{2}{R}|Legendary Creature - Human Warrior|3|2|Whenever a Warrior attacks, you may have its controller create a 1/1 white Warrior creature token that's tapped and attacking.${W}{U}{B}{R}{G}: Untap all attacking creatures. They gain trample, lifelink, and haste until end of turn. After this phase, there is an additional combat phase. Activate this ability only during combat.| Stadium Vendors|Battlebond|63|C|{3}{R}|Creature - Goblin|3|3|When Stadium Vendors enters the battlefield, choose a player. That player adds two mana of any one color they choose.| Stolen Strategy|Battlebond|64|R|{4}{R}|Enchantment|||At the beginning of your upkeep, exile the top card of each opponent's library. Until end of turn, you may cast nonland cards from among those exiled cards, and you may spend mana as though it were mana of any color to cast those spells.| @@ -33420,6 +33426,7 @@ Bramble Sovereign|Battlebond|65|M|{2}{G}{G}|Creature - Dryad|4|4|Whenever anothe Charging Binox|Battlebond|66|C|{7}{G}|Creature - Beast|7|5|Assist$Trample| Combo Attack|Battlebond|67|C|{2}{G}|Sorcery|||Two target creatures your team controls each deal damage equal to their power to target creature.| The Crowd Goes Wild|Battlebond|68|U|{X}{G}|Sorcery|||Assist$Each creature with a +1/+1 counter on it gains trample until end of turn.| +Decorated Champion|Battlebond|69|U|{1}{G}|Creature - Elf Warrior|2|2|Whenever another Warrior enters the battlefield under your team's control, put a +1/+1 counter on Decorated Champion.| Generous Patron|Battlebond|70|R|{2}{G}|Creature - Elf Advisor|1|4|When Generous Patron enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)$Whenever you put one or more counters on a creature you don't control, draw a card.| Grothama, All-Devouring|Battlebond|71|M|{3}{G}{G}|Legendary Creature - Wurm|10|8|Other creatures have "Whenever this creature attacks, you may have it fight Grothama, All-Devouring."$When Grothama leaves the battlefield, each player draws cards equal to the amount of damage dealt to Grothama this turn by sources they controlled.| Jungle Wayfinder|Battlebond|72|C|{2}{G}|Creature - Elf Warrior|3|3|When Jungle Wayfinder enters the battlefield, each player may search their library for a basic land card, reveal it, put it into their hand, then shuffle their library.| @@ -33428,50 +33435,178 @@ Archon of Valor's Reach|Battlebond|74|R|{4}{W}{G}|Creature - Archon|5|6|Flying, Azra Oddsmaker|Battlebond|75|U|{1}{B}{R}|Creature - Azra Warrior|3|3|At the beginning of combat on your turn, you may discard a card. If you do, choose a creature. Whenever that creature deals combat damage to a player this turn, you draw two cards.| Last One Standing|Battlebond|76|R|{1}{B}{R}|Sorcery|||Choose a creature at random, then destroy the rest.| Rushblade Commander|Battlebond|77|U|{B}{R}|Creature - Azra Warrior|2|2|Warriors your team controls have haste.| -Sentinel Tower|Battlebond|79|R|{4}|Artifact|||Whenever an instant or sorcery spell is cast during your turn, Sentinel Tower deals 1 damage to any target equal to 1 plus the number of instant and sorcery spells cast before that spell this turn.| +Vampire Charmseeker|Battlebond|78|U|{6}{U}{B}|Creature - Vampire Wizard|3|4|Assist$Flying$When Vampire Charmseeker enters the battlefield, return target instant, sorcery, or creature card from a graveyard to its owner's hand.| +Sentinel Tower|Battlebond|79|R|{4}|Artifact|||Whenever an instant or sorcery spell is cast during your turn, Sentinel Tower deals damage to any target equal to 1 plus the number of instant and sorcery spells cast before that spell this turn.| Victory Chimes|Battlebond|80|R|{3}|Artifact|||Untap Victory Chimes during each other player's untap step.${T}: A player of your choice adds {C}.| Bountiful Promenade|Battlebond|81|R||Land|||Bountiful Promenade enters the battlefield tapped unless you have two or more opponents.${T}: Add {G} or {W}.| Luxury Suite|Battlebond|82|R||Land|||Luxury Suite enters the battlefield tapped unless you have two or more opponents.${T}: Add {B} or {R}.| Morphic Pool|Battlebond|83|R||Land|||Morphic Pool enters the battlefield tapped unless you have two or more opponents.${T}: Add {U} or {B}.| Sea of Clouds|Battlebond|84|R||Land|||Sea of Clouds enters the battlefield tapped unless you have two or more opponents.${T}: Add {W} or {U}.| Spire Garden|Battlebond|85|R||Land|||Spire Garden enters the battlefield tapped unless you have two or more opponents.${T}: Add {R} or {G}.| +Angel of Retribution|Battlebond|86|U|{6}{W}|Creature - Angel|5|5|Flying, first strike| Angelic Chorus|Battlebond|87|R|{3}{W}{W}|Enchantment|||Whenever a creature enters the battlefield under your control, you gain life equal to its toughness.| +Angelic Gift|Battlebond|88|C|{1}{W}|Enchantment - Aura|||Enchant creature$When Angelic Gift enters the battlefield, draw a card.$Enchanted creature has flying.| +Battle Mastery|Battlebond|89|U|{2}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature has double strike. (It deals both first-strike and regular combat damage.)| +Champion of Arashin|Battlebond|90|C|{3}{W}|Creature - Hound Warrior|3|2|Lifelink (Damage dealt by this creature also causes you to gain that much life.)| Doomed Traveler|Battlebond|91|C|{W}|Creature - Human Soldier|1|1|When Doomed Traveler dies, create a 1/1 white Spirit creature token with flying.| Expedition Raptor|Battlebond|92|C|{3}{W}{W}|Creature - Bird|2|2|Flying$When Expedition Raptor enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| Kor Spiritdancer|Battlebond|93|R|{1}{W}|Creature - Kor Wizard|0|2|Kor Spiritdancer gets +2/+2 for each Aura attached to it.$Whenever you cast an Aura spell, you may draw a card.| Land Tax|Battlebond|94|M|{W}|Enchantment|||At the beginning of your upkeep, if an opponent controls more lands than you, you may search your library for up to three basic land cards, reveal them, and put them into your hand. If you do, shuffle your library.| +Lightwalker|Battlebond|95|C|{1}{W}|Creature - Human Warrior|2|1|Lightwalker has flying as long as it has a +1/+1 counter on it.| +Long Road Home|Battlebond|96|U|{1}{W}|Instant|||Exile target creature. At the beginning of the next end step, return that card to the battlefield under its owner's control with a +1/+1 counter on it.| +Loyal Pegasus|Battlebond|97|U|{W}|Creature - Pegasus|2|1|Flying$Loyal Pegasus can't attack or block alone.| Mangara of Corondor|Battlebond|98|R|{1}{W}{W}|Legendary Creature - Human Wizard|1|1|{T}: Exile Mangara of Corondor and target permanent.| +Midnight Guard|Battlebond|99|C|{2}{W}|Creature - Human Soldier|2|3|Whenever another creature enters the battlefield, untap Midnight Guard.| +Oreskos Explorer|Battlebond|100|U|{1}{W}|Creature - Cat Scout|2|2|When Oreskos Explorer enters the battlefield, search your library for up to X Plains cards, where X is the number of players who control more lands than you. Reveal those cards, put them into your hand, then shuffle your library.| +Pacifism|Battlebond|101|C|{1}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature can't attack or block.| +Raptor Companion|Battlebond|102|C|{1}{W}|Creature - Dinosaur|3|1|| +Rebuke|Battlebond|103|C|{2}{W}|Instant|||Destroy target attacking creature.| +Royal Trooper|Battlebond|104|C|{2}{W}|Creature - Human Soldier|2|2|Whenever Royal Trooper blocks, it gets +2/+2 until end of turn.| Shoulder to Shoulder|Battlebond|105|C|{2}{W}|Sorcery|||Support 2. (Put a +1/+1 counter on each of up to two target creatures.)$Draw a card.| +Silverchase Fox|Battlebond|106|C|{1}{W}|Creature - Fox|2|2|{1}{W}, Sacrifice Silverchase Fox: Exile target enchantment.| +Solemn Offering|Battlebond|107|U|{2}{W}|Sorcery|||Destroy target artifact or enchantment. You gain 4 life.| +Sparring Mummy|Battlebond|108|C|{3}{W}|Creature - Zombie|3|3|When Sparring Mummy enters the battlefield, untap target creature.| +Steppe Glider|Battlebond|109|U|{4}{W}|Creature - Elemental|2|4|Flying, vigilance${1}{W}: Target creature with a +1/+1 counter on it gains flying and vigilance until end of turn.| Swords to Plowshares|Battlebond|110|U|{W}|Instant|||Exile target creature. Its controller gains life equal to its power.| +Take Up Arms|Battlebond|111|U|{4}{W}|Instant|||Create three 1/1 white Warrior creature tokens.| Tandem Tactics|Battlebond|112|C|{1}{W}|Instant|||Up to two target creatures each get +1/+2 until end of turn. You gain 2 life.| +Benthic Giant|Battlebond|113|C|{5}{U}|Creature - Giant|4|5|Hexproof (This creature can't be the target of spells or abilities your opponents control.)| +Call to Heel|Battlebond|114|C|{1}{U}|Instant|||Return target creature to its owner's hand. Its controller draws a card.| +Claustrophobia|Battlebond|115|C|{1}{U}{U}|Enchantment - Aura|||Enchant creature$When Claustrophobia enters the battlefield, tap enchanted creature.$Enchanted creature doesn't untap during its controller's untap step.| +Coralhelm Guide|Battlebond|116|C|{1}{U}|Creature - Merfolk Scout Ally|2|1|{4}{U}: Target creature can't be blocked this turn.| +Fog Bank|Battlebond|117|U|{1}{U}|Creature - Wall|0|2|Defender, flying$Prevent all combat damage that would be dealt to and dealt by Fog Bank.| +Frost Lynx|Battlebond|118|C|{2}{U}|Creature - Elemental Cat|2|2|When Frost Lynx enters the battlefield, tap target creature an opponent controls. That creature doesn't untap during its controller's next untap step.| Impulse|Battlebond|119|C|{1}{U}|Instant|||Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.| +Kitesail Corsair|Battlebond|120|C|{1}{U}|Creature - Human Pirate|2|1|Kitesail Corsair has flying as long as it's attacking.| Kraken Hatchling|Battlebond|121|C|{U}|Creature - Kraken|0|4|| Mystic Confluence|Battlebond|122|R|{3}{U}{U}|Instant|||Choose three. You may choose the same mode more than once.$• Counter target spell unless its controller pays {3}.$• Return target creature to its owner's hand.$• Draw a card.| +Negate|Battlebond|123|C|{1}{U}|Instant|||Counter target noncreature spell.| +Nimbus of the Isles|Battlebond|124|C|{4}{U}|Creature - Elemental|3|3|Flying (This creature can't be blocked except by creatures with flying or reach.)| +Omenspeaker|Battlebond|125|C|{1}{U}|Creature - Human Wizard|1|3|When Omenspeaker enters the battlefield, scry 2. (Look at the top two cards of your library, then put any number of them on the bottom of your library and the rest on top in any order.)| +Opportunity|Battlebond|126|U|{4}{U}{U}|Instant|||Target player draws four cards.| +Oracle's Insight|Battlebond|127|U|{3}{U}|Enchantment - Aura|||Enchant creature$Enchanted creature has "{T}: Scry 1, then draw a card." (To scry 1, look at the top card of your library, then you may put that card on the bottom of your library.)| Peregrine Drake|Battlebond|128|U|{4}{U}|Creature - Drake|2|3|Flying$When Peregrine Drake enters the battlefield, untap up to five lands.| +Phantom Warrior|Battlebond|129|U|{1}{U}{U}|Creature - Illusion Warrior|2|2|Phantom Warrior can't be blocked.| +Reckless Scholar|Battlebond|130|U|{2}{U}|Creature - Human Wizard|2|1|{T}: Target player draws a card, then discards a card.| Sower of Temptation|Battlebond|131|R|{2}{U}{U}|Creature - Faerie Wizard|2|2|Flying$When Sower of Temptation enters the battlefield, gain control of target creature for as long as Sower of Temptation remains on the battlefield.| Spell Snare|Battlebond|132|U|{U}|Instant|||Counter target spell with converted mana cost 2.| +Switcheroo|Battlebond|133|U|{4}{U}|Sorcery|||Exchange control of two target creatures.| Tidespout Tyrant|Battlebond|134|R|{5}{U}{U}{U}|Creature - Djinn|5|5|Flying$Whenever you cast a spell, return target permanent to its owner's hand.| +Totally Lost|Battlebond|135|C|{4}{U}|Instant|||Put target nonland permanent on top of its owner's library.| True-Name Nemesis|Battlebond|136|M|{1}{U}{U}|Creature - Merfolk Rogue|3|1|As True-Name Nemesis enters the battlefield, choose a player.$True-Name Nemesis has protection from the chosen player. (This creature can't be blocked, targeted, dealt damage, or enchanted by anything controlled by that player.)| +Watercourser|Battlebond|137|C|{2}{U}|Creature - Elemental|2|3|{U}: Watercourser gets +1/-1 until end of turn.| +Assassin's Strike|Battlebond|138|U|{4}{B}{B}|Sorcery|||Destroy target creature. Its controller discards a card.| +Assassinate|Battlebond|139|C|{2}{B}|Sorcery|||Destroy target tapped creature.| Daggerdrome Imp|Battlebond|140|C|{1}{B}|Creature - Imp|1|1|Flying$Lifelink (Damage dealt by this creature also causes you to gain that much life.)| Diabolic Intent|Battlebond|141|R|{1}{B}|Sorcery|||As an additional cost to cast this spell, sacrifice a creature.$Search your library for a card and put that card into your hand. Then shuffle your library.| Doomed Dissenter|Battlebond|142|C|{1}{B}|Creature - Human|1|1|When Doomed Dissenter dies, create a 2/2 black Zombie creature token.| +Eyeblight Assassin|Battlebond|143|C|{2}{B}|Creature - Elf Assassin|2|2|When Eyeblight Assassin enters the battlefield, target creature an opponent controls gets -1/-1 until end of turn.| +Fill with Fright|Battlebond|144|C|{3}{B}|Sorcery|||Target player discards two cards. Scry 2. (Look at the top two cards of your library, then put any number of them on the bottom of your library and the rest on top in any order.)| +Grotesque Mutation|Battlebond|145|C|{1}{B}|Instant|||Target creature gets +3/+1 and gains lifelink until end of turn. (Damage dealt by the creature also causes its controller to gain that much life.)| +Hand of Silumgar|Battlebond|146|C|{1}{B}|Creature - Human Warrior|2|1|Deathtouch (Any amount of damage this deals to a creature is enough to destroy it.)| +Last Gasp|Battlebond|147|C|{1}{B}|Instant|||Target creature gets -3/-3 until end of turn.| +Liturgy of Blood|Battlebond|148|C|{3}{B}{B}|Sorcery|||Destroy target creature. Add {B}{B}{B}.| +Morbid Curiosity|Battlebond|149|U|{1}{B}{B}|Sorcery|||As an additional cost to cast this spell, sacrifice an artifact or creature.$Draw cards equal to the converted mana cost of the sacrificed permanent.| Nirkana Revenant|Battlebond|150|M|{4}{B}{B}|Creature - Vampire Shade|4|4|Whenever you tap a Swamp for mana, add an additional {B}.${B}: Nirkana Revenant gets +1/+1 until end of turn.| +Noosegraf Mob|Battlebond|151|R|{4}{B}{B}|Creature - Zombie|0|0|Noosegraf Mob enters the battlefield with five +1/+1 counters on it.$Whenever a player casts a spell, remove a +1/+1 counter from Noosegraf Mob. If you do, create a 2/2 black Zombie creature token.| +Noxious Dragon|Battlebond|152|U|{4}{B}{B}|Creature - Dragon|4|4|Flying$When Noxious Dragon dies, you may destroy target creature with converted mana cost 3 or less.| +Nyxathid|Battlebond|153|R|{1}{B}{B}|Creature - Elemental|7|7|As Nyxathid enters the battlefield, choose an opponent.$Nyxathid gets -1/-1 for each card in the chosen player's hand.| +Painful Lesson|Battlebond|154|C|{2}{B}|Sorcery|||Target player draws two cards and loses 2 life.| +Prakhata Club Security|Battlebond|155|C|{3}{B}|Creature - Aetherborn Warrior|3|4|| +Quest for the Gravelord|Battlebond|156|U|{B}|Enchantment|||Whenever a creature dies, you may put a quest counter on Quest for the Gravelord.$Remove three quest counters from Quest for the Gravelord and sacrifice it: Create a 5/5 black Zombie Giant creature token.| +Rotfeaster Maggot|Battlebond|157|C|{4}{B}|Creature - Insect|3|5|When Rotfeaster Maggot enters the battlefield, exile target creature card from a graveyard. You gain life equal to that card's toughness.| +Screeching Buzzard|Battlebond|158|C|{3}{B}|Creature - Bird|2|2|Flying$When Screeching Buzzard dies, each opponent discards a card.| +Shambling Ghoul|Battlebond|159|C|{1}{B}|Creature - Zombie|2|3|Shambling Ghoul enters the battlefield tapped.| +Slum Reaper|Battlebond|160|U|{3}{B}|Creature - Horror|4|2|When Slum Reaper enters the battlefield, each player sacrifices a creature.| +Swarm of Bloodflies|Battlebond|161|U|{4}{B}|Creature - Insect|0|0|Flying$Swarm of Bloodflies enters the battlefield with two +1/+1 counters on it.$Whenever another creature dies, put a +1/+1 counter on Swarm of Bloodflies.| +Tavern Swindler|Battlebond|162|U|{1}{B}|Creature - Human Rogue|2|2|{T}, Pay 3 life: Flip a coin. If you win the flip, you gain 6 life.| +Tenacious Dead|Battlebond|163|U|{B}|Creature - Skeleton Warrior|1|1|When Tenacious Dead dies, you may pay {1}{B}. If you do, return it to the battlefield tapped under its owner's control.| +Bathe in Dragonfire|Battlebond|164|C|{2}{R}|Sorcery|||Bathe in Dragonfire deals 4 damage to target creature.| +Battle Rampart|Battlebond|165|C|{2}{R}|Creature - Wall|1|3|Defender${T}: Target creature gains haste until end of turn.| +Battle-Rattle Shaman|Battlebond|166|U|{3}{R}|Creature - Goblin Shaman|2|2|At the beginning of combat on your turn, you may have target creature get +2/+0 until end of turn.| +Blaze|Battlebond|167|U|{X}{R}|Sorcery|||Blaze deals X damage to any target.| +Blood Feud|Battlebond|168|U|{4}{R}{R}|Sorcery|||Target creature fights another target creature. (Each deals damage equal to its power to the other.)| Boldwyr Intimidator|Battlebond|169|U|{5}{R}{R}|Creature - Giant Warrior|5|5|Cowards can't block Warriors.${R}: Target creature becomes a Coward until end of turn.${2}{R}: Target creature becomes a Warrior until end of turn.| +Borderland Marauder|Battlebond|170|C|{1}{R}|Creature - Human Warrior|1|2|Whenever Borderland Marauder attacks, it gets +2/+0 until end of turn.| Chain Lightning|Battlebond|171|U|{R}|Sorcery|||Chain Lightning deals 3 damage to any target. Then that player or that permanent's controller may pay {R}{R}. If the player does, they may copy this spell and may choose a new target for that copy.| +Dragon Breath|Battlebond|172|U|{1}{R}|Enchantment - Aura|||Enchant creature$Enchanted creature has haste.${R}: Enchanted creature gets +1/+0 until end of turn.$When a creature with converted mana cost 6 or greater enters the battlefield, you may return Dragon Breath from your graveyard to the battlefield attached to that creature.| +Dragon Hatchling|Battlebond|173|C|{1}{R}|Creature - Dragon|0|1|Flying${R}: Dragon Hatchling gets +1/+0 until end of turn.| +Earth Elemental|Battlebond|174|C|{3}{R}{R}|Creature - Elemental|4|5|| +Ember Beast|Battlebond|175|C|{2}{R}|Creature - Beast|3|4|Ember Beast can't attack or block alone.| +Enthralling Victor|Battlebond|176|U|{3}{R}|Creature - Human Warrior|3|2|When Enthralling Victor enters the battlefield, gain control of target creature an opponent controls with power 2 or less until end of turn. Untap that creature. It gains haste until end of turn. (It can attack and {T} this turn.)| +Expedite|Battlebond|177|C|{R}|Instant|||Target creature gains haste until end of turn.$Draw a card.| +Flamewave Invoker|Battlebond|178|U|{2}{R}|Creature - Goblin Mutant|2|2|{7}{R}: Flamewave Invoker deals 5 damage to target player or planeswalker.| +Goblin Razerunners|Battlebond|179|R|{2}{R}{R}|Creature - Goblin Warrior|3|4|{1}{R}, Sacrifice a land: Put a +1/+1 counter on Goblin Razerunners.$At the beginning of your end step, you may have Goblin Razerunners deal damage equal to the number of +1/+1 counters on it to target player or planeswalker.| +Lightning Talons|Battlebond|180|C|{2}{R}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +3/+0 and has first strike. (It deals combat damage before creatures without first strike.)| +Magmatic Force|Battlebond|181|R|{5}{R}{R}{R}|Creature - Elemental|7|7|At the beginning of each upkeep, Magmatic Force deals 3 damage to any target.| +Pathmaker Initiate|Battlebond|182|C|{1}{R}|Creature - Human Wizard|2|1|{T}: Target creature with power 2 or less can't be blocked this turn.| +Reckless Reveler|Battlebond|183|C|{1}{R}|Creature - Satyr|2|1|{R}, Sacrifice Reckless Reveler: Destroy target artifact.| +Shock|Battlebond|184|C|{R}|Instant|||Shock deals 2 damage to any target.| +Thunder Strike|Battlebond|185|C|{1}{R}|Instant|||Target creature gets +2/+0 and gains first strike until end of turn. (It deals combat damage before creatures without first strike.)| +Trumpet Blast|Battlebond|186|C|{2}{R}|Instant|||Attacking creatures get +2/+0 until end of turn.| +War's Toll|Battlebond|187|R|{3}{R}|Enchantment|||Whenever an opponent taps a land for mana, tap all lands that player controls.$If a creature an opponent controls attacks, all creatures that opponent controls attack if able.| +Wrap in Flames|Battlebond|188|C|{3}{R}|Sorcery|||Wrap in Flames deals 1 damage to each of up to three target creatures. Those creatures can't block this turn.| +Aim High|Battlebond|189|U|{1}{G}|Instant|||Untap target creature. It gets +2/+2 and gains reach until end of turn. (It can block creatures with flying.)| Beast Within|Battlebond|190|U|{2}{G}|Instant|||Destroy target permanent. Its controller creates a 3/3 green Beast creature token.| +Canopy Spider|Battlebond|191|C|{1}{G}|Creature - Spider|1|3|Reach (This creature can block creatures with flying.)| +Charging Rhino|Battlebond|192|C|{3}{G}{G}|Creature - Rhino|4|4|Charging Rhino can't be blocked by more than one creature.| +Cowl Prowler|Battlebond|193|C|{4}{G}{G}|Creature - Wurm|6|6|| +Daggerback Basilisk|Battlebond|194|C|{2}{G}|Creature - Basilisk|2|2|Deathtouch| Doubling Season|Battlebond|195|M|{4}{G}|Enchantment|||If an effect would create one or more tokens under your control, it creates twice that many of those tokens instead.$If an effect would put one or more counters on a permanent you control, it puts twice that many of those counters on that permanent instead.| +Elvish Visionary|Battlebond|196|C|{1}{G}|Creature - Elf Shaman|1|1|When Elvish Visionary enters the battlefield, draw a card.| +Feral Hydra|Battlebond|197|U|{X}{G}|Creature - Hydra Beast|0|0|Feral Hydra enters the battlefield with X +1/+1 counters on it.${3}: Put a +1/+1 counter on Feral Hydra. Any player may activate this ability.| Fertile Ground|Battlebond|198|C|{1}{G}|Enchantment - Aura|||Enchant land$Whenever enchanted land is tapped for mana, its controller adds an additional one mana of any color.| +Fertilid|Battlebond|199|C|{2}{G}|Creature - Elemental|0|0|Fertilid enters the battlefield with two +1/+1 counters on it.${1}{G}, Remove a +1/+1 counter from Fertilid: Target player searches their library for a basic land card and puts it onto the battlefield tapped. Then that player shuffles their library.| +Giant Growth|Battlebond|200|C|{G}|Instant|||Target creature gets +3/+3 until end of turn.| Greater Good|Battlebond|201|R|{2}{G}{G}|Enchantment|||Sacrifice a creature: Draw cards equal to the sacrificed creature's power, then discard three cards.| +Hunted Wumpus|Battlebond|202|U|{3}{G}|Creature - Beast|6|6|When Hunted Wumpus enters the battlefield, each other player may put a creature card from their hand onto the battlefield.| +Karametra's Favor|Battlebond|203|U|{1}{G}|Enchantment - Aura|||Enchant creature$When Karametra's Favor enters the battlefield, draw a card.$Enchanted creature has "{T}: Add one mana of any color."| +Kraul Warrior|Battlebond|204|C|{1}{G}|Creature - Insect Warrior|2|2|{5}{G}: Kraul Warrior gets +3/+3 until end of turn.| +Lead by Example|Battlebond|205|C|{1}{G}|Instant|||Support 2. (Put a +1/+1 counter on each of up to two target creatures.)| Magus of the Candelabra|Battlebond|206|R|{G}|Creature - Human Wizard|1|2|{X}, {T}: Untap X target lands.| +Plated Crusher|Battlebond|207|U|{4}{G}{G}{G}|Creature - Beast|7|6|Trample, hexproof| +Primal Huntbeast|Battlebond|208|C|{3}{G}|Creature - Beast|3|3|Hexproof (This creature can't be the target of spells or abilities your opponents control.)| +Pulse of Murasa|Battlebond|209|U|{2}{G}|Instant|||Return target creature or land card from a graveyard to its owner's hand. You gain 6 life.| +Return to the Earth|Battlebond|210|C|{3}{G}|Instant|||Destroy target artifact, enchantment, or creature with flying.| Saddleback Lagac|Battlebond|211|C|{3}{G}|Creature - Lizard|3|1|When Saddleback Lagac enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.)| Seedborn Muse|Battlebond|212|R|{3}{G}{G}|Creature - Spirit|2|4|Untap all permanents you control during each other player's untap step.| Skyshroud Claim|Battlebond|213|C|{3}{G}|Sorcery|||Search your library for up to two Forest cards and put them onto the battlefield. Then shuffle your library.| Veteran Explorer|Battlebond|214|U|{G}|Creature - Human Soldier Scout|1|1|When Veteran Explorer dies, each player may search their library for up to two basic land cards and put them onto the battlefield. Then each player who searched their library this way shuffles it.| Vigor|Battlebond|215|R|{3}{G}{G}{G}|Creature - Elemental Incarnation|6|6|Trample$If damage would be dealt to a creature you control other than Vigor, prevent that damage. Put a +1/+1 counter on that creature for each 1 damage prevented this way.$When Vigor is put into a graveyard from anywhere, shuffle it into its owner's library.| +Wandering Wolf|Battlebond|216|C|{1}{G}|Creature - Wolf|2|1|Creatures with power less than Wandering Wolf's power can't block it.| +Apocalypse Hydra|Battlebond|217|R|{X}{R}{G}|Creature - Hydra|0|0|Apocalypse Hydra enters the battlefield with X +1/+1 counters on it. If X is 5 or more, it enters the battlefield with an additional X +1/+1 counters on it.${1}{R}, Remove a +1/+1 counter from Apocalypse Hydra: Apocalypse Hydra deals 1 damage to any target.| Auger Spree|Battlebond|218|C|{1}{B}{R}|Instant|||Target creature gets +4/-4 until end of turn.| Centaur Healer|Battlebond|219|C|{1}{G}{W}|Creature - Centaur Cleric|3|3|When Centaur Healer enters the battlefield, you gain 3 life.| +Dinrova Horror|Battlebond|220|U|{4}{U}{B}|Creature - Horror|4|4|When Dinrova Horror enters the battlefield, return target permanent to its owner's hand, then that player discards a card.| +Enduring Scalelord|Battlebond|221|U|{4}{G}{W}|Creature - Dragon|4|4|Flying$Whenever one or more +1/+1 counters are put on another creature you control, you may put a +1/+1 counter on Enduring Scalelord.| +Evil Twin|Battlebond|222|R|{2}{U}{B}|Creature - Shapeshifter|0|0|You may have Evil Twin enter the battlefield as a copy of any creature on the battlefield, except it gains "{U}{B}, {T}: Destroy target creature with the same name as this creature."| +Gwafa Hazid, Profiteer|Battlebond|223|R|{1}{W}{U}|Legendary Creature - Human Rogue|2|2|{W}{U}, {T}: Put a bribery counter on target creature you don't control. Its controller draws a card.$Creatures with bribery counters on them can't attack or block.| +Jelenn Sphinx|Battlebond|224|U|{3}{W}{U}|Creature - Sphinx|1|5|Flying, vigilance$Whenever Jelenn Sphinx attacks, other attacking creatures get +1/+1 until end of turn.| +Kiss of the Amesha|Battlebond|225|U|{4}{W}{U}|Sorcery|||Target player gains 7 life and draws two cards.| +Relentless Hunter|Battlebond|226|U|{1}{R}{G}|Creature - Human Warrior|3|3|{1}{R}{G}: Relentless Hunter gets +1/+1 and gains trample until end of turn.| +Rhox Brute|Battlebond|227|C|{2}{R}{G}|Creature - Rhino Warrior|4|4|| +Riptide Crab|Battlebond|228|C|{1}{W}{U}|Creature - Crab|1|3|Vigilance$When Riptide Crab dies, draw a card.| +Savage Ventmaw|Battlebond|229|U|{4}{R}{G}|Creature - Dragon|4|4|Flying$Whenever Savage Ventmaw attacks, add {R}{R}{R}{G}{G}{G}. Until end of turn, you don't lose this mana as steps and phases end.| +Unflinching Courage|Battlebond|230|U|{1}{G}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +2/+2 and has trample and lifelink.| +Urborg Drake|Battlebond|231|C|{1}{U}{B}|Creature - Drake|2|3|Flying$Urborg Drake attacks each combat if able.| +Consulate Skygate|Battlebond|232|C|{2}|Artifact Creature - Wall|0|4|Defender$Reach (This creature can block creatures with flying.)| +Culling Dais|Battlebond|233|U|{2}|Artifact|||{T}, Sacrifice a creature: Put a charge counter on Culling Dais.${1}, Sacrifice Culling Dais: Draw a card for each charge counter on Culling Dais.| Eager Construct|Battlebond|234|C|{2}|Artifact Creature - Construct|2|2|When Eager Construct enters the battlefield, each player may scry 1. (To scry 1, look at the top card of your library, then you may put that card on the bottom of your library.)| +Genesis Chamber|Battlebond|235|U|{2}|Artifact|||Whenever a nontoken creature enters the battlefield, if Genesis Chamber is untapped, that creature's controller creates a 1/1 colorless Myr artifact creature token.| +Gold-Forged Sentinel|Battlebond|236|U|{6}|Artifact Creature - Chimera|4|4|Flying| +Hexplate Golem|Battlebond|237|C|{7}|Artifact Creature - Golem|5|7|| +Juggernaut|Battlebond|238|U|{4}|Artifact Creature - Juggernaut|5|3|Juggernaut attacks each combat if able.$Juggernaut can't be blocked by Walls.| +Millennial Gargoyle|Battlebond|239|C|{4}|Artifact Creature - Gargoyle|2|2|Flying| Mind's Eye|Battlebond|240|R|{5}|Artifact|||Whenever an opponent draws a card, you may pay {1}. If you do, draw a card.| +Mycosynth Lattice|Battlebond|241|M|{6}|Artifact|||All permanents are artifacts in addition to their other types.$All cards that aren't on the battlefield, spells, and permanents are colorless.$Players may spend mana as though it were mana of any color.| +Night Market Guard|Battlebond|242|C|{3}|Artifact Creature - Construct|3|1|Night Market Guard can block an additional creature each combat.| +Peace Strider|Battlebond|243|C|{4}|Artifact Creature - Construct|3|3|When Peace Strider enters the battlefield, you gain 3 life.| +Pierce Strider|Battlebond|244|C|{4}|Artifact Creature - Construct|3|3|When Pierce Strider enters the battlefield, target opponent loses 3 life.| +Seer's Lantern|Battlebond|245|C|{3}|Artifact|||{T}: Add {C}. ({C} represents colorless mana.)${2}, {T}: Scry 1. (Look at the top card of your library. You may put that card on the bottom of your library.)| +Spectral Searchlight|Battlebond|246|U|{3}|Artifact|||{T}: Choose a player. That player adds one mana of any color they choose.| +Stone Golem|Battlebond|247|C|{5}|Artifact Creature - Golem|4|4|| +Tyrant's Machine|Battlebond|248|C|{2}|Artifact|||{4}, {T}: Tap target creature.| +Yotian Soldier|Battlebond|249|C|{3}|Artifact Creature - Soldier|1|4|Vigilance| Plains|Battlebond|250|C||Basic Land - Plains|||({T}: Add {W}.)| Island|Battlebond|251|C||Basic Land - Island|||({T}: Add {U}.)| Swamp|Battlebond|252|C||Basic Land - Swamp|||({T}: Add {B}.)| From ba2717d7d2b780d1477961e7044fc4be3a1a8537 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 14:19:10 -0400 Subject: [PATCH 105/154] Added all Battlebond reprints --- Mage.Sets/src/mage/sets/Battlebond.java | 137 +++++++++++++++++++++++- 1 file changed, 132 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 2a0ee02b0a..0b4de0a4f0 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -53,108 +53,235 @@ public class Battlebond extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; + cards.add(new SetCardInfo("Aim High", 189, Rarity.UNCOMMON, mage.cards.a.AimHigh.class)); + cards.add(new SetCardInfo("Angel of Retribution", 86, Rarity.UNCOMMON, mage.cards.a.AngelOfRetribution.class)); cards.add(new SetCardInfo("Angelic Chorus", 87, Rarity.RARE, mage.cards.a.AngelicChorus.class)); + cards.add(new SetCardInfo("Angelic Gift", 88, Rarity.COMMON, mage.cards.a.AngelicGift.class)); + cards.add(new SetCardInfo("Apocalypse Hydra", 217, Rarity.RARE, mage.cards.a.ApocalypseHydra.class)); cards.add(new SetCardInfo("Archfiend of Despair", 44, Rarity.MYTHIC, mage.cards.a.ArchfiendOfDespair.class)); cards.add(new SetCardInfo("Arena Rector", 23, Rarity.MYTHIC, mage.cards.a.ArenaRector.class)); + cards.add(new SetCardInfo("Assassin's Strike", 138, Rarity.UNCOMMON, mage.cards.a.AssassinsStrike.class)); + cards.add(new SetCardInfo("Assassinate", 139, Rarity.COMMON, mage.cards.a.Assassinate.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); - cards.add(new SetCardInfo("Azra Oddsmaker", 75, Rarity.UNCOMMON, mage.cards.a.AzraOddsmaker.class)); + cards.add(new SetCardInfo("Azra Oddsmaker", 75, Rarity.UNCOMMON, mage.cards.a.AzraOddsmaker.class)); + cards.add(new SetCardInfo("Bathe in Dragonfire", 164, Rarity.COMMON, mage.cards.b.BatheInDragonfire.class)); + cards.add(new SetCardInfo("Battle Mastery", 89, Rarity.UNCOMMON, mage.cards.b.BattleMastery.class)); + cards.add(new SetCardInfo("Battle Rampart", 165, Rarity.COMMON, mage.cards.b.BattleRampart.class)); + cards.add(new SetCardInfo("Battle-Rattle Shaman", 166, Rarity.UNCOMMON, mage.cards.b.BattleRattleShaman.class)); cards.add(new SetCardInfo("Beast Within", 190, Rarity.UNCOMMON, mage.cards.b.BeastWithin.class)); + cards.add(new SetCardInfo("Benthic Giant", 113, Rarity.COMMON, mage.cards.b.BenthicGiant.class)); cards.add(new SetCardInfo("Blaring Captain", 14, Rarity.UNCOMMON, mage.cards.b.BlaringCaptain.class)); cards.add(new SetCardInfo("Blaring Recruiter", 13, Rarity.UNCOMMON, mage.cards.b.BlaringRecruiter.class)); - cards.add(new SetCardInfo("Bloodborn Scoundrels", 45, Rarity.COMMON, mage.cards.b.BloodbornScoundrels.class)); + cards.add(new SetCardInfo("Blaze", 167, Rarity.UNCOMMON, mage.cards.b.Blaze.class)); + cards.add(new SetCardInfo("Blood Feud", 168, Rarity.UNCOMMON, mage.cards.b.BloodFeud.class)); + cards.add(new SetCardInfo("Bloodborn Scoundrels", 45, Rarity.COMMON, mage.cards.b.BloodbornScoundrels.class)); cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); + cards.add(new SetCardInfo("Borderland Marauder", 170, Rarity.COMMON, mage.cards.b.BorderlandMarauder.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); cards.add(new SetCardInfo("Brightling", 25, Rarity.MYTHIC, mage.cards.b.Brightling.class)); + cards.add(new SetCardInfo("Call to Heel", 114, Rarity.COMMON, mage.cards.c.CallToHeel.class)); + cards.add(new SetCardInfo("Canopy Spider", 191, Rarity.COMMON, mage.cards.c.CanopySpider.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); cards.add(new SetCardInfo("Chain Lightning", 171, Rarity.UNCOMMON, mage.cards.c.ChainLightning.class)); cards.add(new SetCardInfo("Chakram Retriever", 15, Rarity.UNCOMMON, mage.cards.c.ChakramRetriever.class)); cards.add(new SetCardInfo("Chakram Slinger", 16, Rarity.UNCOMMON, mage.cards.c.ChakramSlinger.class)); + cards.add(new SetCardInfo("Champion of Arashin", 90, Rarity.COMMON, mage.cards.c.ChampionOfArashin.class)); cards.add(new SetCardInfo("Charging Binox", 66, Rarity.COMMON, mage.cards.c.ChargingBinox.class)); + cards.add(new SetCardInfo("Charging Rhino", 192, Rarity.COMMON, mage.cards.c.ChargingRhino.class)); cards.add(new SetCardInfo("Cheering Fanatic", 58, Rarity.UNCOMMON, mage.cards.c.CheeringFanatic.class)); + cards.add(new SetCardInfo("Claustrophobia", 115, Rarity.COMMON, mage.cards.c.Claustrophobia.class)); + cards.add(new SetCardInfo("Consulate Skygate", 232, Rarity.COMMON, mage.cards.c.ConsulateSkygate.class)); + cards.add(new SetCardInfo("Coralhelm Guide", 116, Rarity.COMMON, mage.cards.c.CoralhelmGuide.class)); + cards.add(new SetCardInfo("Cowl Prowler", 193, Rarity.COMMON, mage.cards.c.CowlProwler.class)); + cards.add(new SetCardInfo("Culling Dais", 233, Rarity.UNCOMMON, mage.cards.c.CullingDais.class)); + cards.add(new SetCardInfo("Daggerback Basilisk", 194, Rarity.COMMON, mage.cards.d.DaggerbackBasilisk.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); cards.add(new SetCardInfo("Diabolic Intent", 141, Rarity.RARE, mage.cards.d.DiabolicIntent.class)); + cards.add(new SetCardInfo("Dinrova Horror", 220, Rarity.UNCOMMON, mage.cards.d.DinrovaHorror.class)); cards.add(new SetCardInfo("Doomed Dissenter", 142, Rarity.COMMON, mage.cards.d.DoomedDissenter.class)); cards.add(new SetCardInfo("Doomed Traveler", 91, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); cards.add(new SetCardInfo("Doubling Season", 195, Rarity.MYTHIC, mage.cards.d.DoublingSeason.class)); + cards.add(new SetCardInfo("Dragon Breath", 172, Rarity.UNCOMMON, mage.cards.d.DragonBreath.class)); + cards.add(new SetCardInfo("Dragon Hatchling", 173, Rarity.COMMON, mage.cards.d.DragonHatchling.class)); cards.add(new SetCardInfo("Dwarven Lightsmith", 27, Rarity.COMMON, mage.cards.d.DwarvenLightsmith.class)); cards.add(new SetCardInfo("Eager Construct", 234, Rarity.COMMON, mage.cards.e.EagerConstruct.class)); + cards.add(new SetCardInfo("Earth Elemental", 174, Rarity.COMMON, mage.cards.e.EarthElemental.class)); + cards.add(new SetCardInfo("Elvish Visionary", 196, Rarity.COMMON, mage.cards.e.ElvishVisionary.class)); + cards.add(new SetCardInfo("Ember Beast", 175, Rarity.COMMON, mage.cards.e.EmberBeast.class)); + cards.add(new SetCardInfo("Enduring Scalelord", 221, Rarity.UNCOMMON, mage.cards.e.EnduringScalelord.class)); + cards.add(new SetCardInfo("Enthralling Victor", 176, Rarity.UNCOMMON, mage.cards.e.EnthrallingVictor.class)); + cards.add(new SetCardInfo("Evil Twin", 222, Rarity.RARE, mage.cards.e.EvilTwin.class)); + cards.add(new SetCardInfo("Expedite", 177, Rarity.COMMON, mage.cards.e.Expedite.class)); cards.add(new SetCardInfo("Expedition Raptor", 92, Rarity.COMMON, mage.cards.e.ExpeditionRaptor.class)); + cards.add(new SetCardInfo("Eyeblight Assassin", 143, Rarity.COMMON, mage.cards.e.EyeblightAssassin.class)); cards.add(new SetCardInfo("Fan Favorite", 46, Rarity.COMMON, mage.cards.f.FanFavorite.class)); + cards.add(new SetCardInfo("Feral Hydra", 197, Rarity.UNCOMMON, mage.cards.f.FeralHydra.class)); cards.add(new SetCardInfo("Fertile Ground", 198, Rarity.COMMON, mage.cards.f.FertileGround.class)); + cards.add(new SetCardInfo("Fertilid", 199, Rarity.COMMON, mage.cards.f.Fertilid.class)); + cards.add(new SetCardInfo("Fill with Fright", 144, Rarity.COMMON, mage.cards.f.FillWithFright.class)); + cards.add(new SetCardInfo("Flamewave Invoker", 178, Rarity.UNCOMMON, mage.cards.f.FlamewaveInvoker.class)); + cards.add(new SetCardInfo("Fog Bank", 117, Rarity.UNCOMMON, mage.cards.f.FogBank.class)); cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Frost Lynx", 118, Rarity.COMMON, mage.cards.f.FrostLynx.class)); cards.add(new SetCardInfo("Game Plan", 35, Rarity.RARE, mage.cards.g.GamePlan.class)); cards.add(new SetCardInfo("Gang Up", 47, Rarity.UNCOMMON, mage.cards.g.GangUp.class)); cards.add(new SetCardInfo("Generous Patron", 70, Rarity.RARE, mage.cards.g.GenerousPatron.class)); + cards.add(new SetCardInfo("Genesis Chamber", 235, Rarity.UNCOMMON, mage.cards.g.GenesisChamber.class)); + cards.add(new SetCardInfo("Giant Growth", 200, Rarity.COMMON, mage.cards.g.GiantGrowth.class)); + cards.add(new SetCardInfo("Goblin Razerunners", 179, Rarity.RARE, mage.cards.g.GoblinRazerunners.class)); + cards.add(new SetCardInfo("Gold-Forged Sentinel", 236, Rarity.UNCOMMON, mage.cards.g.GoldForgedSentinel.class)); cards.add(new SetCardInfo("Greater Good", 201, Rarity.RARE, mage.cards.g.GreaterGood.class)); + cards.add(new SetCardInfo("Grotesque Mutation", 145, Rarity.COMMON, mage.cards.g.GrotesqueMutation.class)); + cards.add(new SetCardInfo("Gwafa Hazid, Profiteer", 223, Rarity.RARE, mage.cards.g.GwafaHazidProfiteer.class)); + cards.add(new SetCardInfo("Hand of Silumgar", 146, Rarity.COMMON, mage.cards.h.HandOfSilumgar.class)); + cards.add(new SetCardInfo("Hexplate Golem", 237, Rarity.COMMON, mage.cards.h.HexplateGolem.class)); cards.add(new SetCardInfo("Huddle Up", 36, Rarity.COMMON, mage.cards.h.HuddleUp.class)); + cards.add(new SetCardInfo("Hunted Wumpus", 202, Rarity.UNCOMMON, mage.cards.h.HuntedWumpus.class)); cards.add(new SetCardInfo("Impetuous Protege", 19, Rarity.UNCOMMON, mage.cards.i.ImpetuousProtege.class)); cards.add(new SetCardInfo("Impulse", 119, Rarity.COMMON, mage.cards.i.Impulse.class)); cards.add(new SetCardInfo("Inner Demon", 48, Rarity.UNCOMMON, mage.cards.i.InnerDemon.class)); cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jelenn Sphinx", 224, Rarity.UNCOMMON, mage.cards.j.JelennSphinx.class)); cards.add(new SetCardInfo("Jubilant Mascot", 28, Rarity.UNCOMMON, mage.cards.j.JubilantMascot.class)); + cards.add(new SetCardInfo("Juggernaut", 238, Rarity.UNCOMMON, mage.cards.j.Juggernaut.class)); cards.add(new SetCardInfo("Jungle Wayfinder", 72, Rarity.COMMON, mage.cards.j.JungleWayfinder.class)); + cards.add(new SetCardInfo("Karametra's Favor", 203, Rarity.UNCOMMON, mage.cards.k.KarametrasFavor.class)); cards.add(new SetCardInfo("Khorvath Brightflame", 9, Rarity.RARE, mage.cards.k.KhorvathBrightflame.class)); + cards.add(new SetCardInfo("Kiss of the Amesha", 225, Rarity.UNCOMMON, mage.cards.k.KissOfTheAmesha.class)); + cards.add(new SetCardInfo("Kitesail Corsair", 120, Rarity.COMMON, mage.cards.k.KitesailCorsair.class)); cards.add(new SetCardInfo("Kor Spiritdancer", 93, Rarity.RARE, mage.cards.k.KorSpiritdancer.class)); cards.add(new SetCardInfo("Kraken Hatchling", 121, Rarity.COMMON, mage.cards.k.KrakenHatchling.class)); + cards.add(new SetCardInfo("Kraul Warrior", 204, Rarity.COMMON, mage.cards.k.KraulWarrior.class)); cards.add(new SetCardInfo("Krav, the Unredeemed", 4, Rarity.RARE, mage.cards.k.KravTheUnredeemed.class)); cards.add(new SetCardInfo("Land Tax", 94, Rarity.MYTHIC, mage.cards.l.LandTax.class)); + cards.add(new SetCardInfo("Last Gasp", 147, Rarity.COMMON, mage.cards.l.LastGasp.class)); cards.add(new SetCardInfo("Last One Standing", 76, Rarity.RARE, mage.cards.l.LastOneStanding.class)); cards.add(new SetCardInfo("Lava-Field Overlord", 60, Rarity.UNCOMMON, mage.cards.l.LavaFieldOverlord.class)); + cards.add(new SetCardInfo("Lead by Example", 205, Rarity.COMMON, mage.cards.l.LeadByExample.class)); cards.add(new SetCardInfo("Ley Weaver", 21, Rarity.UNCOMMON, mage.cards.l.LeyWeaver.class)); + cards.add(new SetCardInfo("Lightning Talons", 180, Rarity.COMMON, mage.cards.l.LightningTalons.class)); + cards.add(new SetCardInfo("Lightwalker", 95, Rarity.COMMON, mage.cards.l.Lightwalker.class)); + cards.add(new SetCardInfo("Liturgy of Blood", 148, Rarity.COMMON, mage.cards.l.LiturgyOfBlood.class)); + cards.add(new SetCardInfo("Long Road Home", 96, Rarity.UNCOMMON, mage.cards.l.LongRoadHome.class)); cards.add(new SetCardInfo("Lore Weaver", 22, Rarity.UNCOMMON, mage.cards.l.LoreWeaver.class)); + cards.add(new SetCardInfo("Loyal Pegasus", 97, Rarity.UNCOMMON, mage.cards.l.LoyalPegasus.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); + cards.add(new SetCardInfo("Magmatic Force", 181, Rarity.RARE, mage.cards.m.MagmaticForce.class)); cards.add(new SetCardInfo("Magus of the Candelabra", 206, Rarity.RARE, mage.cards.m.MagusOfTheCandelabra.class)); cards.add(new SetCardInfo("Mangara of Corondor", 98, Rarity.RARE, mage.cards.m.MangaraOfCorondor.class)); + cards.add(new SetCardInfo("Midnight Guard", 99, Rarity.COMMON, mage.cards.m.MidnightGuard.class)); + cards.add(new SetCardInfo("Millennial Gargoyle", 239, Rarity.COMMON, mage.cards.m.MillennialGargoyle.class)); cards.add(new SetCardInfo("Mind's Eye", 240, Rarity.RARE, mage.cards.m.MindsEye.class)); cards.add(new SetCardInfo("Mindblade Render", 49, Rarity.RARE, mage.cards.m.MindbladeRender.class)); + cards.add(new SetCardInfo("Morbid Curiosity", 149, Rarity.UNCOMMON, mage.cards.m.MorbidCuriosity.class)); cards.add(new SetCardInfo("Morphic Pool", 83, Rarity.RARE, mage.cards.m.MorphicPool.class)); cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mycosynth Lattice", 241, Rarity.MYTHIC, mage.cards.m.MycosynthLattice.class)); cards.add(new SetCardInfo("Mystic Confluence", 122, Rarity.RARE, mage.cards.m.MysticConfluence.class)); cards.add(new SetCardInfo("Najeela, the Blade-Blossom", 62, Rarity.MYTHIC, mage.cards.n.NajeelaTheBladeBlossom.class)); + cards.add(new SetCardInfo("Negate", 123, Rarity.COMMON, mage.cards.n.Negate.class)); + cards.add(new SetCardInfo("Night Market Guard", 242, Rarity.COMMON, mage.cards.n.NightMarketGuard.class)); + cards.add(new SetCardInfo("Nimbus of the Isles", 124, Rarity.COMMON, mage.cards.n.NimbusOfTheIsles.class)); cards.add(new SetCardInfo("Nirkana Revenant", 150, Rarity.MYTHIC, mage.cards.n.NirkanaRevenant.class)); + cards.add(new SetCardInfo("Noosegraf Mob", 151, Rarity.RARE, mage.cards.n.NoosegrafMob.class)); + cards.add(new SetCardInfo("Noxious Dragon", 152, Rarity.UNCOMMON, mage.cards.n.NoxiousDragon.class)); + cards.add(new SetCardInfo("Nyxathid", 153, Rarity.RARE, mage.cards.n.Nyxathid.class)); cards.add(new SetCardInfo("Okaun, Eye of Chaos", 6, Rarity.RARE, mage.cards.o.OkaunEyeOfChaos.class)); - cards.add(new SetCardInfo("Out of Bounds", 38, Rarity.COMMON, mage.cards.o.OutOfBounds.class)); + cards.add(new SetCardInfo("Omenspeaker", 125, Rarity.COMMON, mage.cards.o.Omenspeaker.class)); + cards.add(new SetCardInfo("Opportunity", 126, Rarity.UNCOMMON, mage.cards.o.Opportunity.class)); + cards.add(new SetCardInfo("Oracle's Insight", 127, Rarity.UNCOMMON, mage.cards.o.OraclesInsight.class)); + cards.add(new SetCardInfo("Oreskos Explorer", 100, Rarity.UNCOMMON, mage.cards.o.OreskosExplorer.class)); + cards.add(new SetCardInfo("Out of Bounds", 38, Rarity.UNCOMMON, mage.cards.o.OutOfBounds.class)); + cards.add(new SetCardInfo("Pacifism", 101, Rarity.COMMON, mage.cards.p.Pacifism.class)); + cards.add(new SetCardInfo("Painful Lesson", 154, Rarity.COMMON, mage.cards.p.PainfulLesson.class)); + cards.add(new SetCardInfo("Pathmaker Initiate", 182, Rarity.COMMON, mage.cards.p.PathmakerInitiate.class)); + cards.add(new SetCardInfo("Peace Strider", 243, Rarity.COMMON, mage.cards.p.PeaceStrider.class)); cards.add(new SetCardInfo("Peregrine Drake", 128, Rarity.UNCOMMON, mage.cards.p.PeregrineDrake.class)); + cards.add(new SetCardInfo("Phantom Warrior", 129, Rarity.UNCOMMON, mage.cards.p.PhantomWarrior.class)); + cards.add(new SetCardInfo("Pierce Strider", 244, Rarity.COMMON, mage.cards.p.PierceStrider.class)); cards.add(new SetCardInfo("Pir's Whim", 73, Rarity.RARE, mage.cards.p.PirsWhim.class)); cards.add(new SetCardInfo("Pir, Imaginative Rascal", 11, Rarity.RARE, mage.cards.p.PirImaginativeRascal.class)); cards.add(new SetCardInfo("Plains", 250, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plated Crusher", 207, Rarity.UNCOMMON, mage.cards.p.PlatedCrusher.class)); cards.add(new SetCardInfo("Play of the Game", 29, Rarity.RARE, mage.cards.p.PlayOfTheGame.class)); + cards.add(new SetCardInfo("Prakhata Club Security", 155, Rarity.COMMON, mage.cards.p.PrakhataClubSecurity.class)); + cards.add(new SetCardInfo("Primal Huntbeast", 208, Rarity.COMMON, mage.cards.p.PrimalHuntbeast.class)); cards.add(new SetCardInfo("Proud Mentor", 20, Rarity.UNCOMMON, mage.cards.p.ProudMentor.class)); + cards.add(new SetCardInfo("Pulse of Murasa", 209, Rarity.UNCOMMON, mage.cards.p.PulseOfMurasa.class)); + cards.add(new SetCardInfo("Quest for the Gravelord", 156, Rarity.UNCOMMON, mage.cards.q.QuestForTheGravelord.class)); + cards.add(new SetCardInfo("Raptor Companion", 102, Rarity.COMMON, mage.cards.r.RaptorCompanion.class)); + cards.add(new SetCardInfo("Rebuke", 103, Rarity.COMMON, mage.cards.r.Rebuke.class)); + cards.add(new SetCardInfo("Reckless Reveler", 183, Rarity.COMMON, mage.cards.r.RecklessReveler.class)); + cards.add(new SetCardInfo("Reckless Scholar", 130, Rarity.UNCOMMON, mage.cards.r.RecklessScholar.class)); cards.add(new SetCardInfo("Regna, the Redeemer", 3, Rarity.RARE, mage.cards.r.RegnaTheRedeemer.class)); + cards.add(new SetCardInfo("Relentless Hunter", 226, Rarity.UNCOMMON, mage.cards.r.RelentlessHunter.class)); + cards.add(new SetCardInfo("Return to the Earth", 210, Rarity.COMMON, mage.cards.r.ReturnToTheEarth.class)); + cards.add(new SetCardInfo("Rhox Brute", 227, Rarity.COMMON, mage.cards.r.RhoxBrute.class)); + cards.add(new SetCardInfo("Riptide Crab", 228, Rarity.COMMON, mage.cards.r.RiptideCrab.class)); + cards.add(new SetCardInfo("Rotfeaster Maggot", 157, Rarity.COMMON, mage.cards.r.RotfeasterMaggot.class)); cards.add(new SetCardInfo("Rowan Kenrith", 2, Rarity.MYTHIC, mage.cards.r.RowanKenrith.class)); + cards.add(new SetCardInfo("Royal Trooper", 104, Rarity.COMMON, mage.cards.r.RoyalTrooper.class)); cards.add(new SetCardInfo("Rushblade Commander", 77, Rarity.UNCOMMON, mage.cards.r.RushbladeCommander.class)); cards.add(new SetCardInfo("Saddleback Lagac", 211, Rarity.COMMON, mage.cards.s.SaddlebackLagac.class)); cards.add(new SetCardInfo("Saltwater Stalwart", 39, Rarity.COMMON, mage.cards.s.SaltwaterStalwart.class)); + cards.add(new SetCardInfo("Savage Ventmaw", 229, Rarity.UNCOMMON, mage.cards.s.SavageVentmaw.class)); + cards.add(new SetCardInfo("Screeching Buzzard", 158, Rarity.COMMON, mage.cards.s.ScreechingBuzzard.class)); cards.add(new SetCardInfo("Sea of Clouds", 84, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Seedborn Muse", 212, Rarity.RARE, mage.cards.s.SeedbornMuse.class)); - cards.add(new SetCardInfo("Sentinel Tower", 79, Rarity.RARE, mage.cards.s.SentinelTower.class)); + cards.add(new SetCardInfo("Seer's Lantern", 245, Rarity.COMMON, mage.cards.s.SeersLantern.class)); + cards.add(new SetCardInfo("Sentinel Tower", 79, Rarity.RARE, mage.cards.s.SentinelTower.class)); + cards.add(new SetCardInfo("Shambling Ghoul", 159, Rarity.COMMON, mage.cards.s.ShamblingGhoul.class)); + cards.add(new SetCardInfo("Shock", 184, Rarity.COMMON, mage.cards.s.Shock.class)); cards.add(new SetCardInfo("Shoulder to Shoulder", 105, Rarity.COMMON, mage.cards.s.ShoulderToShoulder.class)); cards.add(new SetCardInfo("Sickle Dancer", 50, Rarity.COMMON, mage.cards.s.SickleDancer.class)); + cards.add(new SetCardInfo("Silverchase Fox", 106, Rarity.COMMON, mage.cards.s.SilverchaseFox.class)); cards.add(new SetCardInfo("Skyshroud Claim", 213, Rarity.COMMON, mage.cards.s.SkyshroudClaim.class)); cards.add(new SetCardInfo("Skystreamer", 31, Rarity.COMMON, mage.cards.s.Skystreamer.class)); + cards.add(new SetCardInfo("Slum Reaper", 160, Rarity.UNCOMMON, mage.cards.s.SlumReaper.class)); cards.add(new SetCardInfo("Soaring Show-Off", 40, Rarity.COMMON, mage.cards.s.SoaringShowOff.class)); + cards.add(new SetCardInfo("Solemn Offering", 107, Rarity.UNCOMMON, mage.cards.s.SolemnOffering.class)); cards.add(new SetCardInfo("Soulblade Corrupter", 17, Rarity.UNCOMMON, mage.cards.s.SoulbladeCorrupter.class)); cards.add(new SetCardInfo("Soulblade Renewer", 18, Rarity.UNCOMMON, mage.cards.s.SoulbladeRenewer.class)); cards.add(new SetCardInfo("Sower of Temptation", 131, Rarity.RARE, mage.cards.s.SowerOfTemptation.class)); + cards.add(new SetCardInfo("Sparring Mummy", 108, Rarity.COMMON, mage.cards.s.SparringMummy.class)); + cards.add(new SetCardInfo("Spectral Searchlight", 246, Rarity.UNCOMMON, mage.cards.s.SpectralSearchlight.class)); cards.add(new SetCardInfo("Spell Snare", 132, Rarity.UNCOMMON, mage.cards.s.SpellSnare.class)); cards.add(new SetCardInfo("Spellseeker", 41, Rarity.RARE, mage.cards.s.Spellseeker.class)); - cards.add(new SetCardInfo("Spellweaver Duo", 42, Rarity.COMMON, mage.cards.s.SpellweaverDuo.class)); + cards.add(new SetCardInfo("Spellweaver Duo", 42, Rarity.COMMON, mage.cards.s.SpellweaverDuo.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); + cards.add(new SetCardInfo("Steppe Glider", 109, Rarity.UNCOMMON, mage.cards.s.SteppeGlider.class)); + cards.add(new SetCardInfo("Stone Golem", 247, Rarity.COMMON, mage.cards.s.StoneGolem.class)); cards.add(new SetCardInfo("Stunning Reversal", 51, Rarity.MYTHIC, mage.cards.s.StunningReversal.class)); cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swarm of Bloodflies", 161, Rarity.UNCOMMON, mage.cards.s.SwarmOfBloodflies.class)); + cards.add(new SetCardInfo("Switcheroo", 133, Rarity.UNCOMMON, mage.cards.s.Switcheroo.class)); cards.add(new SetCardInfo("Swords to Plowshares", 110, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); cards.add(new SetCardInfo("Sylvia Brightspear", 10, Rarity.RARE, mage.cards.s.SylviaBrightspear.class)); + cards.add(new SetCardInfo("Take Up Arms", 111, Rarity.UNCOMMON, mage.cards.t.TakeUpArms.class)); cards.add(new SetCardInfo("Tandem Tactics", 112, Rarity.COMMON, mage.cards.t.TandemTactics.class)); + cards.add(new SetCardInfo("Tavern Swindler", 162, Rarity.UNCOMMON, mage.cards.t.TavernSwindler.class)); + cards.add(new SetCardInfo("Tenacious Dead", 163, Rarity.UNCOMMON, mage.cards.t.TenaciousDead.class)); cards.add(new SetCardInfo("The Crowd Goes Wild", 68, Rarity.UNCOMMON, mage.cards.t.TheCrowdGoesWild.class)); cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); + cards.add(new SetCardInfo("Thunder Strike", 185, Rarity.COMMON, mage.cards.t.ThunderStrike.class)); cards.add(new SetCardInfo("Tidespout Tyrant", 134, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); + cards.add(new SetCardInfo("Totally Lost", 135, Rarity.COMMON, mage.cards.t.TotallyLost.class)); cards.add(new SetCardInfo("True-Name Nemesis", 136, Rarity.MYTHIC, mage.cards.t.TrueNameNemesis.class)); + cards.add(new SetCardInfo("Trumpet Blast", 186, Rarity.COMMON, mage.cards.t.TrumpetBlast.class)); + cards.add(new SetCardInfo("Tyrant's Machine", 248, Rarity.COMMON, mage.cards.t.TyrantsMachine.class)); + cards.add(new SetCardInfo("Unflinching Courage", 230, Rarity.UNCOMMON, mage.cards.u.UnflinchingCourage.class)); + cards.add(new SetCardInfo("Urborg Drake", 231, Rarity.COMMON, mage.cards.u.UrborgDrake.class)); cards.add(new SetCardInfo("Veteran Explorer", 214, Rarity.UNCOMMON, mage.cards.v.VeteranExplorer.class)); cards.add(new SetCardInfo("Vigor", 215, Rarity.RARE, mage.cards.v.Vigor.class)); cards.add(new SetCardInfo("Virtus the Veiled", 7, Rarity.RARE, mage.cards.v.VirtusTheVeiled.class)); + cards.add(new SetCardInfo("Wandering Wolf", 216, Rarity.COMMON, mage.cards.w.WanderingWolf.class)); + cards.add(new SetCardInfo("War's Toll", 187, Rarity.RARE, mage.cards.w.WarsToll.class)); + cards.add(new SetCardInfo("Watercourser", 137, Rarity.COMMON, mage.cards.w.Watercourser.class)); cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); + cards.add(new SetCardInfo("Wrap in Flames", 188, Rarity.COMMON, mage.cards.w.WrapInFlames.class)); + cards.add(new SetCardInfo("Yotian Soldier", 249, Rarity.COMMON, mage.cards.y.YotianSoldier.class)); cards.add(new SetCardInfo("Zndrsplt, Eye of Wisdom", 5, Rarity.RARE, mage.cards.z.ZndrspltEyeOfWisdom.class)); } } From ccdce0a42e233637869283b66fe513209ddcbee4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 15:06:12 -0400 Subject: [PATCH 106/154] Implemented Aurora Champion --- .../src/mage/cards/a/AuroraChampion.java | 87 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 88 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AuroraChampion.java diff --git a/Mage.Sets/src/mage/cards/a/AuroraChampion.java b/Mage.Sets/src/mage/cards/a/AuroraChampion.java new file mode 100644 index 0000000000..ac4d3b685a --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AuroraChampion.java @@ -0,0 +1,87 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.TapTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class AuroraChampion extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent(SubType.WARRIOR, "another Warrior"); + + static { + filter.add(new AnotherPredicate()); + filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); + } + + public AuroraChampion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Whenever Aurora Champion attacks, if you team controls another Warrior, tap target creature. + Ability ability = new ConditionalTriggeredAbility( + new AttacksTriggeredAbility(new TapTargetEffect(), false), + new PermanentsOnTheBattlefieldCondition(filter), + "Whenever {this} attacks, if you team controls another Warrior, tap target creature." + ); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public AuroraChampion(final AuroraChampion card) { + super(card); + } + + @Override + public AuroraChampion copy() { + return new AuroraChampion(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 0b4de0a4f0..ff3f51bda8 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -63,6 +63,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Assassin's Strike", 138, Rarity.UNCOMMON, mage.cards.a.AssassinsStrike.class)); cards.add(new SetCardInfo("Assassinate", 139, Rarity.COMMON, mage.cards.a.Assassinate.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); + cards.add(new SetCardInfo("Aurora Champion", 24, Rarity.COMMON, mage.cards.a.AuroraChampion.class)); cards.add(new SetCardInfo("Azra Oddsmaker", 75, Rarity.UNCOMMON, mage.cards.a.AzraOddsmaker.class)); cards.add(new SetCardInfo("Bathe in Dragonfire", 164, Rarity.COMMON, mage.cards.b.BatheInDragonfire.class)); cards.add(new SetCardInfo("Battle Mastery", 89, Rarity.UNCOMMON, mage.cards.b.BattleMastery.class)); From bdac4dda539ff35f7b6b760a237fd35112abb849 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 15:11:17 -0400 Subject: [PATCH 107/154] Implemented Bring Down --- Mage.Sets/src/mage/cards/b/BringDown.java | 72 +++++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 73 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BringDown.java diff --git a/Mage.Sets/src/mage/cards/b/BringDown.java b/Mage.Sets/src/mage/cards/b/BringDown.java new file mode 100644 index 0000000000..9f30c3f758 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BringDown.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.AssistAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.target.TargetPermanent; + +/** + * + * @author TheElk801 + */ +public class BringDown extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power 4 or greater"); + + static { + filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 3)); + } + + public BringDown(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{W}"); + + // Assist + this.addAbility(new AssistAbility()); + + // Destroy target creature with power 4 or greater. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + } + + public BringDown(final BringDown card) { + super(card); + } + + @Override + public BringDown copy() { + return new BringDown(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index ff3f51bda8..c9e1167e22 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -81,6 +81,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); cards.add(new SetCardInfo("Brightling", 25, Rarity.MYTHIC, mage.cards.b.Brightling.class)); + cards.add(new SetCardInfo("Bring Down", 26, Rarity.UNCOMMON, mage.cards.b.BringDown.class)); cards.add(new SetCardInfo("Call to Heel", 114, Rarity.COMMON, mage.cards.c.CallToHeel.class)); cards.add(new SetCardInfo("Canopy Spider", 191, Rarity.COMMON, mage.cards.c.CanopySpider.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); From f5351b466466e4675ec655f21cf998be57b524a5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 15:17:02 -0400 Subject: [PATCH 108/154] Implemented Bull-Rush Bruiser --- .../src/mage/cards/a/AuroraChampion.java | 4 +- .../src/mage/cards/b/BullRushBruiser.java | 85 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 3 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/b/BullRushBruiser.java diff --git a/Mage.Sets/src/mage/cards/a/AuroraChampion.java b/Mage.Sets/src/mage/cards/a/AuroraChampion.java index ac4d3b685a..cef9b795ba 100644 --- a/Mage.Sets/src/mage/cards/a/AuroraChampion.java +++ b/Mage.Sets/src/mage/cards/a/AuroraChampion.java @@ -66,11 +66,11 @@ public class AuroraChampion extends CardImpl { this.power = new MageInt(3); this.toughness = new MageInt(2); - // Whenever Aurora Champion attacks, if you team controls another Warrior, tap target creature. + // Whenever Aurora Champion attacks, if your team controls another Warrior, tap target creature. Ability ability = new ConditionalTriggeredAbility( new AttacksTriggeredAbility(new TapTargetEffect(), false), new PermanentsOnTheBattlefieldCondition(filter), - "Whenever {this} attacks, if you team controls another Warrior, tap target creature." + "Whenever {this} attacks, if your team controls another Warrior, tap target creature." ); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/b/BullRushBruiser.java b/Mage.Sets/src/mage/cards/b/BullRushBruiser.java new file mode 100644 index 0000000000..0c0a3cb19e --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BullRushBruiser.java @@ -0,0 +1,85 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class BullRushBruiser extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent(SubType.WARRIOR, "another Warrior"); + + static { + filter.add(new AnotherPredicate()); + filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); + } + + public BullRushBruiser(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.MINOTAUR); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Whenever Bull-Rush Bruiser attacks, if your team controls another Warrior, Bull-Rush Bruiser gains first strike until end of turn. + this.addAbility(new ConditionalTriggeredAbility( + new AttacksTriggeredAbility(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance()), false), + new PermanentsOnTheBattlefieldCondition(filter), + "Whenever {this} attacks, if your team controls another Warrior, " + + "{this} gains first strike until end of turn." + )); + } + + public BullRushBruiser(final BullRushBruiser card) { + super(card); + } + + @Override + public BullRushBruiser copy() { + return new BullRushBruiser(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index c9e1167e22..c91da699f6 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -82,6 +82,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); cards.add(new SetCardInfo("Brightling", 25, Rarity.MYTHIC, mage.cards.b.Brightling.class)); cards.add(new SetCardInfo("Bring Down", 26, Rarity.UNCOMMON, mage.cards.b.BringDown.class)); + cards.add(new SetCardInfo("Bull-Rush Bruiser", 57, Rarity.COMMON, mage.cards.b.BullRushBruiser.class)); cards.add(new SetCardInfo("Call to Heel", 114, Rarity.COMMON, mage.cards.c.CallToHeel.class)); cards.add(new SetCardInfo("Canopy Spider", 191, Rarity.COMMON, mage.cards.c.CanopySpider.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); From 96d3330aca1d0991ba0a275dc0aec224ad2a1478 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 15:22:50 -0400 Subject: [PATCH 109/154] Implemented Decorated Champion --- .../src/mage/cards/d/DecoratedChampion.java | 82 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 83 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DecoratedChampion.java diff --git a/Mage.Sets/src/mage/cards/d/DecoratedChampion.java b/Mage.Sets/src/mage/cards/d/DecoratedChampion.java new file mode 100644 index 0000000000..13e38c2af8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DecoratedChampion.java @@ -0,0 +1,82 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class DecoratedChampion extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent(SubType.WARRIOR, "another Warrior"); + + static { + filter.add(new AnotherPredicate()); + filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); + } + + public DecoratedChampion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever another Warrior enters the battlefield under your team's control, put a +1/+1 counter on Decorated Champion. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filter, + "Whenever another Warrior enters the battlefield under your team's control," + + " put a +1/+1 counter on {this}" + )); + } + + public DecoratedChampion(final DecoratedChampion card) { + super(card); + } + + @Override + public DecoratedChampion copy() { + return new DecoratedChampion(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index c91da699f6..9f9264eb45 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -100,6 +100,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Culling Dais", 233, Rarity.UNCOMMON, mage.cards.c.CullingDais.class)); cards.add(new SetCardInfo("Daggerback Basilisk", 194, Rarity.COMMON, mage.cards.d.DaggerbackBasilisk.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); + cards.add(new SetCardInfo("Decorated Champion", 69, Rarity.UNCOMMON, mage.cards.d.DecoratedChampion.class)); cards.add(new SetCardInfo("Diabolic Intent", 141, Rarity.RARE, mage.cards.d.DiabolicIntent.class)); cards.add(new SetCardInfo("Dinrova Horror", 220, Rarity.UNCOMMON, mage.cards.d.DinrovaHorror.class)); cards.add(new SetCardInfo("Doomed Dissenter", 142, Rarity.COMMON, mage.cards.d.DoomedDissenter.class)); From 3da25d1d966fd33d9f89d1da7e75e3b49dd3f633 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 15:23:34 -0400 Subject: [PATCH 110/154] Implemented Magma Hellion --- Mage.Sets/src/mage/cards/m/MagmaHellion.java | 72 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 73 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MagmaHellion.java diff --git a/Mage.Sets/src/mage/cards/m/MagmaHellion.java b/Mage.Sets/src/mage/cards/m/MagmaHellion.java new file mode 100644 index 0000000000..13a4d668dd --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MagmaHellion.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.abilities.keyword.AssistAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class MagmaHellion extends CardImpl { + + public MagmaHellion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{R}"); + + this.subtype.add(SubType.HELLION); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // Assist + this.addAbility(new AssistAbility()); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + } + + public MagmaHellion(final MagmaHellion card) { + super(card); + } + + @Override + public MagmaHellion copy() { + return new MagmaHellion(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 9f9264eb45..141422423f 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -171,6 +171,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Lore Weaver", 22, Rarity.UNCOMMON, mage.cards.l.LoreWeaver.class)); cards.add(new SetCardInfo("Loyal Pegasus", 97, Rarity.UNCOMMON, mage.cards.l.LoyalPegasus.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); + cards.add(new SetCardInfo("Magma Hellion", 61, Rarity.COMMON, mage.cards.m.MagmaHellion.class)); cards.add(new SetCardInfo("Magmatic Force", 181, Rarity.RARE, mage.cards.m.MagmaticForce.class)); cards.add(new SetCardInfo("Magus of the Candelabra", 206, Rarity.RARE, mage.cards.m.MagusOfTheCandelabra.class)); cards.add(new SetCardInfo("Mangara of Corondor", 98, Rarity.RARE, mage.cards.m.MangaraOfCorondor.class)); From e9e53e50b1e361ddc789815f3b19832a47b3bc03 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 15:36:18 -0400 Subject: [PATCH 111/154] Implemented Nimbus Champion --- .../src/mage/cards/n/NimbusChampion.java | 117 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 118 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/n/NimbusChampion.java diff --git a/Mage.Sets/src/mage/cards/n/NimbusChampion.java b/Mage.Sets/src/mage/cards/n/NimbusChampion.java new file mode 100644 index 0000000000..0e7f04dd2b --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NimbusChampion.java @@ -0,0 +1,117 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.n; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class NimbusChampion extends CardImpl { + + public NimbusChampion(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}"); + + this.subtype.add(SubType.AVATAR); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever Nimbus Champion attacks, you may return target creature to its owner's hand if that creature's power is less than or equal to the number of Warriors your team control. + Ability ability = new AttacksTriggeredAbility(new NimbusChampionEffect(), true); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public NimbusChampion(final NimbusChampion card) { + super(card); + } + + @Override + public NimbusChampion copy() { + return new NimbusChampion(this); + } +} + +class NimbusChampionEffect extends OneShotEffect { + + private static final FilterPermanent filter = new FilterPermanent(SubType.WARRIOR, "Warriors your team controls"); + + static { + filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); + } + + NimbusChampionEffect() { + super(Outcome.Benefit); + this.staticText = "return target creature to its owner's hand if " + + "that creature's power is less than or equal to " + + "the number of Warriors your team control."; + } + + NimbusChampionEffect(final NimbusChampionEffect effect) { + super(effect); + } + + @Override + public NimbusChampionEffect copy() { + return new NimbusChampionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent creature = game.getPermanent(source.getFirstTarget()); + if (creature == null || creature.getPower().getValue() + > new PermanentsOnBattlefieldCount(filter).calculate(game, source, this)) { + return false; + } + return new ReturnToHandTargetEffect().apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 141422423f..7bc1c6a3a7 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -187,6 +187,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Najeela, the Blade-Blossom", 62, Rarity.MYTHIC, mage.cards.n.NajeelaTheBladeBlossom.class)); cards.add(new SetCardInfo("Negate", 123, Rarity.COMMON, mage.cards.n.Negate.class)); cards.add(new SetCardInfo("Night Market Guard", 242, Rarity.COMMON, mage.cards.n.NightMarketGuard.class)); + cards.add(new SetCardInfo("Nimbus Champion", 37, Rarity.UNCOMMON, mage.cards.n.NimbusChampion.class)); cards.add(new SetCardInfo("Nimbus of the Isles", 124, Rarity.COMMON, mage.cards.n.NimbusOfTheIsles.class)); cards.add(new SetCardInfo("Nirkana Revenant", 150, Rarity.MYTHIC, mage.cards.n.NirkanaRevenant.class)); cards.add(new SetCardInfo("Noosegraf Mob", 151, Rarity.RARE, mage.cards.n.NoosegrafMob.class)); From b7eaba72b28c2a9796cd08c44e278702ae568a47 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 15:47:55 -0400 Subject: [PATCH 112/154] Implemented Vampire Charmseeker --- .../src/mage/cards/v/VampireCharmseeker.java | 90 +++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 91 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/v/VampireCharmseeker.java diff --git a/Mage.Sets/src/mage/cards/v/VampireCharmseeker.java b/Mage.Sets/src/mage/cards/v/VampireCharmseeker.java new file mode 100644 index 0000000000..954fbd2883 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VampireCharmseeker.java @@ -0,0 +1,90 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.constants.SubType; +import mage.abilities.keyword.AssistAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.common.TargetCardInGraveyard; + +/** + * + * @author TheElk801 + */ +public class VampireCharmseeker extends CardImpl { + + private static final FilterCard filter = new FilterCard("instant, sorcery, or creature card from a graveyard"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY), + new CardTypePredicate(CardType.CREATURE) + )); + } + + public VampireCharmseeker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{U}{B}"); + + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Assist + this.addAbility(new AssistAbility()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Vampire Charmseeker enters the battlefield, return target instant, sorcery, or creature card from a graveyard to its owner's hand. + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), false); + ability.addTarget(new TargetCardInGraveyard(filter)); + this.addAbility(ability); + } + + public VampireCharmseeker(final VampireCharmseeker card) { + super(card); + } + + @Override + public VampireCharmseeker copy() { + return new VampireCharmseeker(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 7bc1c6a3a7..dadf0faa2b 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -279,6 +279,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Tyrant's Machine", 248, Rarity.COMMON, mage.cards.t.TyrantsMachine.class)); cards.add(new SetCardInfo("Unflinching Courage", 230, Rarity.UNCOMMON, mage.cards.u.UnflinchingCourage.class)); cards.add(new SetCardInfo("Urborg Drake", 231, Rarity.COMMON, mage.cards.u.UrborgDrake.class)); + cards.add(new SetCardInfo("Vampire Charmseeker", 78, Rarity.UNCOMMON, mage.cards.v.VampireCharmseeker.class)); cards.add(new SetCardInfo("Veteran Explorer", 214, Rarity.UNCOMMON, mage.cards.v.VeteranExplorer.class)); cards.add(new SetCardInfo("Vigor", 215, Rarity.RARE, mage.cards.v.Vigor.class)); cards.add(new SetCardInfo("Virtus the Veiled", 7, Rarity.RARE, mage.cards.v.VirtusTheVeiled.class)); From e153c3adbf226fc394809d0d73f22c6b2b5dfec8 Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Fri, 25 May 2018 23:11:11 +0200 Subject: [PATCH 113/154] * Siren Reaver - Fixed that it doesn't always cost reduce (fixes #4914). --- Mage.Sets/src/mage/cards/s/SirenReaver.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/s/SirenReaver.java b/Mage.Sets/src/mage/cards/s/SirenReaver.java index f8df0f59e3..587ab828ee 100644 --- a/Mage.Sets/src/mage/cards/s/SirenReaver.java +++ b/Mage.Sets/src/mage/cards/s/SirenReaver.java @@ -40,6 +40,7 @@ import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.watchers.common.PlayerAttackedWatcher; /** * @@ -59,7 +60,7 @@ public class SirenReaver extends CardImpl { Ability ability = new SimpleStaticAbility(Zone.STACK, new SpellCostReductionSourceEffect(1, RaidCondition.instance)); ability.setAbilityWord(AbilityWord.RAID); ability.setRuleAtTheTop(true); - this.addAbility(ability); + this.addAbility(ability, new PlayerAttackedWatcher()); // Flying this.addAbility(FlyingAbility.getInstance()); From 475032d3f6c258c8d4126bfaf29cc8a7da16e38c Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 18:24:54 -0400 Subject: [PATCH 114/154] Implemented Together Forever --- .../src/mage/cards/t/TogetherForever.java | 190 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 191 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TogetherForever.java diff --git a/Mage.Sets/src/mage/cards/t/TogetherForever.java b/Mage.Sets/src/mage/cards/t/TogetherForever.java new file mode 100644 index 0000000000..72df016909 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TogetherForever.java @@ -0,0 +1,190 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.SupportAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.CounterPredicate; +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; + +/** + * + * @author TheElk801, jeffwadsworth + */ +public class TogetherForever extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(""); + + static { + filter.add(new CounterPredicate(CounterType.P1P1)); + } + + public TogetherForever(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{W}"); + + // When Together Forever enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.) + this.addAbility(new SupportAbility(this, 2)); + + // {1}: Choose target creature with a counter on it. When that creature dies this turn, return that card to its owner's hand. + Ability ability = new SimpleActivatedAbility(new TogetherForeverEffect(), new GenericManaCost(1)); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public TogetherForever(final TogetherForever card) { + super(card); + } + + @Override + public TogetherForever copy() { + return new TogetherForever(this); + } +} + +class TogetherForeverEffect extends OneShotEffect { + + public TogetherForeverEffect() { + super(Outcome.Benefit); + this.staticText = "Choose target creature with a counter on it. When that creature dies this turn, return that card to its owner's hand."; + } + + public TogetherForeverEffect(final TogetherForeverEffect effect) { + super(effect); + } + + @Override + public TogetherForeverEffect copy() { + return new TogetherForeverEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + DelayedTriggeredAbility delayedAbility = new TogetherForeverDelayedTriggeredAbility(targetPointer.getFirst(game, source)); + game.addDelayedTriggeredAbility(delayedAbility, source); + return true; + } +} + +class TogetherForeverDelayedTriggeredAbility extends DelayedTriggeredAbility { + + private UUID target; + + public TogetherForeverDelayedTriggeredAbility(UUID target) { + super(new TogetherForeverDelayedEffect(target), Duration.EndOfTurn); + this.target = target; + } + + public TogetherForeverDelayedTriggeredAbility(TogetherForeverDelayedTriggeredAbility ability) { + super(ability); + this.target = ability.target; + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getTargetId().equals(target)) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { + return true; + } + } + return false; + } + + @Override + public TogetherForeverDelayedTriggeredAbility copy() { + return new TogetherForeverDelayedTriggeredAbility(this); + } + + @Override + public String getRule() { + return "When that creature dies this turn, return that card to its owner's hand"; + } +} + +class TogetherForeverDelayedEffect extends OneShotEffect { + + private final UUID target; + + public TogetherForeverDelayedEffect(UUID target) { + super(Outcome.PutCreatureInPlay); + this.target = target; + this.staticText = "return that card to its owner's hand"; + } + + public TogetherForeverDelayedEffect(final TogetherForeverDelayedEffect effect) { + super(effect); + this.target = effect.target; + } + + @Override + public TogetherForeverDelayedEffect copy() { + return new TogetherForeverDelayedEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = (Permanent) game.getLastKnownInformation(target, Zone.BATTLEFIELD); + if (controller != null + && permanent != null) { + Player player = game.getPlayer(permanent.getOwnerId()); + if (player != null) { + Card card = game.getCard(target); + if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD) { + return player.moveCards(card, Zone.HAND, source, game); + } + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index dadf0faa2b..4aecbe7b64 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -272,6 +272,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); cards.add(new SetCardInfo("Thunder Strike", 185, Rarity.COMMON, mage.cards.t.ThunderStrike.class)); cards.add(new SetCardInfo("Tidespout Tyrant", 134, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); + cards.add(new SetCardInfo("Together Forever", 32, Rarity.RARE, mage.cards.t.TogetherForever.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); cards.add(new SetCardInfo("Totally Lost", 135, Rarity.COMMON, mage.cards.t.TotallyLost.class)); cards.add(new SetCardInfo("True-Name Nemesis", 136, Rarity.MYTHIC, mage.cards.t.TrueNameNemesis.class)); From 9e7041f44b126e7b00dc6e9bcac57fad071146f5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 19:08:52 -0400 Subject: [PATCH 115/154] Updated some mana loss text --- .../src/mage/cards/k/KruphixGodOfHorizons.java | 10 +++++----- Mage.Sets/src/mage/cards/o/OmnathLocusOfMana.java | 9 +++++---- Mage.Sets/src/mage/cards/u/Upwelling.java | 13 ++++++------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Mage.Sets/src/mage/cards/k/KruphixGodOfHorizons.java b/Mage.Sets/src/mage/cards/k/KruphixGodOfHorizons.java index c2cd7c15a7..6c25716767 100644 --- a/Mage.Sets/src/mage/cards/k/KruphixGodOfHorizons.java +++ b/Mage.Sets/src/mage/cards/k/KruphixGodOfHorizons.java @@ -50,7 +50,7 @@ import mage.game.events.GameEvent; public class KruphixGodOfHorizons extends CardImpl { public KruphixGodOfHorizons(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{3}{G}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{G}{U}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.GOD); @@ -86,7 +86,7 @@ class KruphixGodOfHorizonsEffect extends ReplacementEffectImpl { public KruphixGodOfHorizonsEffect() { super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "If unused mana would empty from your mana pool, that mana becomes colorless instead"; + staticText = "If you would lose unspent mana, that mana becomes colorless instead."; } public KruphixGodOfHorizonsEffect(final KruphixGodOfHorizonsEffect effect) { @@ -108,13 +108,13 @@ class KruphixGodOfHorizonsEffect extends ReplacementEffectImpl { return true; } - @Override + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.EMPTY_MANA_POOL; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { return event.getPlayerId().equals(source.getControllerId()); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/o/OmnathLocusOfMana.java b/Mage.Sets/src/mage/cards/o/OmnathLocusOfMana.java index 4b87eb887b..923bd1cec1 100644 --- a/Mage.Sets/src/mage/cards/o/OmnathLocusOfMana.java +++ b/Mage.Sets/src/mage/cards/o/OmnathLocusOfMana.java @@ -48,7 +48,7 @@ import mage.players.Player; public class OmnathLocusOfMana extends CardImpl { public OmnathLocusOfMana(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.ELEMENTAL); @@ -78,7 +78,7 @@ class OmnathRuleEffect extends ContinuousEffectImpl { public OmnathRuleEffect() { super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "Green mana doesn't empty from your mana pool as steps and phases end"; + staticText = "You don’t lose unspent green mana as steps and phases end"; } public OmnathRuleEffect(final OmnathRuleEffect effect) { @@ -93,10 +93,11 @@ class OmnathRuleEffect extends ContinuousEffectImpl { @Override public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { Player player = game.getPlayer(source.getControllerId()); - if (player != null){ + if (player != null) { player.getManaPool().addDoNotEmptyManaType(ManaType.GREEN); } - return false; } + return false; + } @Override public boolean apply(Game game, Ability source) { diff --git a/Mage.Sets/src/mage/cards/u/Upwelling.java b/Mage.Sets/src/mage/cards/u/Upwelling.java index 4260d2eb9b..35fe094ee4 100644 --- a/Mage.Sets/src/mage/cards/u/Upwelling.java +++ b/Mage.Sets/src/mage/cards/u/Upwelling.java @@ -51,8 +51,7 @@ import mage.players.Player; public class Upwelling extends CardImpl { public Upwelling(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); // Mana pools don't empty as steps and phases end. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new UpwellingRuleEffect())); @@ -73,7 +72,7 @@ class UpwellingRuleEffect extends ContinuousEffectImpl { public UpwellingRuleEffect() { super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "Mana pools don't empty as steps and phases end"; + staticText = "Players don’t lose unspent mana as steps and phases end"; } public UpwellingRuleEffect(final UpwellingRuleEffect effect) { @@ -89,9 +88,9 @@ class UpwellingRuleEffect extends ContinuousEffectImpl { public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (UUID playerId: game.getState().getPlayersInRange(controller.getId(), game)) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); - if (player != null){ + if (player != null) { ManaPool pool = player.getManaPool(); pool.addDoNotEmptyManaType(ManaType.WHITE); pool.addDoNotEmptyManaType(ManaType.GREEN); @@ -99,11 +98,11 @@ class UpwellingRuleEffect extends ContinuousEffectImpl { pool.addDoNotEmptyManaType(ManaType.RED); pool.addDoNotEmptyManaType(ManaType.BLACK); pool.addDoNotEmptyManaType(ManaType.COLORLESS); - } + } } return true; } - return false; + return false; } @Override From af2d55f8aadbdbecc3ace439492edb1d9490f05f Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Sat, 26 May 2018 01:20:55 +0200 Subject: [PATCH 116/154] Deck editor - Fixed a bug that the card list could not be sorted by color text. --- .../mage/client/deckeditor/table/MageCardComparator.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/table/MageCardComparator.java b/Mage.Client/src/main/java/mage/client/deckeditor/table/MageCardComparator.java index 0ae3255a20..1570c99aa7 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/table/MageCardComparator.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/table/MageCardComparator.java @@ -26,11 +26,10 @@ */ package mage.client.deckeditor.table; +import java.util.Comparator; import mage.cards.MageCard; import mage.view.CardView; -import java.util.Comparator; - /** * {@link MageCard} comparator. Used to sort cards in Deck Editor Table View * pane. @@ -75,7 +74,7 @@ public class MageCardComparator implements Comparator<CardView> { // Color case 3: aCom = a.getColorText(); - bCom = a.getColorText(); + bCom = b.getColorText(); break; // Type case 4: From fcc6174e5e7660e048b22cdd89a2e78ce201c499 Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Sat, 26 May 2018 01:22:28 +0200 Subject: [PATCH 117/154] Some null exceptions checking and fixed some other minor problems. --- .../mage/client/deckeditor/CardSelector.form | 1 - .../mage/client/deckeditor/CardSelector.java | 150 ++++++++---------- .../java/mage/server/TableController.java | 10 +- Mage.Sets/src/mage/cards/c/CorrosiveOoze.java | 2 +- Mage.Sets/src/mage/cards/j/JinxedIdol.java | 2 +- .../src/mage/cards/m/MutagenicGrowth.java | 9 +- Mage.Sets/src/mage/cards/p/Paralyze.java | 19 ++- .../abilities/keywords/ConstellationTest.java | 13 +- .../cards/abilities/keywords/SuspendTest.java | 40 +++++ .../abilities/effects/ContinuousEffects.java | 9 +- .../mage/abilities/keyword/KickerAbility.java | 10 +- Mage/src/main/java/mage/cards/decks/Deck.java | 2 +- .../java/mage/game/combat/CombatGroup.java | 19 ++- 13 files changed, 156 insertions(+), 130 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.form b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.form index 9bc0fefed7..fee373f4c1 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.form +++ b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.form @@ -851,7 +851,6 @@ </Component> <Component class="javax.swing.JCheckBox" name="chkUnique"> <Properties> - <Property name="selected" type="boolean" value="false"/> <Property name="text" type="java.lang.String" value="Unique"/> <Property name="toolTipText" type="java.lang.String" value="Show only the first found card of every card name."/> <Property name="focusable" type="boolean" value="false"/> diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java index 6d1292bb4e..9d406fa78e 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java @@ -51,13 +51,13 @@ import mage.client.MageFrame; import mage.client.cards.*; import mage.client.constants.Constants.SortBy; import mage.client.deckeditor.table.TableModel; +import mage.client.dialog.CheckBoxList; import static mage.client.dialog.PreferencesDialog.KEY_DECK_EDITOR_SEARCH_NAMES; import static mage.client.dialog.PreferencesDialog.KEY_DECK_EDITOR_SEARCH_RULES; import static mage.client.dialog.PreferencesDialog.KEY_DECK_EDITOR_SEARCH_TYPES; import static mage.client.dialog.PreferencesDialog.KEY_DECK_EDITOR_SEARCH_UNIQUE; import mage.client.util.GUISizeHelper; import mage.client.util.gui.FastSearchUtil; -import mage.client.dialog.CheckBoxList; import mage.client.util.sets.ConstructedFormats; import mage.constants.CardType; import mage.constants.Rarity; @@ -85,7 +85,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene private final SortSetting sortSetting; private static final Map<String, Integer> pdAllowed = new HashMap<>(); - private final String TEST_MULTI_SET="Multiple Sets selected"; + private final String TEST_MULTI_SET = "Multiple Sets selected"; private final ActionListener searchAction = evt -> jButtonSearchActionPerformed(evt); @@ -100,22 +100,20 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene initListViewComponents(); setGUISize(); currentView = mainModel; // by default we use List View - - listCodeSelected = new CheckBoxList(); + + listCodeSelected = new CheckBoxList(); // remove the all option - boolean is_removeFinish=false; - - String[] setCodes = ConstructedFormats.getTypes(); - java.util.List<String> result = new ArrayList<>(); - - for(int i=0; (i<setCodes.length)&&(!is_removeFinish);i++) - { + boolean is_removeFinish = false; + + String[] setCodes = ConstructedFormats.getTypes(); + java.util.List<String> result = new ArrayList<>(); + + for (int i = 0; (i < setCodes.length) && (!is_removeFinish); i++) { String item = setCodes[i]; - if(!item.equals(ConstructedFormats.ALL)) - { + if (!item.equals(ConstructedFormats.ALL)) { result.add(item); } - } + } listCodeSelected.setListData(result.toArray()); } @@ -377,33 +375,29 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene criteria.rarities(Rarity.BONUS); } if (this.cbExpansionSet.isVisible()) { - if(listCodeSelected.getCheckedIndices().length <= 1) - { - String expansionSelection = this.cbExpansionSet.getSelectedItem().toString(); - if (!expansionSelection.equals("- All Sets")) { - java.util.List<String> setCodes = ConstructedFormats.getSetsByFormat(expansionSelection); - criteria.setCodes(setCodes.toArray(new String[0])); - } - } - else - { - java.util.List<String> setCodes = new ArrayList<>() ; - //java.util.List<String> listReceived=new ArrayList<>() ; + if (listCodeSelected.getCheckedIndices().length <= 1) { + String expansionSelection = this.cbExpansionSet.getSelectedItem().toString(); + if (!expansionSelection.equals("- All Sets")) { + java.util.List<String> setCodes = ConstructedFormats.getSetsByFormat(expansionSelection); + criteria.setCodes(setCodes.toArray(new String[0])); + } + } else { + java.util.List<String> setCodes = new ArrayList<>(); + //java.util.List<String> listReceived=new ArrayList<>() ; - int[] choiseValue=listCodeSelected.getCheckedIndices(); - ListModel x= listCodeSelected.getModel(); + int[] choiseValue = listCodeSelected.getCheckedIndices(); + ListModel x = listCodeSelected.getModel(); - for(int itemIndex: choiseValue){ - - java.util.List<String> listReceived=ConstructedFormats.getSetsByFormat(x.getElementAt(itemIndex).toString()); - listReceived.stream().filter((item) -> (setCodes.contains(item)==false)).forEachOrdered((item) -> { - setCodes.add(item); - }); - } - criteria.setCodes(setCodes.toArray(new String[0])); - } - } + for (int itemIndex : choiseValue) { + java.util.List<String> listReceived = ConstructedFormats.getSetsByFormat(x.getElementAt(itemIndex).toString()); + listReceived.stream().filter((item) -> (setCodes.contains(item) == false)).forEachOrdered((item) -> { + setCodes.add(item); + }); + } + criteria.setCodes(setCodes.toArray(new String[0])); + } + } return criteria; } @@ -1234,22 +1228,19 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene }// </editor-fold>//GEN-END:initComponents private void cbExpansionSetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbExpansionSetActionPerformed - if(!cbExpansionSet.getSelectedItem().toString().contains(TEST_MULTI_SET)) - { - int index=cbExpansionSet.getSelectedIndex(); - if(cbExpansionSet.getItemAt(0).contains(TEST_MULTI_SET)) - { + if (!cbExpansionSet.getSelectedItem().toString().contains(TEST_MULTI_SET)) { + int index = cbExpansionSet.getSelectedIndex(); + if (cbExpansionSet.getItemAt(0).contains(TEST_MULTI_SET)) { cbExpansionSet.removeItemAt(0); index--; } - listCodeSelected.uncheckAll(); - if(index > 0) - { + listCodeSelected.uncheckAll(); + if (index > 0) { //ofset because all sets is removed from the list - listCodeSelected.setChecked(index-1, true); + listCodeSelected.setChecked(index - 1, true); } } - + filterCards(); }//GEN-LAST:event_cbExpansionSetActionPerformed @@ -1422,62 +1413,53 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene // TODO add your handling code here: }//GEN-LAST:event_chkTypesActionPerformed - private void chkRulesActionPerformed(java.awt.event.ActionEvent evt) { + private void chkRulesActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: - } + } private void chkUniqueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkRulesActionPerformed // TODO add your handling code here: }//GEN-LAST:event_chkRulesActionPerformed private void btnExpansionSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExpansionSearchActionPerformed - FastSearchUtil.showFastSearchForStringComboBox(listCodeSelected, FastSearchUtil.DEFAULT_EXPANSION_SEARCH_MESSAGE); + FastSearchUtil.showFastSearchForStringComboBox(listCodeSelected, FastSearchUtil.DEFAULT_EXPANSION_SEARCH_MESSAGE); // - int[] choiseValue=listCodeSelected.getCheckedIndices(); - ListModel x= listCodeSelected.getModel(); - - if(choiseValue.length==0)//none + int[] choiseValue = listCodeSelected.getCheckedIndices(); + ListModel x = listCodeSelected.getModel(); + + if (choiseValue.length == 0)//none { - cbExpansionSet.setSelectedIndex(0); - } - else if(choiseValue.length==1)//one + cbExpansionSet.setSelectedIndex(0); + } else if (choiseValue.length == 1)//one { - String itemSelected=listCodeSelected.getModel().getElementAt(choiseValue[0]).toString(); - for(int index=0;index < cbExpansionSet.getItemCount();index++) - { - if(cbExpansionSet.getItemAt(index).equals(itemSelected)) - { + String itemSelected = listCodeSelected.getModel().getElementAt(choiseValue[0]).toString(); + for (int index = 0; index < cbExpansionSet.getItemCount(); index++) { + if (cbExpansionSet.getItemAt(index).equals(itemSelected)) { cbExpansionSet.setSelectedIndex(index); } } - - } - else//many + + } else//many { - String message=String.format("%s:%d",TEST_MULTI_SET,choiseValue.length); - - - + String message = String.format("%s:%d", TEST_MULTI_SET, choiseValue.length); + cbExpansionSet.insertItemAt(message, 0); cbExpansionSet.setSelectedIndex(0); - - if(cbExpansionSet.getItemAt(1).contains(TEST_MULTI_SET)) - { - cbExpansionSet.removeItemAt(1); + + if (cbExpansionSet.getItemAt(1).contains(TEST_MULTI_SET)) { + cbExpansionSet.removeItemAt(1); } - - + //listCodeSelected.setChecked(index-1, true); - //cbExpansionSet. + //cbExpansionSet. } - - /*for(int itemIndex: choiseValue){ + + /*for(int itemIndex: choiseValue){ // LogLog.warn(String.format("%d:%s",itemIndex,x.getElementAt(itemIndex).toString())); } - */ + */ // - - filterCards(); + filterCards(); }//GEN-LAST:event_btnExpansionSearchActionPerformed private void tbCommonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbCommonActionPerformed @@ -1537,8 +1519,8 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene private TableModel mainModel; private JTable mainTable; private ICardGrid currentView; - - private CheckBoxList listCodeSelected; + + private final CheckBoxList listCodeSelected; // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.ButtonGroup bgView; diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java index 6464095de5..4275592c56 100644 --- a/Mage.Server/src/main/java/mage/server/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -100,7 +100,7 @@ public class TableController { } else { controllerName = "System"; } - table = new Table(roomId, options.getGameType(), options.getName(), controllerName, DeckValidatorFactory.instance.createDeckValidator(options.getDeckType()), + table = new Table(roomId, options.getGameType(), options.getName(), controllerName, DeckValidatorFactory.instance.createDeckValidator(options.getDeckType()), options.getPlayerTypes(), TableRecorderImpl.instance, match, options.getBannedUsers(), options.isPlaneChase()); chatId = ChatManager.instance.createChatSession("Match Table " + table.getId()); init(); @@ -120,7 +120,7 @@ public class TableController { } else { controllerName = "System"; } - table = new Table(roomId, options.getTournamentType(), options.getName(), controllerName, DeckValidatorFactory.instance.createDeckValidator(options.getMatchOptions().getDeckType()), + table = new Table(roomId, options.getTournamentType(), options.getName(), controllerName, DeckValidatorFactory.instance.createDeckValidator(options.getMatchOptions().getDeckType()), options.getPlayerTypes(), TableRecorderImpl.instance, tournament, options.getMatchOptions().getBannedUsers(), options.isPlaneChase()); chatId = ChatManager.instance.createChatSession("Tourn. table " + table.getId()); } @@ -486,7 +486,11 @@ public class TableController { if (userPlayerMap.get(userId) != null) { return false; } - return UserManager.instance.getUser(userId).get().ccWatchGame(match.getGame().getId()); + Optional<User> _user = UserManager.instance.getUser(userId); + if (!_user.isPresent()) { + return false; + } + return _user.get().ccWatchGame(match.getGame().getId()); } } diff --git a/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java b/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java index 7fa4894f67..ef43f7e358 100644 --- a/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java +++ b/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java @@ -182,7 +182,7 @@ class CorrosiveOozeCombatWatcher extends Watcher { if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED) { Permanent attacker = game.getPermanent(event.getTargetId()); Permanent blocker = game.getPermanent(event.getSourceId()); - if (attacker != null && attacker.getName().equals("Corrosive Ooze")) { + if (attacker != null && attacker.getName().equals("Corrosive Ooze")) { // To check for name is not working if Ooze is copied but name changed if (blocker != null && hasAttachedEquipment(game, blocker)) { MageObjectReference oozeMor = new MageObjectReference(attacker, game); HashSet<MageObjectReference> relatedCreatures = oozeBlocksOrBlocked.getOrDefault(oozeMor, new HashSet<>()); diff --git a/Mage.Sets/src/mage/cards/j/JinxedIdol.java b/Mage.Sets/src/mage/cards/j/JinxedIdol.java index a2448b980a..a722c825f0 100644 --- a/Mage.Sets/src/mage/cards/j/JinxedIdol.java +++ b/Mage.Sets/src/mage/cards/j/JinxedIdol.java @@ -92,7 +92,7 @@ class JinxedIdolEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = (Permanent) source.getSourceObjectIfItStillExists(game); + Permanent permanent = source.getSourcePermanentIfItStillExists(game); if (permanent != null) { return permanent.changeControllerId(source.getFirstTarget(), game); } else { diff --git a/Mage.Sets/src/mage/cards/m/MutagenicGrowth.java b/Mage.Sets/src/mage/cards/m/MutagenicGrowth.java index 213fc1c79b..c3244f56e6 100644 --- a/Mage.Sets/src/mage/cards/m/MutagenicGrowth.java +++ b/Mage.Sets/src/mage/cards/m/MutagenicGrowth.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.m; import java.util.UUID; @@ -42,14 +41,16 @@ import mage.target.common.TargetCreaturePermanent; */ public class MutagenicGrowth extends CardImpl { - public MutagenicGrowth (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{G/P}"); + public MutagenicGrowth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G/P}"); + // ({GP} can be paid with either {G} or 2 life.) + // Target creature gets +2/+2 until end of turn. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn)); } - public MutagenicGrowth (final MutagenicGrowth card) { + public MutagenicGrowth(final MutagenicGrowth card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/p/Paralyze.java b/Mage.Sets/src/mage/cards/p/Paralyze.java index 19f3a57a75..73351e3d6e 100644 --- a/Mage.Sets/src/mage/cards/p/Paralyze.java +++ b/Mage.Sets/src/mage/cards/p/Paralyze.java @@ -52,10 +52,9 @@ import mage.target.common.TargetCreaturePermanent; public class Paralyze extends CardImpl { public Paralyze(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}"); this.subtype.add(SubType.AURA); - // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); @@ -96,14 +95,18 @@ class ParalyzeEffect extends DoIfCostPaid { @Override protected Player getPayingPlayer(Game game, Ability source) { - Permanent attachment = game.getPermanent(source.getSourceId()); - Permanent attachedTo = game.getPermanent(attachment.getAttachedTo()); - return game.getPlayer(attachedTo.getControllerId()); + Permanent attachment = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (attachment != null && attachment.getAttachedTo() != null) { + Permanent attachedTo = game.getPermanent(attachment.getAttachedTo()); + if (attachedTo != null) { + return game.getPlayer(attachedTo.getControllerId()); + } + } + return null; } @Override public String getText(Mode mode) { - return new StringBuilder("that player may ").append(getCostText()) - .append(". If he or she does, ").append(executingEffects.getText(mode)).toString(); + return "that player may " + getCostText() + ". If he or she does, " + executingEffects.getText(mode); } -} \ No newline at end of file +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ConstellationTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ConstellationTest.java index 22755f1ac7..a7c55a1cae 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ConstellationTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ConstellationTest.java @@ -6,7 +6,6 @@ import mage.constants.CardType; import mage.constants.PhaseStep; import mage.constants.SubType; import mage.constants.Zone; -import mage.util.functions.Function; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -16,11 +15,11 @@ import org.mage.test.serverside.base.CardTestPlayerBase; public class ConstellationTest extends CardTestPlayerBase { /** - * Daxos's Torment {3}{B} - * Constellation — Whenever Daxos’s Torment or another enchantment enters the battlefield under your control, - * Daxos’s Torment becomes a 5/5 Demon creature with flying and haste in addition to its other types until end of turn. + * Daxos's Torment {3}{B} Constellation — Whenever Daxos’s Torment or + * another enchantment enters the battlefield under your control, Daxos’s + * Torment becomes a 5/5 Demon creature with flying and haste in addition to + * its other types until end of turn. */ - private final String daxosCard = "Daxos's Torment"; private void assertDaxosBoost(boolean mustHave) { @@ -150,7 +149,7 @@ public class ConstellationTest extends CardTestPlayerBase { assertHandCount(playerA, daxosCard, 0); assertPermanentCount(playerA, daxosCard, 1); - assertHandCount(playerA, "Gravity Sphere", 0); + assertHandCount(playerA, "Gravity Sphere", 0); // Possible problem : this is sometimes 1 assertPermanentCount(playerA, "Gravity Sphere", 1); assertPowerToughness(playerA, daxosCard, 5, 5); @@ -227,5 +226,3 @@ public class ConstellationTest extends CardTestPlayerBase { playDaxosAndVampire(true); } } - - diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java index d8836b3dba..401cbb6dd7 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java @@ -185,4 +185,44 @@ public class SuspendTest extends CardTestPlayerBase { assertHandCount(playerA, "Rift Bolt", 0); } + + /** + * Cards cast from other zones that aren't the hand should not trigger + * Knowledge Pool, as it states that only cards cast from the hand should be + * exiled afterwards. + * + * Example: cards coming off suspend shouldn't trigger Knowledge Pool. + * + */ + @Test + public void testThatNotCastFromHand() { + + // Rift Bolt deals 3 damage to any target. + // Suspend 1-{R} + addCard(Zone.HAND, playerA, "Rift Bolt", 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); + addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 3); + // Imprint - When Knowledge Pool enters the battlefield, each player exiles the top three cards of their library + // Whenever a player casts a spell from their hand, that player exiles it. If the player does, he or she may cast another nonland card + // exiled with Knowledge Pool without paying that card's mana cost. + addCard(Zone.HAND, playerB, "Knowledge Pool", 1); + addCard(Zone.BATTLEFIELD, playerB, "Plains", 6); + addCard(Zone.LIBRARY, playerB, "Silvercoat Lion", 3); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Suspend"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Knowledge Pool"); + + addTarget(playerA, playerB); + + setStopAt(3, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerB, "Knowledge Pool", 1); + assertHandCount(playerA, "Rift Bolt", 0); + assertGraveyardCount(playerA, "Rift Bolt", 1); + assertLife(playerB, 17); + assertPermanentCount(playerA, "Silvercoat Lion", 0); + + } } diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java index 90306488a3..cadb470761 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java @@ -347,7 +347,8 @@ public class ContinuousEffects implements Serializable { } // boolean checkLKI = event.getType().equals(EventType.ZONE_CHANGE) || event.getType().equals(EventType.DESTROYED_PERMANENT); //get all applicable transient Replacement effects - for (ReplacementEffect effect : replacementEffects) { + for (Iterator<ReplacementEffect> iterator = replacementEffects.iterator(); iterator.hasNext();) { + ReplacementEffect effect = iterator.next(); if (!effect.checksEventType(event, game)) { continue; } @@ -378,7 +379,8 @@ public class ContinuousEffects implements Serializable { replaceEffects.put(effect, applicableAbilities); } } - for (PreventionEffect effect : preventionEffects) { + for (Iterator<PreventionEffect> iterator = preventionEffects.iterator(); iterator.hasNext();) { + PreventionEffect effect = iterator.next(); if (!effect.checksEventType(event, game)) { continue; } @@ -932,8 +934,7 @@ public class ContinuousEffects implements Serializable { System.out.println(game.getTurn() + ", " + game.getPhase() + ": " + "need apply " + layer.stream() .map((eff) -> {return eff.getClass().getName().replaceAll(".+\\.(.+)", "$1");}) .collect(Collectors.joining(", "))); - */ - + */ for (ContinuousEffect effect : layer) { if (activeLayerEffects.contains(effect) && !appliedEffects.contains(effect.getId())) { // Effect does still exist and was not applied yet Set<UUID> dependentTo = effect.isDependentTo(layer); diff --git a/Mage/src/main/java/mage/abilities/keyword/KickerAbility.java b/Mage/src/main/java/mage/abilities/keyword/KickerAbility.java index 10f5565cea..d75c6651a0 100644 --- a/Mage/src/main/java/mage/abilities/keyword/KickerAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/KickerAbility.java @@ -27,6 +27,7 @@ */ package mage.abilities.keyword; +import java.util.*; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; @@ -41,8 +42,6 @@ import mage.constants.Zone; import mage.game.Game; import mage.players.Player; -import java.util.*; - /** * 20121001 702.31. Kicker 702.31a Kicker is a static ability that functions * while the spell with kicker is on the stack. "Kicker [cost]" means "You may @@ -134,7 +133,8 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo cost.reset(); } String key = getActivationKey(source, "", game); - for (String activationKey : activations.keySet()) { + for (Iterator<String> iterator = activations.keySet().iterator(); iterator.hasNext();) { + String activationKey = iterator.next(); if (activationKey.startsWith(key) && activations.get(activationKey) > 0) { activations.put(key, 0); } @@ -212,10 +212,10 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo && player.chooseUse(Outcome.Benefit, "Pay " + times + kickerCost.getText(false) + " ?", ability, game)) { this.activateKicker(kickerCost, ability, game); if (kickerCost instanceof Costs) { - for (Iterator itKickerCost = ((Costs) kickerCost).iterator(); itKickerCost.hasNext(); ) { + for (Iterator itKickerCost = ((Costs) kickerCost).iterator(); itKickerCost.hasNext();) { Object kickerCostObject = itKickerCost.next(); if ((kickerCostObject instanceof Costs) || (kickerCostObject instanceof CostsImpl)) { - for (@SuppressWarnings("unchecked") Iterator<Cost> itDetails = ((Costs) kickerCostObject).iterator(); itDetails.hasNext(); ) { + for (@SuppressWarnings("unchecked") Iterator<Cost> itDetails = ((Costs) kickerCostObject).iterator(); itDetails.hasNext();) { addKickerCostsToAbility(itDetails.next(), ability, game); } } else { diff --git a/Mage/src/main/java/mage/cards/decks/Deck.java b/Mage/src/main/java/mage/cards/decks/Deck.java index 57c6a1e96f..b0bb5fe48b 100644 --- a/Mage/src/main/java/mage/cards/decks/Deck.java +++ b/Mage/src/main/java/mage/cards/decks/Deck.java @@ -142,7 +142,7 @@ public class Deck implements Serializable { cardInfo = CardRepository.instance.findCard("Silvercoat Lion"); Logger.getLogger(Deck.class).error("Tried to restart the DB: " + (cardInfo == null ? "not successful" : "successful")); } - return new GameException("Card not found - " + deckCardInfo.getCardName() + " - " + deckCardInfo.getSetCode() + " for deck - " + deckName + '\n' + return new GameException("Card not found - " + deckCardInfo.getCardName() + " - " + deckCardInfo.getSetCode() + "/" + deckCardInfo.getCardNum() + " for deck - " + deckName + '\n' + "Possible reason is, that you use cards in your deck, that are only supported in newer versions of the server.\n" + "So it can help to use the same card from another set, that's already supported from this server."); diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index e1f003e1d8..0fe5834ac9 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -29,7 +29,6 @@ package mage.game.combat; import java.io.Serializable; import java.util.*; - import mage.abilities.common.ControllerAssignCombatDamageToBlockersAbility; import mage.abilities.common.ControllerDivideCombatDamageAbility; import mage.abilities.common.DamageAsThoughNotBlockedAbility; @@ -178,7 +177,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> { } if (attackers.size() != 1) { multiAttackerDamage(first, game); - // } else { + // } else { // singleAttackerDamage(first, game); } } @@ -334,7 +333,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> { defenderDamage(attacker, damage, game); } else if (!blockerOrder.isEmpty()) { // Assign the damage left to first blocker - assigned.put(blockerOrder.get(0), assigned.get(blockerOrder.get(0)) + damage); + assigned.put(blockerOrder.get(0), assigned.get(blockerOrder.get(0)) == null ? 0 : assigned.get(blockerOrder.get(0)) + damage); } } for (UUID blockerId : blockerOrder) { @@ -430,7 +429,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> { } } - public boolean checkSoleBlockerAfter (Permanent blocker, Game game) { + public boolean checkSoleBlockerAfter(Permanent blocker, Game game) { // this solves some corner cases (involving banding) when finding out whether a blocker is blocking alone or not if (blocker.getBlocking() == 1) { if (game.getCombat().blockingGroups.get(blocker.getId()) == null) { @@ -454,9 +453,9 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> { * {@link #singleBlockerDamage}. * * Handles abilities like "{this} an block any number of creatures.". - * - * Blocker damage for blockers blocking single creatures is handled in - * the single/multi blocker methods, so this shouldn't be used anymore. + * + * Blocker damage for blockers blocking single creatures is handled in the + * single/multi blocker methods, so this shouldn't be used anymore. * * @param first * @param game @@ -782,7 +781,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> { /** * There are effects, that set an attacker to be blocked. Therefore this * setter can be used. - * + * * This method lacks a band check, use setBlocked(blocked, game) instead. * * @param blocked @@ -870,8 +869,8 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> { } /** - * Decides damage distribution for blocking creatures with banding or - * if defending player controls the Defensive Formation enchantment. + * Decides damage distribution for blocking creatures with banding or if + * defending player controls the Defensive Formation enchantment. * * @param game */ From ac6c68180a30330678707b275c9d2f828719b4c5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 19:37:54 -0400 Subject: [PATCH 118/154] Replaced more mana pool errata --- Mage.Sets/src/mage/cards/b/BlinkmothUrn.java | 2 +- Mage.Sets/src/mage/cards/b/BubblingMuck.java | 4 ++-- Mage.Sets/src/mage/cards/c/ChaosMoon.java | 16 ++++--------- .../src/mage/cards/d/DawnsReflection.java | 6 ++--- .../src/mage/cards/d/DictateOfKarametra.java | 2 +- Mage.Sets/src/mage/cards/d/DoublingCube.java | 2 +- Mage.Sets/src/mage/cards/d/DroidFoundry.java | 2 +- .../src/mage/cards/e/ElvishGuidance.java | 6 ++--- .../src/mage/cards/e/ExtraplanarLens.java | 2 +- Mage.Sets/src/mage/cards/f/FertileGround.java | 24 +++++++++---------- .../src/mage/cards/g/GauntletOfMight.java | 4 ++-- .../src/mage/cards/g/GauntletOfPower.java | 4 ++-- .../src/mage/cards/g/GlissaSunseeker.java | 8 +++---- .../src/mage/cards/h/HeartbeatOfSpring.java | 2 +- Mage.Sets/src/mage/cards/h/HighTide.java | 4 ++-- Mage.Sets/src/mage/cards/i/IceCauldron.java | 4 ++-- .../src/mage/cards/k/KeeperOfProgenitus.java | 2 +- .../mage/cards/m/MadScienceFairProject.java | 4 ++-- Mage.Sets/src/mage/cards/m/ManaFlare.java | 2 +- Mage.Sets/src/mage/cards/m/ManaShort.java | 6 ++--- Mage.Sets/src/mage/cards/m/MarkOfSakiko.java | 13 +++++----- .../src/mage/cards/m/MarketFestival.java | 6 ++--- Mage.Sets/src/mage/cards/o/Overabundance.java | 2 +- Mage.Sets/src/mage/cards/o/Overgrowth.java | 4 ++-- Mage.Sets/src/mage/cards/p/PowerSink.java | 17 +++++++------ .../mage/cards/s/SakikoMotherOfSummer.java | 8 +++---- .../mage/cards/s/SakuraTribeSpringcaller.java | 4 ++-- Mage.Sets/src/mage/cards/s/SavageVentmaw.java | 4 ++-- .../mage/cards/s/ShizukoCallerOfAutumn.java | 4 ++-- .../src/mage/cards/s/SpectralSearchlight.java | 4 ++-- Mage.Sets/src/mage/cards/t/Tangleroot.java | 2 +- .../src/mage/cards/t/TraceOfAbundance.java | 4 ++-- Mage.Sets/src/mage/cards/u/UtopiaSprawl.java | 6 ++--- Mage.Sets/src/mage/cards/v/Valleymaker.java | 2 +- Mage.Sets/src/mage/cards/v/VerdantHaven.java | 4 ++-- Mage.Sets/src/mage/cards/v/VernalBloom.java | 2 +- Mage.Sets/src/mage/cards/w/WildGrowth.java | 4 ++-- Mage.Sets/src/mage/cards/w/WintersNight.java | 4 ++-- Mage.Sets/src/mage/cards/w/Worldpurge.java | 8 +++---- .../src/mage/cards/z/ZhurTaaAncient.java | 2 +- .../cards/copy/CleverImpersonatorTest.java | 2 +- .../test/cards/mana/EldraziTempleTest.java | 2 +- .../mana/EmptyOnlyOnTurnsEndManaTest.java | 2 +- .../mage/test/cards/mana/ManaFlareTest.java | 2 +- .../cards/triggers/HeartbeatOfSpringTest.java | 2 +- .../common/ManaTypeInManaPoolCount.java | 4 ++-- .../CommanderManaReplacementEffect.java | 1 + ...dManaAnyColorAttachedControllerEffect.java | 2 +- .../mana/AddManaOfAnyTypeProducedEffect.java | 2 +- ...dManaToManaPoolTargetControllerEffect.java | 2 +- 50 files changed, 111 insertions(+), 120 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BlinkmothUrn.java b/Mage.Sets/src/mage/cards/b/BlinkmothUrn.java index 607832d265..a067684b01 100644 --- a/Mage.Sets/src/mage/cards/b/BlinkmothUrn.java +++ b/Mage.Sets/src/mage/cards/b/BlinkmothUrn.java @@ -51,7 +51,7 @@ class BlinkmothUrnEffect extends OneShotEffect { public BlinkmothUrnEffect() { super(Outcome.PutManaInPool); - this.staticText = "if Blinkmoth Urn is untapped, that player adds {1} to their mana pool for each artifact he or she controls"; + this.staticText = "if Blinkmoth Urn is untapped, that player adds {1} for each artifact he or she controls"; } public BlinkmothUrnEffect(final BlinkmothUrnEffect effect) { diff --git a/Mage.Sets/src/mage/cards/b/BubblingMuck.java b/Mage.Sets/src/mage/cards/b/BubblingMuck.java index fd6acd31e9..ab8ab74fab 100644 --- a/Mage.Sets/src/mage/cards/b/BubblingMuck.java +++ b/Mage.Sets/src/mage/cards/b/BubblingMuck.java @@ -56,7 +56,7 @@ public class BubblingMuck extends CardImpl { public BubblingMuck(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}"); - // Until end of turn, whenever a player taps a Swamp for mana, that player adds {B} to their mana pool. + // Until end of turn, whenever a player taps a Swamp for mana, that player adds {B}. this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new BubblingMuckTriggeredAbility())); } @@ -111,6 +111,6 @@ class BubblingMuckTriggeredAbility extends DelayedTriggeredManaAbility { @Override public String getRule() { - return "Until end of turn, whenever a player taps a Swamp for mana, that player adds {B} to their mana pool"; + return "Until end of turn, whenever a player taps a Swamp for mana, that player adds {B}"; } } diff --git a/Mage.Sets/src/mage/cards/c/ChaosMoon.java b/Mage.Sets/src/mage/cards/c/ChaosMoon.java index 8ece9bb8ee..814868f55e 100644 --- a/Mage.Sets/src/mage/cards/c/ChaosMoon.java +++ b/Mage.Sets/src/mage/cards/c/ChaosMoon.java @@ -33,13 +33,10 @@ import mage.Mana; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.TapForManaAllTriggeredManaAbility; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; -import mage.abilities.effects.common.ManaEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; @@ -47,7 +44,6 @@ import mage.abilities.mana.DelayedTriggeredManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.mageobject.ColorPredicate; @@ -67,10 +63,9 @@ import mage.target.targetpointer.FixedTarget; public class ChaosMoon extends CardImpl { public ChaosMoon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); - - // At the beginning of each upkeep, count the number of permanents. If the number is odd, until end of turn, red creatures get +1/+1 and whenever a player taps a Mountain for mana, that player adds {R} to their mana pool (in addition to the mana the land produces). If the number is even, until end of turn, red creatures get -1/-1 and if a player taps a Mountain for mana, that Mountain produces colorless mana instead of any other type. + // At the beginning of each upkeep, count the number of permanents. If the number is odd, until end of turn, red creatures get +1/+1 and whenever a player taps a Mountain for mana, that player adds {R} (in addition to the mana the land produces). If the number is even, until end of turn, red creatures get -1/-1 and if a player taps a Mountain for mana, that Mountain produces colorless mana instead of any other type. this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new ChaosMoonEffect(), TargetController.ANY, false)); } @@ -94,7 +89,7 @@ class ChaosMoonEffect extends OneShotEffect { public ChaosMoonEffect() { super(Outcome.Neutral); - this.staticText = "count the number of permanents. If the number is odd, until end of turn, red creatures get +1/+1 and whenever a player taps a Mountain for mana, that player adds {R} to their mana pool (in addition to the mana the land produces). If the number is even, until end of turn, red creatures get -1/-1 and if a player taps a Mountain for mana, that Mountain produces colorless mana instead of any other type"; + this.staticText = "count the number of permanents. If the number is odd, until end of turn, red creatures get +1/+1 and whenever a player taps a Mountain for mana, that player adds {R} (in addition to the mana the land produces). If the number is even, until end of turn, red creatures get -1/-1 and if a player taps a Mountain for mana, that Mountain produces colorless mana instead of any other type"; } public ChaosMoonEffect(final ChaosMoonEffect effect) { @@ -115,8 +110,7 @@ class ChaosMoonEffect extends OneShotEffect { if (permanentsInPlay % 2 != 0) { game.addEffect(new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false), source); new CreateDelayedTriggeredAbilityEffect(new ChaosMoonOddTriggeredAbility()).apply(game, source); - } - // Even + } // Even else { game.addEffect(new BoostAllEffect(-1, -1, Duration.EndOfTurn, filter, false), source); game.addEffect(new ChaosMoonEvenReplacementEffect(), source); @@ -168,7 +162,7 @@ class ChaosMoonOddTriggeredAbility extends DelayedTriggeredManaAbility { @Override public String getRule() { - return "Until end of turn, whenever a player taps a Mountain for mana, that player adds {R} to their mana pool"; + return "Until end of turn, whenever a player taps a Mountain for mana, that player adds {R}"; } } diff --git a/Mage.Sets/src/mage/cards/d/DawnsReflection.java b/Mage.Sets/src/mage/cards/d/DawnsReflection.java index 8c428f547a..79e2bbf734 100644 --- a/Mage.Sets/src/mage/cards/d/DawnsReflection.java +++ b/Mage.Sets/src/mage/cards/d/DawnsReflection.java @@ -65,7 +65,7 @@ public class DawnsReflection extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - // Whenever enchanted land is tapped for mana, its controller adds two mana in any combination of colors to their mana pool. + // Whenever enchanted land is tapped for mana, its controller adds two mana in any combination of colors. this.addAbility(new DawnsReflectionTriggeredAbility()); } @@ -107,7 +107,7 @@ class DawnsReflectionTriggeredAbility extends TriggeredManaAbility { @Override public String getRule() { - return "Whenever enchanted land is tapped for mana, its controller adds two mana in any combination of colors to their mana pool <i>(in addition to the mana the land produces)</i>."; + return "Whenever enchanted land is tapped for mana, its controller adds two mana in any combination of colors <i>(in addition to the mana the land produces)</i>."; } } @@ -115,7 +115,7 @@ class DawnsReflectionManaEffect extends ManaEffect { public DawnsReflectionManaEffect() { super(); - this.staticText = "its controller adds two mana in any combination of colors to their mana pool"; + this.staticText = "its controller adds two mana in any combination of colors"; } public DawnsReflectionManaEffect(final DawnsReflectionManaEffect effect) { diff --git a/Mage.Sets/src/mage/cards/d/DictateOfKarametra.java b/Mage.Sets/src/mage/cards/d/DictateOfKarametra.java index a1e16a54df..b43f0335af 100644 --- a/Mage.Sets/src/mage/cards/d/DictateOfKarametra.java +++ b/Mage.Sets/src/mage/cards/d/DictateOfKarametra.java @@ -49,7 +49,7 @@ public class DictateOfKarametra extends CardImpl { // Flash this.addAbility(FlashAbility.getInstance()); - // Whenever a player taps a land for mana, that player adds one mana to their mana pool of any type that land produced. + // Whenever a player taps a land for mana, that player adds one mana of any type that land produced. this.addAbility(new TapForManaAllTriggeredManaAbility( new AddManaOfAnyTypeProducedEffect(), new FilterLandPermanent("a player taps a land"), diff --git a/Mage.Sets/src/mage/cards/d/DoublingCube.java b/Mage.Sets/src/mage/cards/d/DoublingCube.java index 5a67189ce6..67c57e7f1a 100644 --- a/Mage.Sets/src/mage/cards/d/DoublingCube.java +++ b/Mage.Sets/src/mage/cards/d/DoublingCube.java @@ -73,7 +73,7 @@ class DoublingCubeEffect extends ManaEffect { DoublingCubeEffect() { super(); - staticText = "Double the amount of each type of mana in your mana pool"; + staticText = "Double the amount of each type of unspent mana you have"; } DoublingCubeEffect(final DoublingCubeEffect effect) { diff --git a/Mage.Sets/src/mage/cards/d/DroidFoundry.java b/Mage.Sets/src/mage/cards/d/DroidFoundry.java index 492600c026..4d2221dfd0 100644 --- a/Mage.Sets/src/mage/cards/d/DroidFoundry.java +++ b/Mage.Sets/src/mage/cards/d/DroidFoundry.java @@ -53,7 +53,7 @@ public class DroidFoundry extends CardImpl { // When Droid Foundry enters the battlefield , add {U}. this.addAbility(new EntersBattlefieldTriggeredAbility(new AddManaToManaPoolSourceControllerEffect(Mana.BlueMana(1)))); - // {T}: Add {W} or {B} to you mana pool. + // {T}: Add {W} or {B}. this.addAbility(new WhiteManaAbility()); this.addAbility(new BlackManaAbility()); } diff --git a/Mage.Sets/src/mage/cards/e/ElvishGuidance.java b/Mage.Sets/src/mage/cards/e/ElvishGuidance.java index 0b40d13062..17bdaae847 100644 --- a/Mage.Sets/src/mage/cards/e/ElvishGuidance.java +++ b/Mage.Sets/src/mage/cards/e/ElvishGuidance.java @@ -55,7 +55,7 @@ import mage.target.common.TargetLandPermanent; public class ElvishGuidance extends CardImpl { public ElvishGuidance(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); this.subtype.add(SubType.AURA); // Enchant land @@ -65,7 +65,7 @@ public class ElvishGuidance extends CardImpl { Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - // Whenever enchanted land is tapped for mana, its controller adds {G} to their mana pool for each Elf on the battlefield. + // Whenever enchanted land is tapped for mana, its controller adds {G} for each Elf on the battlefield. this.addAbility(new ElvishGuidanceTriggeredAbility()); } @@ -107,6 +107,6 @@ class ElvishGuidanceTriggeredAbility extends TriggeredManaAbility { @Override public String getRule() { - return "Whenever enchanted land is tapped for mana, its controller adds {G} to their mana pool for each Elf on the battlefield."; + return "Whenever enchanted land is tapped for mana, its controller adds {G} for each Elf on the battlefield."; } } diff --git a/Mage.Sets/src/mage/cards/e/ExtraplanarLens.java b/Mage.Sets/src/mage/cards/e/ExtraplanarLens.java index 404c886f3d..75982a9d73 100644 --- a/Mage.Sets/src/mage/cards/e/ExtraplanarLens.java +++ b/Mage.Sets/src/mage/cards/e/ExtraplanarLens.java @@ -74,7 +74,7 @@ public class ExtraplanarLens extends CardImpl { ability.addTarget(new TargetLandPermanent(filter)); this.addAbility(ability); - // Whenever a land with the same name as the exiled card is tapped for mana, its controller adds one mana to their mana pool of any type that land produced. + // Whenever a land with the same name as the exiled card is tapped for mana, its controller adds one mana of any type that land produced. this.addAbility(new ExtraplanarLensTriggeredAbility()); } diff --git a/Mage.Sets/src/mage/cards/f/FertileGround.java b/Mage.Sets/src/mage/cards/f/FertileGround.java index 7b98035eed..290fe25b96 100644 --- a/Mage.Sets/src/mage/cards/f/FertileGround.java +++ b/Mage.Sets/src/mage/cards/f/FertileGround.java @@ -54,17 +54,16 @@ import mage.target.targetpointer.FixedTarget; public class FertileGround extends CardImpl { public FertileGround(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); this.subtype.add(SubType.AURA); - // Enchant land TargetPermanent auraTarget = new TargetLandPermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - // Whenever enchanted land is tapped for mana, its controller adds one mana of any color to their mana pool. + // Whenever enchanted land is tapped for mana, its controller adds one mana of any color. this.addAbility(new FertileGroundTriggeredAbility()); } @@ -80,7 +79,6 @@ public class FertileGround extends CardImpl { class FertileGroundTriggeredAbility extends TriggeredManaAbility { - public FertileGroundTriggeredAbility() { super(Zone.BATTLEFIELD, new AddManaAnyColorAttachedControllerEffect()); } @@ -96,14 +94,14 @@ class FertileGroundTriggeredAbility extends TriggeredManaAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent enchantment = game.getPermanent(this.getSourceId()); - if (enchantment != null && event.getSourceId().equals(enchantment.getAttachedTo())) { - Permanent enchanted = game.getPermanent(enchantment.getAttachedTo()); - if (enchanted != null) { - getEffects().get(0).setTargetPointer(new FixedTarget(enchanted.getControllerId())); - return true; - } + Permanent enchantment = game.getPermanent(this.getSourceId()); + if (enchantment != null && event.getSourceId().equals(enchantment.getAttachedTo())) { + Permanent enchanted = game.getPermanent(enchantment.getAttachedTo()); + if (enchanted != null) { + getEffects().get(0).setTargetPointer(new FixedTarget(enchanted.getControllerId())); + return true; } + } return false; } @@ -114,6 +112,6 @@ class FertileGroundTriggeredAbility extends TriggeredManaAbility { @Override public String getRule() { - return "Whenever enchanted land is tapped for mana, its controller adds one mana of any color to their mana pool"; + return "Whenever enchanted land is tapped for mana, its controller adds one mana of any color"; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/g/GauntletOfMight.java b/Mage.Sets/src/mage/cards/g/GauntletOfMight.java index d167731847..30126316b9 100644 --- a/Mage.Sets/src/mage/cards/g/GauntletOfMight.java +++ b/Mage.Sets/src/mage/cards/g/GauntletOfMight.java @@ -63,9 +63,9 @@ public class GauntletOfMight extends CardImpl { // Red creatures get +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, false))); - // Whenever a Mountain is tapped for mana, its controller adds {R} to their mana pool. + // Whenever a Mountain is tapped for mana, its controller adds {R}. ManaEffect effect = new AddManaToManaPoolTargetControllerEffect(new Mana(ColoredManaSymbol.R), "their"); - effect.setText("its controller adds {R} to their mana pool"); + effect.setText("its controller adds {R}"); this.addAbility(new TapForManaAllTriggeredManaAbility( effect, filterMountain, SetTargetPointer.PLAYER)); } diff --git a/Mage.Sets/src/mage/cards/g/GauntletOfPower.java b/Mage.Sets/src/mage/cards/g/GauntletOfPower.java index dbe64da15d..3b22559ef9 100644 --- a/Mage.Sets/src/mage/cards/g/GauntletOfPower.java +++ b/Mage.Sets/src/mage/cards/g/GauntletOfPower.java @@ -73,7 +73,7 @@ public class GauntletOfPower extends CardImpl { // Creatures of the chosen color get +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GauntletOfPowerEffect1())); - // Whenever a basic land is tapped for mana of the chosen color, its controller adds one mana of that color to their mana pool. + // Whenever a basic land is tapped for mana of the chosen color, its controller adds one mana of that color. this.addAbility(new TapForManaAllTriggeredAbility(new GauntletOfPowerEffectEffect2(), filter, SetTargetPointer.PERMANENT)); } @@ -198,7 +198,7 @@ class GauntletOfPowerEffectEffect2 extends ManaEffect { public GauntletOfPowerEffectEffect2() { super(); - staticText = "its controller adds one mana of that color to their mana pool"; + staticText = "its controller adds one mana of that color"; } public GauntletOfPowerEffectEffect2(final GauntletOfPowerEffectEffect2 effect) { diff --git a/Mage.Sets/src/mage/cards/g/GlissaSunseeker.java b/Mage.Sets/src/mage/cards/g/GlissaSunseeker.java index 11c68921bb..9015da3dc1 100644 --- a/Mage.Sets/src/mage/cards/g/GlissaSunseeker.java +++ b/Mage.Sets/src/mage/cards/g/GlissaSunseeker.java @@ -54,7 +54,7 @@ import mage.target.common.TargetArtifactPermanent; public class GlissaSunseeker extends CardImpl { public GlissaSunseeker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.ELF); this.power = new MageInt(3); @@ -62,7 +62,7 @@ public class GlissaSunseeker extends CardImpl { // First strike this.addAbility(FirstStrikeAbility.getInstance()); - + // {tap}: Destroy target artifact if its converted mana cost is equal to the amount of mana in your mana pool. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GlissaSunseekerEffect(), new TapSourceCost()); ability.addTarget(new TargetArtifactPermanent()); @@ -83,7 +83,7 @@ class GlissaSunseekerEffect extends OneShotEffect { public GlissaSunseekerEffect() { super(Outcome.DestroyPermanent); - this.staticText = "Destroy target artifact if its converted mana cost is equal to the amount of mana in your mana pool"; + this.staticText = "Destroy target artifact if its converted mana cost is equal to the amount of unspent mana you have"; } public GlissaSunseekerEffect(final GlissaSunseekerEffect effect) { @@ -114,4 +114,4 @@ class GlissaSunseekerEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/h/HeartbeatOfSpring.java b/Mage.Sets/src/mage/cards/h/HeartbeatOfSpring.java index 82a298b476..f42943f85c 100644 --- a/Mage.Sets/src/mage/cards/h/HeartbeatOfSpring.java +++ b/Mage.Sets/src/mage/cards/h/HeartbeatOfSpring.java @@ -46,7 +46,7 @@ public class HeartbeatOfSpring extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{G}"); - // Whenever a player taps a land for mana, that player adds one mana to their mana pool of any type that land produced. + // Whenever a player taps a land for mana, that player adds one mana of any type that land produced. this.addAbility(new TapForManaAllTriggeredManaAbility( new AddManaOfAnyTypeProducedEffect(), new FilterLandPermanent("a player taps a land"), diff --git a/Mage.Sets/src/mage/cards/h/HighTide.java b/Mage.Sets/src/mage/cards/h/HighTide.java index dddbcd588d..6274054968 100644 --- a/Mage.Sets/src/mage/cards/h/HighTide.java +++ b/Mage.Sets/src/mage/cards/h/HighTide.java @@ -56,7 +56,7 @@ public class HighTide extends CardImpl { public HighTide(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}"); - // Until end of turn, whenever a player taps an Island for mana, that player adds {U} to their mana pool. + // Until end of turn, whenever a player taps an Island for mana, that player adds {U}. this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new HighTideTriggeredAbility())); } @@ -112,6 +112,6 @@ class HighTideTriggeredAbility extends DelayedTriggeredManaAbility { @Override public String getRule() { - return "Until end of turn, whenever a player taps an Island for mana, that player adds {U} to their mana pool"; + return "Until end of turn, whenever a player taps an Island for mana, that player adds {U}"; } } diff --git a/Mage.Sets/src/mage/cards/i/IceCauldron.java b/Mage.Sets/src/mage/cards/i/IceCauldron.java index 9c7555d4a4..893fab8321 100644 --- a/Mage.Sets/src/mage/cards/i/IceCauldron.java +++ b/Mage.Sets/src/mage/cards/i/IceCauldron.java @@ -81,7 +81,7 @@ public class IceCauldron extends CardImpl { ability.addCost(new TapSourceCost()); this.addAbility(ability); - // {T}, Remove a charge counter from Ice Cauldron: Add Ice Cauldron's last noted type and amount of mana to your mana pool. Spend this mana only to cast the last card exiled with Ice Cauldron. + // {T}, Remove a charge counter from Ice Cauldron: Add Ice Cauldron's last noted type and amount of mana. Spend this mana only to cast the last card exiled with Ice Cauldron. Ability ability2 = new SimpleManaAbility(Zone.BATTLEFIELD, new IceCauldronAddManaEffect(), new TapSourceCost()); ability2.addCost(new RemoveCountersSourceCost(CounterType.CHARGE.createInstance())); this.addAbility(ability2); @@ -221,7 +221,7 @@ class IceCauldronAddManaEffect extends ManaEffect { IceCauldronAddManaEffect() { super(); - staticText = "Add {this}'s last noted type and amount of mana to your mana pool. Spend this mana only to cast the last card exiled with {this}"; + staticText = "Add {this}'s last noted type and amount of mana. Spend this mana only to cast the last card exiled with {this}"; } IceCauldronAddManaEffect(IceCauldronAddManaEffect effect) { diff --git a/Mage.Sets/src/mage/cards/k/KeeperOfProgenitus.java b/Mage.Sets/src/mage/cards/k/KeeperOfProgenitus.java index faaf4ad35b..f9ead2736c 100644 --- a/Mage.Sets/src/mage/cards/k/KeeperOfProgenitus.java +++ b/Mage.Sets/src/mage/cards/k/KeeperOfProgenitus.java @@ -64,7 +64,7 @@ public class KeeperOfProgenitus extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(3); - // Whenever a player taps a Mountain, Forest, or Plains for mana, that player adds one mana to their mana pool of any type that land produced. + // Whenever a player taps a Mountain, Forest, or Plains for mana, that player adds one mana of any type that land produced. this.addAbility(new TapForManaAllTriggeredManaAbility( new AddManaOfAnyTypeProducedEffect(), filter, SetTargetPointer.PERMANENT)); diff --git a/Mage.Sets/src/mage/cards/m/MadScienceFairProject.java b/Mage.Sets/src/mage/cards/m/MadScienceFairProject.java index bc79e82ec0..7076823c27 100644 --- a/Mage.Sets/src/mage/cards/m/MadScienceFairProject.java +++ b/Mage.Sets/src/mage/cards/m/MadScienceFairProject.java @@ -51,7 +51,7 @@ public class MadScienceFairProject extends CardImpl { public MadScienceFairProject(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); - // {tap}: Roll a six-sided die. On a 3 or lower, target player adds {C} to their mana pool. Otherwise, that player adds one mana of any color he or she chooses to their mana pool. + // {tap}: Roll a six-sided die. On a 3 or lower, target player adds {C}. Otherwise, that player adds one mana of any color he or she chooses. this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new MadScienceFairManaEffect(), new TapSourceCost())); } @@ -69,7 +69,7 @@ class MadScienceFairManaEffect extends ManaEffect { public MadScienceFairManaEffect() { super(); - this.staticText = "Roll a six-sided die. On a 3 or lower, target player adds {C} to their mana pool. Otherwise, that player adds one mana of any color he or she chooses to their mana pool"; + this.staticText = "Roll a six-sided die. On a 3 or lower, target player adds {C}. Otherwise, that player adds one mana of any color he or she chooses"; } public MadScienceFairManaEffect(final MadScienceFairManaEffect effect) { diff --git a/Mage.Sets/src/mage/cards/m/ManaFlare.java b/Mage.Sets/src/mage/cards/m/ManaFlare.java index ecaa9aa01b..7464ef8112 100644 --- a/Mage.Sets/src/mage/cards/m/ManaFlare.java +++ b/Mage.Sets/src/mage/cards/m/ManaFlare.java @@ -45,7 +45,7 @@ public class ManaFlare extends CardImpl { public ManaFlare(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}"); - // Whenever a player taps a land for mana, that player adds one mana to their mana pool of any type that land produced. + // Whenever a player taps a land for mana, that player adds one mana of any type that land produced. this.addAbility(new TapForManaAllTriggeredManaAbility( new AddManaOfAnyTypeProducedEffect(), new FilterLandPermanent("a player taps a land"), diff --git a/Mage.Sets/src/mage/cards/m/ManaShort.java b/Mage.Sets/src/mage/cards/m/ManaShort.java index 701ebe6c83..b9d2491666 100644 --- a/Mage.Sets/src/mage/cards/m/ManaShort.java +++ b/Mage.Sets/src/mage/cards/m/ManaShort.java @@ -45,7 +45,7 @@ import mage.target.TargetPlayer; public class ManaShort extends CardImpl { public ManaShort(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); // Tap all lands target player controls and empty their mana pool. this.getSpellAbility().addEffect(new ManaShortEffect()); @@ -66,7 +66,7 @@ class ManaShortEffect extends TapAllTargetPlayerControlsEffect { public ManaShortEffect() { super(new FilterLandPermanent()); - staticText = "Tap all lands target player controls and empty their mana pool"; + staticText = "Tap all lands target player controls and that player loses all unspent mana"; } public ManaShortEffect(final ManaShortEffect effect) { @@ -81,7 +81,7 @@ class ManaShortEffect extends TapAllTargetPlayerControlsEffect { @Override public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(source.getFirstTarget()); - if(targetPlayer != null) { + if (targetPlayer != null) { super.apply(game, source); targetPlayer.getManaPool().emptyPool(game); return true; diff --git a/Mage.Sets/src/mage/cards/m/MarkOfSakiko.java b/Mage.Sets/src/mage/cards/m/MarkOfSakiko.java index d68731b7ec..2899c07518 100644 --- a/Mage.Sets/src/mage/cards/m/MarkOfSakiko.java +++ b/Mage.Sets/src/mage/cards/m/MarkOfSakiko.java @@ -59,22 +59,21 @@ import mage.target.targetpointer.FixedTarget; public class MarkOfSakiko extends CardImpl { public MarkOfSakiko(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); this.subtype.add(SubType.AURA); - // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // Enchanted creature has "Whenever this creature deals combat damage to a player, add that much {G}. Until end of turn, you don’t lose this mana as steps and phases end." - Effect effect = new GainAbilityAttachedEffect(new MarkOfSakikoTriggeredAbility(), AttachmentType.AURA); + Effect effect = new GainAbilityAttachedEffect(new MarkOfSakikoTriggeredAbility(), AttachmentType.AURA); effect.setText("Enchanted creature has \"Whenever this creature deals combat damage to a player, add that much {G}. Until end of turn, you don’t lose this mana as steps and phases end.\""); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); - + } public MarkOfSakiko(final MarkOfSakiko card) { @@ -114,7 +113,7 @@ class MarkOfSakikoTriggeredAbility extends TriggeredAbilityImpl { this.getEffects().clear(); Effect effect = new AddManaToManaPoolTargetControllerEffect(Mana.GreenMana(event.getAmount()), "that player", true); effect.setTargetPointer(new FixedTarget(getControllerId())); - effect.setText("add that much {G}. Until end of turn, this mana doesn't empty from your mana pool as steps and phases end"); + effect.setText("add that much {G}. Until end of turn, you don’t lose this mana as steps and phases end"); this.addEffect(effect); return true; } @@ -127,4 +126,4 @@ class MarkOfSakikoTriggeredAbility extends TriggeredAbilityImpl { return "Whenever this creature deals combat damage to a player, add that much {G}. " + "Until end of turn, you don’t lose this mana as steps and phases end."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/m/MarketFestival.java b/Mage.Sets/src/mage/cards/m/MarketFestival.java index 441c57cff8..e986fe6bd2 100644 --- a/Mage.Sets/src/mage/cards/m/MarketFestival.java +++ b/Mage.Sets/src/mage/cards/m/MarketFestival.java @@ -67,7 +67,7 @@ public class MarketFestival extends CardImpl { Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - // Whenever enchanted land is tapped for mana, its controller adds two mana in any combination of colors to their mana pool (in addition to the mana the land produces). + // Whenever enchanted land is tapped for mana, its controller adds two mana in any combination of colors (in addition to the mana the land produces). this.addAbility(new MarketFestivalTriggeredAbility()); } @@ -109,7 +109,7 @@ class MarketFestivalTriggeredAbility extends TriggeredManaAbility { @Override public String getRule() { - return "Whenever enchanted land is tapped for mana, its controller adds two mana in any combination of colors to their mana pool <i>(in addition to the mana the land produces)</i>."; + return "Whenever enchanted land is tapped for mana, its controller adds two mana in any combination of colors <i>(in addition to the mana the land produces)</i>."; } } @@ -117,7 +117,7 @@ class MarketFestivalManaEffect extends ManaEffect { public MarketFestivalManaEffect() { super(); - this.staticText = "its controller adds two mana in any combination of colors to their mana pool"; + this.staticText = "its controller adds two mana in any combination of colors"; } public MarketFestivalManaEffect(final MarketFestivalManaEffect effect) { diff --git a/Mage.Sets/src/mage/cards/o/Overabundance.java b/Mage.Sets/src/mage/cards/o/Overabundance.java index b6fb9b281d..bb36bfef9f 100644 --- a/Mage.Sets/src/mage/cards/o/Overabundance.java +++ b/Mage.Sets/src/mage/cards/o/Overabundance.java @@ -48,7 +48,7 @@ public class Overabundance extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}{G}"); - // Whenever a player taps a land for mana, that player adds one mana to their mana pool of any type that land produced, and Overabundance deals 1 damage to him or her. + // Whenever a player taps a land for mana, that player adds one mana of any type that land produced, and Overabundance deals 1 damage to him or her. this.addAbility(new TapForManaAllTriggeredManaAbility( new AddManaOfAnyTypeProducedEffect(), new FilterLandPermanent( "a player taps a land"), diff --git a/Mage.Sets/src/mage/cards/o/Overgrowth.java b/Mage.Sets/src/mage/cards/o/Overgrowth.java index 26bf28bb89..e1e4a3980a 100644 --- a/Mage.Sets/src/mage/cards/o/Overgrowth.java +++ b/Mage.Sets/src/mage/cards/o/Overgrowth.java @@ -65,7 +65,7 @@ public class Overgrowth extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - // Whenever enchanted land is tapped for mana, its controller adds {G}{G} to their mana pool. + // Whenever enchanted land is tapped for mana, its controller adds {G}{G}. this.addAbility(new OvergrowthTriggeredAbility()); } @@ -116,6 +116,6 @@ class OvergrowthTriggeredAbility extends TriggeredManaAbility { @Override public String getRule() { - return "Whenever enchanted land is tapped for mana, its controller adds {G}{G} to their mana pool"; + return "Whenever enchanted land is tapped for mana, its controller adds {G}{G}"; } } diff --git a/Mage.Sets/src/mage/cards/p/PowerSink.java b/Mage.Sets/src/mage/cards/p/PowerSink.java index 4ed69dbe9a..e078625be1 100644 --- a/Mage.Sets/src/mage/cards/p/PowerSink.java +++ b/Mage.Sets/src/mage/cards/p/PowerSink.java @@ -53,10 +53,9 @@ import mage.target.TargetSpell; public class PowerSink extends CardImpl { public PowerSink(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{U}"); - - // Counter target spell unless its controller pays {X}. If he or she doesn't, that player taps all lands with mana abilities he or she controls and empties their mana pool. + // Counter target spell unless its controller pays {X}. If that player doesn’t, they tap all lands with mana abilities they control and lose all unspent mana. this.getSpellAbility().addEffect(new PowerSinkCounterUnlessPaysEffect()); this.getSpellAbility().addTarget(new TargetSpell()); } @@ -75,7 +74,7 @@ class PowerSinkCounterUnlessPaysEffect extends OneShotEffect { public PowerSinkCounterUnlessPaysEffect() { super(Outcome.Detriment); - this.staticText = "Counter target spell unless its controller pays {X}. If he or she doesn't, that player taps all lands with mana abilities he or she controls and empties their mana pool."; + this.staticText = "Counter target spell unless its controller pays {X}. If that player doesn’t, they tap all lands with mana abilities they control and lose all unspent mana"; } public PowerSinkCounterUnlessPaysEffect(final PowerSinkCounterUnlessPaysEffect effect) { @@ -98,19 +97,19 @@ class PowerSinkCounterUnlessPaysEffect extends OneShotEffect { int amount = source.getManaCostsToPay().getX(); if (amount > 0) { GenericManaCost cost = new GenericManaCost(amount); - StringBuilder sb = new StringBuilder("Pay ").append(cost.getText()).append('?'); - if (player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { + String sb = String.valueOf("Pay " + cost.getText()) + Character.toString('?'); + if (player.chooseUse(Outcome.Benefit, sb, source, game)) { if (cost.pay(source, game, source.getSourceId(), player.getId(), false)) { game.informPlayers(new StringBuilder(sourceObject.getName()).append(": additional cost was paid").toString()); return true; } } - + // Counter target spell unless its controller pays {X} if (game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game)) { game.informPlayers(new StringBuilder(sourceObject.getName()).append(": additional cost wasn't paid - countering ").append(spell.getName()).toString()); } - + // that player taps all lands with mana abilities he or she controls... List<Permanent> lands = game.getBattlefield().getAllActivePermanents(new FilterLandPermanent(), player.getId(), game); for (Permanent land : lands) { @@ -131,5 +130,5 @@ class PowerSinkCounterUnlessPaysEffect extends OneShotEffect { } return false; } - + } diff --git a/Mage.Sets/src/mage/cards/s/SakikoMotherOfSummer.java b/Mage.Sets/src/mage/cards/s/SakikoMotherOfSummer.java index 628c24b519..e1cbb2c81d 100644 --- a/Mage.Sets/src/mage/cards/s/SakikoMotherOfSummer.java +++ b/Mage.Sets/src/mage/cards/s/SakikoMotherOfSummer.java @@ -53,7 +53,7 @@ import mage.target.targetpointer.FixedTarget; public class SakikoMotherOfSummer extends CardImpl { public SakikoMotherOfSummer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.SNAKE); this.subtype.add(SubType.SHAMAN); @@ -63,7 +63,7 @@ public class SakikoMotherOfSummer extends CardImpl { // Whenever a creature you control deals combat damage to a player, add that much {G}. Until end of turn, you don’t lose this mana as steps and phases end. this.addAbility(new SakikoMotherOfSummerTriggeredAbility()); - + } public SakikoMotherOfSummer(final SakikoMotherOfSummer card) { @@ -104,7 +104,7 @@ class SakikoMotherOfSummerTriggeredAbility extends TriggeredAbilityImpl { this.getEffects().clear(); Effect effect = new AddManaToManaPoolTargetControllerEffect(Mana.GreenMana(event.getAmount()), "that player", true); effect.setTargetPointer(new FixedTarget(creature.getControllerId())); - effect.setText("add that much {G}. Until end of turn, this mana doesn't empty from your mana pool as steps and phases end"); + effect.setText("add that much {G}. Until end of turn, you don’t lose this mana as steps and phases end"); this.addEffect(effect); return true; } @@ -116,4 +116,4 @@ class SakikoMotherOfSummerTriggeredAbility extends TriggeredAbilityImpl { public String getRule() { return "Whenever a creature you control deals combat damage to a player, add that much {G}. Until end of turn, you don’t lose this mana as steps and phases end."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/SakuraTribeSpringcaller.java b/Mage.Sets/src/mage/cards/s/SakuraTribeSpringcaller.java index 65ade8f8c3..6f89107eec 100644 --- a/Mage.Sets/src/mage/cards/s/SakuraTribeSpringcaller.java +++ b/Mage.Sets/src/mage/cards/s/SakuraTribeSpringcaller.java @@ -47,7 +47,7 @@ import mage.constants.Zone; public class SakuraTribeSpringcaller extends CardImpl { public SakuraTribeSpringcaller(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.SNAKE); this.subtype.add(SubType.SHAMAN); @@ -56,7 +56,7 @@ public class SakuraTribeSpringcaller extends CardImpl { // At the beginning of your upkeep, add {G}. Until end of turn, you don’t lose this mana as steps and phases end. Effect effect = new AddManaToManaPoolTargetControllerEffect(new Mana(Mana.GreenMana(1)), "your", true); - effect.setText("add {G}. Until end of turn, this mana doesn't empty from your mana pool as steps and phases end"); + effect.setText("add {G}. Until end of turn, you don’t lose this mana as steps and phases end"); this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.YOU, false)); } diff --git a/Mage.Sets/src/mage/cards/s/SavageVentmaw.java b/Mage.Sets/src/mage/cards/s/SavageVentmaw.java index 3f0427cbdd..640d65c1f1 100644 --- a/Mage.Sets/src/mage/cards/s/SavageVentmaw.java +++ b/Mage.Sets/src/mage/cards/s/SavageVentmaw.java @@ -59,7 +59,7 @@ public class SavageVentmaw extends CardImpl { // Whenever Savage Ventmaw attacks, add {R}{R}{R}{G}{G}{G}. Until end of turn, you don’t lose this mana as steps and phases end. Effect effect = new SavageVentmawManaEffect(new Mana(3, 3, 0, 0, 0, 0, 0, 0), "your", true); - effect.setText("add {R}{R}{R}{G}{G}{G}. Until end of turn, this mana doesn't empty from your mana pool as steps and phases end"); + effect.setText("add {R}{R}{R}{G}{G}{G}. Until end of turn, you don’t lose this mana as steps and phases end"); this.addAbility(new AttacksTriggeredAbility(effect, false)); } @@ -83,7 +83,7 @@ class SavageVentmawManaEffect extends ManaEffect { super(); this.mana = mana; this.emptyOnlyOnTurnsEnd = emptyOnTurnsEnd; - this.staticText = (textManaPoolOwner.equals("their") ? "that player adds " : "add ") + mana.toString() + " to " + textManaPoolOwner + " mana pool"; + this.staticText = (textManaPoolOwner.equals("their") ? "that player adds " : "add ") + mana.toString(); } public SavageVentmawManaEffect(final SavageVentmawManaEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/ShizukoCallerOfAutumn.java b/Mage.Sets/src/mage/cards/s/ShizukoCallerOfAutumn.java index 358a169aa4..1ce23d3119 100644 --- a/Mage.Sets/src/mage/cards/s/ShizukoCallerOfAutumn.java +++ b/Mage.Sets/src/mage/cards/s/ShizukoCallerOfAutumn.java @@ -56,9 +56,9 @@ public class ShizukoCallerOfAutumn extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(3); - // At the beginning of each player's upkeep, that player adds {G}{G}{G} to their mana pool. Until end of turn, this mana doesn't empty from that player's mana pool as steps and phases end. + // At the beginning of each player's upkeep, that player adds {G}{G}{G}. Until end of turn, this mana doesn't empty from that player's mana pool as steps and phases end. Effect effect = new AddManaToManaPoolTargetControllerEffect(Mana.GreenMana(3), "that player", true); - effect.setText("that player adds {G}{G}{G} to their mana pool. Until end of turn, this mana doesn't empty from that player's mana pool as steps and phases end"); + effect.setText("that player adds {G}{G}{G}. Until end of turn, this mana doesn't empty from that player's mana pool as steps and phases end"); this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.ANY, false)); } diff --git a/Mage.Sets/src/mage/cards/s/SpectralSearchlight.java b/Mage.Sets/src/mage/cards/s/SpectralSearchlight.java index 05878cda7a..70d83ad73d 100644 --- a/Mage.Sets/src/mage/cards/s/SpectralSearchlight.java +++ b/Mage.Sets/src/mage/cards/s/SpectralSearchlight.java @@ -52,9 +52,9 @@ public class SpectralSearchlight extends CardImpl { public SpectralSearchlight(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); - // {T}: Choose a player. That player adds one mana of any color he or she chooses to their mana pool. + // {T}: Choose a player. That player adds one mana of any color he or she chooses. ManaEffect effect = new SpectralSearchlightManaEffect("chosen player"); - effect.setText("That player adds one mana of any color he or she chooses to their mana pool"); + effect.setText("That player adds one mana of any color he or she chooses"); Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); // choosing player as first effect, before adding mana effect ability.getEffects().add(0, new ChoosePlayerEffect(Outcome.PutManaInPool)); diff --git a/Mage.Sets/src/mage/cards/t/Tangleroot.java b/Mage.Sets/src/mage/cards/t/Tangleroot.java index 2268edc948..ae35b7410d 100644 --- a/Mage.Sets/src/mage/cards/t/Tangleroot.java +++ b/Mage.Sets/src/mage/cards/t/Tangleroot.java @@ -46,7 +46,7 @@ public class Tangleroot extends CardImpl { public Tangleroot(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); - // Whenever a player casts a creature spell, that player adds {G} to their mana pool. + // Whenever a player casts a creature spell, that player adds {G}. this.addAbility(new SpellCastAllTriggeredAbility( new AddManaToManaPoolTargetControllerEffect(Mana.GreenMana(1), "their"), StaticFilters.FILTER_SPELL_A_CREATURE, false, SetTargetPointer.PLAYER)); } diff --git a/Mage.Sets/src/mage/cards/t/TraceOfAbundance.java b/Mage.Sets/src/mage/cards/t/TraceOfAbundance.java index 099a6c57b1..f0462b0225 100644 --- a/Mage.Sets/src/mage/cards/t/TraceOfAbundance.java +++ b/Mage.Sets/src/mage/cards/t/TraceOfAbundance.java @@ -73,7 +73,7 @@ public class TraceOfAbundance extends CardImpl { // Enchanted land has shroud. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ShroudAbility.getInstance(), AttachmentType.AURA, Duration.WhileOnBattlefield, rule))); - // Whenever enchanted land is tapped for mana, its controller adds one mana of any color to their mana pool. + // Whenever enchanted land is tapped for mana, its controller adds one mana of any color. this.addAbility(new TraceOfAbundanceTriggeredAbility()); } @@ -115,6 +115,6 @@ class TraceOfAbundanceTriggeredAbility extends TriggeredManaAbility { @Override public String getRule() { - return "Whenever enchanted land is tapped for mana, its controller adds one mana of any color to their mana pool."; + return "Whenever enchanted land is tapped for mana, its controller adds one mana of any color."; } } diff --git a/Mage.Sets/src/mage/cards/u/UtopiaSprawl.java b/Mage.Sets/src/mage/cards/u/UtopiaSprawl.java index 441f29cfc3..36941251fe 100644 --- a/Mage.Sets/src/mage/cards/u/UtopiaSprawl.java +++ b/Mage.Sets/src/mage/cards/u/UtopiaSprawl.java @@ -69,7 +69,7 @@ public class UtopiaSprawl extends CardImpl { this.addAbility(ability); // As Utopia Sprawl enters the battlefield, choose a color. this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Detriment))); - // Whenever enchanted Forest is tapped for mana, its controller adds one mana of the chosen color to their mana pool. + // Whenever enchanted Forest is tapped for mana, its controller adds one mana of the chosen color. this.addAbility(new UtopiaSprawlTriggeredAbility()); } @@ -111,7 +111,7 @@ class UtopiaSprawlTriggeredAbility extends TriggeredManaAbility { @Override public String getRule() { - return "Whenever enchanted Forest is tapped for mana, its controller adds one mana of the chosen color to their mana pool."; + return "Whenever enchanted Forest is tapped for mana, its controller adds one mana of the chosen color."; } } @@ -119,7 +119,7 @@ class UtopiaSprawlEffect extends ManaEffect { public UtopiaSprawlEffect() { super(); - staticText = "its controller adds one mana of the chosen color to their mana pool"; + staticText = "its controller adds one mana of the chosen color"; } public UtopiaSprawlEffect(final UtopiaSprawlEffect effect) { diff --git a/Mage.Sets/src/mage/cards/v/Valleymaker.java b/Mage.Sets/src/mage/cards/v/Valleymaker.java index 9328310040..c3cce5a9b8 100644 --- a/Mage.Sets/src/mage/cards/v/Valleymaker.java +++ b/Mage.Sets/src/mage/cards/v/Valleymaker.java @@ -74,7 +74,7 @@ public class Valleymaker extends CardImpl { ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); - // {tap}, Sacrifice a Forest: Choose a player. That player adds {G}{G}{G} to their mana pool. + // {tap}, Sacrifice a Forest: Choose a player. That player adds {G}{G}{G}. Ability ability2 = new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaToManaPoolTargetControllerEffect(Mana.GreenMana(3), "chosen player"), new TapSourceCost()); ability2.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); ability2.addTarget(new TargetPlayer(1, 1, true)); diff --git a/Mage.Sets/src/mage/cards/v/VerdantHaven.java b/Mage.Sets/src/mage/cards/v/VerdantHaven.java index 301124c541..55c8e55416 100644 --- a/Mage.Sets/src/mage/cards/v/VerdantHaven.java +++ b/Mage.Sets/src/mage/cards/v/VerdantHaven.java @@ -69,7 +69,7 @@ public class VerdantHaven extends CardImpl { // When Verdant Haven enters the battlefield, you gain 2 life. this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(2))); - // Whenever enchanted land is tapped for mana, its controller adds one mana of any color to their mana pool. + // Whenever enchanted land is tapped for mana, its controller adds one mana of any color. this.addAbility(new VerdantHavenTriggeredAbility()); } @@ -112,6 +112,6 @@ class VerdantHavenTriggeredAbility extends TriggeredManaAbility { @Override public String getRule() { - return "Whenever enchanted land is tapped for mana, its controller adds one mana of any color to their mana pool."; + return "Whenever enchanted land is tapped for mana, its controller adds one mana of any color."; } } diff --git a/Mage.Sets/src/mage/cards/v/VernalBloom.java b/Mage.Sets/src/mage/cards/v/VernalBloom.java index 3420d2fdc4..8d3baf682d 100644 --- a/Mage.Sets/src/mage/cards/v/VernalBloom.java +++ b/Mage.Sets/src/mage/cards/v/VernalBloom.java @@ -55,7 +55,7 @@ public class VernalBloom extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{G}"); - // Whenever a Forest is tapped for mana, its controller adds {G} to their mana pool. + // Whenever a Forest is tapped for mana, its controller adds {G}. this.addAbility(new TapForManaAllTriggeredManaAbility( new AddManaToManaPoolTargetControllerEffect(new Mana(ColoredManaSymbol.G), "their"), filter, SetTargetPointer.PLAYER)); diff --git a/Mage.Sets/src/mage/cards/w/WildGrowth.java b/Mage.Sets/src/mage/cards/w/WildGrowth.java index 2893922d83..a73d8f8f83 100644 --- a/Mage.Sets/src/mage/cards/w/WildGrowth.java +++ b/Mage.Sets/src/mage/cards/w/WildGrowth.java @@ -67,7 +67,7 @@ public class WildGrowth extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - // Whenever enchanted land is tapped for mana, its controller adds {G} to their mana pool. + // Whenever enchanted land is tapped for mana, its controller adds {G}. this.addAbility(new WildGrowthTriggeredAbility()); } @@ -120,6 +120,6 @@ class WildGrowthTriggeredAbility extends TriggeredManaAbility { @Override public String getRule() { - return "Whenever enchanted land is tapped for mana, its controller adds {G} to their mana pool"; + return "Whenever enchanted land is tapped for mana, its controller adds {G}"; } } diff --git a/Mage.Sets/src/mage/cards/w/WintersNight.java b/Mage.Sets/src/mage/cards/w/WintersNight.java index 2b6b78cb34..a90c07ea49 100644 --- a/Mage.Sets/src/mage/cards/w/WintersNight.java +++ b/Mage.Sets/src/mage/cards/w/WintersNight.java @@ -58,10 +58,10 @@ public class WintersNight extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{R}{G}{W}"); addSuperType(SuperType.WORLD); - // Whenever a player taps a snow land for mana, that player adds one mana to their mana pool of any type that land produced. + // Whenever a player taps a snow land for mana, that player adds one mana of any type that land produced. // That land doesn't untap during its controller's next untap step. ManaEffect effect = new AddManaOfAnyTypeProducedEffect(); - effect.setText("that player adds one mana to their mana pool of any type that land produced"); + effect.setText("that player adds one mana of any type that land produced"); Ability ability = new TapForManaAllTriggeredManaAbility(effect, filter, SetTargetPointer.PERMANENT); Effect effect2 = new DontUntapInControllersNextUntapStepTargetEffect(); effect2.setText("That land doesn't untap during its controller's next untap step"); diff --git a/Mage.Sets/src/mage/cards/w/Worldpurge.java b/Mage.Sets/src/mage/cards/w/Worldpurge.java index daf4bd7c4c..a584115a70 100644 --- a/Mage.Sets/src/mage/cards/w/Worldpurge.java +++ b/Mage.Sets/src/mage/cards/w/Worldpurge.java @@ -54,9 +54,9 @@ import mage.target.common.TargetCardInHand; public class Worldpurge extends CardImpl { public Worldpurge(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{W/U}{W/U}{W/U}{W/U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{W/U}{W/U}{W/U}{W/U}"); - // Return all permanents to their owners' hands. Each player chooses up to seven cards in their hand, then shuffles the rest into their library. Empty all mana pools. + // Return all permanents to their owners’ hands. Each player chooses up to seven cards in their hand, then shuffles the rest into their library. Each player loses all unspent mana. this.getSpellAbility().addEffect(new WorldpurgeEffect()); } @@ -75,7 +75,7 @@ class WorldpurgeEffect extends OneShotEffect { public WorldpurgeEffect() { super(Outcome.Discard); - this.staticText = "Return all permanents to their owners' hands. Each player chooses up to seven cards in their hand, then shuffles the rest into their library. Empty all mana pools."; + this.staticText = "Return all permanents to their owners’ hands. Each player chooses up to seven cards in their hand, then shuffles the rest into their library. Each player loses all unspent mana"; } public WorldpurgeEffect(final WorldpurgeEffect effect) { @@ -117,7 +117,7 @@ class WorldpurgeEffect extends OneShotEffect { } } game.emptyManaPools(); - game.informPlayers(sourceObject.getLogName() + " - All mana pools have been emptied"); + game.informPlayers(sourceObject.getLogName() + " - All players have lost all unspent mana"); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/z/ZhurTaaAncient.java b/Mage.Sets/src/mage/cards/z/ZhurTaaAncient.java index cc9cfa39d0..2c259dd1d9 100644 --- a/Mage.Sets/src/mage/cards/z/ZhurTaaAncient.java +++ b/Mage.Sets/src/mage/cards/z/ZhurTaaAncient.java @@ -51,7 +51,7 @@ public class ZhurTaaAncient extends CardImpl { this.power = new MageInt(7); this.toughness = new MageInt(5); - // Whenever a player taps a land for mana, that player adds one mana to their mana pool of any type that land produced. + // Whenever a player taps a land for mana, that player adds one mana of any type that land produced. this.addAbility(new TapForManaAllTriggeredManaAbility( new AddManaOfAnyTypeProducedEffect(), new FilterLandPermanent("a player taps a land"), diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CleverImpersonatorTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CleverImpersonatorTest.java index 7cb9d15d87..cab6b2eadd 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CleverImpersonatorTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CleverImpersonatorTest.java @@ -191,7 +191,7 @@ public class CleverImpersonatorTest extends CardTestPlayerBase { /* {3}{G} Dawn's Reflection Enchantment - Aura, Enchant Land - Whenever enchanted land is tapped for mana, its controller adds two mana in any combination of colors to their mana pool (in addition to the mana the land produces). + Whenever enchanted land is tapped for mana, its controller adds two mana in any combination of colors (in addition to the mana the land produces). */ addCard(Zone.HAND, playerA, dReflection); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/EldraziTempleTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/EldraziTempleTest.java index 20f7586743..f975c154a2 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/EldraziTempleTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/EldraziTempleTest.java @@ -97,7 +97,7 @@ public class EldraziTempleTest extends CardTestPlayerBase { // {T}: Add {C}{C}. Spend this mana only to cast colorless Eldrazi spells or activate abilities of colorless Eldrazi. addCard(Zone.BATTLEFIELD, playerA, "Eldrazi Temple", 1); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); - // {T}: Add {W}, {B}, or {G} to your mana pool. + // {T}: Add {W}, {B}, or {G}. // {W}{B}{G}, {T}, Sacrifice Abzan Banner: Draw a card. addCard(Zone.HAND, playerA, "Abzan Banner", 1); // Artifact {3} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/EmptyOnlyOnTurnsEndManaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/EmptyOnlyOnTurnsEndManaTest.java index 9ab2021b2e..bde2f8aefd 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/EmptyOnlyOnTurnsEndManaTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/EmptyOnlyOnTurnsEndManaTest.java @@ -41,7 +41,7 @@ public class EmptyOnlyOnTurnsEndManaTest extends CardTestPlayerBase { @Test public void testDaxosOfMeletis() { - // At the beginning of each player's upkeep, that player adds {G}{G}{G} to their mana pool. Until end of turn, this mana doesn't empty from that player's mana pool as steps and phases end. + // At the beginning of each player's upkeep, that player adds {G}{G}{G}. Until end of turn, this mana doesn't empty from that player's mana pool as steps and phases end. addCard(Zone.BATTLEFIELD, playerA, "Shizuko, Caller of Autumn", 1); addCard(Zone.HAND, playerA, "Birds of Paradise", 1); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ManaFlareTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ManaFlareTest.java index f8d954ed36..cd7b4d121a 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ManaFlareTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ManaFlareTest.java @@ -40,7 +40,7 @@ public class ManaFlareTest extends CardTestPlayerBase { @Test public void testIsland() { - // Whenever a player taps a land for mana, that player adds one mana to their mana pool of any type that land produced. + // Whenever a player taps a land for mana, that player adds one mana of any type that land produced. addCard(Zone.BATTLEFIELD, playerA, "Mana Flare", 1); addCard(Zone.BATTLEFIELD, playerA, "Island", 1); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/HeartbeatOfSpringTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/HeartbeatOfSpringTest.java index 5ac66853f0..8f9db4bd86 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/HeartbeatOfSpringTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/HeartbeatOfSpringTest.java @@ -46,7 +46,7 @@ public class HeartbeatOfSpringTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); // {T}: Add {C}. If you control an Urza's Power-Plant and an Urza's Tower, add {C}{C} instead. addCard(Zone.HAND, playerA, "Urza's Mine", 1); - // Whenever a player taps a land for mana, that player adds one mana to their mana pool of any type that land produced. + // Whenever a player taps a land for mana, that player adds one mana of any type that land produced. addCard(Zone.HAND, playerA, "Heartbeat of Spring"); // {2}{G} // Whenever a player casts a white spell, you may gain 1 life. addCard(Zone.HAND, playerA, "Angel's Feather"); // {2} diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ManaTypeInManaPoolCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ManaTypeInManaPoolCount.java index 73572da3be..55dc44ddbc 100644 --- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ManaTypeInManaPoolCount.java +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ManaTypeInManaPoolCount.java @@ -45,7 +45,7 @@ public class ManaTypeInManaPoolCount implements DynamicValue { @Override public String getMessage() { - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new StringBuilder("unspent "); switch (manaType) { case BLACK: sb.append("black"); @@ -66,7 +66,7 @@ public class ManaTypeInManaPoolCount implements DynamicValue { sb.append("colorless"); break; } - sb.append(" mana in your mana pool"); + sb.append(" mana you have"); return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CommanderManaReplacementEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CommanderManaReplacementEffect.java index 6730243964..8737704aec 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CommanderManaReplacementEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CommanderManaReplacementEffect.java @@ -50,6 +50,7 @@ import mage.game.events.ManaEvent; * Commander rule #4 was removed Jan. 18, 2016 * */ +@Deprecated public class CommanderManaReplacementEffect extends ReplacementEffectImpl { private final UUID playerId; diff --git a/Mage/src/main/java/mage/abilities/effects/mana/AddManaAnyColorAttachedControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/mana/AddManaAnyColorAttachedControllerEffect.java index 2fdf2db807..52eb55bf84 100644 --- a/Mage/src/main/java/mage/abilities/effects/mana/AddManaAnyColorAttachedControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/mana/AddManaAnyColorAttachedControllerEffect.java @@ -45,7 +45,7 @@ public class AddManaAnyColorAttachedControllerEffect extends ManaEffect { public AddManaAnyColorAttachedControllerEffect() { super(); - staticText = "its controller adds one mana of any color to their mana pool"; + staticText = "its controller adds one mana of any color"; } public AddManaAnyColorAttachedControllerEffect(final AddManaAnyColorAttachedControllerEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/mana/AddManaOfAnyTypeProducedEffect.java b/Mage/src/main/java/mage/abilities/effects/mana/AddManaOfAnyTypeProducedEffect.java index 2885f791b4..21424b9222 100644 --- a/Mage/src/main/java/mage/abilities/effects/mana/AddManaOfAnyTypeProducedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/mana/AddManaOfAnyTypeProducedEffect.java @@ -44,7 +44,7 @@ public class AddManaOfAnyTypeProducedEffect extends ManaEffect { public AddManaOfAnyTypeProducedEffect() { super(); - staticText = "that player adds one mana to their mana pool of any type that land produced"; + staticText = "that player adds one mana of any type that land produced"; } public AddManaOfAnyTypeProducedEffect(final AddManaOfAnyTypeProducedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/mana/AddManaToManaPoolTargetControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/mana/AddManaToManaPoolTargetControllerEffect.java index 44bfec584d..0770c1f94d 100644 --- a/Mage/src/main/java/mage/abilities/effects/mana/AddManaToManaPoolTargetControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/mana/AddManaToManaPoolTargetControllerEffect.java @@ -38,7 +38,7 @@ public class AddManaToManaPoolTargetControllerEffect extends ManaEffect { super(); this.mana = mana; this.emptyOnlyOnTurnsEnd = emptyOnTurnsEnd; - this.staticText = (textManaPoolOwner.equals("their") ? "that player adds " : "add ") + mana.toString() + " to " + textManaPoolOwner + " mana pool"; + this.staticText = (textManaPoolOwner.equals("their") ? "that player adds " : "add ") + mana.toString(); } public AddManaToManaPoolTargetControllerEffect(final AddManaToManaPoolTargetControllerEffect effect) { From 07973c8bc1a984673ea615fd73ed448790b8f550 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Fri, 25 May 2018 21:41:12 -0400 Subject: [PATCH 119/154] Implemented Archon of Valor's Reach --- .../src/mage/cards/a/ArchonOfValorsReach.java | 214 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 215 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/ArchonOfValorsReach.java diff --git a/Mage.Sets/src/mage/cards/a/ArchonOfValorsReach.java b/Mage.Sets/src/mage/cards/a/ArchonOfValorsReach.java new file mode 100644 index 0000000000..773e73cfef --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArchonOfValorsReach.java @@ -0,0 +1,214 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.constants.SubType; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.ChoiceImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * + * @author TheElk801 + */ +public class ArchonOfValorsReach extends CardImpl { + + public ArchonOfValorsReach(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{G}"); + + this.subtype.add(SubType.ARCHON); + this.power = new MageInt(5); + this.toughness = new MageInt(6); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // As Archon of Valor's Reach enters the battlefield, choose artifact, enchantment, instant, sorcery, or planeswalker. + this.addAbility(new AsEntersBattlefieldAbility(new ArchonOfValorsReachChooseEffect())); + + // Players can't cast spells of the chosen type. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ArchonOfValorsReachReplacementEffect())); + } + + public ArchonOfValorsReach(final ArchonOfValorsReach card) { + super(card); + } + + @Override + public ArchonOfValorsReach copy() { + return new ArchonOfValorsReach(this); + } +} + +class ArchonOfValorsReachChooseEffect extends OneShotEffect { + + public static String VALUE_KEY = "_cardtype"; + + public ArchonOfValorsReachChooseEffect() { + super(Outcome.Benefit); + this.staticText = "choose artifact, enchantment, instant, sorcery, or planeswalker"; + } + + public ArchonOfValorsReachChooseEffect(final ArchonOfValorsReachChooseEffect effect) { + super(effect); + } + + @Override + public ArchonOfValorsReachChooseEffect copy() { + return new ArchonOfValorsReachChooseEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); + if (mageObject == null) { + mageObject = game.getObject(source.getSourceId()); + } + if (controller != null && mageObject != null) { + ArchonOfValorsReachChoice choices = new ArchonOfValorsReachChoice(); + if (controller.choose(Outcome.Neutral, choices, game)) { + game.informPlayers(mageObject.getName() + ": Chosen card type is " + choices.getChoice()); + System.out.println(mageObject.getId()); + game.getState().setValue(mageObject.getId().toString() + VALUE_KEY, choices.getChoice()); + if (mageObject instanceof Permanent) { + ((Permanent) mageObject).addInfo("chosen color", CardUtil.addToolTipMarkTags("Chosen card type: " + choices.getChoice()), game); + } + return true; + } + } + return false; + } +} + +class ArchonOfValorsReachChoice extends ChoiceImpl { + + public ArchonOfValorsReachChoice() { + super(true); + this.choices.add("Artifact"); + this.choices.add("Enchantment"); + this.choices.add("Instant"); + this.choices.add("Sorcery"); + this.choices.add("Planeswalker"); + this.message = "Choose artifact, enchantment, instant, sorcery, or planeswalker"; + } + + public ArchonOfValorsReachChoice(final ArchonOfValorsReachChoice choice) { + super(choice); + } + + public static CardType getType(String ch) { + switch (ch) { + case "Artifact": + return CardType.ARTIFACT; + case "Enchantment": + return CardType.ENCHANTMENT; + case "Instant": + return CardType.INSTANT; + case "Sorcery": + return CardType.SORCERY; + case "Planewswalker": + return CardType.PLANESWALKER; + default: + return null; + } + } + + @Override + public ArchonOfValorsReachChoice copy() { + return new ArchonOfValorsReachChoice(this); + } + +} + +class ArchonOfValorsReachReplacementEffect extends ContinuousRuleModifyingEffectImpl { + + ArchonOfValorsReachReplacementEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = "Players can't cast spells of the chosen type"; + } + + ArchonOfValorsReachReplacementEffect(final ArchonOfValorsReachReplacementEffect effect) { + super(effect); + } + + @Override + public String getInfoMessage(Ability source, GameEvent event, Game game) { + CardType cardType = (CardType) game.getState().getValue(source.getSourceId().toString() + "_cardtype"); + MageObject mageObject = game.getObject(source.getSourceId()); + if (mageObject != null && cardType != null) { + return "You can't cast " + cardType.toString() + " spells (" + mageObject.getIdName() + ")."; + } + return null; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CAST_SPELL; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + CardType cardType = ArchonOfValorsReachChoice.getType((String) game.getState().getValue(source.getSourceId().toString() + "_cardtype")); + // spell is not on the stack yet, so we have to check the card + Card card = game.getCard(event.getSourceId()); + return cardType != null && card != null && card.getCardType().contains(cardType); + } + + @Override + public ArchonOfValorsReachReplacementEffect copy() { + return new ArchonOfValorsReachReplacementEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 4aecbe7b64..befa0b26ed 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -59,6 +59,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Angelic Gift", 88, Rarity.COMMON, mage.cards.a.AngelicGift.class)); cards.add(new SetCardInfo("Apocalypse Hydra", 217, Rarity.RARE, mage.cards.a.ApocalypseHydra.class)); cards.add(new SetCardInfo("Archfiend of Despair", 44, Rarity.MYTHIC, mage.cards.a.ArchfiendOfDespair.class)); + cards.add(new SetCardInfo("Archon of Valor's Reach", 74, Rarity.RARE, mage.cards.a.ArchonOfValorsReach.class)); cards.add(new SetCardInfo("Arena Rector", 23, Rarity.MYTHIC, mage.cards.a.ArenaRector.class)); cards.add(new SetCardInfo("Assassin's Strike", 138, Rarity.UNCOMMON, mage.cards.a.AssassinsStrike.class)); cards.add(new SetCardInfo("Assassinate", 139, Rarity.COMMON, mage.cards.a.Assassinate.class)); From 93d014a50273773b7a4bd3904c9edac5b21f1260 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sat, 26 May 2018 15:50:30 -0400 Subject: [PATCH 120/154] Implemented Azra Bladeseeker --- .../src/mage/cards/a/AzraBladeseeker.java | 137 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + .../mage/target/common/TargetDiscard.java | 6 +- 3 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/AzraBladeseeker.java diff --git a/Mage.Sets/src/mage/cards/a/AzraBladeseeker.java b/Mage.Sets/src/mage/cards/a/AzraBladeseeker.java new file mode 100644 index 0000000000..c87274ea8c --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AzraBladeseeker.java @@ -0,0 +1,137 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetDiscard; + +/** + * + * @author TheElk801 + */ +public class AzraBladeseeker extends CardImpl { + + public AzraBladeseeker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.AZRA); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // When Azra Bladeseeker enters the battlefield, each player on your team may discard a card, then each player who discarded a card this way draws a card. + this.addAbility(new EntersBattlefieldTriggeredAbility(new AzraBladeseekerEffect(), false)); + } + + public AzraBladeseeker(final AzraBladeseeker card) { + super(card); + } + + @Override + public AzraBladeseeker copy() { + return new AzraBladeseeker(this); + } +} + +class AzraBladeseekerEffect extends OneShotEffect { + + AzraBladeseekerEffect() { + super(Outcome.Benefit); + this.staticText = "each player on your team may discard a card, then each player who discarded a card this way draws a card"; + } + + AzraBladeseekerEffect(final AzraBladeseekerEffect effect) { + super(effect); + } + + @Override + public AzraBladeseekerEffect copy() { + return new AzraBladeseekerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + List<PlayerCard> playerCardList = new ArrayList<>(); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null + || player.hasOpponent(source.getControllerId(), game) + || player.getHand().isEmpty() + || !player.chooseUse(Outcome.DrawCard, "Discard a card?", source, game)) { + continue; + } + Target target = new TargetDiscard(playerId); + if (target.choose(Outcome.DrawCard, playerId, source.getSourceId(), game)) { + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + playerCardList.add(new PlayerCard(player, card)); + } + } + } + for (PlayerCard playerCard : playerCardList) { + if (playerCard.getPlayer().discard(playerCard.getCard(), source, game)) { + playerCard.getPlayer().drawCards(1, game); + } + } + return true; + } + + class PlayerCard { + + private final Player player; + private final Card card; + + private PlayerCard(Player player, Card card) { + this.player = player; + this.card = card; + } + + public Player getPlayer() { + return player; + } + + public Card getCard() { + return card; + } + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index befa0b26ed..ad0c83dce3 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -65,6 +65,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Assassinate", 139, Rarity.COMMON, mage.cards.a.Assassinate.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); cards.add(new SetCardInfo("Aurora Champion", 24, Rarity.COMMON, mage.cards.a.AuroraChampion.class)); + cards.add(new SetCardInfo("Azra Bladeseeker", 55, Rarity.COMMON, mage.cards.a.AzraBladeseeker.class)); cards.add(new SetCardInfo("Azra Oddsmaker", 75, Rarity.UNCOMMON, mage.cards.a.AzraOddsmaker.class)); cards.add(new SetCardInfo("Bathe in Dragonfire", 164, Rarity.COMMON, mage.cards.b.BatheInDragonfire.class)); cards.add(new SetCardInfo("Battle Mastery", 89, Rarity.UNCOMMON, mage.cards.b.BattleMastery.class)); diff --git a/Mage/src/main/java/mage/target/common/TargetDiscard.java b/Mage/src/main/java/mage/target/common/TargetDiscard.java index 51a3071b7c..a6068bc7f9 100644 --- a/Mage/src/main/java/mage/target/common/TargetDiscard.java +++ b/Mage/src/main/java/mage/target/common/TargetDiscard.java @@ -24,8 +24,7 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.target.common; import mage.constants.Zone; @@ -36,6 +35,7 @@ import mage.game.Game; import mage.target.TargetCard; import java.util.UUID; +import mage.filter.StaticFilters; import mage.filter.predicate.other.OwnerIdPredicate; /** @@ -47,7 +47,7 @@ public class TargetDiscard extends TargetCard { private final UUID playerId; public TargetDiscard(UUID playerId) { - this(1, 1, new FilterCard(), playerId); + this(1, 1, StaticFilters.FILTER_CARD, playerId); } public TargetDiscard(FilterCard filter, UUID playerId) { From b28bf51c02531dfb058be2552f0abc863b0725ad Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Sat, 26 May 2018 22:39:20 +0200 Subject: [PATCH 121/154] * Reworked some more card movement handling (#4866). --- .../src/mage/cards/a/AtarkasCommand.java | 29 +++--- Mage.Sets/src/mage/cards/b/BelbesPortal.java | 4 +- .../src/mage/cards/b/BraidsConjurerAdept.java | 4 +- .../src/mage/cards/b/BriarbridgePatrol.java | 13 ++- Mage.Sets/src/mage/cards/b/BrokenBond.java | 4 +- .../src/mage/cards/b/BudokaGardener.java | 7 +- Mage.Sets/src/mage/cards/b/Burgeoning.java | 9 +- .../src/mage/cards/c/ChampionOfRhonas.java | 6 +- Mage.Sets/src/mage/cards/c/CopperGnomes.java | 4 +- .../src/mage/cards/c/CrypticGateway.java | 4 +- .../src/mage/cards/d/DearlyDeparted.java | 5 +- Mage.Sets/src/mage/cards/d/Dermoplasm.java | 4 +- Mage.Sets/src/mage/cards/d/Didgeridoo.java | 4 +- Mage.Sets/src/mage/cards/d/DragonArch.java | 4 +- .../src/mage/cards/d/DramaticEntrance.java | 4 +- Mage.Sets/src/mage/cards/e/ElvishPioneer.java | 8 +- Mage.Sets/src/mage/cards/e/ElvishPiper.java | 9 +- .../src/mage/cards/f/FirebrandRanger.java | 61 +----------- Mage.Sets/src/mage/cards/f/Flickerform.java | 25 +++-- Mage.Sets/src/mage/cards/g/GaeasTouch.java | 61 ++---------- .../mage/cards/g/GarrukCallerOfBeasts.java | 4 +- .../src/mage/cards/g/GemstoneCaverns.java | 14 ++- .../src/mage/cards/g/GiftOfImmortality.java | 4 +- Mage.Sets/src/mage/cards/g/GoblinLackey.java | 4 +- Mage.Sets/src/mage/cards/g/GoblinWizard.java | 4 +- .../src/mage/cards/g/GracefulReprieve.java | 39 ++++---- Mage.Sets/src/mage/cards/g/GraveUpheaval.java | 18 +++- .../src/mage/cards/g/GruesomeEncore.java | 32 ++++--- Mage.Sets/src/mage/cards/g/GryffsBoon.java | 8 +- Mage.Sets/src/mage/cards/g/GuildFeud.java | 14 +-- Mage.Sets/src/mage/cards/h/HuntedWumpus.java | 27 ++---- .../src/mage/cards/h/HuntingGrounds.java | 4 +- Mage.Sets/src/mage/cards/i/Incoming.java | 10 +- Mage.Sets/src/mage/cards/i/IntoTheWilds.java | 25 ++--- .../src/mage/cards/k/KrosanWayfarer.java | 8 +- Mage.Sets/src/mage/cards/k/Kudzu.java | 15 +-- .../src/mage/cards/l/LilianaDeathWielder.java | 11 +-- Mage.Sets/src/mage/cards/l/LlanowarScout.java | 6 +- Mage.Sets/src/mage/cards/l/LoamDweller.java | 8 +- Mage.Sets/src/mage/cards/l/LoyalCathar.java | 39 ++++---- .../src/mage/cards/m/MasterTransmuter.java | 4 +- .../src/mage/cards/m/MatterReshaper.java | 27 +++--- .../src/mage/cards/m/MindwrackLiege.java | 4 +- .../src/mage/cards/m/MoldgrafMonstrosity.java | 41 +++----- .../src/mage/cards/n/NettlevineBlight.java | 6 +- Mage.Sets/src/mage/cards/n/NewFrontiers.java | 12 +-- .../mage/cards/n/NissaStewardOfElements.java | 17 ++-- .../src/mage/cards/n/NissasPilgrimage.java | 8 +- .../src/mage/cards/n/NomadMythmaker.java | 5 +- .../src/mage/cards/n/NorwoodPriestess.java | 4 +- .../src/mage/cards/p/PreeminentCaptain.java | 18 ++-- .../cards/p/PrimevalsGloriousRebirth.java | 13 +-- .../src/mage/cards/p/PyrrhicRevival.java | 41 ++++---- .../src/mage/cards/q/QuestForUlasTemple.java | 63 +++--------- .../src/mage/cards/q/QuicksilverAmulet.java | 10 +- Mage.Sets/src/mage/cards/r/Reincarnation.java | 8 +- .../src/mage/cards/r/ReinsOfTheVinesteed.java | 11 +-- Mage.Sets/src/mage/cards/r/Restore.java | 6 +- Mage.Sets/src/mage/cards/r/Retether.java | 16 ++-- .../cards/r/ReturnOfTheNightstalkers.java | 14 ++- .../src/mage/cards/r/RoarOfReclamation.java | 25 ++--- Mage.Sets/src/mage/cards/r/RootElemental.java | 8 +- .../src/mage/cards/s/SakuraTribeScout.java | 8 +- .../src/mage/cards/s/ScionOfDarkness.java | 20 ++-- .../src/mage/cards/s/SettleTheWreckage.java | 46 ++++----- .../src/mage/cards/s/SkyshroudRanger.java | 10 +- .../src/mage/cards/s/StoneforgeMystic.java | 4 +- Mage.Sets/src/mage/cards/s/SwellOfGrowth.java | 7 +- .../src/mage/cards/t/TerrainGenerator.java | 13 +-- Mage.Sets/src/mage/cards/t/TheUrDragon.java | 16 ++-- .../mage/cards/t/ThranTemporalGateway.java | 4 +- .../src/mage/cards/t/TimmyPowerGamer.java | 8 +- Mage.Sets/src/mage/cards/t/TriassicEgg.java | 5 +- Mage.Sets/src/mage/cards/w/WalkingAtlas.java | 13 +-- .../src/mage/cards/w/WarrenInstigator.java | 4 +- .../src/mage/cards/w/WillowPriestess.java | 4 +- .../mana/VorinclexVoiceOfHungerTest.java | 1 + .../abilities/effects/ContinuousEffects.java | 3 + ...PutCardFromHandOntoBattlefieldEffect.java} | 25 +++-- .../PutLandFromHandOntoBattlefieldEffect.java | 96 ------------------- ...efieldUnderOwnerControlAttachedEffect.java | 24 ++--- ...ttlefieldUnderYourControlSourceEffect.java | 23 +++-- .../abilities/keyword/AuraSwapAbility.java | 4 +- .../abilities/keyword/NinjutsuAbility.java | 7 +- .../main/java/mage/filter/StaticFilters.java | 19 ++++ .../mage/game/permanent/PermanentImpl.java | 4 +- 86 files changed, 534 insertions(+), 758 deletions(-) rename Mage/src/main/java/mage/abilities/effects/common/{PutPermanentOnBattlefieldEffect.java => PutCardFromHandOntoBattlefieldEffect.java} (70%) delete mode 100644 Mage/src/main/java/mage/abilities/effects/common/PutLandFromHandOntoBattlefieldEffect.java diff --git a/Mage.Sets/src/mage/cards/a/AtarkasCommand.java b/Mage.Sets/src/mage/cards/a/AtarkasCommand.java index c9e04b5576..ab4ee2e30e 100644 --- a/Mage.Sets/src/mage/cards/a/AtarkasCommand.java +++ b/Mage.Sets/src/mage/cards/a/AtarkasCommand.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.abilities.Mode; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamagePlayersEffect; -import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.CantGainLifeAllEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; @@ -41,6 +41,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.TargetController; +import mage.filter.StaticFilters; /** * @@ -49,35 +50,35 @@ import mage.constants.TargetController; public class AtarkasCommand extends CardImpl { public AtarkasCommand(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}{G}"); - // Choose two - + // Choose two - this.getSpellAbility().getModes().setMinModes(2); this.getSpellAbility().getModes().setMaxModes(2); - - // Your opponents can't gain life this turn; + + // Your opponents can't gain life this turn; this.getSpellAbility().addEffect(new CantGainLifeAllEffect(Duration.EndOfTurn, TargetController.OPPONENT)); - - // or Atarka's Command deals 3 damage to each opponent; + + // or Atarka's Command deals 3 damage to each opponent; Mode mode = new Mode(); mode.getEffects().add(new DamagePlayersEffect(3, TargetController.OPPONENT)); this.getSpellAbility().addMode(mode); - - // or You may put a land card from your hand onto the battlefield; + + // or You may put a land card from your hand onto the battlefield; mode = new Mode(); - mode.getEffects().add(new PutLandFromHandOntoBattlefieldEffect()); + mode.getEffects().add(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A)); this.getSpellAbility().addMode(mode); // or Creatures you control get +1/+1 and gain reach until the end of turn. mode = new Mode(); - Effect effect = new BoostControlledEffect(1,1, Duration.EndOfTurn); - effect.setText("Creatures you control get +1/+1"); + Effect effect = new BoostControlledEffect(1, 1, Duration.EndOfTurn); + effect.setText("Creatures you control get +1/+1"); mode.getEffects().add(effect); effect = new GainAbilityControlledEffect(ReachAbility.getInstance(), Duration.EndOfTurn); - effect.setText("and gain reach until the end of turn"); + effect.setText("and gain reach until the end of turn"); mode.getEffects().add(effect); this.getSpellAbility().addMode(mode); - + } public AtarkasCommand(final AtarkasCommand card) { diff --git a/Mage.Sets/src/mage/cards/b/BelbesPortal.java b/Mage.Sets/src/mage/cards/b/BelbesPortal.java index c061bf88c8..0e357f1985 100644 --- a/Mage.Sets/src/mage/cards/b/BelbesPortal.java +++ b/Mage.Sets/src/mage/cards/b/BelbesPortal.java @@ -34,7 +34,7 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.ChooseCreatureTypeEffect; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -58,7 +58,7 @@ public class BelbesPortal extends CardImpl { FilterCreatureCard filter = new FilterCreatureCard("a creature card of the chosen type"); filter.add(new ChosenSubtypePredicate(this.getId())); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutPermanentOnBattlefieldEffect(filter), + new PutCardFromHandOntoBattlefieldEffect(filter), new ManaCostsImpl("{3}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/b/BraidsConjurerAdept.java b/Mage.Sets/src/mage/cards/b/BraidsConjurerAdept.java index ef3276fb41..9a46a43ec9 100644 --- a/Mage.Sets/src/mage/cards/b/BraidsConjurerAdept.java +++ b/Mage.Sets/src/mage/cards/b/BraidsConjurerAdept.java @@ -30,7 +30,7 @@ package mage.cards.b; import java.util.UUID; import mage.MageInt; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -64,7 +64,7 @@ public class BraidsConjurerAdept extends CardImpl { this.toughness = new MageInt(2); // At the beginning of each player's upkeep, that player may put an artifact, creature, or land card from their hand onto the battlefield. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new PutPermanentOnBattlefieldEffect(filter, true), TargetController.ANY, false)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect(filter, true), TargetController.ANY, false)); } public BraidsConjurerAdept(final BraidsConjurerAdept card) { diff --git a/Mage.Sets/src/mage/cards/b/BriarbridgePatrol.java b/Mage.Sets/src/mage/cards/b/BriarbridgePatrol.java index 9cbfc70cc3..3cd17f3d3c 100644 --- a/Mage.Sets/src/mage/cards/b/BriarbridgePatrol.java +++ b/Mage.Sets/src/mage/cards/b/BriarbridgePatrol.java @@ -27,12 +27,14 @@ */ package mage.cards.b; +import java.util.List; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.DealsDamageToOneOrMoreCreaturesTriggeredAbility; import mage.abilities.condition.Condition; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.keyword.InvestigateEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -40,14 +42,11 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; -import mage.filter.common.FilterCreatureCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.watchers.common.PermanentsSacrificedWatcher; -import java.util.List; -import java.util.UUID; - /** * @author LevelX2 */ @@ -62,7 +61,7 @@ public class BriarbridgePatrol extends CardImpl { // Whenever Briarbridge Patrol deals damage to one or more creatures, investigate (Create a colorless Clue artifact token with "2, Sacrifice this artifact: Draw a card."). this.addAbility(new DealsDamageToOneOrMoreCreaturesTriggeredAbility(new InvestigateEffect(), false, false, false)); // At the beginning of each end step, if you sacrificed three or more Clues this turn, you may put a creature card from your hand onto the battlefield. - this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(new FilterCreatureCard("a creature card")), TargetController.ANY, + this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_CREATURE_A), TargetController.ANY, BriarbridgePatrolCondition.instance, true), new PermanentsSacrificedWatcher()); } @@ -104,4 +103,4 @@ enum BriarbridgePatrolCondition implements Condition { return "if you sacrificed three or more Clues this turn"; } - } +} diff --git a/Mage.Sets/src/mage/cards/b/BrokenBond.java b/Mage.Sets/src/mage/cards/b/BrokenBond.java index edd5b097aa..5f4241c5a5 100644 --- a/Mage.Sets/src/mage/cards/b/BrokenBond.java +++ b/Mage.Sets/src/mage/cards/b/BrokenBond.java @@ -30,7 +30,7 @@ package mage.cards.b; import java.util.UUID; import mage.abilities.effects.common.DestroyTargetEffect; -import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -49,7 +49,7 @@ public class BrokenBond extends CardImpl { // Destroy target artifact or enchantment. You may put a land card from your hand onto the battlefield. this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); this.getSpellAbility().addEffect(new DestroyTargetEffect()); - this.getSpellAbility().addEffect(new PutLandFromHandOntoBattlefieldEffect()); + this.getSpellAbility().addEffect(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A)); } public BrokenBond(final BrokenBond card) { diff --git a/Mage.Sets/src/mage/cards/b/BudokaGardener.java b/Mage.Sets/src/mage/cards/b/BudokaGardener.java index a9463b13f2..d76d6ef12a 100644 --- a/Mage.Sets/src/mage/cards/b/BudokaGardener.java +++ b/Mage.Sets/src/mage/cards/b/BudokaGardener.java @@ -35,7 +35,6 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.FlipSourceEffect; -import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -44,10 +43,11 @@ import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.permanent.token.DokaiWeaverofLifeToken; import mage.game.permanent.token.TokenImpl; -import mage.game.permanent.token.Token; import mage.players.Player; import java.util.UUID; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; +import mage.filter.StaticFilters; /** * @author Loki @@ -64,7 +64,7 @@ public class BudokaGardener extends CardImpl { this.flipCardName = "Dokai, Weaver of Life"; // {T}: You may put a land card from your hand onto the battlefield. If you control ten or more lands, flip Budoka Gardener. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLandFromHandOntoBattlefieldEffect(), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new TapSourceCost()); ability.addEffect(new BudokaGardenerEffect()); this.addAbility(ability); } @@ -128,6 +128,7 @@ class DokaiWeaverofLife extends TokenImpl { ability.addCost(new TapSourceCost()); this.addAbility(ability); } + public DokaiWeaverofLife(final DokaiWeaverofLife token) { super(token); } diff --git a/Mage.Sets/src/mage/cards/b/Burgeoning.java b/Mage.Sets/src/mage/cards/b/Burgeoning.java index aeb7593fbc..11cfd535ec 100644 --- a/Mage.Sets/src/mage/cards/b/Burgeoning.java +++ b/Mage.Sets/src/mage/cards/b/Burgeoning.java @@ -29,11 +29,12 @@ package mage.cards.b; import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; 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.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -45,7 +46,7 @@ import mage.game.permanent.Permanent; public class Burgeoning extends CardImpl { public Burgeoning(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); // Whenever an opponent plays a land, you may put a land card from your hand onto the battlefield. this.addAbility(new BurgeoningTriggeredAbility()); @@ -61,10 +62,10 @@ public class Burgeoning extends CardImpl { } } - class BurgeoningTriggeredAbility extends TriggeredAbilityImpl { + BurgeoningTriggeredAbility() { - super(Zone.BATTLEFIELD, new PutLandFromHandOntoBattlefieldEffect()); + super(Zone.BATTLEFIELD, new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A)); } BurgeoningTriggeredAbility(BurgeoningTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/cards/c/ChampionOfRhonas.java b/Mage.Sets/src/mage/cards/c/ChampionOfRhonas.java index 4d65190d27..83578e985f 100644 --- a/Mage.Sets/src/mage/cards/c/ChampionOfRhonas.java +++ b/Mage.Sets/src/mage/cards/c/ChampionOfRhonas.java @@ -30,13 +30,13 @@ package mage.cards.c; import java.util.UUID; import mage.MageInt; import mage.abilities.common.BecomesExertSourceTriggeredAbility; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.keyword.ExertAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.filter.common.FilterCreatureCard; +import mage.filter.StaticFilters; /** * @@ -53,7 +53,7 @@ public class ChampionOfRhonas extends CardImpl { this.toughness = new MageInt(3); // You may exert Champion of Rhonas as it attacks. When you do, you may put a creature card from your hand onto the battlefield. - BecomesExertSourceTriggeredAbility ability = new BecomesExertSourceTriggeredAbility(new PutPermanentOnBattlefieldEffect(new FilterCreatureCard("a creature card"))); + BecomesExertSourceTriggeredAbility ability = new BecomesExertSourceTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_CREATURE_A)); this.addAbility(new ExertAbility(ability)); } diff --git a/Mage.Sets/src/mage/cards/c/CopperGnomes.java b/Mage.Sets/src/mage/cards/c/CopperGnomes.java index d926d333a8..29254ffc22 100644 --- a/Mage.Sets/src/mage/cards/c/CopperGnomes.java +++ b/Mage.Sets/src/mage/cards/c/CopperGnomes.java @@ -33,7 +33,7 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -54,7 +54,7 @@ public class CopperGnomes extends CardImpl { this.toughness = new MageInt(1); // {4}, Sacrifice Copper Gnomes: You may put an artifact card from your hand onto the battlefield. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(new FilterArtifactCard()), new ManaCostsImpl("{4}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutCardFromHandOntoBattlefieldEffect(new FilterArtifactCard()), new ManaCostsImpl("{4}")); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/CrypticGateway.java b/Mage.Sets/src/mage/cards/c/CrypticGateway.java index 9821618bf7..1437f484bb 100644 --- a/Mage.Sets/src/mage/cards/c/CrypticGateway.java +++ b/Mage.Sets/src/mage/cards/c/CrypticGateway.java @@ -33,7 +33,7 @@ import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.keyword.ChangelingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -223,7 +223,7 @@ class CrypticGatewayEffect extends OneShotEffect { } if (commonSubType) { - PutPermanentOnBattlefieldEffect putIntoPlay = new PutPermanentOnBattlefieldEffect(filter); + PutCardFromHandOntoBattlefieldEffect putIntoPlay = new PutCardFromHandOntoBattlefieldEffect(filter); putIntoPlay.apply(game, source); } } diff --git a/Mage.Sets/src/mage/cards/d/DearlyDeparted.java b/Mage.Sets/src/mage/cards/d/DearlyDeparted.java index 74b092938b..c469f16f24 100644 --- a/Mage.Sets/src/mage/cards/d/DearlyDeparted.java +++ b/Mage.Sets/src/mage/cards/d/DearlyDeparted.java @@ -27,6 +27,7 @@ */ package mage.cards.d; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -42,8 +43,6 @@ import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; -import java.util.UUID; - /** * @author nantuko */ @@ -75,7 +74,7 @@ public class DearlyDeparted extends CardImpl { class DearlyDepartedEntersBattlefieldEffect extends ReplacementEffectImpl { public DearlyDepartedEntersBattlefieldEffect() { - super(Duration.OneUse, Outcome.BoostCreature); + super(Duration.WhileInGraveyard, Outcome.BoostCreature); staticText = "As long as {this} is in your graveyard, each Human creature you control enters the battlefield with an additional +1/+1 counter on it"; } diff --git a/Mage.Sets/src/mage/cards/d/Dermoplasm.java b/Mage.Sets/src/mage/cards/d/Dermoplasm.java index 3fe7abef13..441aeac1c0 100644 --- a/Mage.Sets/src/mage/cards/d/Dermoplasm.java +++ b/Mage.Sets/src/mage/cards/d/Dermoplasm.java @@ -35,7 +35,7 @@ import mage.abilities.keyword.FlyingAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.abilities.keyword.MorphAbility; import mage.cards.CardImpl; @@ -103,7 +103,7 @@ class DermoplasmEffect extends OneShotEffect { Permanent thisCreature = game.getPermanent(source.getId()); FilterCreatureCard filter = new FilterCreatureCard("a creature card with a morph ability"); filter.add(new AbilityPredicate(MorphAbility.class)); - Effect effect = new PutPermanentOnBattlefieldEffect(new FilterCreatureCard(filter)); + Effect effect = new PutCardFromHandOntoBattlefieldEffect(new FilterCreatureCard(filter)); if (effect.apply(game, source)) { if (thisCreature != null) { effect = new ReturnToHandTargetEffect(); diff --git a/Mage.Sets/src/mage/cards/d/Didgeridoo.java b/Mage.Sets/src/mage/cards/d/Didgeridoo.java index ec0870fceb..75fc8b297d 100644 --- a/Mage.Sets/src/mage/cards/d/Didgeridoo.java +++ b/Mage.Sets/src/mage/cards/d/Didgeridoo.java @@ -30,7 +30,7 @@ package mage.cards.d; import java.util.UUID; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -55,7 +55,7 @@ public class Didgeridoo extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}"); // {3}: You may put a Minotaur permanent card from your hand onto the battlefield. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(filter), new ManaCostsImpl("{3}"))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutCardFromHandOntoBattlefieldEffect(filter), new ManaCostsImpl("{3}"))); } public Didgeridoo(final Didgeridoo card) { diff --git a/Mage.Sets/src/mage/cards/d/DragonArch.java b/Mage.Sets/src/mage/cards/d/DragonArch.java index 66441fa4ab..e76357850b 100644 --- a/Mage.Sets/src/mage/cards/d/DragonArch.java +++ b/Mage.Sets/src/mage/cards/d/DragonArch.java @@ -32,7 +32,7 @@ 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.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -57,7 +57,7 @@ public class DragonArch extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}"); // {2}, {T}: You may put a multicolored creature card from your hand onto the battlefield. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(filter), + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutCardFromHandOntoBattlefieldEffect(filter), new ManaCostsImpl("{2}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/d/DramaticEntrance.java b/Mage.Sets/src/mage/cards/d/DramaticEntrance.java index 610c17b2be..28659fe973 100644 --- a/Mage.Sets/src/mage/cards/d/DramaticEntrance.java +++ b/Mage.Sets/src/mage/cards/d/DramaticEntrance.java @@ -29,7 +29,7 @@ package mage.cards.d; import java.util.UUID; import mage.ObjectColor; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -52,7 +52,7 @@ public class DramaticEntrance extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{G}{G}"); // You may put a green creature card from your hand onto the battlefield. - this.getSpellAbility().addEffect(new PutPermanentOnBattlefieldEffect(filter)); + this.getSpellAbility().addEffect(new PutCardFromHandOntoBattlefieldEffect(filter)); } diff --git a/Mage.Sets/src/mage/cards/e/ElvishPioneer.java b/Mage.Sets/src/mage/cards/e/ElvishPioneer.java index 8062bdbacf..f9bbb4e051 100644 --- a/Mage.Sets/src/mage/cards/e/ElvishPioneer.java +++ b/Mage.Sets/src/mage/cards/e/ElvishPioneer.java @@ -30,12 +30,12 @@ package mage.cards.e; import java.util.UUID; import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.filter.common.FilterLandCard; +import mage.filter.StaticFilters; /** * @@ -44,7 +44,7 @@ import mage.filter.common.FilterLandCard; public class ElvishPioneer extends CardImpl { public ElvishPioneer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.ELF); this.subtype.add(SubType.DRUID); @@ -52,7 +52,7 @@ public class ElvishPioneer extends CardImpl { this.toughness = new MageInt(1); // When Elvish Pioneer enters the battlefield, you may put a basic land card from your hand onto the battlefield tapped. - this.addAbility(new EntersBattlefieldTriggeredAbility(new PutLandFromHandOntoBattlefieldEffect(true, FilterLandCard.basicLandCard()), false)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A, false, true), false)); } public ElvishPioneer(final ElvishPioneer card) { diff --git a/Mage.Sets/src/mage/cards/e/ElvishPiper.java b/Mage.Sets/src/mage/cards/e/ElvishPiper.java index 77b8a475ba..26013d4dea 100644 --- a/Mage.Sets/src/mage/cards/e/ElvishPiper.java +++ b/Mage.Sets/src/mage/cards/e/ElvishPiper.java @@ -27,19 +27,18 @@ */ package mage.cards.e; - import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterCreatureCard; +import mage.filter.StaticFilters; /** * @@ -48,7 +47,7 @@ import mage.filter.common.FilterCreatureCard; public class ElvishPiper extends CardImpl { public ElvishPiper(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.ELF); this.subtype.add(SubType.SHAMAN); @@ -57,7 +56,7 @@ public class ElvishPiper extends CardImpl { // {G}, {tap}: You may put a creature card from your hand onto the battlefield. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutPermanentOnBattlefieldEffect(new FilterCreatureCard("a creature card")), + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_CREATURE_A), new ManaCostsImpl("{G}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/f/FirebrandRanger.java b/Mage.Sets/src/mage/cards/f/FirebrandRanger.java index 3c335a7fd5..c46cbf97cc 100644 --- a/Mage.Sets/src/mage/cards/f/FirebrandRanger.java +++ b/Mage.Sets/src/mage/cards/f/FirebrandRanger.java @@ -33,22 +33,13 @@ 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.OneShotEffect; -import mage.cards.Card; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Outcome; -import mage.constants.SuperType; import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.CardTypePredicate; -import mage.filter.predicate.mageobject.SupertypePredicate; -import mage.game.Game; -import mage.players.Player; -import mage.target.common.TargetCardInHand; +import mage.filter.StaticFilters; /** * @@ -63,8 +54,9 @@ public class FirebrandRanger extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(1); - // {G}, {tap}: You may put a basic land card from your hand onto the battlefield. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLandOnBattlefieldEffect(), new ManaCostsImpl("{G}")); + // {G}, {T}: You may put a basic land card from your hand onto the battlefield. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new ManaCostsImpl("{G}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); } @@ -78,46 +70,3 @@ public class FirebrandRanger extends CardImpl { return new FirebrandRanger(this); } } - -class PutLandOnBattlefieldEffect extends OneShotEffect { - - private static final FilterCard filter = new FilterCard("basic land card"); - - static { - filter.add(Predicates.and(new CardTypePredicate(CardType.LAND), new SupertypePredicate(SuperType.BASIC))); - } - - private static final String choiceText = "Put a basic land card from your hand onto the battlefield?"; - - public PutLandOnBattlefieldEffect() { - super(Outcome.PutLandInPlay); - this.staticText = "you may put a basic land card from your hand onto the battlefield"; - } - - public PutLandOnBattlefieldEffect(final PutLandOnBattlefieldEffect effect) { - super(effect); - } - - @Override - public PutLandOnBattlefieldEffect copy() { - return new PutLandOnBattlefieldEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutLandInPlay, choiceText, source, game)) { - return false; - } - - TargetCardInHand target = new TargetCardInHand(filter); - if (player.choose(Outcome.PutLandInPlay, target, source.getSourceId(), game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId()); - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/f/Flickerform.java b/Mage.Sets/src/mage/cards/f/Flickerform.java index f1bbbbba8b..3898d93bfb 100644 --- a/Mage.Sets/src/mage/cards/f/Flickerform.java +++ b/Mage.Sets/src/mage/cards/f/Flickerform.java @@ -27,6 +27,8 @@ */ package mage.cards.f; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -50,8 +52,8 @@ import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.ExileZone; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.game.permanent.token.TokenImpl; import mage.game.permanent.token.Token; +import mage.players.Player; import mage.target.Target; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -63,7 +65,7 @@ import mage.target.common.TargetCreaturePermanent; public class Flickerform extends CardImpl { public Flickerform(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -128,7 +130,7 @@ class FlickerformEffect extends OneShotEffect { } } if (!(enchantedCreature instanceof Token)) { - // At the beginning of the next end step, return that card to the battlefield under its owner's control. + // At the beginning of the next end step, return that card to the battlefield under its owner's control. // If you do, return the other cards exiled this way to the battlefield under their owners' control attached to that creature AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility( new FlickerformReturnEffect(enchantedCreature.getId(), exileZoneId)); @@ -174,12 +176,17 @@ class FlickerformReturnEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } ExileZone exileZone = game.getExile().getExileZone(exileZoneId); Card enchantedCard = exileZone.get(enchantedCardId, game); if (enchantedCard != null) { - enchantedCard.putOntoBattlefield(game, Zone.EXILED, source.getSourceId(), enchantedCard.getOwnerId()); + controller.moveCards(enchantedCard, Zone.BATTLEFIELD, source, game); Permanent newPermanent = game.getPermanent(enchantedCardId); if (newPermanent != null) { + Set<Card> toBattlefieldAttached = new HashSet<Card>(); for (Card enchantment : exileZone.getCards(game)) { if (filterAura.match(enchantment, game)) { boolean canTarget = false; @@ -196,9 +203,13 @@ class FlickerformReturnEffect extends OneShotEffect { } game.getState().setValue("attachTo:" + enchantment.getId(), newPermanent); } - if (enchantment.putOntoBattlefield(game, Zone.EXILED, source.getSourceId(), enchantment.getOwnerId())) { - if (filterAura.match(enchantment, game)) { - newPermanent.addAttachment(enchantment.getId(), game); + toBattlefieldAttached.add(enchantment); + } + if (!toBattlefieldAttached.isEmpty()) { + controller.moveCards(toBattlefieldAttached, Zone.BATTLEFIELD, source, game); + for (Card card : toBattlefieldAttached) { + if (game.getState().getZone(card.getId()).equals(Zone.BATTLEFIELD)) { + newPermanent.addAttachment(card.getId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/g/GaeasTouch.java b/Mage.Sets/src/mage/cards/g/GaeasTouch.java index f95fc48d67..459c36392b 100644 --- a/Mage.Sets/src/mage/cards/g/GaeasTouch.java +++ b/Mage.Sets/src/mage/cards/g/GaeasTouch.java @@ -29,24 +29,17 @@ package mage.cards.g; import java.util.UUID; import mage.Mana; -import mage.abilities.Ability; import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.mana.SimpleManaAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.FilterCard; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.mageobject.SupertypePredicate; -import mage.game.Game; -import mage.players.Player; -import mage.target.common.TargetCardInHand; /** * @@ -55,10 +48,14 @@ import mage.target.common.TargetCardInHand; public class GaeasTouch extends CardImpl { public GaeasTouch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}{G}"); // You may put a basic Forest card from your hand onto the battlefield. Activate this ability only any time you could cast a sorcery and only once each turn. - LimitedTimesPerTurnActivatedAbility ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new PutBasicForestOnBattlefieldEffect(), new GenericManaCost(0), 1); + FilterCard filter = new FilterCard("basic Forest card"); + filter.add(new SupertypePredicate(SuperType.BASIC)); + filter.add(new SubtypePredicate(SubType.FOREST)); + LimitedTimesPerTurnActivatedAbility ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, + new PutCardFromHandOntoBattlefieldEffect(filter), new GenericManaCost(0), 1); ability.setTiming(TimingRule.SORCERY); addAbility(ability); @@ -75,47 +72,3 @@ public class GaeasTouch extends CardImpl { return new GaeasTouch(this); } } - -class PutBasicForestOnBattlefieldEffect extends OneShotEffect { - - private static final FilterCard filter = new FilterCard("basic Forest card"); - - static { - filter.add(Predicates.and(new CardTypePredicate(CardType.LAND), new SupertypePredicate(SuperType.BASIC))); - filter.add(new SubtypePredicate(SubType.FOREST)); - } - - private static final String choiceText = "Put a basic Forest card from your hand onto the battlefield?"; - - public PutBasicForestOnBattlefieldEffect() { - super(Outcome.PutLandInPlay); - this.staticText = "put a basic Forest card from your hand onto the battlefield"; - } - - public PutBasicForestOnBattlefieldEffect(final PutBasicForestOnBattlefieldEffect effect) { - super(effect); - } - - @Override - public PutBasicForestOnBattlefieldEffect copy() { - return new PutBasicForestOnBattlefieldEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutLandInPlay, choiceText, source, game)) { - return false; - } - - TargetCardInHand target = new TargetCardInHand(filter); - if (player.choose(Outcome.PutLandInPlay, target, source.getSourceId(), game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId()); - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/g/GarrukCallerOfBeasts.java b/Mage.Sets/src/mage/cards/g/GarrukCallerOfBeasts.java index 23fbd9a95d..1bf0676fb7 100644 --- a/Mage.Sets/src/mage/cards/g/GarrukCallerOfBeasts.java +++ b/Mage.Sets/src/mage/cards/g/GarrukCallerOfBeasts.java @@ -32,7 +32,7 @@ import mage.ObjectColor; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.RevealLibraryPutIntoHandEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -67,7 +67,7 @@ public class GarrukCallerOfBeasts extends CardImpl { this.addAbility(new LoyaltyAbility(new RevealLibraryPutIntoHandEffect(5, new FilterCreatureCard("creature cards"), Zone.LIBRARY), 1)); // -3: You may put a green creature card from your hand onto the battlefield. - this.addAbility(new LoyaltyAbility(new PutPermanentOnBattlefieldEffect(filterGreenCreature), -3)); + this.addAbility(new LoyaltyAbility(new PutCardFromHandOntoBattlefieldEffect(filterGreenCreature), -3)); // -7: You get an emblem with "Whenever you cast a creature spell, you may search your library for a creature card, put it onto the battlefield, then shuffle your library."); this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new GarrukCallerOfBeastsEmblem()), -7)); diff --git a/Mage.Sets/src/mage/cards/g/GemstoneCaverns.java b/Mage.Sets/src/mage/cards/g/GemstoneCaverns.java index ef6a00309f..ddd88c5a27 100644 --- a/Mage.Sets/src/mage/cards/g/GemstoneCaverns.java +++ b/Mage.Sets/src/mage/cards/g/GemstoneCaverns.java @@ -37,7 +37,10 @@ import mage.abilities.costs.Cost; import mage.abilities.costs.common.ExileFromHandCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.decorator.ConditionalManaEffect; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.abilities.effects.mana.BasicManaEffect; import mage.abilities.mana.ConditionalManaAbility; @@ -45,6 +48,7 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.SuperType; import mage.constants.Zone; @@ -143,14 +147,16 @@ class GemstoneCavernsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { Card card = game.getCard(source.getSourceId()); if (card != null) { - if (card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId())) { + ContinuousEffect effect = new EntersBattlefieldEffect(new AddCountersSourceEffect(CounterType.LUCK.createInstance()), ""); + effect.setDuration(Duration.OneUse); + game.addEffect(effect, source); + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { - permanent.addCounters(CounterType.LUCK.createInstance(), source, game); Cost cost = new ExileFromHandCost(new TargetCardInHand()); if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game)) { cost.pay(source, game, source.getSourceId(), source.getControllerId(), true, null); diff --git a/Mage.Sets/src/mage/cards/g/GiftOfImmortality.java b/Mage.Sets/src/mage/cards/g/GiftOfImmortality.java index 3360917aea..69f4f574c7 100644 --- a/Mage.Sets/src/mage/cards/g/GiftOfImmortality.java +++ b/Mage.Sets/src/mage/cards/g/GiftOfImmortality.java @@ -39,8 +39,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; @@ -142,7 +142,7 @@ class GiftOfImmortalityReturnEnchantmentEffect extends OneShotEffect { Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source)); if (controller != null && creature != null) { game.getState().setValue("attachTo:" + aura.getId(), creature); - aura.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), controller.getId()); + controller.moveCards(aura, Zone.BATTLEFIELD, source, game); return creature.addAttachment(aura.getId(), game); } } diff --git a/Mage.Sets/src/mage/cards/g/GoblinLackey.java b/Mage.Sets/src/mage/cards/g/GoblinLackey.java index f937117f0a..31bcb46f7c 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinLackey.java +++ b/Mage.Sets/src/mage/cards/g/GoblinLackey.java @@ -30,7 +30,7 @@ package mage.cards.g; import java.util.UUID; import mage.MageInt; import mage.abilities.common.DealsDamageToAPlayerTriggeredAbility; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -58,7 +58,7 @@ public class GoblinLackey extends CardImpl { this.toughness = new MageInt(1); // Whenever Goblin Lackey deals damage to a player, you may put a Goblin permanent card from your hand onto the battlefield. - this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new PutPermanentOnBattlefieldEffect(filter), false)); + this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect(filter), false)); } public GoblinLackey(final GoblinLackey card) { diff --git a/Mage.Sets/src/mage/cards/g/GoblinWizard.java b/Mage.Sets/src/mage/cards/g/GoblinWizard.java index 755c51e88b..c9baf7ecbf 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinWizard.java +++ b/Mage.Sets/src/mage/cards/g/GoblinWizard.java @@ -34,7 +34,7 @@ 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.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.ProtectionAbility; import mage.cards.CardImpl; @@ -72,7 +72,7 @@ public class GoblinWizard extends CardImpl { // {tap}: You may put a Goblin permanent card from your hand onto the battlefield. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutPermanentOnBattlefieldEffect(filter), + new PutCardFromHandOntoBattlefieldEffect(filter), new TapSourceCost())); // {R}: Target Goblin gains protection from white until end of turn. diff --git a/Mage.Sets/src/mage/cards/g/GracefulReprieve.java b/Mage.Sets/src/mage/cards/g/GracefulReprieve.java index f727f6d91b..45309c83ae 100644 --- a/Mage.Sets/src/mage/cards/g/GracefulReprieve.java +++ b/Mage.Sets/src/mage/cards/g/GracefulReprieve.java @@ -28,6 +28,7 @@ package mage.cards.g; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -42,9 +43,9 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.events.ZoneChangeEvent; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; /** * @@ -53,12 +54,12 @@ import mage.target.common.TargetCreaturePermanent; public class GracefulReprieve extends CardImpl { public GracefulReprieve(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); // When target creature dies this turn, return that card to the battlefield under its owner's control. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addEffect(new GracefulReprieveEffect()); - + } public GracefulReprieve(final GracefulReprieve card) { @@ -89,7 +90,7 @@ class GracefulReprieveEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - DelayedTriggeredAbility delayedAbility = new GracefulReprieveDelayedTriggeredAbility(targetPointer.getFirst(game, source)); + DelayedTriggeredAbility delayedAbility = new GracefulReprieveDelayedTriggeredAbility(new MageObjectReference(targetPointer.getFirst(game, source), game)); game.addDelayedTriggeredAbility(delayedAbility, source); return true; } @@ -97,10 +98,10 @@ class GracefulReprieveEffect extends OneShotEffect { class GracefulReprieveDelayedTriggeredAbility extends DelayedTriggeredAbility { - private UUID target; + private MageObjectReference target; - public GracefulReprieveDelayedTriggeredAbility(UUID target) { - super(new GracefulReprieveDelayedEffect(target), Duration.EndOfTurn); + public GracefulReprieveDelayedTriggeredAbility(MageObjectReference target) { + super(new GracefulReprieveDelayedEffect(), Duration.EndOfTurn); this.target = target; } @@ -116,9 +117,10 @@ class GracefulReprieveDelayedTriggeredAbility extends DelayedTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getTargetId().equals(target)) { + if (target.refersTo(((ZoneChangeEvent) event).getTarget(), game)) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { + getEffects().setTargetPointer(new FixedTarget(target.getSourceId())); return true; } } @@ -138,17 +140,13 @@ class GracefulReprieveDelayedTriggeredAbility extends DelayedTriggeredAbility { class GracefulReprieveDelayedEffect extends OneShotEffect { - private final UUID target; - - public GracefulReprieveDelayedEffect(UUID target) { + public GracefulReprieveDelayedEffect() { super(Outcome.PutCreatureInPlay); - this.target = target; this.staticText = "return that card to the battlefield under its owner's control"; } public GracefulReprieveDelayedEffect(final GracefulReprieveDelayedEffect effect) { super(effect); - this.target = effect.target; } @Override @@ -159,17 +157,12 @@ class GracefulReprieveDelayedEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = (Permanent) game.getLastKnownInformation(target, Zone.BATTLEFIELD); - if (controller != null - && permanent != null) { - Player player = game.getPlayer(permanent.getOwnerId()); - if (player != null) { - Card card = game.getCard(target); - if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD) { - return card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), player.getId()); - } - return true; + if (controller != null) { + Card card = game.getCard(getTargetPointer().getFirst(game, source)); + if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null); } + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/g/GraveUpheaval.java b/Mage.Sets/src/mage/cards/g/GraveUpheaval.java index 60ccfd4700..3cd069f880 100644 --- a/Mage.Sets/src/mage/cards/g/GraveUpheaval.java +++ b/Mage.Sets/src/mage/cards/g/GraveUpheaval.java @@ -43,6 +43,8 @@ import mage.constants.Duration; 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.TargetCardInGraveyard; import mage.target.targetpointer.FixedTarget; @@ -55,7 +57,6 @@ public class GraveUpheaval extends CardImpl { public GraveUpheaval(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}{R}"); - // Put target creature card from a graveyard onto the battlefield under your control. It gains haste. this.getSpellAbility().addEffect(new GraveUpheavalEffect()); this.getSpellAbility().addTarget(new TargetCardInGraveyard()); @@ -92,12 +93,19 @@ class GraveUpheavalEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } Card card = game.getCard(source.getFirstTarget()); if (card != null) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); - ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); - effect.setTargetPointer(new FixedTarget(card.getId())); - game.addEffect(effect, source); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + Permanent permanent = game.getPermanent(card.getId()); + if (permanent != null) { + ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); + } return true; } diff --git a/Mage.Sets/src/mage/cards/g/GruesomeEncore.java b/Mage.Sets/src/mage/cards/g/GruesomeEncore.java index 162c5f0259..26b1d86fff 100644 --- a/Mage.Sets/src/mage/cards/g/GruesomeEncore.java +++ b/Mage.Sets/src/mage/cards/g/GruesomeEncore.java @@ -48,6 +48,8 @@ import mage.filter.common.FilterCreatureCard; 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.TargetCardInOpponentsGraveyard; import mage.target.targetpointer.FixedTarget; @@ -60,7 +62,7 @@ public class GruesomeEncore extends CardImpl { private static final FilterCreatureCard filter = new FilterCreatureCard("creature card from an opponent's graveyard"); public GruesomeEncore(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); // Put target creature card from an opponent's graveyard onto the battlefield under your control. It gains haste. this.getSpellAbility().addEffect(new GruesomeEncoreEffect()); @@ -97,19 +99,23 @@ class GruesomeEncoreEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Card card = game.getCard(source.getFirstTarget()); + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card != null) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); - - ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); - effect.setTargetPointer(new FixedTarget(card.getId())); - game.addEffect(effect, source); - - ExileTargetEffect exileEffect = new ExileTargetEffect(); - exileEffect.setTargetPointer(new FixedTarget(card.getId())); - DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect); - game.addDelayedTriggeredAbility(delayedAbility, source); - + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + Permanent permanent = game.getPermanent(card.getId()); + if (permanent != null) { + ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); + ExileTargetEffect exileEffect = new ExileTargetEffect(); + exileEffect.setTargetPointer(new FixedTarget(permanent, game)); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect); + game.addDelayedTriggeredAbility(delayedAbility, source); + } return true; } diff --git a/Mage.Sets/src/mage/cards/g/GryffsBoon.java b/Mage.Sets/src/mage/cards/g/GryffsBoon.java index 171fc5c063..df26c590d8 100644 --- a/Mage.Sets/src/mage/cards/g/GryffsBoon.java +++ b/Mage.Sets/src/mage/cards/g/GryffsBoon.java @@ -45,6 +45,7 @@ import mage.cards.CardSetInfo; import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -55,7 +56,7 @@ import mage.target.common.TargetCreaturePermanent; public class GryffsBoon extends CardImpl { public GryffsBoon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -102,12 +103,13 @@ class GryffsBoonEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Card aura = game.getCard(source.getSourceId()); - if (aura != null + Player controller = game.getPlayer(source.getControllerId()); + if (aura != null && controller != null && game.getState().getZone(aura.getId()) == Zone.GRAVEYARD) { Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (!targetPermanent.cantBeAttachedBy(aura, game)) { game.getState().setValue("attachTo:" + aura.getId(), targetPermanent); - aura.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); + controller.moveCards(aura, Zone.BATTLEFIELD, source, game); return targetPermanent.addAttachment(aura.getId(), game); } } diff --git a/Mage.Sets/src/mage/cards/g/GuildFeud.java b/Mage.Sets/src/mage/cards/g/GuildFeud.java index c3dceb9c07..7276a9159b 100644 --- a/Mage.Sets/src/mage/cards/g/GuildFeud.java +++ b/Mage.Sets/src/mage/cards/g/GuildFeud.java @@ -27,6 +27,7 @@ */ package mage.cards.g; +import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -43,8 +44,6 @@ import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetOpponent; -import java.util.UUID; - /** * * @author LevelX2 @@ -52,7 +51,7 @@ import java.util.UUID; public class GuildFeud extends CardImpl { public GuildFeud(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{5}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{R}"); // At the beginning of your upkeep, target opponent reveals the top three cards // of their library, may put a creature card from among them onto the battlefield, @@ -95,9 +94,8 @@ class GuildFeudEffect extends OneShotEffect { if (opponent != null && controller != null && sourceObject != null) { for (int activePlayer = 0; activePlayer < 2; activePlayer++) { Player player = (activePlayer == 0 ? opponent : controller); - Cards topThreeCards = new CardsImpl(); - topThreeCards.addAll(player.getLibrary().getTopCards(game, 3)); - player.revealCards(sourceObject.getIdName() + " - " + player.getName() + " top library cards", topThreeCards, game); + Cards topThreeCards = new CardsImpl(player.getLibrary().getTopCards(game, 3)); + player.revealCards(source, player.getName() + " top library cards", topThreeCards, game); Card creatureToBattlefield; if (!topThreeCards.isEmpty()) { if (player.chooseUse(Outcome.PutCreatureInPlay, "Put a creature card among them to the battlefield?", source, game)) { @@ -108,9 +106,7 @@ class GuildFeudEffect extends OneShotEffect { creatureToBattlefield = topThreeCards.get(target.getFirstTarget(), game); if (creatureToBattlefield != null) { topThreeCards.remove(creatureToBattlefield); - if (creatureToBattlefield.putOntoBattlefield(game, Zone.LIBRARY, - source.getSourceId(), player.getId())) { - game.informPlayers("Guild Feud: " + player.getLogName() + " put " + creatureToBattlefield.getName() + " to the battlefield"); + if (player.moveCards(creatureToBattlefield, Zone.BATTLEFIELD, source, game)) { if (activePlayer == 0) { opponentCreature = game.getPermanent(creatureToBattlefield.getId()); } else { diff --git a/Mage.Sets/src/mage/cards/h/HuntedWumpus.java b/Mage.Sets/src/mage/cards/h/HuntedWumpus.java index 712c0c2dc4..98ef9b971e 100644 --- a/Mage.Sets/src/mage/cards/h/HuntedWumpus.java +++ b/Mage.Sets/src/mage/cards/h/HuntedWumpus.java @@ -31,18 +31,18 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.common.FilterCreatureCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; -import mage.target.common.TargetCardInHand; +import mage.target.targetpointer.FixedTarget; /** * @@ -51,7 +51,7 @@ import mage.target.common.TargetCardInHand; public class HuntedWumpus extends CardImpl { public HuntedWumpus(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.BEAST); this.power = new MageInt(6); @@ -92,20 +92,11 @@ class HuntedWumpusEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for(UUID playerId: game.getState().getPlayersInRange(controller.getId(), game)) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { if (!playerId.equals(controller.getId())) { - Player player = game.getPlayer(playerId); - if (player != null) { - TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard()); - if (target.canChoose(source.getSourceId(), playerId, game) - && player.chooseUse(Outcome.Neutral, "Put a creature card from your hand onto the battlefield?", source, game) - && player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), player.getId()); - } - } - } + Effect effect = new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_CREATURE_A, true); + effect.setTargetPointer(new FixedTarget(playerId)); + effect.apply(game, source); } } return true; diff --git a/Mage.Sets/src/mage/cards/h/HuntingGrounds.java b/Mage.Sets/src/mage/cards/h/HuntingGrounds.java index 3e03f591a5..de57563194 100644 --- a/Mage.Sets/src/mage/cards/h/HuntingGrounds.java +++ b/Mage.Sets/src/mage/cards/h/HuntingGrounds.java @@ -33,7 +33,7 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SpellCastOpponentTriggeredAbility; import mage.abilities.condition.common.CardsInControllerGraveCondition; import mage.abilities.decorator.ConditionalContinuousEffect; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -53,7 +53,7 @@ public class HuntingGrounds extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}{W}"); // Threshold - As long as seven or more cards are in your graveyard, Hunting Grounds has "Whenever an opponent casts a spell, you may put a creature card from your hand onto the battlefield." - Ability gainedAbility = new SpellCastOpponentTriggeredAbility(new PutPermanentOnBattlefieldEffect( + Ability gainedAbility = new SpellCastOpponentTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect( new FilterCreatureCard("a creature card")), true); Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( new GainAbilitySourceEffect(gainedAbility, Duration.WhileOnBattlefield), new CardsInControllerGraveCondition(7), diff --git a/Mage.Sets/src/mage/cards/i/Incoming.java b/Mage.Sets/src/mage/cards/i/Incoming.java index 2ad9b51cc7..f00eadbf6e 100644 --- a/Mage.Sets/src/mage/cards/i/Incoming.java +++ b/Mage.Sets/src/mage/cards/i/Incoming.java @@ -30,9 +30,9 @@ package mage.cards.i; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; @@ -101,13 +101,7 @@ class IncomingEffect extends OneShotEffect { if (player != null) { TargetCardInLibrary target = new TargetCardInLibrary(0, Integer.MAX_VALUE, filter); if (player.searchLibrary(target, game)) { - for (UUID cardId : target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); - if (card != null) { - card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId(), true); - } - - } + player.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); player.shuffleLibrary(source, game); } } diff --git a/Mage.Sets/src/mage/cards/i/IntoTheWilds.java b/Mage.Sets/src/mage/cards/i/IntoTheWilds.java index 27b2f15ba9..f64cd9c128 100644 --- a/Mage.Sets/src/mage/cards/i/IntoTheWilds.java +++ b/Mage.Sets/src/mage/cards/i/IntoTheWilds.java @@ -34,13 +34,11 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; -import mage.filter.common.FilterLandCard; import mage.game.Game; import mage.players.Player; @@ -51,10 +49,9 @@ import mage.players.Player; public class IntoTheWilds extends CardImpl { public IntoTheWilds(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); - - // At the beginning of your upkeep, look at the top card of your library. If it's a land card, you may put it onto the battlefield. + // At the beginning of your upkeep, look at the top card of your library. If it's a land card, you may put it onto the battlefield. this.addAbility(new BeginningOfUpkeepTriggeredAbility(new IntoTheWildsEffect(), TargetController.YOU, false)); } @@ -71,8 +68,6 @@ public class IntoTheWilds extends CardImpl { class IntoTheWildsEffect extends OneShotEffect { - private final static FilterLandCard filter = new FilterLandCard(); - public IntoTheWildsEffect() { super(Outcome.PutLandInPlay); this.staticText = "look at the top card of your library. If it's a land card, you may put it onto the battlefield"; @@ -89,20 +84,18 @@ class IntoTheWildsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } - Card card = player.getLibrary().getFromTop(game); + Card card = controller.getLibrary().getFromTop(game); if (card != null) { - Cards cards = new CardsImpl(); - cards.add(card); - player.lookAtCards("Into the Wilds", cards, game); - if (filter.match(card, game)) { + controller.lookAtCards(source, "", new CardsImpl(card), game); + if (card.isLand()) { String message = "Put " + card.getName() + " onto the battlefield?"; - if (player.chooseUse(outcome, message, source, game)) { - return card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId(), false); + if (controller.chooseUse(outcome, message, source, game)) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } } diff --git a/Mage.Sets/src/mage/cards/k/KrosanWayfarer.java b/Mage.Sets/src/mage/cards/k/KrosanWayfarer.java index 2d8ff4b391..bbe0b97502 100644 --- a/Mage.Sets/src/mage/cards/k/KrosanWayfarer.java +++ b/Mage.Sets/src/mage/cards/k/KrosanWayfarer.java @@ -31,12 +31,13 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; -import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; /** * @@ -45,14 +46,15 @@ import mage.constants.Zone; public class KrosanWayfarer extends CardImpl { public KrosanWayfarer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.DRUID); this.power = new MageInt(1); this.toughness = new MageInt(1); // Sacrifice Krosan Wayfarer: You may put a land card from your hand onto the battlefield. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLandFromHandOntoBattlefieldEffect(), new SacrificeSourceCost())); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new SacrificeSourceCost())); } public KrosanWayfarer(final KrosanWayfarer card) { diff --git a/Mage.Sets/src/mage/cards/k/Kudzu.java b/Mage.Sets/src/mage/cards/k/Kudzu.java index 398a081c93..7ceb1215dc 100644 --- a/Mage.Sets/src/mage/cards/k/Kudzu.java +++ b/Mage.Sets/src/mage/cards/k/Kudzu.java @@ -37,10 +37,9 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.Filter; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -120,22 +119,18 @@ class KudzuEffect extends OneShotEffect { Permanent landChosen = game.getPermanent(target.getFirstTarget()); if (landChosen != null) { for (Target targetTest : kudzuCard.getSpellAbility().getTargets()) { - Filter filterTest = targetTest.getFilter(); - if (filterTest.match(landChosen, game)) { - if (game.getBattlefield().containsPermanent(landChosen.getId())) { //verify that it is still on the battlefield - game.getState().setValue("attachTo:" + kudzuCard.getId(), landChosen); - Zone zone = game.getState().getZone(kudzuCard.getId()); - kudzuCard.putOntoBattlefield(game, zone, source.getSourceId(), controller.getId()); - return landChosen.addAttachment(kudzuCard.getId(), game); - } + if (targetTest.getFilter().match(landChosen, game)) { + landChosen.addAttachment(kudzu.getId(), game); } } } } } } + } } + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/l/LilianaDeathWielder.java b/Mage.Sets/src/mage/cards/l/LilianaDeathWielder.java index 93bf9c481e..55c77da720 100644 --- a/Mage.Sets/src/mage/cards/l/LilianaDeathWielder.java +++ b/Mage.Sets/src/mage/cards/l/LilianaDeathWielder.java @@ -34,7 +34,6 @@ import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -43,7 +42,7 @@ import mage.constants.Outcome; import mage.constants.SuperType; import mage.constants.Zone; import mage.counters.CounterType; -import mage.filter.common.FilterCreatureCard; +import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.CounterPredicate; import mage.game.Game; @@ -111,11 +110,9 @@ class LilianaDeathWielderEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null){ - for (Card card : player.getGraveyard().getCards(new FilterCreatureCard(), game)) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); - } + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + controller.moveCards(controller.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game), Zone.BATTLEFIELD, source, game); } return true; } diff --git a/Mage.Sets/src/mage/cards/l/LlanowarScout.java b/Mage.Sets/src/mage/cards/l/LlanowarScout.java index abd1722d94..46332c0816 100644 --- a/Mage.Sets/src/mage/cards/l/LlanowarScout.java +++ b/Mage.Sets/src/mage/cards/l/LlanowarScout.java @@ -31,12 +31,13 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Zone; +import mage.filter.StaticFilters; /** * @@ -53,7 +54,8 @@ public class LlanowarScout extends CardImpl { this.toughness = new MageInt(3); // {T}: You may put a land card from your hand onto the battlefield. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLandFromHandOntoBattlefieldEffect(), new TapSourceCost())); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new TapSourceCost())); } public LlanowarScout(final LlanowarScout card) { diff --git a/Mage.Sets/src/mage/cards/l/LoamDweller.java b/Mage.Sets/src/mage/cards/l/LoamDweller.java index 2f338e36cc..a8899d21da 100644 --- a/Mage.Sets/src/mage/cards/l/LoamDweller.java +++ b/Mage.Sets/src/mage/cards/l/LoamDweller.java @@ -30,7 +30,7 @@ package mage.cards.l; import java.util.UUID; import mage.MageInt; import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -44,14 +44,16 @@ import mage.filter.StaticFilters; public class LoamDweller extends CardImpl { public LoamDweller(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(2); this.toughness = new MageInt(2); // Whenever you cast a Spirit or Arcane spell, you may put a land card from your hand onto the battlefield tapped. - this.addAbility(new SpellCastControllerTriggeredAbility(new PutLandFromHandOntoBattlefieldEffect(true), StaticFilters.SPIRIT_OR_ARCANE_CARD, true)); + this.addAbility(new SpellCastControllerTriggeredAbility( + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A, false, true), + StaticFilters.SPIRIT_OR_ARCANE_CARD, true)); } public LoamDweller(final LoamDweller card) { diff --git a/Mage.Sets/src/mage/cards/l/LoyalCathar.java b/Mage.Sets/src/mage/cards/l/LoyalCathar.java index e0805cb145..dbad114028 100644 --- a/Mage.Sets/src/mage/cards/l/LoyalCathar.java +++ b/Mage.Sets/src/mage/cards/l/LoyalCathar.java @@ -32,6 +32,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DiesTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.VigilanceAbility; @@ -40,11 +41,12 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.u.UnhallowedCathar; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; /** * @@ -53,7 +55,7 @@ import mage.game.permanent.Permanent; public class LoyalCathar extends CardImpl { public LoyalCathar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SOLDIER); @@ -96,8 +98,11 @@ class LoyalCatharEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { //create delayed triggered ability - AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnLoyalCatharEffect(source.getSourceId())); - game.addDelayedTriggeredAbility(delayedAbility, source); + if (Zone.GRAVEYARD == game.getState().getZone(source.getSourceId())) { + Effect effect = new ReturnLoyalCatharEffect(); + effect.setTargetPointer(new FixedTarget(source.getSourceId(), game.getState().getZoneChangeCounter(source.getSourceId()))); + game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); + } return true; } @@ -110,17 +115,13 @@ class LoyalCatharEffect extends OneShotEffect { class ReturnLoyalCatharEffect extends OneShotEffect { - private UUID cardId; - - public ReturnLoyalCatharEffect(UUID cardId) { + public ReturnLoyalCatharEffect() { super(Outcome.PutCardInPlay); - this.cardId = cardId; this.staticText = "return it to the battlefield transformed under your control"; } public ReturnLoyalCatharEffect(final ReturnLoyalCatharEffect effect) { super(effect); - this.cardId = effect.cardId; } @Override @@ -130,16 +131,16 @@ class ReturnLoyalCatharEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Card card = game.getCard(cardId); - if (card != null) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); - Permanent perm = game.getPermanent(cardId); - if (perm != null && perm.isTransformable()) { - perm.transform(game); - return true; - } + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; } - return false; + Card card = game.getCard(getTargetPointer().getFirst(game, source)); + if (card != null) { + game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/m/MasterTransmuter.java b/Mage.Sets/src/mage/cards/m/MasterTransmuter.java index c9e2b9359b..bf144ba75f 100644 --- a/Mage.Sets/src/mage/cards/m/MasterTransmuter.java +++ b/Mage.Sets/src/mage/cards/m/MasterTransmuter.java @@ -34,7 +34,7 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -59,7 +59,7 @@ public class MasterTransmuter extends CardImpl { this.toughness = new MageInt(2); // {U}, {tap}, Return an artifact you control to its owner's hand: You may put an artifact card from your hand onto the battlefield. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(new FilterArtifactCard("an artifact card")), new ManaCostsImpl("{U}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutCardFromHandOntoBattlefieldEffect(new FilterArtifactCard("an artifact card")), new ManaCostsImpl("{U}")); ability.addCost(new TapSourceCost()); ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact")))); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/m/MatterReshaper.java b/Mage.Sets/src/mage/cards/m/MatterReshaper.java index 8a7f6aef6c..e1e8536734 100644 --- a/Mage.Sets/src/mage/cards/m/MatterReshaper.java +++ b/Mage.Sets/src/mage/cards/m/MatterReshaper.java @@ -29,7 +29,6 @@ package mage.cards.m; import java.util.UUID; import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.DiesTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -38,9 +37,9 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.ComparisonType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterPermanentCard; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; @@ -54,7 +53,7 @@ import mage.players.Player; public class MatterReshaper extends CardImpl { public MatterReshaper(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{C}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{C}"); this.subtype.add(SubType.ELDRAZI); this.power = new MageInt(3); this.toughness = new MageInt(2); @@ -89,22 +88,20 @@ class MatterReshaperEffect extends OneShotEffect { @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 && controller.getLibrary().hasCards()) { + if (controller != null) { Card card = controller.getLibrary().getFromTop(game); if (card == null) { - return false; - } - controller.revealCards(sourceObject.getIdName(), new CardsImpl(card), game); - FilterPermanentCard filter = new FilterPermanentCard("permanent card with converted mana cost 3 or less"); - filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 4)); - if (filter.match(card, game)) { - if (controller.chooseUse(Outcome.PutCardInPlay, "Put " + card.getName() + " onto the battlefield (otherwise put in hand)?", source, game)) { - card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId(), false); - return true; + controller.revealCards(source, new CardsImpl(card), game); + FilterPermanentCard filter = new FilterPermanentCard("permanent card with converted mana cost 3 or less"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 4)); + if (filter.match(card, game)) { + if (controller.chooseUse(Outcome.PutCardInPlay, "Put " + card.getName() + " onto the battlefield (otherwise put in hand)?", source, game)) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + return true; + } } + controller.moveCards(card, Zone.HAND, source, game); } - card.moveToZone(Zone.HAND, source.getSourceId(), game, false); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/m/MindwrackLiege.java b/Mage.Sets/src/mage/cards/m/MindwrackLiege.java index e2deb019e0..3bb93115b2 100644 --- a/Mage.Sets/src/mage/cards/m/MindwrackLiege.java +++ b/Mage.Sets/src/mage/cards/m/MindwrackLiege.java @@ -33,7 +33,7 @@ import mage.ObjectColor; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -81,7 +81,7 @@ public class MindwrackLiege extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter2, true))); // {UR}{UR}{UR}{UR}: You may put a blue or red creature card from your hand onto the battlefield. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(filter3), new ManaCostsImpl("{U/R}{U/R}{U/R}{U/R}"))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutCardFromHandOntoBattlefieldEffect(filter3), new ManaCostsImpl("{U/R}{U/R}{U/R}{U/R}"))); } public MindwrackLiege(final MindwrackLiege card) { diff --git a/Mage.Sets/src/mage/cards/m/MoldgrafMonstrosity.java b/Mage.Sets/src/mage/cards/m/MoldgrafMonstrosity.java index 4eaef9de47..781181f75b 100644 --- a/Mage.Sets/src/mage/cards/m/MoldgrafMonstrosity.java +++ b/Mage.Sets/src/mage/cards/m/MoldgrafMonstrosity.java @@ -27,7 +27,6 @@ */ package mage.cards.m; -import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; @@ -39,14 +38,15 @@ import mage.abilities.keyword.TrampleAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.Zone; -import mage.filter.common.FilterCreatureCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; -import mage.util.RandomUtil; /** * @@ -98,34 +98,21 @@ class MoldgrafMonstrosityEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - boolean returned = false; - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - Set<Card> cards = player.getGraveyard().getCards(new FilterCreatureCard("creature cards"), game); - + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards possibleCards = new CardsImpl(controller.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game)); + // Set<Card> cards = controller.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game); + Cards toBattlefield = new CardsImpl(); for (int i = 0; i < 2; i++) { - Card card = getRandomCard(cards); + Card card = possibleCards.getRandom(game); if (card != null) { - returned |= card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); - cards.remove(card); + toBattlefield.add(card); + possibleCards.remove(card); } } + controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game); + return true; } - return returned; - } - - private Card getRandomCard(Set<Card> cards) { - if (cards == null || cards.size() < 1) { - return null; - } - int i = 0; - int pick = RandomUtil.nextInt(cards.size()); - for (Card card : cards) { - if (i == pick) { - return card; - } - i = i + 1; - } - return null; + return false; } } diff --git a/Mage.Sets/src/mage/cards/n/NettlevineBlight.java b/Mage.Sets/src/mage/cards/n/NettlevineBlight.java index 23a52cc2af..17b7bb3c3e 100644 --- a/Mage.Sets/src/mage/cards/n/NettlevineBlight.java +++ b/Mage.Sets/src/mage/cards/n/NettlevineBlight.java @@ -40,7 +40,6 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.TargetController; -import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -134,10 +133,7 @@ class NettlevineBlightEffect extends OneShotEffect { if (chosenPermanent != null) { Card nettlevineBlightCard = game.getCard(source.getSourceId()); if (nettlevineBlightCard != null) { - Zone zone = game.getState().getZone(nettlevineBlightCard.getId()); - nettlevineBlightCard.putOntoBattlefield(game, zone, source.getSourceId(), newController.getId()); - game.getState().setValue("attachTo:" + nettlevineBlight.getId(), chosenPermanent); - chosenPermanent.addAttachment(nettlevineBlight.getId(), game); + nettlevineBlight.attachTo(chosenPermanent.getId(), game); return true; } } diff --git a/Mage.Sets/src/mage/cards/n/NewFrontiers.java b/Mage.Sets/src/mage/cards/n/NewFrontiers.java index 246b24e817..9311f5aad7 100644 --- a/Mage.Sets/src/mage/cards/n/NewFrontiers.java +++ b/Mage.Sets/src/mage/cards/n/NewFrontiers.java @@ -29,7 +29,6 @@ package mage.cards.n; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -41,6 +40,7 @@ import mage.players.Player; import mage.target.common.TargetCardInLibrary; import java.util.UUID; +import mage.cards.CardsImpl; /** * @@ -86,18 +86,12 @@ class NewFrontiersEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { int amount = source.getManaCostsToPay().getX(); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); - if (player != null) { + if (player != null && player.chooseUse(outcome, "Search your library for up to " + amount + " basic lands?", source, game)) { TargetCardInLibrary target = new TargetCardInLibrary(0, amount, StaticFilters.FILTER_BASIC_LAND_CARD); if (player.searchLibrary(target, game)) { - for (UUID cardId : target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); - if (card != null) { - card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId(), true); - } - } + player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null); player.shuffleLibrary(source, game); } diff --git a/Mage.Sets/src/mage/cards/n/NissaStewardOfElements.java b/Mage.Sets/src/mage/cards/n/NissaStewardOfElements.java index 1b827c9bdb..d0f6e2b096 100644 --- a/Mage.Sets/src/mage/cards/n/NissaStewardOfElements.java +++ b/Mage.Sets/src/mage/cards/n/NissaStewardOfElements.java @@ -51,7 +51,6 @@ import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.game.permanent.token.TokenImpl; -import mage.game.permanent.token.Token; import mage.players.Player; import mage.target.TargetPermanent; @@ -117,8 +116,8 @@ class NissaStewardOfElementsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } int count = 1 + new CountersSourceCount(CounterType.LOYALTY).calculate(game, source, this); @@ -126,15 +125,12 @@ class NissaStewardOfElementsEffect extends OneShotEffect { filter.add(Predicates.or(new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.LAND))); filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, count)); - Card card = player.getLibrary().getFromTop(game); + Card card = controller.getLibrary().getFromTop(game); if (card != null) { - Cards cards = new CardsImpl(); - cards.add(card); - player.lookAtCards("Nissa, Steward of Elements", cards, game); + controller.lookAtCards(source, null, new CardsImpl(card), game); if (filter.match(card, game)) { - String message = "Put " + card.getName() + " onto the battlefield?"; - if (player.chooseUse(outcome, message, source, game)) { - return card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId(), false); + if (controller.chooseUse(outcome, "Put " + card.getName() + " onto the battlefield?", source, game)) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } } @@ -153,6 +149,7 @@ class NissaStewardOfElementsToken extends TokenImpl { this.addAbility(FlyingAbility.getInstance()); this.addAbility(HasteAbility.getInstance()); } + public NissaStewardOfElementsToken(final NissaStewardOfElementsToken token) { super(token); } diff --git a/Mage.Sets/src/mage/cards/n/NissasPilgrimage.java b/Mage.Sets/src/mage/cards/n/NissasPilgrimage.java index 9b6ba2b1dc..34f5209ced 100644 --- a/Mage.Sets/src/mage/cards/n/NissasPilgrimage.java +++ b/Mage.Sets/src/mage/cards/n/NissasPilgrimage.java @@ -40,10 +40,11 @@ import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; +import mage.constants.SuperType; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.common.FilterBasicLandCard; import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.mageobject.SupertypePredicate; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInLibrary; @@ -55,7 +56,7 @@ import mage.target.common.TargetCardInLibrary; public class NissasPilgrimage extends CardImpl { public NissasPilgrimage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}"); // Search your library for up to two basic Forest cards, reveal those cards, and put one onto the battlefield tapped and the rest into your hand. Then shuffle your library. // <i>Spell Mastery</i> — If there are two or more instant and/or sorcery cards in your graveyard, search your library for up to three basic Forest cards instead of two. @@ -74,9 +75,10 @@ public class NissasPilgrimage extends CardImpl { class NissasPilgrimageEffect extends OneShotEffect { - private static final FilterCard filter = new FilterBasicLandCard("basic Forest"); + private static final FilterCard filter = new FilterCard("basic Forest card"); static { + filter.add(new SupertypePredicate(SuperType.BASIC)); filter.add(new SubtypePredicate(SubType.FOREST)); } diff --git a/Mage.Sets/src/mage/cards/n/NomadMythmaker.java b/Mage.Sets/src/mage/cards/n/NomadMythmaker.java index 70540ac8fb..1ebff537f7 100644 --- a/Mage.Sets/src/mage/cards/n/NomadMythmaker.java +++ b/Mage.Sets/src/mage/cards/n/NomadMythmaker.java @@ -110,8 +110,7 @@ class NomadMythmakerEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Card aura = game.getCard(source.getFirstTarget()); - if (controller == null - || aura == null) { + if (controller == null || aura == null) { return false; } FilterControlledCreaturePermanent FILTER = new FilterControlledCreaturePermanent("Choose a creature you control"); @@ -122,7 +121,7 @@ class NomadMythmakerEffect extends OneShotEffect { if (permanent != null && !permanent.cantBeAttachedBy(aura, game)) { game.getState().setValue("attachTo:" + aura.getId(), permanent); - aura.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), controller.getId()); + controller.moveCards(aura, Zone.BATTLEFIELD, source, game); return permanent.addAttachment(aura.getId(), game); } } diff --git a/Mage.Sets/src/mage/cards/n/NorwoodPriestess.java b/Mage.Sets/src/mage/cards/n/NorwoodPriestess.java index 50e5f25441..e6575475f0 100644 --- a/Mage.Sets/src/mage/cards/n/NorwoodPriestess.java +++ b/Mage.Sets/src/mage/cards/n/NorwoodPriestess.java @@ -33,7 +33,7 @@ import mage.ObjectColor; import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.condition.common.MyTurnBeforeAttackersDeclaredCondition; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -64,7 +64,7 @@ public class NorwoodPriestess extends CardImpl { // {tap}: You may put a green creature card from your hand onto the battlefield. Activate this ability only during your turn, before attackers are declared. this.addAbility(new ActivateIfConditionActivatedAbility( Zone.BATTLEFIELD, - new PutPermanentOnBattlefieldEffect(filter), + new PutCardFromHandOntoBattlefieldEffect(filter), new TapSourceCost(), MyTurnBeforeAttackersDeclaredCondition.instance )); diff --git a/Mage.Sets/src/mage/cards/p/PreeminentCaptain.java b/Mage.Sets/src/mage/cards/p/PreeminentCaptain.java index a49ff3ea02..b702c28489 100644 --- a/Mage.Sets/src/mage/cards/p/PreeminentCaptain.java +++ b/Mage.Sets/src/mage/cards/p/PreeminentCaptain.java @@ -48,13 +48,13 @@ import mage.players.Player; import mage.target.common.TargetCardInHand; /** - * + * * @author Rafbill */ public class PreeminentCaptain extends CardImpl { public PreeminentCaptain(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); this.subtype.add(SubType.KITHKIN); this.subtype.add(SubType.SOLDIER); @@ -96,20 +96,22 @@ class PreeminentCaptainEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); TargetCardInHand target = new TargetCardInHand(filter); - if (target.canChoose(player.getId(), game) && target.choose(getOutcome(), player.getId(), source.getSourceId(), game)) { + if (target.canChoose(controller.getId(), game) && target.choose(getOutcome(), controller.getId(), source.getSourceId(), game)) { if (!target.getTargets().isEmpty()) { UUID cardId = target.getFirstTarget(); - Card card = player.getHand().get(cardId, game); + Card card = controller.getHand().get(cardId, game); if (card != null) { - if (card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId(), true)) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { Permanent permanent = game.getPermanent(card.getId()); - game.getCombat().addAttackingCreature(permanent.getId(), game); + if (permanent != null) { + game.getCombat().addAttackingCreature(permanent.getId(), game); + } } } - return true; } + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/p/PrimevalsGloriousRebirth.java b/Mage.Sets/src/mage/cards/p/PrimevalsGloriousRebirth.java index 9e1963d270..8c6713e7e5 100644 --- a/Mage.Sets/src/mage/cards/p/PrimevalsGloriousRebirth.java +++ b/Mage.Sets/src/mage/cards/p/PrimevalsGloriousRebirth.java @@ -5,7 +5,6 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.LegendarySpellAbility; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -15,8 +14,7 @@ import mage.game.Game; import mage.players.Player; /** - * @author JRHerlehy - * Created on 4/8/18. + * @author JRHerlehy Created on 4/8/18. */ public class PrimevalsGloriousRebirth extends CardImpl { @@ -61,11 +59,10 @@ class PrimevalsGloriousRebirthEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - for (Card card : player.getGraveyard().getCards(filter, game)) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); - } + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + controller.moveCards(controller.getGraveyard().getCards(filter, game), Zone.BATTLEFIELD, source, game); + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/p/PyrrhicRevival.java b/Mage.Sets/src/mage/cards/p/PyrrhicRevival.java index 3110ce8a5c..f286c90362 100644 --- a/Mage.Sets/src/mage/cards/p/PyrrhicRevival.java +++ b/Mage.Sets/src/mage/cards/p/PyrrhicRevival.java @@ -27,20 +27,25 @@ */ package mage.cards.p; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.Cards; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; +import mage.target.targetpointer.FixedTarget; /** * @@ -50,8 +55,7 @@ import mage.players.Player; public class PyrrhicRevival extends CardImpl { public PyrrhicRevival(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{W/B}{W/B}{W/B}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{W/B}{W/B}{W/B}"); // Each player returns each creature card from their graveyard to the battlefield with an additional -1/-1 counter on it. this.getSpellAbility().addEffect(new PyrrhicRevivalEffect()); @@ -86,23 +90,26 @@ class PyrrhicRevivalEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - boolean result = false; - for (Player player : game.getPlayers().values()) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Set<Card> toBattlefield = new HashSet<>(); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); if (player != null) { - Cards cards = player.getGraveyard(); - for (Card card : cards.getCards(game)) { + for (Card card : player.getGraveyard().getCards(game)) { if (card != null && card.isCreature()) { - if (card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), card.getOwnerId(), false)) { - Permanent permanent = game.getPermanent(card.getId()); - if (permanent != null) { - permanent.addCounters(CounterType.M1M1.createInstance(), source, game); - } - result = true; - } + toBattlefield.add(card); + ContinuousEffect effect = new EntersBattlefieldEffect(new AddCountersTargetEffect(CounterType.M1M1.createInstance())); + effect.setDuration(Duration.OneUse); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); } } } } - return result; + controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game, false, false, true, null); + return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/q/QuestForUlasTemple.java b/Mage.Sets/src/mage/cards/q/QuestForUlasTemple.java index 3d0a9b608e..dfdcbd7ecb 100644 --- a/Mage.Sets/src/mage/cards/q/QuestForUlasTemple.java +++ b/Mage.Sets/src/mage/cards/q/QuestForUlasTemple.java @@ -31,7 +31,9 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -47,7 +49,6 @@ import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetCardInHand; /** * @@ -56,13 +57,19 @@ import mage.target.common.TargetCardInHand; public class QuestForUlasTemple extends CardImpl { public QuestForUlasTemple(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); // At the beginning of your upkeep, you may look at the top card of your library. If it's a creature card, you may reveal it and put a quest counter on Quest for Ula's Temple. this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new QuestForUlasTempleEffect(), TargetController.YOU, true)); // At the beginning of each end step, if there are three or more quest counters on Quest for Ula's Temple, you may put a Kraken, Leviathan, Octopus, or Serpent creature card from your hand onto the battlefield. - this.addAbility(new QuestForUlasTempleTriggeredAbility()); + FilterCreatureCard filter = new FilterCreatureCard("Kraken, Leviathan, Octopus, or Serpent creature card"); + filter.add(Predicates.or( + new SubtypePredicate(SubType.KRAKEN), + new SubtypePredicate(SubType.LEVIATHAN), + new SubtypePredicate(SubType.OCTOPUS), + new SubtypePredicate(SubType.SERPENT))); + this.addAbility(new QuestForUlasTempleTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect(filter))); } public QuestForUlasTemple(final QuestForUlasTemple card) { @@ -116,8 +123,8 @@ class QuestForUlasTempleEffect extends OneShotEffect { class QuestForUlasTempleTriggeredAbility extends TriggeredAbilityImpl { - public QuestForUlasTempleTriggeredAbility() { - super(Zone.BATTLEFIELD, new QuestForUlasTempleEffect2(), true); + public QuestForUlasTempleTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect, true); } public QuestForUlasTempleTriggeredAbility(final QuestForUlasTempleTriggeredAbility ability) { @@ -142,50 +149,6 @@ class QuestForUlasTempleTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "At the beginning of each end step, if there are three or more quest counters on {this}, you may put a Kraken, Leviathan, Octopus, or Serpent creature card from your hand onto the battlefield."; - } -} - -class QuestForUlasTempleEffect2 extends OneShotEffect { - - private static final String query = "Do you want to put a Kraken, Leviathan, Octopus, or Serpent creature card from your hand onto the battlefield?"; - private static final FilterCreatureCard filter = new FilterCreatureCard("Kraken, Leviathan, Octopus, or Serpent creature card from your hand"); - - static { - filter.add(Predicates.or( - new SubtypePredicate(SubType.KRAKEN), - new SubtypePredicate(SubType.LEVIATHAN), - new SubtypePredicate(SubType.OCTOPUS), - new SubtypePredicate(SubType.SERPENT))); - } - - QuestForUlasTempleEffect2() { - super(Outcome.PutCreatureInPlay); - } - - QuestForUlasTempleEffect2(final QuestForUlasTempleEffect2 effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - TargetCardInHand target = new TargetCardInHand(filter); - if (target.canChoose(source.getSourceId(), controller.getId(), game) - && controller.chooseUse(Outcome.PutCreatureInPlay, query, source, game)) { - if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { - Card card = game.getCard(target.getFirstTarget()); - controller.moveCards(card, Zone.BATTLEFIELD, source, game); - } - } - return true; - } - return false; - } - - @Override - public QuestForUlasTempleEffect2 copy() { - return new QuestForUlasTempleEffect2(this); + return "At the beginning of each end step, if there are three or more quest counters on {this}, " + super.getRule(); } } diff --git a/Mage.Sets/src/mage/cards/q/QuicksilverAmulet.java b/Mage.Sets/src/mage/cards/q/QuicksilverAmulet.java index fc31254cc6..bd640c680e 100644 --- a/Mage.Sets/src/mage/cards/q/QuicksilverAmulet.java +++ b/Mage.Sets/src/mage/cards/q/QuicksilverAmulet.java @@ -31,12 +31,12 @@ import java.util.UUID; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Zone; -import mage.filter.common.FilterCreatureCard; +import mage.filter.StaticFilters; /** * @@ -45,11 +45,11 @@ import mage.filter.common.FilterCreatureCard; public class QuicksilverAmulet extends CardImpl { public QuicksilverAmulet(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); // {4}, {tap}: You may put a creature card from your hand onto the battlefield. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutPermanentOnBattlefieldEffect(new FilterCreatureCard("a creature card")), + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_CREATURE_A), new ManaCostsImpl("{4}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); @@ -64,5 +64,3 @@ public class QuicksilverAmulet extends CardImpl { return new QuicksilverAmulet(this); } } - - diff --git a/Mage.Sets/src/mage/cards/r/Reincarnation.java b/Mage.Sets/src/mage/cards/r/Reincarnation.java index 9c61c9a692..ed717e6238 100644 --- a/Mage.Sets/src/mage/cards/r/Reincarnation.java +++ b/Mage.Sets/src/mage/cards/r/Reincarnation.java @@ -57,7 +57,7 @@ import mage.target.common.TargetCreaturePermanent; public class Reincarnation extends CardImpl { public Reincarnation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}{G}"); // Choose target creature. When that creature dies this turn, return a creature card from its owner's graveyard to the battlefield under the control of that creature's owner. this.getSpellAbility().addEffect(new ReincarnationEffect()); @@ -141,7 +141,7 @@ class ReincarnationDelayedTriggeredAbility extends DelayedTriggeredAbility { class ReincarnationDelayedEffect extends OneShotEffect { - private UUID target; + private final UUID target; public ReincarnationDelayedEffect(UUID target) { super(Outcome.Detriment); @@ -166,14 +166,14 @@ class ReincarnationDelayedEffect extends OneShotEffect { if (permanent != null && controller != null) { Player player = game.getPlayer(permanent.getOwnerId()); if (player != null) { - FilterCreatureCard filter = new FilterCreatureCard(new StringBuilder("a creature card from ").append(player.getLogName()).append("'s graveyard").toString()); + FilterCreatureCard filter = new FilterCreatureCard("a creature card from " + player.getName() + "'s graveyard"); filter.add(new OwnerIdPredicate(player.getId())); Target targetCreature = new TargetCardInGraveyard(filter); if (targetCreature.canChoose(source.getSourceId(), controller.getId(), game) && controller.chooseTarget(outcome, targetCreature, source, game)) { Card card = game.getCard(targetCreature.getFirstTarget()); if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD) { - return card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), player.getId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null); } } return true; diff --git a/Mage.Sets/src/mage/cards/r/ReinsOfTheVinesteed.java b/Mage.Sets/src/mage/cards/r/ReinsOfTheVinesteed.java index 837efc634a..e59c361311 100644 --- a/Mage.Sets/src/mage/cards/r/ReinsOfTheVinesteed.java +++ b/Mage.Sets/src/mage/cards/r/ReinsOfTheVinesteed.java @@ -27,6 +27,9 @@ */ package mage.cards.r; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.DiesAttachedTriggeredAbility; @@ -49,10 +52,6 @@ import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - /** * * @author jeffwadsworth @@ -60,7 +59,7 @@ import java.util.UUID; public class ReinsOfTheVinesteed extends CardImpl { public ReinsOfTheVinesteed(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -127,7 +126,7 @@ class ReinsOfTheVinesteedEffect extends OneShotEffect { Permanent targetPermanent = game.getPermanent(target.getFirstTarget()); if (!targetPermanent.cantBeAttachedBy(aura, game)) { game.getState().setValue("attachTo:" + aura.getId(), targetPermanent); - aura.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), controller.getId()); + controller.moveCards(aura, Zone.BATTLEFIELD, source, game); return targetPermanent.addAttachment(aura.getId(), game); } } diff --git a/Mage.Sets/src/mage/cards/r/Restore.java b/Mage.Sets/src/mage/cards/r/Restore.java index 804ab78032..f05738b2bc 100644 --- a/Mage.Sets/src/mage/cards/r/Restore.java +++ b/Mage.Sets/src/mage/cards/r/Restore.java @@ -51,8 +51,7 @@ public class Restore extends CardImpl { private static final FilterLandCard filter = new FilterLandCard(); public Restore(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}"); // Put target land card from a graveyard onto the battlefield under your control. this.getSpellAbility().addEffect(new RestoreEffect()); @@ -91,7 +90,8 @@ class RestoreEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Card land = game.getCard(this.getTargetPointer().getFirst(game, source)); if (controller != null && game.getState().getZone(land.getId()) == Zone.GRAVEYARD) { - return land.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), controller.getId()); + controller.moveCards(land, Zone.BATTLEFIELD, source, game); + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/r/Retether.java b/Mage.Sets/src/mage/cards/r/Retether.java index beab992681..22efa8b76c 100644 --- a/Mage.Sets/src/mage/cards/r/Retether.java +++ b/Mage.Sets/src/mage/cards/r/Retether.java @@ -58,7 +58,7 @@ import mage.target.Target; public class Retether extends CardImpl { public Retether(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{W}"); // Return each Aura card from your graveyard to the battlefield. Only creatures can be enchanted this way. this.getSpellAbility().addEffect(new RetetherEffect()); @@ -108,7 +108,7 @@ class RetetherEffect extends OneShotEffect { FilterCreaturePermanent filter = new FilterCreaturePermanent("creature to enchant (" + aura.getLogName() + ')'); filter.add(new CanBeEnchantedByPredicate(aura)); Target target = null; - + auraLegalitySearch: for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, playerId, game)) { @@ -135,6 +135,7 @@ class RetetherEffect extends OneShotEffect { Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null && !permanent.cantBeAttachedBy(aura, game)) { auraMap.put(aura, permanent); + game.getState().setValue("attachTo:" + aura.getId(), permanent); continue auraCardsInGraveyard; } } @@ -143,17 +144,12 @@ class RetetherEffect extends OneShotEffect { game.informPlayers("No valid creature targets for " + aura.getLogName()); } } + controller.moveCards(auraMap.keySet(), Zone.BATTLEFIELD, source, game); for (Entry<Card, Permanent> entry : auraMap.entrySet()) { Card aura = entry.getKey(); Permanent permanent = entry.getValue(); - if (aura != null) { - if (permanent != null) { - game.getState().setValue("attachTo:" + aura.getId(), permanent); - } - aura.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), controller.getId()); - if (permanent != null) { - permanent.addAttachment(aura.getId(), game); - } + if (aura != null && permanent != null) { + permanent.addAttachment(aura.getId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/r/ReturnOfTheNightstalkers.java b/Mage.Sets/src/mage/cards/r/ReturnOfTheNightstalkers.java index e4fc525b19..0883601d9d 100644 --- a/Mage.Sets/src/mage/cards/r/ReturnOfTheNightstalkers.java +++ b/Mage.Sets/src/mage/cards/r/ReturnOfTheNightstalkers.java @@ -30,7 +30,6 @@ package mage.cards.r; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -79,7 +78,7 @@ class ReturnOfTheNightstalkersEffect extends OneShotEffect { public ReturnOfTheNightstalkersEffect() { super(Outcome.PutCreatureInPlay); - staticText = "Return all Nightstalker permanent cards from your graveyard to the battlefield. Then destroy all Swamps you control."; + staticText = "Return all Nightstalker permanent cards from your graveyard to the battlefield. Then destroy all Swamps you control"; } public ReturnOfTheNightstalkersEffect(final ReturnOfTheNightstalkersEffect effect) { @@ -93,15 +92,14 @@ class ReturnOfTheNightstalkersEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - for (Card card : player.getGraveyard().getCards(filter1, game)) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); - } + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + controller.moveCards(controller.getGraveyard().getCards(filter1, game), Zone.BATTLEFIELD, source, game); for (Permanent permanent : game.getBattlefield().getActivePermanents(filter2, source.getControllerId(), source.getSourceId(), game)) { permanent.destroy(source.getSourceId(), game, false); } + return true; } - return true; + return false; } } diff --git a/Mage.Sets/src/mage/cards/r/RoarOfReclamation.java b/Mage.Sets/src/mage/cards/r/RoarOfReclamation.java index 2e343879e4..fbf9ab2513 100644 --- a/Mage.Sets/src/mage/cards/r/RoarOfReclamation.java +++ b/Mage.Sets/src/mage/cards/r/RoarOfReclamation.java @@ -30,14 +30,12 @@ package mage.cards.r; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.Cards; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; -import mage.filter.common.FilterArtifactCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; @@ -48,7 +46,7 @@ import mage.players.Player; public class RoarOfReclamation extends CardImpl { public RoarOfReclamation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{W}{W}"); // Each player returns all artifact cards from their graveyard to the battlefield. this.getSpellAbility().addEffect(new RoarOfReclamationEffect()); @@ -65,7 +63,7 @@ public class RoarOfReclamation extends CardImpl { } class RoarOfReclamationEffect extends OneShotEffect { - + public RoarOfReclamationEffect() { super(Outcome.PutCardInPlay); staticText = "Each player returns all artifact cards from their graveyard to the battlefield"; @@ -82,19 +80,12 @@ class RoarOfReclamationEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - boolean result = true; - for (Player player : game.getPlayers().values()) { + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); if (player != null) { - Cards cards = player.getGraveyard(); - for (Card card : cards.getCards(new FilterArtifactCard(), game)) { - if (card != null) { - if (!card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), card.getOwnerId(), false)) { - result = false; - } - } - } + player.moveCards(player.getGraveyard().getCards(StaticFilters.FILTER_CARD_ARTIFACT, game), Zone.BATTLEFIELD, source, game); } } - return result; + return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/r/RootElemental.java b/Mage.Sets/src/mage/cards/r/RootElemental.java index 1a1c59270a..c73e690a8a 100644 --- a/Mage.Sets/src/mage/cards/r/RootElemental.java +++ b/Mage.Sets/src/mage/cards/r/RootElemental.java @@ -31,13 +31,13 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.keyword.MorphAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.filter.common.FilterCreatureCard; +import mage.filter.StaticFilters; /** * @@ -46,7 +46,7 @@ import mage.filter.common.FilterCreatureCard; public class RootElemental extends CardImpl { public RootElemental(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); this.subtype.add(SubType.ELEMENTAL); this.power = new MageInt(6); this.toughness = new MageInt(5); @@ -54,7 +54,7 @@ public class RootElemental extends CardImpl { // Morph {5}{G}{G} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{G}{G}"))); // When Root Elemental is turned face up, you may put a creature card from your hand onto the battlefield. - this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new PutPermanentOnBattlefieldEffect(new FilterCreatureCard("a creature card")))); + this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_CREATURE_A))); } public RootElemental(final RootElemental card) { diff --git a/Mage.Sets/src/mage/cards/s/SakuraTribeScout.java b/Mage.Sets/src/mage/cards/s/SakuraTribeScout.java index 0104db981f..5e297bd67e 100644 --- a/Mage.Sets/src/mage/cards/s/SakuraTribeScout.java +++ b/Mage.Sets/src/mage/cards/s/SakuraTribeScout.java @@ -31,12 +31,13 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; /** * @@ -45,7 +46,7 @@ import mage.constants.Zone; public class SakuraTribeScout extends CardImpl { public SakuraTribeScout(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.SNAKE); this.subtype.add(SubType.SHAMAN); this.subtype.add(SubType.SCOUT); @@ -54,7 +55,8 @@ public class SakuraTribeScout extends CardImpl { this.toughness = new MageInt(1); // {tap}: You may put a land card from your hand onto the battlefield. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLandFromHandOntoBattlefieldEffect(), new TapSourceCost())); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new TapSourceCost())); } public SakuraTribeScout(final SakuraTribeScout card) { diff --git a/Mage.Sets/src/mage/cards/s/ScionOfDarkness.java b/Mage.Sets/src/mage/cards/s/ScionOfDarkness.java index 45e1b12a58..af68d9e413 100644 --- a/Mage.Sets/src/mage/cards/s/ScionOfDarkness.java +++ b/Mage.Sets/src/mage/cards/s/ScionOfDarkness.java @@ -39,8 +39,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -56,7 +56,7 @@ import mage.target.common.TargetCardInGraveyard; public class ScionOfDarkness extends CardImpl { public ScionOfDarkness(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{B}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}{B}"); this.subtype.add(SubType.AVATAR); this.power = new MageInt(6); @@ -102,20 +102,22 @@ class ScionOfDarknessEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player damagedPlayer = game.getPlayer(targetPointer.getFirst(game, source)); - Player you = game.getPlayer(source.getControllerId()); - FilterCard filter = new FilterCard("creature in that player's graveyard"); + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null || damagedPlayer == null) { + return false; + } + FilterCard filter = new FilterCard("creature in " + damagedPlayer.getName() + "'s graveyard"); filter.add(new CardTypePredicate(CardType.CREATURE)); filter.add(new OwnerIdPredicate(damagedPlayer.getId())); TargetCardInGraveyard target = new TargetCardInGraveyard(filter); - if (target.canChoose(source.getSourceId(), you.getId(), game)) { - if (you.chooseTarget(Outcome.PutCreatureInPlay, target, source, game)) { + if (target.canChoose(source.getSourceId(), controller.getId(), game)) { + if (controller.chooseTarget(Outcome.PutCreatureInPlay, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), you.getId()); - return true; + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } } - return false; + return true; } } diff --git a/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java b/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java index 11392ad722..704c74f141 100644 --- a/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java +++ b/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java @@ -27,13 +27,16 @@ */ package mage.cards.s; +import java.util.HashSet; import java.util.Iterator; +import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; @@ -87,28 +90,27 @@ class SettleTheWreckageEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getFirstTarget()); - if (player != null) { - int attackers = 0; - Iterator<UUID> creatureIds = game.getCombat().getAttackers().iterator(); - while (creatureIds.hasNext()) { - Permanent creature = game.getPermanent(creatureIds.next()); - if (creature != null && creature.getControllerId().equals(player.getId())) { - creature.moveToExile(null, null, source.getId(), game); - attackers++; - } - } - TargetCardInLibrary target = new TargetCardInLibrary(0, attackers, StaticFilters.FILTER_BASIC_LAND_CARD); - if (player.chooseUse(Outcome.Benefit, "Search for up to " + attackers + " basic land" + ((attackers == 1) ? "" : "s") + "?", source, game) && player.searchLibrary(target, game)) { - for (UUID cardId : target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); - if (card != null) { - card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId(), true); - } - } - player.shuffleLibrary(source, game); - } - return true; + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null || player == null) { + return false; } - return false; + int attackers = 0; + Set<Card> toExile = new HashSet<>(); + Iterator<UUID> creatureIds = game.getCombat().getAttackers().iterator(); + while (creatureIds.hasNext()) { + Permanent creature = game.getPermanent(creatureIds.next()); + if (creature != null && creature.getControllerId().equals(player.getId())) { + toExile.add(creature); + attackers++; + } + } + controller.moveCards(toExile, Zone.EXILED, source, game); + TargetCardInLibrary target = new TargetCardInLibrary(0, attackers, StaticFilters.FILTER_BASIC_LAND_CARD); + if (player.chooseUse(Outcome.Benefit, "Search for up to " + attackers + " basic land" + ((attackers == 1) ? "" : "s") + "?", source, game) && player.searchLibrary(target, game)) { + player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null); + player.shuffleLibrary(source, game); + } + return true; + } } diff --git a/Mage.Sets/src/mage/cards/s/SkyshroudRanger.java b/Mage.Sets/src/mage/cards/s/SkyshroudRanger.java index bb09b6d0dc..614b015bf3 100644 --- a/Mage.Sets/src/mage/cards/s/SkyshroudRanger.java +++ b/Mage.Sets/src/mage/cards/s/SkyshroudRanger.java @@ -31,12 +31,13 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; /** * @@ -45,15 +46,16 @@ import mage.constants.Zone; public class SkyshroudRanger extends CardImpl { public SkyshroudRanger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.ELF); this.power = new MageInt(1); this.toughness = new MageInt(1); // {tap}: You may put a land card from your hand onto the battlefield. Activate this ability only any time you could cast a sorcery. - this.addAbility(new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new PutLandFromHandOntoBattlefieldEffect(), new TapSourceCost())); - + this.addAbility(new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new TapSourceCost())); + } public SkyshroudRanger(final SkyshroudRanger card) { diff --git a/Mage.Sets/src/mage/cards/s/StoneforgeMystic.java b/Mage.Sets/src/mage/cards/s/StoneforgeMystic.java index d8bc4e7b8c..e18c83b4e7 100644 --- a/Mage.Sets/src/mage/cards/s/StoneforgeMystic.java +++ b/Mage.Sets/src/mage/cards/s/StoneforgeMystic.java @@ -34,7 +34,7 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -70,7 +70,7 @@ public class StoneforgeMystic extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); // {1}{W}, {T}: You may put an Equipment card from your hand onto the battlefield. - SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(filter), new ManaCostsImpl("{1}{W}")); + SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutCardFromHandOntoBattlefieldEffect(filter), new ManaCostsImpl("{1}{W}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SwellOfGrowth.java b/Mage.Sets/src/mage/cards/s/SwellOfGrowth.java index b90a7986a7..8710a17a82 100644 --- a/Mage.Sets/src/mage/cards/s/SwellOfGrowth.java +++ b/Mage.Sets/src/mage/cards/s/SwellOfGrowth.java @@ -28,12 +28,13 @@ package mage.cards.s; import java.util.UUID; -import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; 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.StaticFilters; import mage.target.common.TargetCreaturePermanent; /** @@ -43,12 +44,12 @@ import mage.target.common.TargetCreaturePermanent; public class SwellOfGrowth extends CardImpl { public SwellOfGrowth(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); // Target creature gets +2/+2 until end of turn. You may put a land card from your hand onto the battlefield. this.getSpellAbility().addEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addEffect(new PutLandFromHandOntoBattlefieldEffect()); + this.getSpellAbility().addEffect(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A)); } public SwellOfGrowth(final SwellOfGrowth card) { diff --git a/Mage.Sets/src/mage/cards/t/TerrainGenerator.java b/Mage.Sets/src/mage/cards/t/TerrainGenerator.java index c661ce064a..91447add72 100644 --- a/Mage.Sets/src/mage/cards/t/TerrainGenerator.java +++ b/Mage.Sets/src/mage/cards/t/TerrainGenerator.java @@ -32,13 +32,13 @@ 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.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Zone; -import mage.filter.common.FilterLandCard; +import mage.filter.StaticFilters; /** * @@ -47,13 +47,14 @@ import mage.filter.common.FilterLandCard; public class TerrainGenerator extends CardImpl { public TerrainGenerator(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); // {tap}: Add {C}. this.addAbility(new ColorlessManaAbility()); - - // {2}, {tap}: You may put a basic land card from your hand onto the battlefield tapped. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLandFromHandOntoBattlefieldEffect(true, FilterLandCard.basicLandCard()), new ManaCostsImpl("{2}")); + + // {2}, {T}: You may put a basic land card from your hand onto the battlefield tapped. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A, false, true), new ManaCostsImpl("{2}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TheUrDragon.java b/Mage.Sets/src/mage/cards/t/TheUrDragon.java index 88b2653f77..f0380b3be9 100644 --- a/Mage.Sets/src/mage/cards/t/TheUrDragon.java +++ b/Mage.Sets/src/mage/cards/t/TheUrDragon.java @@ -27,6 +27,9 @@ */ 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; @@ -34,13 +37,14 @@ import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.game.events.GameEvent; @@ -48,10 +52,6 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.watchers.Watcher; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - /** * @author TheElk801 */ @@ -180,7 +180,7 @@ 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."; + this.staticText = "draw that many cards, then you may put a permanent card from your hand onto the battlefield"; } public TheUrDragonEffect(final TheUrDragonEffect effect) { @@ -207,9 +207,7 @@ class TheUrDragonEffect extends OneShotEffect { if (attackingDragons > 0) { controller.drawCards(attackingDragons, game); } - Effect effect = new PutPermanentOnBattlefieldEffect(); - effect.apply(game, source); - return true; + return new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A).apply(game, source); } } return false; diff --git a/Mage.Sets/src/mage/cards/t/ThranTemporalGateway.java b/Mage.Sets/src/mage/cards/t/ThranTemporalGateway.java index 13db844ec0..4807f0b0c5 100644 --- a/Mage.Sets/src/mage/cards/t/ThranTemporalGateway.java +++ b/Mage.Sets/src/mage/cards/t/ThranTemporalGateway.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -59,7 +59,7 @@ public class ThranTemporalGateway extends CardImpl { // {4}, {t}: You may put a historic permanent card from your hand onto the battlefield. (Artifacts, legendaries, and Sagas are historic.) SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutPermanentOnBattlefieldEffect(filter) + new PutCardFromHandOntoBattlefieldEffect(filter) .setText("You may put a historic permanent card from your hand onto the battlefield. " + "<i>(Artifacts, legendaries, and Sagas are historic.)</i>"), new ManaCostsImpl("{4}")); diff --git a/Mage.Sets/src/mage/cards/t/TimmyPowerGamer.java b/Mage.Sets/src/mage/cards/t/TimmyPowerGamer.java index 84b635f6b2..e52df31c04 100644 --- a/Mage.Sets/src/mage/cards/t/TimmyPowerGamer.java +++ b/Mage.Sets/src/mage/cards/t/TimmyPowerGamer.java @@ -30,16 +30,16 @@ package mage.cards.t; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; -import mage.filter.common.FilterCreatureCard; import java.util.UUID; +import mage.filter.StaticFilters; /** * @@ -48,7 +48,7 @@ import java.util.UUID; public class TimmyPowerGamer extends CardImpl { public TimmyPowerGamer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); this.supertype.add(SuperType.LEGENDARY); @@ -60,7 +60,7 @@ public class TimmyPowerGamer extends CardImpl { // {4}: You may put a creature card from your hand onto the battlefield. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutPermanentOnBattlefieldEffect(new FilterCreatureCard("a creature card")), + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_CREATURE_A), new ManaCostsImpl("{4}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TriassicEgg.java b/Mage.Sets/src/mage/cards/t/TriassicEgg.java index a33791f351..d77b356df6 100644 --- a/Mage.Sets/src/mage/cards/t/TriassicEgg.java +++ b/Mage.Sets/src/mage/cards/t/TriassicEgg.java @@ -36,7 +36,7 @@ import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.decorator.ConditionalActivatedAbility; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; @@ -45,7 +45,6 @@ import mage.constants.CardType; import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.StaticFilters; -import mage.filter.common.FilterCreatureCard; import mage.target.Target; import mage.target.common.TargetCardInYourGraveyard; @@ -67,7 +66,7 @@ public class TriassicEgg extends CardImpl { // Sacrifice Triassic Egg: Choose one - You may put a creature card from your hand onto the battlefield; ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, - new PutPermanentOnBattlefieldEffect(new FilterCreatureCard("a creature card")), + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_CREATURE_A), new SacrificeSourceCost(), new SourceHasCounterCondition(CounterType.HATCHLING, 2, Integer.MAX_VALUE), "Sacrifice Triassic Egg: Choose one - You may put a creature card from your hand onto the battlefield; or return target creature card from your graveyard to the battlefield. Activate this ability only if two or more hatchling counters are on {this}."); diff --git a/Mage.Sets/src/mage/cards/w/WalkingAtlas.java b/Mage.Sets/src/mage/cards/w/WalkingAtlas.java index 19a64228c4..7b04146037 100644 --- a/Mage.Sets/src/mage/cards/w/WalkingAtlas.java +++ b/Mage.Sets/src/mage/cards/w/WalkingAtlas.java @@ -25,19 +25,19 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.w; import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.common.PutLandFromHandOntoBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; /** * @@ -45,17 +45,18 @@ import mage.constants.Zone; */ public class WalkingAtlas extends CardImpl { - public WalkingAtlas (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}"); + public WalkingAtlas(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); this.subtype.add(SubType.CONSTRUCT); this.power = new MageInt(1); this.toughness = new MageInt(1); // {tap}: You may put a land card from your hand onto the battlefield. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLandFromHandOntoBattlefieldEffect(), new TapSourceCost())); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new TapSourceCost())); } - public WalkingAtlas (final WalkingAtlas card) { + public WalkingAtlas(final WalkingAtlas card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/w/WarrenInstigator.java b/Mage.Sets/src/mage/cards/w/WarrenInstigator.java index afc26696a5..8babe5cb4e 100644 --- a/Mage.Sets/src/mage/cards/w/WarrenInstigator.java +++ b/Mage.Sets/src/mage/cards/w/WarrenInstigator.java @@ -30,7 +30,7 @@ package mage.cards.w; import java.util.UUID; import mage.MageInt; import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; -import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.keyword.DoubleStrikeAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -62,7 +62,7 @@ public class WarrenInstigator extends CardImpl { this.addAbility(DoubleStrikeAbility.getInstance()); // Whenever Warren Instigator deals damage to an opponent, you may put a Goblin creature card from your hand onto the battlefield. - this.addAbility(new DealsDamageToOpponentTriggeredAbility(new PutPermanentOnBattlefieldEffect(filter), false)); + this.addAbility(new DealsDamageToOpponentTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect(filter), false)); } public WarrenInstigator(final WarrenInstigator card) { diff --git a/Mage.Sets/src/mage/cards/w/WillowPriestess.java b/Mage.Sets/src/mage/cards/w/WillowPriestess.java index 3b1d6e2e34..08a37374f1 100644 --- a/Mage.Sets/src/mage/cards/w/WillowPriestess.java +++ b/Mage.Sets/src/mage/cards/w/WillowPriestess.java @@ -34,7 +34,7 @@ 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.PutPermanentOnBattlefieldEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.ProtectionAbility; import mage.cards.CardImpl; @@ -73,7 +73,7 @@ public class WillowPriestess extends CardImpl { // {T}: You may put a Faerie permanent card from your hand onto the battlefield. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutPermanentOnBattlefieldEffect(filter), + new PutCardFromHandOntoBattlefieldEffect(filter), new TapSourceCost())); // {2}{G}: Target green creature gains protection from black until end of turn. 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 d425019311..54828ccbf5 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 @@ -110,6 +110,7 @@ public class VorinclexVoiceOfHungerTest extends CardTestPlayerBase { execute(); assertPermanentCount(playerB, "Gemstone Caverns", 1); + assertCounterCount("Gemstone Caverns", CounterType.LUCK, 1); assertPermanentCount(playerB, "Silvercoat Lion", 1); assertExileCount("Silvercoat Lion", 1); assertTapped("Gemstone Caverns", true); diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java index cadb470761..880e67ad44 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java @@ -851,6 +851,9 @@ public class ContinuousEffects implements Serializable { if (rEffect != null) { event.getAppliedEffects().add(rEffect.getId()); caught = rEffect.replaceEvent(event, rAbility, game); + if (Duration.OneUse.equals(rEffect.getDuration())) { + rEffect.discard(); + } } if (caught) { // Event was completely replaced -> stop applying effects to it break; diff --git a/Mage/src/main/java/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PutCardFromHandOntoBattlefieldEffect.java similarity index 70% rename from Mage/src/main/java/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java rename to Mage/src/main/java/mage/abilities/effects/common/PutCardFromHandOntoBattlefieldEffect.java index c6f2461b5a..4ea64c17dc 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PutCardFromHandOntoBattlefieldEffect.java @@ -15,34 +15,41 @@ import mage.target.common.TargetCardInHand; /** * @author magenoxx_at_gmail.com */ -public class PutPermanentOnBattlefieldEffect extends OneShotEffect { +public class PutCardFromHandOntoBattlefieldEffect extends OneShotEffect { private final FilterCard filter; private final boolean useTargetController; + private final boolean tapped; - public PutPermanentOnBattlefieldEffect() { + public PutCardFromHandOntoBattlefieldEffect() { this(new FilterPermanentCard("a permanent card"), false); } - public PutPermanentOnBattlefieldEffect(FilterCard filter) { + public PutCardFromHandOntoBattlefieldEffect(FilterCard filter) { this(filter, false); } - public PutPermanentOnBattlefieldEffect(FilterCard filter, boolean useTargetController) { + public PutCardFromHandOntoBattlefieldEffect(FilterCard filter, boolean useTargetController) { + this(filter, useTargetController, false); + } + + public PutCardFromHandOntoBattlefieldEffect(FilterCard filter, boolean useTargetController, boolean tapped) { super(Outcome.PutCardInPlay); this.filter = filter; this.useTargetController = useTargetController; + this.tapped = tapped; } - public PutPermanentOnBattlefieldEffect(final PutPermanentOnBattlefieldEffect effect) { + public PutCardFromHandOntoBattlefieldEffect(final PutCardFromHandOntoBattlefieldEffect effect) { super(effect); this.filter = effect.filter.copy(); this.useTargetController = effect.useTargetController; + this.tapped = effect.tapped; } @Override - public PutPermanentOnBattlefieldEffect copy() { - return new PutPermanentOnBattlefieldEffect(this); + public PutCardFromHandOntoBattlefieldEffect copy() { + return new PutCardFromHandOntoBattlefieldEffect(this); } @Override @@ -58,10 +65,10 @@ public class PutPermanentOnBattlefieldEffect extends OneShotEffect { } if (player.chooseUse(Outcome.PutCardInPlay, "Put " + filter.getMessage() + " from your hand onto the battlefield?", source, game)) { TargetCardInHand target = new TargetCardInHand(filter); - if (player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { + if (player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - return player.moveCards(card, Zone.BATTLEFIELD, source, game); + return player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, false, null); } } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PutLandFromHandOntoBattlefieldEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PutLandFromHandOntoBattlefieldEffect.java deleted file mode 100644 index 45edec3a94..0000000000 --- a/Mage/src/main/java/mage/abilities/effects/common/PutLandFromHandOntoBattlefieldEffect.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of BetaSteward_at_googlemail.com. - */ -package mage.abilities.effects.common; - -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.filter.common.FilterLandCard; -import mage.game.Game; -import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetCardInHand; - -/** - * - * @author LevelX2 - */ -public class PutLandFromHandOntoBattlefieldEffect extends OneShotEffect { - - private FilterCard filter; - private boolean tapped; - - public PutLandFromHandOntoBattlefieldEffect() { - this(false); - } - - public PutLandFromHandOntoBattlefieldEffect(boolean tapped) { - this(tapped, new FilterLandCard()); - } - - public PutLandFromHandOntoBattlefieldEffect(boolean tapped, FilterCard filter) { - super(Outcome.PutLandInPlay); - this.tapped = tapped; - this.filter = filter; - staticText = "you may put a " + filter.getMessage() + " from your hand onto the battlefield" + (tapped ? " tapped" : ""); - } - - public PutLandFromHandOntoBattlefieldEffect(final PutLandFromHandOntoBattlefieldEffect effect) { - super(effect); - this.tapped = effect.tapped; - this.filter = effect.filter; - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Target target = new TargetCardInHand(filter); - if (target.canChoose(source.getSourceId(), source.getControllerId(), game) - && controller.chooseUse(outcome, "Put land onto battlefield?", source, game) - && controller.choose(outcome, target, source.getSourceId(), game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - controller.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, false, null); - } - } - return true; - } - return false; - - } - - @Override - public PutLandFromHandOntoBattlefieldEffect copy() { - return new PutLandFromHandOntoBattlefieldEffect(this); - } - -} diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderOwnerControlAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderOwnerControlAttachedEffect.java index 18c5bad257..09545bd4cc 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderOwnerControlAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderOwnerControlAttachedEffect.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,22 +20,21 @@ * 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.constants.Outcome; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; - - import mage.game.permanent.Permanent; +import mage.players.Player; /** * @@ -59,12 +58,15 @@ public class ReturnToBattlefieldUnderOwnerControlAttachedEffect extends OneShotE @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } Object object = getValue("attachedTo"); if (object != null && object instanceof Permanent) { Card card = game.getCard(((Permanent) object).getId()); if (card != null) { - Zone currentZone = game.getState().getZone(card.getId()); - if (card.putOntoBattlefield(game, currentZone, source.getSourceId(), card.getOwnerId())) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null)) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlSourceEffect.java index 07048c0624..e2383ead40 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlSourceEffect.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,22 +20,22 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common; import java.util.UUID; -import mage.constants.Outcome; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.constants.Outcome; import mage.constants.Zone; import mage.game.ExileZone; import mage.game.Game; +import mage.players.Player; import mage.util.CardUtil; /** @@ -60,11 +60,16 @@ public class ReturnToBattlefieldUnderYourControlSourceEffect extends OneShotEffe @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); ExileZone exileZone = game.getExile().getExileZone(exileZoneId); if (exileZone != null && exileZone.contains(source.getSourceId())) { - Card card = game.getCard(source.getSourceId()); - if (card != null && card.putOntoBattlefield(game, Zone.EXILED, source.getSourceId(), source.getControllerId())) { + Card card = game.getCard(source.getSourceId()); + if (card != null + && controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/keyword/AuraSwapAbility.java b/Mage/src/main/java/mage/abilities/keyword/AuraSwapAbility.java index b662a74911..655ccff0aa 100644 --- a/Mage/src/main/java/mage/abilities/keyword/AuraSwapAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/AuraSwapAbility.java @@ -103,11 +103,11 @@ class AuraSwapEffect extends OneShotEffect { Card auraInHand = game.getCard(target.getFirstTarget()); if (auraInHand != null) { game.getState().setValue("attachTo:" + auraInHand.getId(), enchantedPermanent); - auraInHand.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), controller.getId()); + controller.moveCards(auraInHand, Zone.BATTLEFIELD, source, game); enchantedPermanent.addAttachment(auraInHand.getId(), game); game.informPlayers(controller.getLogName() + " put " + auraInHand.getLogName() + " on the battlefield attached to " + enchantedPermanent.getLogName() + '.'); enchantedPermanent.removeAttachment(auraSourcePermanent.getId(), game); - return controller.moveCards(game.getCard(source.getSourceId()), Zone.HAND, source, game); + return controller.moveCards(auraSourcePermanent, Zone.HAND, source, game); } } } diff --git a/Mage/src/main/java/mage/abilities/keyword/NinjutsuAbility.java b/Mage/src/main/java/mage/abilities/keyword/NinjutsuAbility.java index 893fad9d4e..86b04eccc3 100644 --- a/Mage/src/main/java/mage/abilities/keyword/NinjutsuAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/NinjutsuAbility.java @@ -120,9 +120,13 @@ class NinjutsuEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } Card card = game.getCard(source.getSourceId()); if (card != null) { - card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { UUID defendingPlayerId = null; @@ -133,7 +137,6 @@ class NinjutsuEffect extends OneShotEffect { } if (defendingPlayerId != null) { game.getCombat().addAttackerToCombat(permanent.getId(), defendingPlayerId, game); - permanent.setTapped(true); return true; } } diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index e540945a42..3fca15f61e 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -71,6 +71,13 @@ public final class StaticFilters { static { FILTER_CARD_CREATURE.setLockedFilter(true); } + + public static final FilterCreatureCard FILTER_CARD_CREATURE_A = new FilterCreatureCard("a creature card"); + + static { + FILTER_CARD_CREATURE_A.setLockedFilter(true); + } + public static final FilterCreatureCard FILTER_CARD_CREATURE_YOUR_GRAVEYARD = new FilterCreatureCard("creature card from your graveyard"); static { @@ -88,6 +95,12 @@ public final class StaticFilters { static { FILTER_CARD_LAND.setLockedFilter(true); } + + public static final FilterLandCard FILTER_CARD_LAND_A = new FilterLandCard("a land card"); + + static { + FILTER_CARD_LAND_A.setLockedFilter(true); + } public static final FilterNonlandCard FILTER_CARD_NON_LAND = new FilterNonlandCard(); static { @@ -292,6 +305,12 @@ public final class StaticFilters { FILTER_BASIC_LAND_CARD.setLockedFilter(true); } + public static final FilterBasicLandCard FILTER_BASIC_LAND_CARD_A = new FilterBasicLandCard("a basic land card"); + + static { + FILTER_BASIC_LAND_CARD_A.setLockedFilter(true); + } + // Used for sacrifice targets that don't need the "you control" text public static final FilterControlledLandPermanent FILTER_CONTROLLED_LAND_SHORT_TEXT = new FilterControlledLandPermanent("a land"); diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index 427b46ef05..1f6eeacb01 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java @@ -152,7 +152,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { this.blocking = permanent.blocking; this.maxBlocks = permanent.maxBlocks; this.deathtouched = permanent.deathtouched; -// this.attachments.addAll(permanent.attachments); + for (Map.Entry<String, List<UUID>> entry : permanent.connectedCards.entrySet()) { this.connectedCards.put(entry.getKey(), entry.getValue()); } @@ -696,7 +696,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { for (Iterator<Effect> ite = ability.getEffects(game, EffectType.CONTINUOUS).iterator(); ite.hasNext();) { ContinuousEffect effect = (ContinuousEffect) ite.next(); game.getContinuousEffects().setOrder(effect); - // It's important is to update timestamp of the copied effect in ContinuousEffects because it does the action + // It's important to update the timestamp of the copied effect in ContinuousEffects because it does the action for (ContinuousEffect conEffect : game.getContinuousEffects().getLayeredEffects(game)) { if (conEffect.getId().equals(effect.getId())) { game.getContinuousEffects().setOrder(conEffect); From b200b2e642c32f989e08be62192169e1309a03e8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sat, 26 May 2018 16:45:38 -0400 Subject: [PATCH 122/154] Fixed Malfegor not requiring the correct amount of sacrifices --- Mage.Sets/src/mage/cards/m/Malfegor.java | 43 +++++++----------------- 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/Malfegor.java b/Mage.Sets/src/mage/cards/m/Malfegor.java index 999ca60a96..8edbd3b7e4 100644 --- a/Mage.Sets/src/mage/cards/m/Malfegor.java +++ b/Mage.Sets/src/mage/cards/m/Malfegor.java @@ -32,6 +32,8 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SacrificeOpponentsEffect; +import mage.abilities.effects.common.discard.DiscardHandControllerEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -39,12 +41,9 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.SuperType; -import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.StaticFilters; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetControlledPermanent; /** * @@ -53,11 +52,11 @@ import mage.target.common.TargetControlledPermanent; public class Malfegor extends CardImpl { public Malfegor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{B}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}{R}{R}"); + addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.DEMON); this.subtype.add(SubType.DRAGON); - this.power = new MageInt(6); this.toughness = new MageInt(6); @@ -93,35 +92,19 @@ class MalfegorEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - int sacrificeNumber = controller.getHand().size(); - if (sacrificeNumber > 0) { - controller.discard(sacrificeNumber, source, game); - for (UUID opponentId : game.getOpponents(controller.getId())) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - for (int i = 0; i < sacrificeNumber; i++) { - Target target = new TargetControlledPermanent(new FilterControlledCreaturePermanent()); - if (target.canChoose(opponentId, game)) { - if (opponent.choose(Outcome.Sacrifice, target, source.getSourceId(), game)) { - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent != null) { - permanent.sacrifice(source.getSourceId(), game); - } - } - } - } - } - } - } + if (controller == null) { + return false; + } + int sacrificeNumber = controller.getHand().size(); + if (sacrificeNumber == 0) { return true; } - return false; - + new DiscardHandControllerEffect().apply(game, source); + return new SacrificeOpponentsEffect(sacrificeNumber, StaticFilters.FILTER_PERMANENT_CREATURE).apply(game, source); } @Override public MalfegorEffect copy() { return new MalfegorEffect(this); } -} \ No newline at end of file +} From 3f42dcb58cc3a848316b99a076514d58d694401d Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sat, 26 May 2018 18:07:10 -0400 Subject: [PATCH 123/154] Implemented Stadium Vendors --- .../src/mage/cards/s/StadiumVendors.java | 111 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 112 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/StadiumVendors.java diff --git a/Mage.Sets/src/mage/cards/s/StadiumVendors.java b/Mage.Sets/src/mage/cards/s/StadiumVendors.java new file mode 100644 index 0000000000..dede6d7eea --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StadiumVendors.java @@ -0,0 +1,111 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.mana.AddManaToManaPoolTargetControllerEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.ChoiceColor; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class StadiumVendors extends CardImpl { + + public StadiumVendors(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.GOBLIN); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When Stadium Vendors enters the battlefield, choose a player. That player adds two mana of any one color they choose. + Ability ability = new EntersBattlefieldTriggeredAbility(new StadiumVendorsEffect(), false); + this.addAbility(ability); + } + + public StadiumVendors(final StadiumVendors card) { + super(card); + } + + @Override + public StadiumVendors copy() { + return new StadiumVendors(this); + } +} + +class StadiumVendorsEffect extends OneShotEffect { + + StadiumVendorsEffect() { + super(Outcome.Benefit); + this.staticText = "choose a player. That player adds two mana of any one color they choose"; + } + + StadiumVendorsEffect(final StadiumVendorsEffect effect) { + super(effect); + } + + @Override + public StadiumVendorsEffect copy() { + return new StadiumVendorsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getSourceId()); + if (controller == null) { + return false; + } + TargetPlayer target = new TargetPlayer(1, 1, true); + if (!controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) { + return false; + } + Player player = game.getPlayer(target.getFirstTarget()); + ChoiceColor colorChoice = new ChoiceColor(true); + if (player == null || !player.choose(Outcome.Benefit, colorChoice, game)) { + return false; + } + Effect effect = new AddManaToManaPoolTargetControllerEffect(colorChoice.getMana(2), "that player's"); + effect.setTargetPointer(new FixedTarget(player.getId(), game)); + return effect.apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index ad0c83dce3..22b32f7294 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -258,6 +258,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Spellseeker", 41, Rarity.RARE, mage.cards.s.Spellseeker.class)); cards.add(new SetCardInfo("Spellweaver Duo", 42, Rarity.COMMON, mage.cards.s.SpellweaverDuo.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); + cards.add(new SetCardInfo("Stadium Vendors", 63, Rarity.COMMON, mage.cards.s.StadiumVendors.class)); cards.add(new SetCardInfo("Steppe Glider", 109, Rarity.UNCOMMON, mage.cards.s.SteppeGlider.class)); cards.add(new SetCardInfo("Stone Golem", 247, Rarity.COMMON, mage.cards.s.StoneGolem.class)); cards.add(new SetCardInfo("Stunning Reversal", 51, Rarity.MYTHIC, mage.cards.s.StunningReversal.class)); From d743864bbd5f3b13cdb0c74651e7b91b7b0ffc03 Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Sun, 27 May 2018 00:41:30 +0200 Subject: [PATCH 124/154] * Try to fix URL handling. --- .../java/mage/client/table/TablesPanel.java | 20 +++++++++---------- .../java/mage/client/util/URLHandler.java | 5 +++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index 31b1868657..379075fb8d 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -60,7 +60,6 @@ import static mage.client.dialog.PreferencesDialog.KEY_TABLES_FILTER_SETTINGS; import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_1; import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2; import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3; -import static mage.client.dialog.PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE; import mage.client.util.ButtonColumn; import mage.client.util.GUISizeHelper; import mage.client.util.IgnoreList; @@ -427,15 +426,15 @@ public class TablesPanel extends javax.swing.JPanel { } private void restoreDividers() { - Rectangle currentBounds = MageFrame.getDesktop().getBounds(); - if (currentBounds != null) { - String firstDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_1, null); - String tableDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_2, null); - String chatDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_3, null); - GuiDisplayUtil.restoreDividerLocations(currentBounds, firstDivider, jSplitPane1); - GuiDisplayUtil.restoreDividerLocations(currentBounds, tableDivider, jSplitPaneTables); - GuiDisplayUtil.restoreDividerLocations(currentBounds, chatDivider, chatPanelMain); - } + Rectangle currentBounds = MageFrame.getDesktop().getBounds(); + if (currentBounds != null) { + String firstDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_1, null); + String tableDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_2, null); + String chatDivider = PreferencesDialog.getCachedValue(KEY_TABLES_DIVIDER_LOCATION_3, null); + GuiDisplayUtil.restoreDividerLocations(currentBounds, firstDivider, jSplitPane1); + GuiDisplayUtil.restoreDividerLocations(currentBounds, tableDivider, jSplitPaneTables); + GuiDisplayUtil.restoreDividerLocations(currentBounds, chatDivider, chatPanelMain); + } } public Map<String, JComponent> getUIComponents() { @@ -550,6 +549,7 @@ public class TablesPanel extends javax.swing.JPanel { this.jPanelBottom.setVisible(false); } else { this.jPanelBottom.setVisible(true); + URLHandler.RemoveMouseAdapter(jLabelFooterText); URLHandler.handleMessage(serverMessages.get(0), this.jLabelFooterText); this.jButtonFooterNext.setVisible(serverMessages.size() > 1); } diff --git a/Mage.Client/src/main/java/mage/client/util/URLHandler.java b/Mage.Client/src/main/java/mage/client/util/URLHandler.java index 6208bddbf7..19ee86f638 100644 --- a/Mage.Client/src/main/java/mage/client/util/URLHandler.java +++ b/Mage.Client/src/main/java/mage/client/util/URLHandler.java @@ -9,10 +9,10 @@ import java.awt.Desktop; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.IOException; -import java.net.URL; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; +import java.net.URL; import javax.swing.JLabel; /** @@ -47,6 +47,7 @@ public class URLHandler { private static MouseAdapter createMouseAdapter(String url) { currentMouseAdapter = new MouseAdapter() { + @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() > 0) { if (Desktop.isDesktopSupported()) { @@ -57,7 +58,7 @@ public class URLHandler { } catch (IOException | URISyntaxException ex) { // do nothing } - } + } } } }; From 66cc29325c6a1a5c601bcb2fe81eda7765ae57f5 Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Sun, 27 May 2018 00:41:53 +0200 Subject: [PATCH 125/154] * Some fixes to some Battleebond cards. --- .../card/dl/sources/MythicspoilerComSource.java | 1 + .../card/dl/sources/ScryfallImageSource.java | 1 + Mage.Sets/src/mage/cards/a/ArenaRector.java | 4 ++-- Mage.Sets/src/mage/cards/b/Brightling.java | 4 ++-- Mage.Sets/src/mage/cards/c/ChakramRetriever.java | 3 ++- Mage.Sets/src/mage/cards/f/FanFavorite.java | 3 ++- Mage.Sets/src/mage/cards/h/HuddleUp.java | 2 +- Mage.Sets/src/mage/cards/k/KissOfTheAmesha.java | 5 ++--- Mage.Sets/src/mage/cards/l/LoreWeaver.java | 3 ++- Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java | 6 +++--- Mage.Sets/src/mage/cards/r/RecklessScholar.java | 9 ++++----- .../src/mage/cards/s/SoulbladeCorrupter.java | 15 ++++++++++++--- Mage.Sets/src/mage/cards/s/Spellseeker.java | 6 +++--- Mage.Sets/src/mage/cards/s/StunningReversal.java | 4 ++-- Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java | 4 ++-- .../src/mage/cards/t/ToothyImaginaryFriend.java | 8 +++++--- .../src/mage/cards/u/UnflinchingCourage.java | 12 ++++++------ Mage.Sets/src/mage/cards/v/VirtusTheVeiled.java | 4 ++-- .../common/WinsCoinFlipTriggeredAbility.java | 3 +-- .../effects/common/DrawCardTargetEffect.java | 2 +- .../abilities/keyword/PartnerWithAbility.java | 2 +- 21 files changed, 57 insertions(+), 44 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java index b33a8b0846..1b7ff4125e 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java @@ -257,6 +257,7 @@ public enum MythicspoilerComSource implements CardImageSource { supportedSets.add("UST"); supportedSets.add("RIX"); supportedSets.add("DOM"); + supportedSets.add("BBD"); sets = new LinkedHashMap<>(); setsAliases = new HashMap<>(); diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index 3a43aec961..f38b1a80e6 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -210,6 +210,7 @@ public enum ScryfallImageSource implements CardImageSource { supportedSets.add("PPRO"); supportedSets.add("A25"); supportedSets.add("DOM"); + supportedSets.add("BBD"); // supportedSets.add("M19"); } diff --git a/Mage.Sets/src/mage/cards/a/ArenaRector.java b/Mage.Sets/src/mage/cards/a/ArenaRector.java index 63b5ab78fd..5ec9bbda56 100644 --- a/Mage.Sets/src/mage/cards/a/ArenaRector.java +++ b/Mage.Sets/src/mage/cards/a/ArenaRector.java @@ -33,10 +33,10 @@ import mage.abilities.common.DiesTriggeredAbility; import mage.abilities.costs.common.ExileSourceFromGraveCost; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.filter.common.FilterPlaneswalkerCard; import mage.target.common.TargetCardInLibrary; @@ -60,7 +60,7 @@ public class ArenaRector extends CardImpl { new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterPlaneswalkerCard())), new ExileSourceFromGraveCost(), "Exile to search for a planeswalker?" - ), false + ).setText("you may exile it. If you do, search your library for a planeswalker card, put it onto the battlefield, then shuffle your library"), false )); } diff --git a/Mage.Sets/src/mage/cards/b/Brightling.java b/Mage.Sets/src/mage/cards/b/Brightling.java index 812dd97c18..5ea0c973e6 100644 --- a/Mage.Sets/src/mage/cards/b/Brightling.java +++ b/Mage.Sets/src/mage/cards/b/Brightling.java @@ -32,7 +32,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ColoredManaCost; -import mage.abilities.costs.mana.ColorlessManaCost; +import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; @@ -95,7 +95,7 @@ public class Brightling extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new BrightlingEffect(), - new ColorlessManaCost(1) + new GenericManaCost(1) )); } diff --git a/Mage.Sets/src/mage/cards/c/ChakramRetriever.java b/Mage.Sets/src/mage/cards/c/ChakramRetriever.java index 4d0c17f885..dda65506b7 100644 --- a/Mage.Sets/src/mage/cards/c/ChakramRetriever.java +++ b/Mage.Sets/src/mage/cards/c/ChakramRetriever.java @@ -35,10 +35,10 @@ import mage.abilities.condition.common.MyTurnCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.keyword.PartnerWithAbility; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.target.common.TargetCreaturePermanent; /** @@ -65,6 +65,7 @@ public class ChakramRetriever extends CardImpl { "Whenever you cast a spell during your turn, untap target creature." ); ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); } public ChakramRetriever(final ChakramRetriever card) { diff --git a/Mage.Sets/src/mage/cards/f/FanFavorite.java b/Mage.Sets/src/mage/cards/f/FanFavorite.java index d45b13cb12..ff317b4627 100644 --- a/Mage.Sets/src/mage/cards/f/FanFavorite.java +++ b/Mage.Sets/src/mage/cards/f/FanFavorite.java @@ -34,12 +34,12 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.constants.SubType; import mage.abilities.keyword.AssistAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.TargetController; /** @@ -63,6 +63,7 @@ public class FanFavorite extends CardImpl { ActivatedAbility ability = new SimpleActivatedAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn), new GenericManaCost(2)); ability.setMayActivate(TargetController.ANY); ability.addEffect(new InfoEffect("Any player may activate this ability")); + this.addAbility(ability); } public FanFavorite(final FanFavorite card) { diff --git a/Mage.Sets/src/mage/cards/h/HuddleUp.java b/Mage.Sets/src/mage/cards/h/HuddleUp.java index d2098c1cef..9236ba57c4 100644 --- a/Mage.Sets/src/mage/cards/h/HuddleUp.java +++ b/Mage.Sets/src/mage/cards/h/HuddleUp.java @@ -48,7 +48,7 @@ public class HuddleUp extends CardImpl { this.addAbility(new AssistAbility()); // Two target players each draw a card. - this.getSpellAbility().addEffect(new DrawCardTargetEffect(1)); + this.getSpellAbility().addEffect(new DrawCardTargetEffect(1).setText("Two target players each draw a card")); this.getSpellAbility().addTarget(new TargetPlayer(2)); } diff --git a/Mage.Sets/src/mage/cards/k/KissOfTheAmesha.java b/Mage.Sets/src/mage/cards/k/KissOfTheAmesha.java index a0ce05c355..05fa837b1c 100644 --- a/Mage.Sets/src/mage/cards/k/KissOfTheAmesha.java +++ b/Mage.Sets/src/mage/cards/k/KissOfTheAmesha.java @@ -42,13 +42,12 @@ import mage.target.TargetPlayer; public class KissOfTheAmesha extends CardImpl { public KissOfTheAmesha(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{W}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{W}{U}"); // Target player gains 7 life and draws two cards. this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addEffect(new GainLifeTargetEffect(7)); - this.getSpellAbility().addEffect(new DrawCardTargetEffect(2)); + this.getSpellAbility().addEffect(new DrawCardTargetEffect(2).setText("and draws two cards")); } public KissOfTheAmesha(final KissOfTheAmesha card) { diff --git a/Mage.Sets/src/mage/cards/l/LoreWeaver.java b/Mage.Sets/src/mage/cards/l/LoreWeaver.java index 1e74242463..763f46f35d 100644 --- a/Mage.Sets/src/mage/cards/l/LoreWeaver.java +++ b/Mage.Sets/src/mage/cards/l/LoreWeaver.java @@ -34,10 +34,10 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DrawCardTargetEffect; import mage.abilities.keyword.PartnerWithAbility; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.target.TargetPlayer; /** @@ -60,6 +60,7 @@ public class LoreWeaver extends CardImpl { // {5}{U}{U}: Target player draws two cards. Ability ability = new SimpleActivatedAbility(new DrawCardTargetEffect(2), new ManaCostsImpl("{5}{U}{U}")); ability.addTarget(new TargetPlayer()); + this.addAbility(ability); } public LoreWeaver(final LoreWeaver card) { diff --git a/Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java b/Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java index 35ce845d90..0188555724 100644 --- a/Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java +++ b/Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java @@ -37,12 +37,12 @@ import mage.abilities.dynamicvalue.common.SourcePermanentToughnessValue; import mage.abilities.effects.common.FlipUntilLoseEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.PartnerWithAbility; -import mage.constants.SubType; -import mage.constants.SuperType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.constants.TargetController; /** @@ -75,7 +75,7 @@ public class OkaunEyeOfChaos extends CardImpl { sourceToughness, Duration.EndOfTurn, true - ).setText("double {this}'s power until end of turn") + ).setText("double {this}'s power and toughness until end of turn") )); } diff --git a/Mage.Sets/src/mage/cards/r/RecklessScholar.java b/Mage.Sets/src/mage/cards/r/RecklessScholar.java index 69ed4bd7b7..80abc15137 100644 --- a/Mage.Sets/src/mage/cards/r/RecklessScholar.java +++ b/Mage.Sets/src/mage/cards/r/RecklessScholar.java @@ -32,8 +32,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.common.DrawCardTargetEffect; -import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.abilities.effects.common.DrawDiscardTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -48,15 +47,15 @@ import mage.target.TargetPlayer; public class RecklessScholar extends CardImpl { public RecklessScholar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); this.power = new MageInt(2); this.toughness = new MageInt(1); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardTargetEffect(1), new TapSourceCost()); - ability.addEffect(new DiscardTargetEffect(1)); + // {T}: Target player draws a card, then discards a card. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawDiscardTargetEffect(1, 1), new TapSourceCost()); ability.addTarget(new TargetPlayer()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SoulbladeCorrupter.java b/Mage.Sets/src/mage/cards/s/SoulbladeCorrupter.java index 69a85513c7..055cca5373 100644 --- a/Mage.Sets/src/mage/cards/s/SoulbladeCorrupter.java +++ b/Mage.Sets/src/mage/cards/s/SoulbladeCorrupter.java @@ -31,7 +31,6 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.AttacksAllTriggeredAbility; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.constants.SubType; import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.PartnerWithAbility; import mage.cards.CardImpl; @@ -39,6 +38,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SetTargetPointer; +import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.CounterPredicate; @@ -46,6 +46,7 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; +import mage.target.targetpointer.FixedTarget; /** * @@ -93,7 +94,7 @@ class SoulbladeCorrupterTriggeredAbility extends AttacksAllTriggeredAbility { super(new GainAbilityTargetEffect( DeathtouchAbility.getInstance(), Duration.EndOfTurn - ), false, filter2, SetTargetPointer.PERMANENT, false); + ).setText("that creature gains deathtouch until end of turn"), false, filter2, SetTargetPointer.PERMANENT, false); } SoulbladeCorrupterTriggeredAbility(final SoulbladeCorrupterTriggeredAbility effect) { @@ -106,12 +107,20 @@ class SoulbladeCorrupterTriggeredAbility extends AttacksAllTriggeredAbility { Permanent permanent = game.getPermanent(event.getSourceId()); if (permanent != null) { Player player = game.getPlayer(permanent.getControllerId()); - return player != null && player.hasOpponent(getControllerId(), game); + if (player != null && player.hasOpponent(getControllerId(), game)) { + getEffects().setTargetPointer(new FixedTarget(permanent, game)); + return true; + } } } return false; } + @Override + public String getRule() { + return "Whenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn."; + } + @Override public SoulbladeCorrupterTriggeredAbility copy() { return new SoulbladeCorrupterTriggeredAbility(this); diff --git a/Mage.Sets/src/mage/cards/s/Spellseeker.java b/Mage.Sets/src/mage/cards/s/Spellseeker.java index 15efb2e2ee..a94125d378 100644 --- a/Mage.Sets/src/mage/cards/s/Spellseeker.java +++ b/Mage.Sets/src/mage/cards/s/Spellseeker.java @@ -31,11 +31,11 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ComparisonType; +import mage.constants.SubType; import mage.filter.common.FilterInstantOrSorceryCard; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.target.common.TargetCardInLibrary; @@ -60,9 +60,9 @@ public class Spellseeker extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(1); - // When Spellseeker enters the battlefield, you may search your library for an instant or sorcery card with converted mana cost 2 or less, reveal it, put it into your hand, then shuffle your library. + // When Spellseeker enters the battlefield, you may search your library for an instant or sorcery card with converted mana cost 2 or less, reveal it, put it into your hand, then shuffle your library. this.addAbility(new EntersBattlefieldTriggeredAbility( - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, filter), true, true), + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true, true), true )); } diff --git a/Mage.Sets/src/mage/cards/s/StunningReversal.java b/Mage.Sets/src/mage/cards/s/StunningReversal.java index 1e03ed5757..8300a0ead9 100644 --- a/Mage.Sets/src/mage/cards/s/StunningReversal.java +++ b/Mage.Sets/src/mage/cards/s/StunningReversal.java @@ -49,7 +49,7 @@ public class StunningReversal extends CardImpl { public StunningReversal(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{B}"); - // The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1. + // The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1. this.getSpellAbility().addEffect(new StunningReversalEffect()); // Exile Stunning Reversal. @@ -70,7 +70,7 @@ class StunningReversalEffect extends ReplacementEffectImpl { public StunningReversalEffect() { super(Duration.EndOfTurn, Outcome.Benefit); - staticText = "The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1. "; + staticText = "The next time you would lose the game this turn, instead draw seven cards and your life total becomes 1"; } public StunningReversalEffect(final StunningReversalEffect effect) { diff --git a/Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java b/Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java index ca3588b58a..6b5adcd6d6 100644 --- a/Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java +++ b/Mage.Sets/src/mage/cards/t/TheCrowdGoesWild.java @@ -50,7 +50,7 @@ import mage.target.common.TargetCreaturePermanent; */ public class TheCrowdGoesWild extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with a +1/+1 counter on it"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("each creature with a +1/+1 counter on it"); static { filter.add(new CounterPredicate(CounterType.P1P1)); @@ -64,7 +64,7 @@ public class TheCrowdGoesWild extends CardImpl { // Support X (Put a +1/+1 counter on each of up to X target creatures.) this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance()) - .setText("Support X <i>(Put a +1/+1 counter on each of up to X target creatures.)</i>") + .setText("Support X <i>(Put a +1/+1 counter on each of up to X target creatures.)</i><br>") ); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/t/ToothyImaginaryFriend.java b/Mage.Sets/src/mage/cards/t/ToothyImaginaryFriend.java index d480130b85..0a35157351 100644 --- a/Mage.Sets/src/mage/cards/t/ToothyImaginaryFriend.java +++ b/Mage.Sets/src/mage/cards/t/ToothyImaginaryFriend.java @@ -35,11 +35,11 @@ import mage.abilities.dynamicvalue.common.CountersSourceCount; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.PartnerWithAbility; -import mage.constants.SubType; -import mage.constants.SuperType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.counters.CounterType; /** @@ -63,7 +63,9 @@ public class ToothyImaginaryFriend extends CardImpl { this.addAbility(new DrawCardControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), true)); // When Toothy leaves the battlefield, draw a card for each +1/+1 counter on it. - this.addAbility(new LeavesBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(new CountersSourceCount(CounterType.P1P1)), false)); + this.addAbility(new LeavesBattlefieldTriggeredAbility( + new DrawCardSourceControllerEffect(new CountersSourceCount(CounterType.P1P1)) + .setText("draw a card for each +1/+1 counter on it"), false)); } public ToothyImaginaryFriend(final ToothyImaginaryFriend card) { diff --git a/Mage.Sets/src/mage/cards/u/UnflinchingCourage.java b/Mage.Sets/src/mage/cards/u/UnflinchingCourage.java index 6b443fa376..7279c6c60d 100644 --- a/Mage.Sets/src/mage/cards/u/UnflinchingCourage.java +++ b/Mage.Sets/src/mage/cards/u/UnflinchingCourage.java @@ -40,9 +40,9 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AttachmentType; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -54,10 +54,9 @@ import mage.target.common.TargetCreaturePermanent; public class UnflinchingCourage extends CardImpl { public UnflinchingCourage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{W}"); this.subtype.add(SubType.AURA); - // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); @@ -66,9 +65,10 @@ public class UnflinchingCourage extends CardImpl { this.addAbility(ability); // Enchanted creature gets +2/+2 and has trample and lifelink. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.AURA))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(LifelinkAbility.getInstance(), AttachmentType.AURA))); + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield)); + ability.addEffect(new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.AURA).setText("and has trample")); + ability.addEffect(new GainAbilityAttachedEffect(LifelinkAbility.getInstance(), AttachmentType.AURA).setText("and lifelink")); + this.addAbility(ability); } public UnflinchingCourage(final UnflinchingCourage card) { diff --git a/Mage.Sets/src/mage/cards/v/VirtusTheVeiled.java b/Mage.Sets/src/mage/cards/v/VirtusTheVeiled.java index 65d21fe242..6a04329042 100644 --- a/Mage.Sets/src/mage/cards/v/VirtusTheVeiled.java +++ b/Mage.Sets/src/mage/cards/v/VirtusTheVeiled.java @@ -29,7 +29,7 @@ package mage.cards.v; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.common.LoseHalfLifeTargetEffect; import mage.constants.SubType; import mage.constants.SuperType; @@ -61,7 +61,7 @@ public class VirtusTheVeiled extends CardImpl { this.addAbility(DeathtouchAbility.getInstance()); // Whenever Virtus the Veiled deals combat damage to a player, that player loses half their life, rounded up. - this.addAbility(new DealsDamageToOpponentTriggeredAbility(new LoseHalfLifeTargetEffect(), false, true, true)); + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new LoseHalfLifeTargetEffect(), false, true)); } public VirtusTheVeiled(final VirtusTheVeiled card) { diff --git a/Mage/src/main/java/mage/abilities/common/WinsCoinFlipTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/WinsCoinFlipTriggeredAbility.java index 1d049cfb73..2cd87803c8 100644 --- a/Mage/src/main/java/mage/abilities/common/WinsCoinFlipTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/WinsCoinFlipTriggeredAbility.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; @@ -65,6 +64,6 @@ public class WinsCoinFlipTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever a player wins a coin flip," + super.getRule(); + return "Whenever a player wins a coin flip, " + super.getRule(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DrawCardTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DrawCardTargetEffect.java index 0068c5a701..ca91d44997 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DrawCardTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DrawCardTargetEffect.java @@ -115,7 +115,7 @@ public class DrawCardTargetEffect extends OneShotEffect { } else { target = mode.getTargets().get(0); } - sb.append("Target ").append(target.getTargetName()); + sb.append("target ").append(target.getTargetName()); } else { sb.append("that player"); } diff --git a/Mage/src/main/java/mage/abilities/keyword/PartnerWithAbility.java b/Mage/src/main/java/mage/abilities/keyword/PartnerWithAbility.java index 63cbcf4343..77dc2461a5 100644 --- a/Mage/src/main/java/mage/abilities/keyword/PartnerWithAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/PartnerWithAbility.java @@ -117,7 +117,7 @@ class PartnersWithSearchEffect extends OneShotEffect { private final String partnerName; public PartnersWithSearchEffect(String partnerName) { - super(Outcome.Detriment); + super(Outcome.DrawCard); this.partnerName = partnerName; this.staticText = ""; } From 21e834a5a124780a00245af7554aad9ba16c333c Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sat, 26 May 2018 18:51:49 -0400 Subject: [PATCH 126/154] Implemented Zndrsplt's Judgment --- .../src/mage/cards/z/ZndrspltsJudgment.java | 122 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + .../common/CreateTokenCopyTargetEffect.java | 14 +- 3 files changed, 124 insertions(+), 13 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/z/ZndrspltsJudgment.java diff --git a/Mage.Sets/src/mage/cards/z/ZndrspltsJudgment.java b/Mage.Sets/src/mage/cards/z/ZndrspltsJudgment.java new file mode 100644 index 0000000000..7706dc5061 --- /dev/null +++ b/Mage.Sets/src/mage/cards/z/ZndrspltsJudgment.java @@ -0,0 +1,122 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.z; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.ChooseFriendsAndFoes; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class ZndrspltsJudgment extends CardImpl { + + public ZndrspltsJudgment(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}"); + + // For each player, choose friend or foe. Each friend creates a token that's a copy of a creature they control. Each foe returns a creature they control to its owner's hand. + this.getSpellAbility().addEffect(new ZndrspltsJudgmentEffect()); + } + + public ZndrspltsJudgment(final ZndrspltsJudgment card) { + super(card); + } + + @Override + public ZndrspltsJudgment copy() { + return new ZndrspltsJudgment(this); + } +} + +class ZndrspltsJudgmentEffect extends OneShotEffect { + + ZndrspltsJudgmentEffect() { + super(Outcome.Benefit); + this.staticText = "For each player, choose friend or foe. Each friend creates a token that's a copy of a creature they control. Each foe returns a creature they control to its owner's hand"; + } + + ZndrspltsJudgmentEffect(final ZndrspltsJudgmentEffect effect) { + super(effect); + } + + @Override + public ZndrspltsJudgmentEffect copy() { + return new ZndrspltsJudgmentEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + ChooseFriendsAndFoes choice = new ChooseFriendsAndFoes(); + choice.chooseFriendOrFoe(controller, source, game); + for (Player player : choice.getFriends()) { + if (player == null) { + continue; + } + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control"); + filter.add(new ControllerIdPredicate(player.getId())); + TargetCreaturePermanent target = new TargetCreaturePermanent(filter); + if (!player.choose(Outcome.Copy, target, source.getSourceId(), game)) { + continue; + } + Effect effect = new CreateTokenCopyTargetEffect(player.getId()); + effect.setTargetPointer(new FixedTarget(target.getFirstTarget(), game)); + effect.apply(game, source); + } + for (Player player : choice.getFoes()) { + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control"); + filter.add(new ControllerIdPredicate(player.getId())); + TargetCreaturePermanent target = new TargetCreaturePermanent(filter); + if (!player.choose(Outcome.ReturnToHand, target, source.getSourceId(), game)) { + continue; + } + Effect effect = new ReturnToHandTargetEffect(); + effect.setTargetPointer(new FixedTarget(target.getFirstTarget(), game)); + effect.apply(game, source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 22b32f7294..8f2d6ee3db 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -293,6 +293,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); cards.add(new SetCardInfo("Wrap in Flames", 188, Rarity.COMMON, mage.cards.w.WrapInFlames.class)); cards.add(new SetCardInfo("Yotian Soldier", 249, Rarity.COMMON, mage.cards.y.YotianSoldier.class)); + cards.add(new SetCardInfo("Zndrsplt's Judgment", 43, Rarity.RARE, mage.cards.z.ZndrspltsJudgment.class)); cards.add(new SetCardInfo("Zndrsplt, Eye of Wisdom", 5, Rarity.RARE, mage.cards.z.ZndrspltEyeOfWisdom.class)); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java index 6bb2ce18c5..50435d05c7 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java @@ -81,19 +81,7 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect { } public CreateTokenCopyTargetEffect() { - super(Outcome.PutCreatureInPlay); - this.playerId = null; - this.additionalCardType = null; - this.addedTokenPermanents = new ArrayList<>(); - this.number = 1; - this.additionalSubType = null; - this.onlySubType = null; - this.attackedPlayer = null; - this.tokenPower = Integer.MIN_VALUE; - this.tokenToughness = Integer.MIN_VALUE; - this.gainsFlying = false; - this.becomesArtifact = false; - this.color = null; + this((UUID) null); } public CreateTokenCopyTargetEffect(UUID playerId) { From cfe712efc63d63ce3ecabdc3b83c4d9dbac6322a Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Sun, 27 May 2018 01:00:55 +0200 Subject: [PATCH 127/154] XMage 1.4.29V5 --- .../src/main/java/mage/utils/MageVersion.java | 2 +- Mage.Server/config/config.xml | 371 +++++++++--------- Mage.Server/release/config/config.xml | 7 +- .../mage/cards/repository/CardRepository.java | 2 +- .../cards/repository/ExpansionRepository.java | 10 +- 5 files changed, 197 insertions(+), 195 deletions(-) diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java index 26802409ef..6995bdef54 100644 --- a/Mage.Common/src/main/java/mage/utils/MageVersion.java +++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java @@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable<MageVersion> { public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MINOR = 4; public final static int MAGE_VERSION_PATCH = 29; - public final static String MAGE_VERSION_MINOR_PATCH = "V4"; + public final static String MAGE_VERSION_MINOR_PATCH = "V5"; public final static String MAGE_VERSION_INFO = ""; private final int major; diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml index 898e9475b4..01a8513084 100644 --- a/Mage.Server/config/config.xml +++ b/Mage.Server/config/config.xml @@ -1,187 +1,186 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Config.xsd"> - <!-- - Official guide to setup public server and NAT: https://www.slightlymagic.net/forum/viewtopic.php?f=70&t=15898 - - serverAddress - ip or domain of the XMage server. Set it to "0.0.0.0" for local host or to the IP the server should use - Public server should be accessable to all clients by it's name (example: xmage.mydomain.com) - port - the port the primary server socket is bound to - secondaryBindPort - the port to which the secondary server socket is to be bound. if "-1" is set , an arbitrary port is selected. - backlogSize - the preferred number of unaccepted incoming connections allowed at a given time. The actual number may be greater - than the specified backlog. When the queue is full, further connection requests are rejected. The JBoss default value is 200 - numAcceptThreads - the number of threads listening on the ServerSocket. The JBoss default value is 1 - maxPoolSize - the maximum number of ServerThreads that can exist at any given time. The JBoss default value is 300 - leasePeriod - To turn on server side connection failure detection of remoting clients, it is necessary to satisfy two criteria. - The first is that the client lease period is set and is a value greater than 0. The value is represented in milliseconds. - The client lease period can be set by either the 'clientLeasePeriod' attribute within the Connector configuration or by calling the Connector method - socketWriteTimeout - All write operations will time out if they do not complete within the configured period. - maxGameThreads - Number of games that can be started simultanously on the server - maxSecondsIdle - Number of seconds after that a game is auto conceded by the player that was idle for such a time - minUserNameLength - minmal allowed length of a user name to connect to the server - maxUserNameLength - maximal allowed length of a user name to connect to the server - userNamePattern - pattern for user name validity check - maxAiOpponents - number of allowed AI opponents on the server - saveGameActivated - allow game save and replay options (not working correctly yet) - - authenticationActivated - "true" = user have to register to signon "false" = user need not to register - * mail configs only needed if authentication is activated: - * if mailUser = "" mailgun is used otherwise nativ mail server on the system - googleAccount - not supported currently - mailgunApiKey - key from the mailgun domain e.g. = "key-12121111..." - mailgunDomain - domain for the mailgun message sending - mailSmtpHost - hostname to send the mail - mailSmtpPort - port to send the mail - mailUser - username used to send the mail - mailPassword - passworf of the used user to send the mail - mailFromAddress - sender address - --> - <server serverAddress="0.0.0.0" - serverName="mage-server" - port="17171" - secondaryBindPort="17179" - backlogSize="200" - numAcceptThreads="2" - maxPoolSize="300" - leasePeriod="5000" - socketWriteTimeout="10000" - maxGameThreads="10" - maxSecondsIdle="300" - minUserNameLength="3" - maxUserNameLength="14" - invalidUserNamePattern="[^a-z0-9_]" - minPasswordLength="8" - maxPasswordLength="100" - maxAiOpponents="15" - saveGameActivated="false" - authenticationActivated="false" - googleAccount="" - mailgunApiKey="key-d93e81f19a9c9ed243ebb7cc9381385c" - mailgunDomain="sandbox401a433f30d445309a5e86b6c53f7812.mailgun.org" - mailSmtpHost="smtp.1und1.de" - mailSmtpPort="465" - mailUser="xmageserver@online.de" - mailPassword="24wrsfxv" - mailFromAddress="xmageserver@online.de" - /> - <playerTypes> - <playerType name="Human" jar="mage-player-human.jar" className="mage.player.human.HumanPlayer"/> - <!--<playerType name="Computer - minimax" jar="mage-player-aiminimax.jar" className="mage.player.ai.ComputerPlayer3"/>--> - <playerType name="Computer - mad" jar="mage-player-ai-ma.jar" className="mage.player.ai.ComputerPlayer7"/> - <!--<playerType name="Computer - monte carlo" jar="mage-player-aimcts.jar" className="mage.player.ai.ComputerPlayerMCTS"/>--> - <playerType name="Computer - draftbot" jar="mage-player-ai-draft-bot.jar" className="mage.player.ai.ComputerDraftPlayer"/> - </playerTypes> - <gameTypes> - <gameType name="Two Player Duel" jar="mage-game-twoplayerduel.jar" className="mage.game.TwoPlayerMatch" typeName="mage.game.TwoPlayerDuelType"/> - <gameType name="Free For All" jar="mage-game-freeforall.jar" className="mage.game.FreeForAllMatch" typeName="mage.game.FreeForAllType"/> - <gameType name="Commander Two Player Duel" jar="mage-game-commanderduel.jar" className="mage.game.CommanderDuelMatch" typeName="mage.game.CommanderDuelType"/> - <gameType name="Commander Free For All" jar="mage-game-commanderfreeforall.jar" className="mage.game.CommanderFreeForAllMatch" typeName="mage.game.CommanderFreeForAllType"/> - <gameType name="Tiny Leaders Two Player Duel" jar="mage-game-tinyleadersduel.jar" className="mage.game.TinyLeadersDuelMatch" typeName="mage.game.TinyLeadersDuelType"/> - <gameType name="Canadian Highlander Two Player Duel" jar="mage-game-canadianhighlanderduel.jar" className="mage.game.CanadianHighlanderDuelMatch" typeName="mage.game.CanadianHighlanderDuelType"/> - <gameType name="Penny Dreadful Commander Free For All" jar="mage-game-pennydreadfulcommanderfreeforall.jar" className="mage.game.PennyDreadfulCommanderFreeForAllMatch" typeName="mage.game.PennyDreadfulCommanderFreeForAllType"/> - <gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/> - <gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/> - <gameType name="Brawl Free For All" jar="mage-game-brawlfreeforall.jar" className="mage.game.BrawlFreeForAllMatch" typeName="mage.game.BrawlFreeForAllType"/> - <gameType name="Momir Basic Two Player Duel" jar="mage-game-momirduel.jar" className="mage.game.MomirDuelMatch" typeName="mage.game.MomirDuelType"/> - <gameType name="Momir Basic Free For All" jar="mage-game-momir.jar" className="mage.game.MomirFreeForAllMatch" typeName="mage.game.MomirFreeForAllType"/> - </gameTypes> - <tournamentTypes> - <tournamentType name="Constructed Elimination" jar="mage-tournament-constructed.jar" className="mage.tournament.ConstructedEliminationTournament" typeName="mage.tournament.ConstructedEliminationTournamentType"/> - <tournamentType name="Constructed Swiss" jar="mage-tournament-constructed.jar" className="mage.tournament.ConstructedSwissTournament" typeName="mage.tournament.ConstructedSwissTournamentType"/> - <tournamentType name="Booster Draft Elimination" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationTournamentType"/> - <tournamentType name="Booster Draft Elimination (Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationCubeTournamentType"/> - <tournamentType name="Booster Draft Elimination (Random)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RandomBoosterDraftEliminationTournament" typeName="mage.tournament.RandomBoosterDraftEliminationTournamentType"/> - <tournamentType name="Booster Draft Elimination (Rich Man)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RichManDraftEliminationTournament" typeName="mage.tournament.RichManDraftEliminationTournamentType"/> - <tournamentType name="Booster Draft Elimination (Rich Man Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RichManCubeDraftEliminationTournament" typeName="mage.tournament.RichManCubeDraftEliminationTournamentType"/> - <tournamentType name="Booster Draft Swiss" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissTournamentType"/> - <tournamentType name="Booster Draft Swiss (Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissCubeTournamentType"/> - <tournamentType name="Booster Draft Swiss (Random)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RandomBoosterDraftSwissTournament" typeName="mage.tournament.RandomBoosterDraftSwissTournamentType"/> - <tournamentType name="Sealed Elimination" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationTournamentType"/> - <tournamentType name="Sealed Elimination (Cube)" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationCubeTournamentType"/> - <tournamentType name="Sealed Swiss" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissTournamentType"/> - <tournamentType name="Sealed Swiss (Cube)" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissCubeTournamentType"/> - </tournamentTypes> - <draftCubes> - <draftCube name="Adam Styborski's Pauper Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.AdamStyborskisPauperCube"/> - <draftCube name="Ben's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.BensCube"/> - <draftCube name="Cube Tutor 360 Pauper" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeTutor360Pauper"/> - <draftCube name="Cube Tutor 720" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeTutor720"/> - <draftCube name="Eric Klug's Pro Tour Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.EricKlugsProTourCube"/> - <draftCube name="Guillaume Matignon's Jenny's/Johnny's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.GuillaumeMatignonsJennysJohnnysCube"/> - <draftCube name="Jim Davis's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.JimDavisCube"/> - <draftCube name="Joseph Vasoli's Peasant Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.JosephVasolisPeasantCube"/> - <draftCube name="Mono Blue Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MonoBlueCube"/> - <draftCube name="Sam Black's No Search Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.SamBlacksCube"/> - <draftCube name="Timothee Simonot's Twisted Color Pie Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.TimotheeSimonotsTwistedColorPieCube"/> - <draftCube name="MTGO Cube March 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGOMarchCube2014"/> - <draftCube name="MTGO Legacy Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCube"/> - <draftCube name="MTGO Legacy Cube 2015 March" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeMarch2015"/> - <draftCube name="MTGO Legacy Cube 2015 September" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2015"/> - <draftCube name="MTGO Legacy Cube 2016 January" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2016"/> - <draftCube name="MTGO Legacy Cube 2016 September" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2016"/> - <draftCube name="MTGO Legacy Cube 2017 January" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2017"/> - <draftCube name="MTGO Legacy Cube 2017 April" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeApril2017"/> - <draftCube name="MTGO Legacy Cube 2018 February" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCube2018February"/> - <draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCube"/> - <draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/> - <draftCube name="MTGO Modern Cube 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.ModernCube2017"/> - <draftCube name="MTGO Vintage Cube 2013" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2013"/> - <draftCube name="MTGO Vintage Cube 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2014"/> - <draftCube name="MTGO Vintage Cube 2015" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2015"/> - <draftCube name="MTGO Vintage Cube 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2016"/> - <draftCube name="MTGO Vintage Cube June 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2016"/> - <draftCube name="MTGO Vintage Cube November 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeNovember2016"/> - <draftCube name="MTGO Vintage Cube June 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2017"/> - <draftCube name="MTGO Vintage Cube December 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeDecember2017"/> - <draftCube name="The Peasant's Toolbox" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.PeasantsToolboxCube"/> - <draftCube name="www.MTGCube.com" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGCube"/> - <draftCube name="Cube From Deck" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeFromDeck"/> - </draftCubes> - <deckTypes> - <deckType name="Constructed - Standard" jar="mage-deck-constructed.jar" className="mage.deck.Standard"/> - <deckType name="Constructed - Extended" jar="mage-deck-constructed.jar" className="mage.deck.Extended"/> - <deckType name="Constructed - Frontier" jar="mage-deck-constructed.jar" className="mage.deck.Frontier"/> - <deckType name="Constructed - Modern" jar="mage-deck-constructed.jar" className="mage.deck.Modern"/> - <deckType name="Constructed - Modern - No Banned List" jar="mage-deck-constructed.jar" className="mage.deck.ModernNoBannedList"/> - <deckType name="Constructed - Eternal" jar="mage-deck-constructed.jar" className="mage.deck.Eternal"/> - <deckType name="Constructed - Legacy" jar="mage-deck-constructed.jar" className="mage.deck.Legacy"/> - <deckType name="Constructed - Vintage" jar="mage-deck-constructed.jar" className="mage.deck.Vintage"/> - <deckType name="Constructed - Pauper" jar="mage-deck-constructed.jar" className="mage.deck.Pauper"/> - <deckType name="Constructed - Historical Type 2" jar="mage-deck-constructed.jar" className="mage.deck.HistoricalType2"/> - <deckType name="Constructed - Super Type 2" jar="mage-deck-constructed.jar" className="mage.deck.SuperType2"/> - <deckType name="Constructed - Freeform" jar="mage-deck-constructed.jar" className="mage.deck.Freeform"/> - <deckType name="Constructed - Old School 93/94" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394"/> - <deckType name="Constructed - Old School 93/94 - Italian Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394Italian"/> - <deckType name="Constructed - Old School 93/94 - Channel Fireball Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394CFB"/> - <deckType name="Constructed - Old School 93/94 - EudoGames Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EG"/> - <deckType name="Constructed - Old School 93/94 - EC Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EC"/> - <deckType name="Constructed - Australian Highlander" jar="mage-deck-constructed.jar" className="mage.deck.AusHighlander"/> - <deckType name="Constructed - Canadian Highlander" jar="mage-deck-constructed.jar" className="mage.deck.CanadianHighlander"/> - <deckType name="Constructed - Freeform" jar="mage-deck-constructed.jar" className="mage.deck.Freeform"/> - <deckType name="Variant Magic - Commander" jar="mage-deck-constructed.jar" className="mage.deck.Commander"/> - <deckType name="Variant Magic - Duel Commander" jar="mage-deck-constructed.jar" className="mage.deck.DuelCommander"/> - <deckType name="Variant Magic - MTGO 1v1 Commander" jar="mage-deck-constructed.jar" className="mage.deck.MTGO1v1Commander"/> - <deckType name="Variant Magic - Tiny Leaders" jar="mage-deck-constructed.jar" className="mage.deck.TinyLeaders"/> - <deckType name="Variant Magic - Momir Basic" jar="mage-deck-constructed.jar" className="mage.deck.Momir"/> - <deckType name="Variant Magic - Penny Dreadful Commander" jar="mage-deck-constructed.jar" className="mage.deck.PennyDreadfulCommander"/> - <deckType name="Variant Magic - Freeform Commander" jar="mage-deck-constructed.jar" className="mage.deck.FreeformCommander"/> - <deckType name="Variant Magic - Brawl" jar="mage-deck-constructed.jar" className="mage.deck.Brawl"/> - <deckType name="Block Constructed - Amonkhet" jar="mage-deck-constructed.jar" className="mage.deck.AmonkhetBlock"/> - <deckType name="Block Constructed - Battle for Zendikar" jar="mage-deck-constructed.jar" className="mage.deck.BattleForZendikarBlock"/> - <deckType name="Block Constructed - Innistrad" jar="mage-deck-constructed.jar" className="mage.deck.InnistradBlock"/> - <deckType name="Block Constructed - Ixalan" jar="mage-deck-constructed.jar" className="mage.deck.IxalanBlock"/> - <deckType name="Block Constructed - Kaladesh" jar="mage-deck-constructed.jar" className="mage.deck.KaladeshBlock"/> - <deckType name="Block Constructed - Kamigawa" jar="mage-deck-constructed.jar" className="mage.deck.KamigawaBlock"/> - <deckType name="Block Constructed - Khans of Tarkir" jar="mage-deck-constructed.jar" className="mage.deck.KhansOfTarkirBlock"/> - <deckType name="Block Constructed - Lorwyn" jar="mage-deck-constructed.jar" className="mage.deck.LorwynBlock"/> - <deckType name="Block Constructed - Return to Ravnica" jar="mage-deck-constructed.jar" className="mage.deck.ReturnToRavnicaBlock"/> - <deckType name="Block Constructed - Scars of Mirrodin" jar="mage-deck-constructed.jar" className="mage.deck.ScarsOfMirrodinBlock"/> - <deckType name="Block Constructed - Shadowmoor" jar="mage-deck-constructed.jar" className="mage.deck.ShadowmoorBlock"/> - <deckType name="Block Constructed - Shadows over Innistrad" jar="mage-deck-constructed.jar" className="mage.deck.ShadowsOverInnistradBlock"/> - <deckType name="Block Constructed - Shards of Alara" jar="mage-deck-constructed.jar" className="mage.deck.ShardsOfAlaraBlock"/> - <deckType name="Block Constructed - Theros" jar="mage-deck-constructed.jar" className="mage.deck.TherosBlock"/> - <deckType name="Block Constructed - Zendikar" jar="mage-deck-constructed.jar" className="mage.deck.ZendikarBlock"/> - <deckType name="Block Constructed Custom - Star Wars" jar="mage-deck-constructed.jar" className="mage.deck.StarWarsBlock"/> - <deckType name="Limited" jar="mage-deck-limited.jar" className="mage.deck.Limited"/> - </deckTypes> +<?xml version="1.0" encoding="UTF-8"?> + +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Config.xsd"> + <!-- + Official guide to setup public server and NAT: https://www.slightlymagic.net/forum/viewtopic.php?f=70&t=15898 + + serverAddress - ip or domain of the XMage server. Set it to "0.0.0.0" for local host or to the IP the server should use + Public server should be accessable to all clients by it's name (example: xmage.mydomain.com) + port - the port the primary server socket is bound to + secondaryBindPort - the port to which the secondary server socket is to be bound. if "-1" is set , an arbitrary port is selected. + backlogSize - the preferred number of unaccepted incoming connections allowed at a given time. The actual number may be greater + than the specified backlog. When the queue is full, further connection requests are rejected. The JBoss default value is 200 + numAcceptThreads - the number of threads listening on the ServerSocket. The JBoss default value is 1 + maxPoolSize - the maximum number of ServerThreads that can exist at any given time. The JBoss default value is 300 + leasePeriod - To turn on server side connection failure detection of remoting clients, it is necessary to satisfy two criteria. + The first is that the client lease period is set and is a value greater than 0. The value is represented in milliseconds. + The client lease period can be set by either the 'clientLeasePeriod' attribute within the Connector configuration or by calling the Connector method + socketWriteTimeout - All write operations will time out if they do not complete within the configured period. + maxGameThreads - Number of games that can be started simultanously on the server + maxSecondsIdle - Number of seconds after that a game is auto conceded by the player that was idle for such a time + minUserNameLength - minmal allowed length of a user name to connect to the server + maxUserNameLength - maximal allowed length of a user name to connect to the server + userNamePattern - pattern for user name validity check + maxAiOpponents - number of allowed AI opponents on the server + saveGameActivated - allow game save and replay options (not working correctly yet) + + authenticationActivated - "true" = user have to register to signon "false" = user need not to register + * mail configs only needed if authentication is activated: + * if mailUser = "" mailgun is used otherwise nativ mail server on the system + googleAccount - not supported currently + mailgunApiKey - key from the mailgun domain e.g. = "key-12121111..." + mailgunDomain - domain for the mailgun message sending + mailSmtpHost - hostname to send the mail + mailSmtpPort - port to send the mail + mailUser - username used to send the mail + mailPassword - passworf of the used user to send the mail + mailFromAddress - sender address + --> + <server serverAddress="0.0.0.0" + serverName="mage-server" + port="17171" + secondaryBindPort="17179" + backlogSize="200" + numAcceptThreads="2" + maxPoolSize="300" + leasePeriod="5000" + socketWriteTimeout="10000" + maxGameThreads="10" + maxSecondsIdle="300" + minUserNameLength="3" + maxUserNameLength="14" + invalidUserNamePattern="[^a-z0-9_]" + minPasswordLength="8" + maxPasswordLength="100" + maxAiOpponents="15" + saveGameActivated="false" + authenticationActivated="false" + googleAccount="" + mailgunApiKey="key-d93e81f19a9c9ed243ebb7cc9381385c" + mailgunDomain="sandbox401a433f30d445309a5e86b6c53f7812.mailgun.org" + mailSmtpHost="smtp.1und1.de" + mailSmtpPort="465" + mailUser="xmageserver@online.de" + mailPassword="24wrsfxv" + mailFromAddress="xmageserver@online.de" + /> + <playerTypes> + <playerType name="Human" jar="mage-player-human.jar" className="mage.player.human.HumanPlayer"/> + <!--<playerType name="Computer - minimax" jar="mage-player-aiminimax.jar" className="mage.player.ai.ComputerPlayer3"/>--> + <playerType name="Computer - mad" jar="mage-player-ai-ma.jar" className="mage.player.ai.ComputerPlayer7"/> + <!--<playerType name="Computer - monte carlo" jar="mage-player-aimcts.jar" className="mage.player.ai.ComputerPlayerMCTS"/>--> + <playerType name="Computer - draftbot" jar="mage-player-ai-draft-bot.jar" className="mage.player.ai.ComputerDraftPlayer"/> + </playerTypes> + <gameTypes> + <gameType name="Two Player Duel" jar="mage-game-twoplayerduel.jar" className="mage.game.TwoPlayerMatch" typeName="mage.game.TwoPlayerDuelType"/> + <gameType name="Free For All" jar="mage-game-freeforall.jar" className="mage.game.FreeForAllMatch" typeName="mage.game.FreeForAllType"/> + <gameType name="Commander Two Player Duel" jar="mage-game-commanderduel.jar" className="mage.game.CommanderDuelMatch" typeName="mage.game.CommanderDuelType"/> + <gameType name="Commander Free For All" jar="mage-game-commanderfreeforall.jar" className="mage.game.CommanderFreeForAllMatch" typeName="mage.game.CommanderFreeForAllType"/> + <gameType name="Tiny Leaders Two Player Duel" jar="mage-game-tinyleadersduel.jar" className="mage.game.TinyLeadersDuelMatch" typeName="mage.game.TinyLeadersDuelType"/> + <gameType name="Canadian Highlander Two Player Duel" jar="mage-game-canadianhighlanderduel.jar" className="mage.game.CanadianHighlanderDuelMatch" typeName="mage.game.CanadianHighlanderDuelType"/> + <gameType name="Penny Dreadful Commander Free For All" jar="mage-game-pennydreadfulcommanderfreeforall.jar" className="mage.game.PennyDreadfulCommanderFreeForAllMatch" typeName="mage.game.PennyDreadfulCommanderFreeForAllType"/> + <gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/> + <gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/> + <gameType name="Brawl Free For All" jar="mage-game-brawlfreeforall.jar" className="mage.game.BrawlFreeForAllMatch" typeName="mage.game.BrawlFreeForAllType"/> + <gameType name="Momir Basic Two Player Duel" jar="mage-game-momirduel.jar" className="mage.game.MomirDuelMatch" typeName="mage.game.MomirDuelType"/> + <gameType name="Momir Basic Free For All" jar="mage-game-momir.jar" className="mage.game.MomirFreeForAllMatch" typeName="mage.game.MomirFreeForAllType"/> + </gameTypes> + <tournamentTypes> + <tournamentType name="Constructed Elimination" jar="mage-tournament-constructed.jar" className="mage.tournament.ConstructedEliminationTournament" typeName="mage.tournament.ConstructedEliminationTournamentType"/> + <tournamentType name="Constructed Swiss" jar="mage-tournament-constructed.jar" className="mage.tournament.ConstructedSwissTournament" typeName="mage.tournament.ConstructedSwissTournamentType"/> + <tournamentType name="Booster Draft Elimination" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationTournamentType"/> + <tournamentType name="Booster Draft Elimination (Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationCubeTournamentType"/> + <tournamentType name="Booster Draft Elimination (Random)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RandomBoosterDraftEliminationTournament" typeName="mage.tournament.RandomBoosterDraftEliminationTournamentType"/> + <tournamentType name="Booster Draft Elimination (Rich Man)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RichManDraftEliminationTournament" typeName="mage.tournament.RichManDraftEliminationTournamentType"/> + <tournamentType name="Booster Draft Elimination (Rich Man Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RichManCubeDraftEliminationTournament" typeName="mage.tournament.RichManCubeDraftEliminationTournamentType"/> + <tournamentType name="Booster Draft Swiss" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissTournamentType"/> + <tournamentType name="Booster Draft Swiss (Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissCubeTournamentType"/> + <tournamentType name="Booster Draft Swiss (Random)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RandomBoosterDraftSwissTournament" typeName="mage.tournament.RandomBoosterDraftSwissTournamentType"/> + <tournamentType name="Sealed Elimination" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationTournamentType"/> + <tournamentType name="Sealed Elimination (Cube)" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedEliminationTournament" typeName="mage.tournament.SealedEliminationCubeTournamentType"/> + <tournamentType name="Sealed Swiss" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissTournamentType"/> + <tournamentType name="Sealed Swiss (Cube)" jar="mage-tournament-sealed.jar" className="mage.tournament.SealedSwissTournament" typeName="mage.tournament.SealedSwissCubeTournamentType"/> + </tournamentTypes> + <draftCubes> + <draftCube name="Adam Styborski's Pauper Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.AdamStyborskisPauperCube"/> + <draftCube name="Ben's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.BensCube"/> + <draftCube name="Cube Tutor 360 Pauper" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeTutor360Pauper"/> + <draftCube name="Cube Tutor 720" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeTutor720"/> + <draftCube name="Eric Klug's Pro Tour Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.EricKlugsProTourCube"/> + <draftCube name="Guillaume Matignon's Jenny's/Johnny's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.GuillaumeMatignonsJennysJohnnysCube"/> + <draftCube name="Jim Davis's Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.JimDavisCube"/> + <draftCube name="Joseph Vasoli's Peasant Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.JosephVasolisPeasantCube"/> + <draftCube name="Mono Blue Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MonoBlueCube"/> + <draftCube name="Sam Black's No Search Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.SamBlacksCube"/> + <draftCube name="Timothee Simonot's Twisted Color Pie Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.TimotheeSimonotsTwistedColorPieCube"/> + <draftCube name="MTGO Cube March 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGOMarchCube2014"/> + <draftCube name="MTGO Legacy Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCube"/> + <draftCube name="MTGO Legacy Cube 2015 March" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeMarch2015"/> + <draftCube name="MTGO Legacy Cube 2015 September" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2015"/> + <draftCube name="MTGO Legacy Cube 2016 January" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2016"/> + <draftCube name="MTGO Legacy Cube 2016 September" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2016"/> + <draftCube name="MTGO Legacy Cube 2017 January" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2017"/> + <draftCube name="MTGO Legacy Cube 2017 April" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeApril2017"/> + <draftCube name="MTGO Legacy Cube 2018 February" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCube2018February"/> + <draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCube"/> + <draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/> + <draftCube name="MTGO Modern Cube 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.ModernCube2017"/> + <draftCube name="MTGO Vintage Cube 2013" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2013"/> + <draftCube name="MTGO Vintage Cube 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2014"/> + <draftCube name="MTGO Vintage Cube 2015" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2015"/> + <draftCube name="MTGO Vintage Cube 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2016"/> + <draftCube name="MTGO Vintage Cube June 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2016"/> + <draftCube name="MTGO Vintage Cube November 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeNovember2016"/> + <draftCube name="MTGO Vintage Cube June 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJune2017"/> + <draftCube name="MTGO Vintage Cube December 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeDecember2017"/> + <draftCube name="The Peasant's Toolbox" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.PeasantsToolboxCube"/> + <draftCube name="www.MTGCube.com" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGCube"/> + <draftCube name="Cube From Deck" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.CubeFromDeck"/> + </draftCubes> + <deckTypes> + <deckType name="Constructed - Standard" jar="mage-deck-constructed.jar" className="mage.deck.Standard"/> + <deckType name="Constructed - Extended" jar="mage-deck-constructed.jar" className="mage.deck.Extended"/> + <deckType name="Constructed - Frontier" jar="mage-deck-constructed.jar" className="mage.deck.Frontier"/> + <deckType name="Constructed - Modern" jar="mage-deck-constructed.jar" className="mage.deck.Modern"/> + <deckType name="Constructed - Modern - No Banned List" jar="mage-deck-constructed.jar" className="mage.deck.ModernNoBannedList"/> + <deckType name="Constructed - Eternal" jar="mage-deck-constructed.jar" className="mage.deck.Eternal"/> + <deckType name="Constructed - Legacy" jar="mage-deck-constructed.jar" className="mage.deck.Legacy"/> + <deckType name="Constructed - Vintage" jar="mage-deck-constructed.jar" className="mage.deck.Vintage"/> + <deckType name="Constructed - Pauper" jar="mage-deck-constructed.jar" className="mage.deck.Pauper"/> + <deckType name="Constructed - Historical Type 2" jar="mage-deck-constructed.jar" className="mage.deck.HistoricalType2"/> + <deckType name="Constructed - Super Type 2" jar="mage-deck-constructed.jar" className="mage.deck.SuperType2"/> + <deckType name="Constructed - Australian Highlander" jar="mage-deck-constructed.jar" className="mage.deck.AusHighlander"/> + <deckType name="Constructed - Canadian Highlander" jar="mage-deck-constructed.jar" className="mage.deck.CanadianHighlander"/> + <deckType name="Constructed - Old School 93/94" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394"/> + <deckType name="Constructed - Old School 93/94 - Italian Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394Italian"/> + <deckType name="Constructed - Old School 93/94 - Channel Fireball Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394CFB"/> + <deckType name="Constructed - Old School 93/94 - EudoGames Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EG"/> + <deckType name="Constructed - Old School 93/94 - EC Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EC"/> + <deckType name="Constructed - Freeform" jar="mage-deck-constructed.jar" className="mage.deck.Freeform"/> + <deckType name="Variant Magic - Commander" jar="mage-deck-constructed.jar" className="mage.deck.Commander"/> + <deckType name="Variant Magic - Duel Commander" jar="mage-deck-constructed.jar" className="mage.deck.DuelCommander"/> + <deckType name="Variant Magic - MTGO 1v1 Commander" jar="mage-deck-constructed.jar" className="mage.deck.MTGO1v1Commander"/> + <deckType name="Variant Magic - Tiny Leaders" jar="mage-deck-constructed.jar" className="mage.deck.TinyLeaders"/> + <deckType name="Variant Magic - Momir Basic" jar="mage-deck-constructed.jar" className="mage.deck.Momir"/> + <deckType name="Variant Magic - Penny Dreadful Commander" jar="mage-deck-constructed.jar" className="mage.deck.PennyDreadfulCommander"/> + <deckType name="Variant Magic - Freeform Commander" jar="mage-deck-constructed.jar" className="mage.deck.FreeformCommander"/> + <deckType name="Variant Magic - Brawl" jar="mage-deck-constructed.jar" className="mage.deck.Brawl"/> + <deckType name="Block Constructed - Amonkhet" jar="mage-deck-constructed.jar" className="mage.deck.AmonkhetBlock"/> + <deckType name="Block Constructed - Battle for Zendikar" jar="mage-deck-constructed.jar" className="mage.deck.BattleForZendikarBlock"/> + <deckType name="Block Constructed - Innistrad" jar="mage-deck-constructed.jar" className="mage.deck.InnistradBlock"/> + <deckType name="Block Constructed - Ixalan" jar="mage-deck-constructed.jar" className="mage.deck.IxalanBlock"/> + <deckType name="Block Constructed - Kaladesh" jar="mage-deck-constructed.jar" className="mage.deck.KaladeshBlock"/> + <deckType name="Block Constructed - Kamigawa" jar="mage-deck-constructed.jar" className="mage.deck.KamigawaBlock"/> + <deckType name="Block Constructed - Khans of Tarkir" jar="mage-deck-constructed.jar" className="mage.deck.KhansOfTarkirBlock"/> + <deckType name="Block Constructed - Lorwyn" jar="mage-deck-constructed.jar" className="mage.deck.LorwynBlock"/> + <deckType name="Block Constructed - Return to Ravnica" jar="mage-deck-constructed.jar" className="mage.deck.ReturnToRavnicaBlock"/> + <deckType name="Block Constructed - Scars of Mirrodin" jar="mage-deck-constructed.jar" className="mage.deck.ScarsOfMirrodinBlock"/> + <deckType name="Block Constructed - Shadowmoor" jar="mage-deck-constructed.jar" className="mage.deck.ShadowmoorBlock"/> + <deckType name="Block Constructed - Shadows over Innistrad" jar="mage-deck-constructed.jar" className="mage.deck.ShadowsOverInnistradBlock"/> + <deckType name="Block Constructed - Shards of Alara" jar="mage-deck-constructed.jar" className="mage.deck.ShardsOfAlaraBlock"/> + <deckType name="Block Constructed - Theros" jar="mage-deck-constructed.jar" className="mage.deck.TherosBlock"/> + <deckType name="Block Constructed - Zendikar" jar="mage-deck-constructed.jar" className="mage.deck.ZendikarBlock"/> + <deckType name="Block Constructed Custom - Star Wars" jar="mage-deck-constructed.jar" className="mage.deck.StarWarsBlock"/> + <deckType name="Limited" jar="mage-deck-limited.jar" className="mage.deck.Limited"/> + </deckTypes> </config> \ No newline at end of file diff --git a/Mage.Server/release/config/config.xml b/Mage.Server/release/config/config.xml index 153d1f24f3..8a09e760ba 100644 --- a/Mage.Server/release/config/config.xml +++ b/Mage.Server/release/config/config.xml @@ -142,10 +142,13 @@ <deckType name="Constructed - Pauper" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Pauper"/> <deckType name="Constructed - Historical Type 2" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.HistoricalType2"/> <deckType name="Constructed - Super Type 2" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.SuperType2"/> - <deckType name="Constructed - Freeform" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Freeform"/> - <deckType name="Constructed - Old School 93/94" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.OldSchool9394"/> <deckType name="Constructed - Australian Highlander" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.AusHighlander"/> <deckType name="Constructed - Canadian Highlander" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.CanadianHighlander"/> + <deckType name="Constructed - Old School 93/94" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.OldSchool9394"/> + <deckType name="Constructed - Old School 93/94 - Italian Rules" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.OldSchool9394Italian"/> + <deckType name="Constructed - Old School 93/94 - Channel Fireball Rules" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.OldSchool9394CFB"/> + <deckType name="Constructed - Old School 93/94 - EudoGames Rules" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.OldSchool9394EG"/> + <deckType name="Constructed - Old School 93/94 - EC Rules" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.OldSchool9394EC"/> <deckType name="Constructed - Freeform" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Freeform"/> <deckType name="Variant Magic - Commander" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.Commander"/> <deckType name="Variant Magic - Duel Commander" jar="mage-deck-constructed-${project.version}.jar" className="mage.deck.DuelCommander"/> diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index 39201d4a6d..8f3a18fcfc 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -58,7 +58,7 @@ public enum CardRepository { // raise this if db structure was changed private static final long CARD_DB_VERSION = 51; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 109; + private static final long CARD_CONTENT_VERSION = 110; private Dao<CardInfo, Object> cardDao; private Set<String> classNames; diff --git a/Mage/src/main/java/mage/cards/repository/ExpansionRepository.java b/Mage/src/main/java/mage/cards/repository/ExpansionRepository.java index 6df02be31e..a8fd506d91 100644 --- a/Mage/src/main/java/mage/cards/repository/ExpansionRepository.java +++ b/Mage/src/main/java/mage/cards/repository/ExpansionRepository.java @@ -29,7 +29,7 @@ public enum ExpansionRepository { private static final String JDBC_URL = "jdbc:h2:file:./db/cards.h2;AUTO_SERVER=TRUE"; private static final String VERSION_ENTITY_NAME = "expansion"; private static final long EXPANSION_DB_VERSION = 5; - private static final long EXPANSION_CONTENT_VERSION = 14; + private static final long EXPANSION_CONTENT_VERSION = 15; private Dao<ExpansionInfo, Object> expansionDao; @@ -88,10 +88,10 @@ public enum ExpansionRepository { try { // only with boosters and cards GenericRawResults<ExpansionInfo> setsList = expansionDao.queryRaw( - "select * from expansion e " + - " where e.boosters = 1 " + - " and exists(select (1) from card c where c.setcode = e.code) " + - " order by e.releasedate desc", + "select * from expansion e " + + " where e.boosters = 1 " + + " and exists(select (1) from card c where c.setcode = e.code) " + + " order by e.releasedate desc", expansionDao.getRawRowMapper()); List<ExpansionInfo> resList = new ArrayList<>(); From 4dd6bbef1484727554d92e0e7494fdc6f2bdd2a3 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sat, 26 May 2018 19:15:44 -0400 Subject: [PATCH 128/154] Updated Adam Styborski's Pauper Cube --- .../cubes/AdamStyborskisPauperCube.java | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/AdamStyborskisPauperCube.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/AdamStyborskisPauperCube.java index 4ef11e8d50..ed73970067 100644 --- a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/AdamStyborskisPauperCube.java +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/AdamStyborskisPauperCube.java @@ -37,15 +37,15 @@ public class AdamStyborskisPauperCube extends DraftCube { public AdamStyborskisPauperCube() { super("Adam Styborkski's Pauper Cube"); // https://docs.google.com/spreadsheets/d/12iQhC4bHqFW7hEWxPBjyC8yBDehFZ0_4DkqzyA8EL3o/edit#gid=0 - // last updated with Hour of Devastation, Iconic Masters and Ixalan 10/18/17 + // last updated with Dominaria 5/1/18 + cubeCards.add(new CardIdentity("Academy Journeymage", "")); cubeCards.add(new CardIdentity("Act of Treason", "")); cubeCards.add(new CardIdentity("Adventuring Gear", "")); + cubeCards.add(new CardIdentity("Aerie Bowmasters", "")); cubeCards.add(new CardIdentity("Aerie Ouphes", "")); cubeCards.add(new CardIdentity("Aether Adept", "")); cubeCards.add(new CardIdentity("Aethersnipe", "")); cubeCards.add(new CardIdentity("Agony Warp", "")); - cubeCards.add(new CardIdentity("Aim High", "")); - cubeCards.add(new CardIdentity("Ambuscade", "")); cubeCards.add(new CardIdentity("Ambush Viper", "")); cubeCards.add(new CardIdentity("Angelic Purge", "")); cubeCards.add(new CardIdentity("Arachnus Web", "")); @@ -61,7 +61,7 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Aven Riftwatcher", "")); cubeCards.add(new CardIdentity("Aven Surveyor", "")); cubeCards.add(new CardIdentity("Azorius Guildgate", "")); - cubeCards.add(new CardIdentity("Baleful Eidolon", "")); + cubeCards.add(new CardIdentity("Baloth Gorger", "")); cubeCards.add(new CardIdentity("Barbed Lightning", "")); cubeCards.add(new CardIdentity("Basking Rootwalla", "")); cubeCards.add(new CardIdentity("Battle Screech", "")); @@ -72,33 +72,31 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Blazing Torch", "")); cubeCards.add(new CardIdentity("Blightning", "")); cubeCards.add(new CardIdentity("Blinding Beam", "")); + cubeCards.add(new CardIdentity("Blink of an Eye", "")); cubeCards.add(new CardIdentity("Bloodfell Caves", "")); cubeCards.add(new CardIdentity("Blossoming Sands", "")); cubeCards.add(new CardIdentity("Bonded Construct", "")); cubeCards.add(new CardIdentity("Bonds of Faith", "")); cubeCards.add(new CardIdentity("Bonesplitter", "")); - cubeCards.add(new CardIdentity("Borderland Marauder", "")); cubeCards.add(new CardIdentity("Boros Guildgate", "")); cubeCards.add(new CardIdentity("Borrowed Grace", "")); cubeCards.add(new CardIdentity("Branching Bolt", "")); - cubeCards.add(new CardIdentity("Brazen Buccaneers", "")); cubeCards.add(new CardIdentity("Brazen Wolves", "")); cubeCards.add(new CardIdentity("Burning-Tree Emissary", "")); cubeCards.add(new CardIdentity("Burst Lightning", "")); cubeCards.add(new CardIdentity("Butcher Ghoul", "")); - cubeCards.add(new CardIdentity("Byway Courier", "")); cubeCards.add(new CardIdentity("Cage of Hands", "")); cubeCards.add(new CardIdentity("Calcite Snapper", "")); cubeCards.add(new CardIdentity("Call of the Conclave", "")); + cubeCards.add(new CardIdentity("Call the Cavalry", "")); cubeCards.add(new CardIdentity("Capsize", "")); cubeCards.add(new CardIdentity("Carnivorous Death-Parrot", "")); cubeCards.add(new CardIdentity("Cartouche of Strength", "")); - cubeCards.add(new CardIdentity("Cathodion", "")); cubeCards.add(new CardIdentity("Cavern Harpy", "")); cubeCards.add(new CardIdentity("Centaur Healer", "")); cubeCards.add(new CardIdentity("Chain Lightning", "")); cubeCards.add(new CardIdentity("Chainer's Edict", "")); - cubeCards.add(new CardIdentity("Chatter of the Squirrel", "")); + cubeCards.add(new CardIdentity("Chivalrous Chevalier", "")); cubeCards.add(new CardIdentity("Cinder Barrens", "")); cubeCards.add(new CardIdentity("Citanul Woodreaders", "")); cubeCards.add(new CardIdentity("Claustrophobia", "")); @@ -108,13 +106,14 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Coalition Honor Guard", "")); cubeCards.add(new CardIdentity("Cogwork Librarian", "")); cubeCards.add(new CardIdentity("Colossal Might", "")); + cubeCards.add(new CardIdentity("Common Iguana", "")); cubeCards.add(new CardIdentity("Compulsive Research", "")); cubeCards.add(new CardIdentity("Compulsory Rest", "")); cubeCards.add(new CardIdentity("Consume Strength", "")); cubeCards.add(new CardIdentity("Corrupted Zendikon", "")); cubeCards.add(new CardIdentity("Counterspell", "")); + cubeCards.add(new CardIdentity("Court Hussar", "")); cubeCards.add(new CardIdentity("Crippling Fatigue", "")); - cubeCards.add(new CardIdentity("Crow of Dark Tidings", "")); cubeCards.add(new CardIdentity("Crypt Rats", "")); cubeCards.add(new CardIdentity("Crystallization", "")); cubeCards.add(new CardIdentity("Cunning Strike", "")); @@ -126,24 +125,23 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Dead Weight", "")); cubeCards.add(new CardIdentity("Deadeye Tormentor", "")); cubeCards.add(new CardIdentity("Death Denied", "")); + cubeCards.add(new CardIdentity("Deathbloom Thallid", "")); cubeCards.add(new CardIdentity("Deep Analysis", "")); cubeCards.add(new CardIdentity("Deprive", "")); cubeCards.add(new CardIdentity("Depths of Desire", "")); cubeCards.add(new CardIdentity("Deputy of Acquittals", "")); cubeCards.add(new CardIdentity("Desert", "")); - cubeCards.add(new CardIdentity("Desperate Sentry", "")); cubeCards.add(new CardIdentity("Devour Flesh", "")); cubeCards.add(new CardIdentity("Diabolic Edict", "")); cubeCards.add(new CardIdentity("Dimir Guildgate", "")); cubeCards.add(new CardIdentity("Dinrova Horror", "")); - cubeCards.add(new CardIdentity("Dire Fleet Hoarder", "")); cubeCards.add(new CardIdentity("Disfigure", "")); cubeCards.add(new CardIdentity("Dismal Backwater", "")); cubeCards.add(new CardIdentity("Disowned Ancestor", "")); cubeCards.add(new CardIdentity("Doom Blade", "")); cubeCards.add(new CardIdentity("Doomed Traveler", "")); - cubeCards.add(new CardIdentity("Drag Under", "")); cubeCards.add(new CardIdentity("Dragon Fodder", "")); + cubeCards.add(new CardIdentity("Dusk Legion Zealot", "")); cubeCards.add(new CardIdentity("Dynacharge", "")); cubeCards.add(new CardIdentity("Eager Construct", "")); cubeCards.add(new CardIdentity("Eldrazi Devastator", "")); @@ -154,12 +152,13 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Emperor Crocodile", "")); cubeCards.add(new CardIdentity("Epic Confrontation", "")); cubeCards.add(new CardIdentity("Errant Ephemeron", "")); - cubeCards.add(new CardIdentity("Esper Cormorants", "")); cubeCards.add(new CardIdentity("Evincar's Justice", "")); cubeCards.add(new CardIdentity("Evolving Wilds", "")); + cubeCards.add(new CardIdentity("Extremely Slow Zombie (C)", "")); cubeCards.add(new CardIdentity("Faceless Butcher", "")); cubeCards.add(new CardIdentity("Faith's Fetters", "")); cubeCards.add(new CardIdentity("Falkenrath Noble", "")); + cubeCards.add(new CardIdentity("Fanatical Firebrand", "")); cubeCards.add(new CardIdentity("Feeling of Dread", "")); cubeCards.add(new CardIdentity("Fervent Cathar", "")); cubeCards.add(new CardIdentity("Firebolt", "")); @@ -170,25 +169,27 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Forsaken Sanctuary", "")); cubeCards.add(new CardIdentity("Fortify", "")); cubeCards.add(new CardIdentity("Foul Orchard", "")); + cubeCards.add(new CardIdentity("Frenzied Goblin", "")); + cubeCards.add(new CardIdentity("Frilled Deathspitter", "")); cubeCards.add(new CardIdentity("Frilled Oculus", "")); cubeCards.add(new CardIdentity("Frostburn Weird", "")); + cubeCards.add(new CardIdentity("Fungal Infection", "")); + cubeCards.add(new CardIdentity("GO TO JAIL", "")); cubeCards.add(new CardIdentity("Gathan Raiders", "")); cubeCards.add(new CardIdentity("Gather the Townsfolk", "")); - cubeCards.add(new CardIdentity("Ghastly Demise", "")); cubeCards.add(new CardIdentity("Ghirapur Gearcrafter", "")); - cubeCards.add(new CardIdentity("Ghitu Slinger", "")); cubeCards.add(new CardIdentity("Giant Growth", "")); cubeCards.add(new CardIdentity("Gideon's Lawkeeper", "")); cubeCards.add(new CardIdentity("Glint-Sleeve Artisan", "")); cubeCards.add(new CardIdentity("Gnawing Zombie", "")); cubeCards.add(new CardIdentity("Goblin Freerunner", "")); cubeCards.add(new CardIdentity("Goblin Heelcutter", "")); + cubeCards.add(new CardIdentity("Goblin Trailblazer", "")); cubeCards.add(new CardIdentity("Gods Willing", "")); cubeCards.add(new CardIdentity("Goldmeadow Harrier", "")); cubeCards.add(new CardIdentity("Golgari Guildgate", "")); cubeCards.add(new CardIdentity("Gravedigger", "")); cubeCards.add(new CardIdentity("Gray Merchant of Asphodel", "")); - cubeCards.add(new CardIdentity("Grazing Whiptail", "")); cubeCards.add(new CardIdentity("Grim Contest", "")); cubeCards.add(new CardIdentity("Grisly Salvage", "")); cubeCards.add(new CardIdentity("Grixis Slavedriver", "")); @@ -204,9 +205,8 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Highland Lake", "")); cubeCards.add(new CardIdentity("Hissing Iguanar", "")); cubeCards.add(new CardIdentity("Hooting Mandrills", "")); - cubeCards.add(new CardIdentity("Humble", "")); + cubeCards.add(new CardIdentity("Hordeling Outburst", "")); cubeCards.add(new CardIdentity("Imperiosaur", "")); - cubeCards.add(new CardIdentity("Incinerate", "")); cubeCards.add(new CardIdentity("Inner-Flame Acolyte", "")); cubeCards.add(new CardIdentity("Insolent Neonate", "")); cubeCards.add(new CardIdentity("Into the Roil", "")); @@ -214,17 +214,20 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Ivy Elemental", "")); cubeCards.add(new CardIdentity("Izzet Chronarch", "")); cubeCards.add(new CardIdentity("Izzet Guildgate", "")); + cubeCards.add(new CardIdentity("Jackal Pup", "")); cubeCards.add(new CardIdentity("Jilt", "")); cubeCards.add(new CardIdentity("Journey to Nowhere", "")); cubeCards.add(new CardIdentity("Jungle Hollow", "")); - cubeCards.add(new CardIdentity("Kabuto Moth", "")); + cubeCards.add(new CardIdentity("Jungleborn Pioneer", "")); cubeCards.add(new CardIdentity("Keldon Marauders", "")); + cubeCards.add(new CardIdentity("Keldon Overseer", "")); + cubeCards.add(new CardIdentity("Keldon Raider", "")); cubeCards.add(new CardIdentity("Kingpin's Pet", "")); + cubeCards.add(new CardIdentity("Kitesail Corsair", "")); cubeCards.add(new CardIdentity("Kor Skyfisher", "")); cubeCards.add(new CardIdentity("Kozilek's Channeler", "")); cubeCards.add(new CardIdentity("Krenko's Command", "")); cubeCards.add(new CardIdentity("Krosan Tusker", "")); - cubeCards.add(new CardIdentity("Kruin Striker", "")); cubeCards.add(new CardIdentity("Lash Out", "")); cubeCards.add(new CardIdentity("Last Gasp", "")); cubeCards.add(new CardIdentity("Leave in the Dust", "")); @@ -232,16 +235,15 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Lifecraft Cavalry", "")); cubeCards.add(new CardIdentity("Lightning Bolt", "")); cubeCards.add(new CardIdentity("Liliana's Specter", "")); - cubeCards.add(new CardIdentity("Lotus Path Djinn", "")); cubeCards.add(new CardIdentity("Loyal Pegasus", "")); cubeCards.add(new CardIdentity("Lurking Automaton", "")); cubeCards.add(new CardIdentity("Magma Jet", "")); cubeCards.add(new CardIdentity("Makeshift Mauler", "")); cubeCards.add(new CardIdentity("Man-o'-War", "")); cubeCards.add(new CardIdentity("Mana Leak", "")); - cubeCards.add(new CardIdentity("Manticore of the Gauntlet", "")); cubeCards.add(new CardIdentity("Mardu Hordechief", "")); cubeCards.add(new CardIdentity("Mardu Skullhunter", "")); + cubeCards.add(new CardIdentity("Martyr of Dusk", "")); cubeCards.add(new CardIdentity("Maul Splicer", "")); cubeCards.add(new CardIdentity("Maze of Ith", "")); cubeCards.add(new CardIdentity("Meandering River", "")); @@ -263,7 +265,6 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Mulldrifter", "")); cubeCards.add(new CardIdentity("Nameless Inversion", "")); cubeCards.add(new CardIdentity("Narcolepsy", "")); - cubeCards.add(new CardIdentity("Necromancer's Assistant", "")); cubeCards.add(new CardIdentity("Nessian Asp", "")); cubeCards.add(new CardIdentity("Nest Robber", "")); cubeCards.add(new CardIdentity("Nezumi Cutthroat", "")); @@ -272,25 +273,22 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Ninja of the Deep Hours", "")); cubeCards.add(new CardIdentity("Oblivion Ring", "")); cubeCards.add(new CardIdentity("Oona's Grace", "")); + cubeCards.add(new CardIdentity("Ordinary Pony", "")); cubeCards.add(new CardIdentity("Orzhov Guildgate", "")); cubeCards.add(new CardIdentity("Otherworldly Journey", "")); + cubeCards.add(new CardIdentity("Overgrown Armasaur", "")); cubeCards.add(new CardIdentity("Pacifism", "")); cubeCards.add(new CardIdentity("Paladin of the Bloodstained", "")); cubeCards.add(new CardIdentity("Peema Outrider", "")); cubeCards.add(new CardIdentity("Penumbra Spider", "")); - cubeCards.add(new CardIdentity("Peregrine Drake", "")); cubeCards.add(new CardIdentity("Perilous Myr", "")); cubeCards.add(new CardIdentity("Pestermite", "")); cubeCards.add(new CardIdentity("Pestilence", "")); - cubeCards.add(new CardIdentity("Phantom Nomad", "")); - cubeCards.add(new CardIdentity("Phantom Tiger", "")); - cubeCards.add(new CardIdentity("Pharika's Chosen", "")); cubeCards.add(new CardIdentity("Phyrexian Rager", "")); cubeCards.add(new CardIdentity("Pillory of the Sleepless", "")); cubeCards.add(new CardIdentity("Pit Fight", "")); cubeCards.add(new CardIdentity("Pit Keeper", "")); cubeCards.add(new CardIdentity("Plated Geopede", "")); - cubeCards.add(new CardIdentity("Plover Knights", "")); cubeCards.add(new CardIdentity("Porcelain Legionnaire", "")); cubeCards.add(new CardIdentity("Pounce", "")); cubeCards.add(new CardIdentity("Predatory Nightstalker", "")); @@ -321,16 +319,18 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Renegade Freighter", "")); cubeCards.add(new CardIdentity("Rift Bolt", "")); cubeCards.add(new CardIdentity("Rishadan Airship", "")); - cubeCards.add(new CardIdentity("Ronin Houndmaster", "")); cubeCards.add(new CardIdentity("Rugged Highlands", "")); cubeCards.add(new CardIdentity("Runed Servitor", "")); cubeCards.add(new CardIdentity("Rushing River", "")); + cubeCards.add(new CardIdentity("Ruthless Ripper", "")); cubeCards.add(new CardIdentity("Sailor of Means", "")); cubeCards.add(new CardIdentity("Sakura-Tribe Elder", "")); cubeCards.add(new CardIdentity("Sandsteppe Outcast", "")); cubeCards.add(new CardIdentity("Sangrite Backlash", "")); + cubeCards.add(new CardIdentity("Saproling Migration", "")); cubeCards.add(new CardIdentity("Sarkhan's Rage", "")); cubeCards.add(new CardIdentity("Savage Punch", "")); + cubeCards.add(new CardIdentity("Savannah Lions", "")); cubeCards.add(new CardIdentity("Scatter the Seeds", "")); cubeCards.add(new CardIdentity("Scion Summoner", "")); cubeCards.add(new CardIdentity("Scion of the Wild", "")); @@ -343,9 +343,10 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Seeker of Insight", "")); cubeCards.add(new CardIdentity("Seeker of the Way", "")); cubeCards.add(new CardIdentity("Selesnya Guildgate", "")); - cubeCards.add(new CardIdentity("Sentinel Spider", "")); + cubeCards.add(new CardIdentity("Selfie Preservation", "")); cubeCards.add(new CardIdentity("Separatist Voidmage", "")); cubeCards.add(new CardIdentity("Seraph of Dawn", "")); + cubeCards.add(new CardIdentity("Sergeant-at-Arms", "")); cubeCards.add(new CardIdentity("Serrated Arrows", "")); cubeCards.add(new CardIdentity("Shaper Parasite", "")); cubeCards.add(new CardIdentity("Sheer Drop", "")); @@ -360,11 +361,12 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Snakeform", "")); cubeCards.add(new CardIdentity("Snap", "")); cubeCards.add(new CardIdentity("Soul Manipulation", "")); + cubeCards.add(new CardIdentity("Soul of the Rapids", "")); cubeCards.add(new CardIdentity("Soulstinger", "")); + cubeCards.add(new CardIdentity("Sparring Construct", "")); cubeCards.add(new CardIdentity("Sphere of the Suns", "")); cubeCards.add(new CardIdentity("Spike Jester", "")); - cubeCards.add(new CardIdentity("Spined Thopter", "")); - cubeCards.add(new CardIdentity("Splatter Thug", "")); + cubeCards.add(new CardIdentity("Squirrel Dealer", "")); cubeCards.add(new CardIdentity("Staggershock", "")); cubeCards.add(new CardIdentity("Star Compass", "")); cubeCards.add(new CardIdentity("Stitched Drake", "")); @@ -372,20 +374,19 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Storm Fleet Pyromancer", "")); cubeCards.add(new CardIdentity("Stormfront Pegasus", "")); cubeCards.add(new CardIdentity("Stormscape Apprentice", "")); - cubeCards.add(new CardIdentity("Strip Mine", "")); + cubeCards.add(new CardIdentity("Strip Min", "")); cubeCards.add(new CardIdentity("Striped Riverwinder", "")); + cubeCards.add(new CardIdentity("Stronghold Confessor", "")); cubeCards.add(new CardIdentity("Submerged Boneyard", "")); cubeCards.add(new CardIdentity("Sultai Scavenger", "")); cubeCards.add(new CardIdentity("Suppression Bonds", "")); cubeCards.add(new CardIdentity("Swiftwater Cliffs", "")); cubeCards.add(new CardIdentity("Sylvan Might", "")); cubeCards.add(new CardIdentity("Sylvok Lifestaff", "")); - cubeCards.add(new CardIdentity("Tah-Crop Elite", "")); cubeCards.add(new CardIdentity("Temporal Isolation", "")); cubeCards.add(new CardIdentity("Tenement Crasher", "")); cubeCards.add(new CardIdentity("Terminate", "")); cubeCards.add(new CardIdentity("Terramorphic Expanse", "")); - cubeCards.add(new CardIdentity("Test of Faith", "")); cubeCards.add(new CardIdentity("Thorn of the Black Rose", "")); cubeCards.add(new CardIdentity("Thornweald Archer", "")); cubeCards.add(new CardIdentity("Thornwood Falls", "")); @@ -393,7 +394,6 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Thraben Inspector", "")); cubeCards.add(new CardIdentity("Thrill-Kill Assassin", "")); cubeCards.add(new CardIdentity("Thundering Giant", "")); - cubeCards.add(new CardIdentity("Thundering Tanadon", "")); cubeCards.add(new CardIdentity("Thunderous Wrath", "")); cubeCards.add(new CardIdentity("Timber Gorge", "")); cubeCards.add(new CardIdentity("Time to Feed", "")); @@ -408,7 +408,6 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Typhoid Rats", "")); cubeCards.add(new CardIdentity("Ulamog's Crusher", "")); cubeCards.add(new CardIdentity("Ulvenwald Captive", "")); - cubeCards.add(new CardIdentity("Undying Rage", "")); cubeCards.add(new CardIdentity("Unearth", "")); cubeCards.add(new CardIdentity("Unmake", "")); cubeCards.add(new CardIdentity("Vampire Interloper", "")); @@ -427,6 +426,7 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Warped Landscape", "")); cubeCards.add(new CardIdentity("Warren Pilferers", "")); cubeCards.add(new CardIdentity("Wasteland Scorpion", "")); + cubeCards.add(new CardIdentity("Waterknot", "")); cubeCards.add(new CardIdentity("Wayfarer's Bauble", "")); cubeCards.add(new CardIdentity("Werebear", "")); cubeCards.add(new CardIdentity("Whitemane Lion", "")); @@ -436,13 +436,13 @@ public class AdamStyborskisPauperCube extends DraftCube { cubeCards.add(new CardIdentity("Wildsize", "")); cubeCards.add(new CardIdentity("Will-Forged Golem", "")); cubeCards.add(new CardIdentity("Wind-Scarred Crag", "")); - cubeCards.add(new CardIdentity("Winds of Rebuke", "")); cubeCards.add(new CardIdentity("Winged Coatl", "")); cubeCards.add(new CardIdentity("Wojek Halberdiers", "")); cubeCards.add(new CardIdentity("Woodland Stream", "")); cubeCards.add(new CardIdentity("Wrecking Ball", "")); cubeCards.add(new CardIdentity("Wretched Gryff", "")); cubeCards.add(new CardIdentity("Yavimaya Elder", "")); + cubeCards.add(new CardIdentity("Yavimaya Sapherd", "")); cubeCards.add(new CardIdentity("Yotian Soldier", "")); } } From a19c257e50a58885b22d8300e92437a8cc55c553 Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Sun, 27 May 2018 01:28:42 +0200 Subject: [PATCH 129/154] XMage 1.4.30V0 --- Mage.Client/pom.xml | 2 +- Mage.Common/pom.xml | 2 +- Mage.Common/src/main/java/mage/utils/MageVersion.java | 4 ++-- Mage.Plugins/Mage.Counter.Plugin/pom.xml | 2 +- Mage.Plugins/pom.xml | 2 +- Mage.Server.Console/pom.xml | 2 +- Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml | 2 +- Mage.Server.Plugins/Mage.Deck.Limited/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml | 2 +- .../Mage.Game.FreeformCommanderFreeForAll/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml | 2 +- .../Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AI/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.Human/pom.xml | 2 +- Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml | 2 +- Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml | 2 +- Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml | 2 +- Mage.Server.Plugins/pom.xml | 2 +- Mage.Server/pom.xml | 2 +- Mage.Sets/pom.xml | 2 +- Mage.Stats/pom.xml | 2 +- Mage.Tests/pom.xml | 2 +- Mage.Updater/pom.xml | 2 +- Mage.Verify/pom.xml | 4 ++-- Mage/pom.xml | 2 +- pom.xml | 4 ++-- 38 files changed, 41 insertions(+), 41 deletions(-) diff --git a/Mage.Client/pom.xml b/Mage.Client/pom.xml index e68ed8ddbc..78daaf6189 100644 --- a/Mage.Client/pom.xml +++ b/Mage.Client/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-root</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <groupId>org.mage</groupId> diff --git a/Mage.Common/pom.xml b/Mage.Common/pom.xml index caf37f8201..1cca97c774 100644 --- a/Mage.Common/pom.xml +++ b/Mage.Common/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-root</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-common</artifactId> diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java index 6995bdef54..c4e991fa49 100644 --- a/Mage.Common/src/main/java/mage/utils/MageVersion.java +++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java @@ -40,8 +40,8 @@ public class MageVersion implements Serializable, Comparable<MageVersion> { */ public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MINOR = 4; - public final static int MAGE_VERSION_PATCH = 29; - public final static String MAGE_VERSION_MINOR_PATCH = "V5"; + public final static int MAGE_VERSION_PATCH = 30; + public final static String MAGE_VERSION_MINOR_PATCH = "V0"; public final static String MAGE_VERSION_INFO = ""; private final int major; diff --git a/Mage.Plugins/Mage.Counter.Plugin/pom.xml b/Mage.Plugins/Mage.Counter.Plugin/pom.xml index 18003b4177..96edf66292 100644 --- a/Mage.Plugins/Mage.Counter.Plugin/pom.xml +++ b/Mage.Plugins/Mage.Counter.Plugin/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-counter-plugin</artifactId> diff --git a/Mage.Plugins/pom.xml b/Mage.Plugins/pom.xml index 4f55088ab0..1bad705990 100644 --- a/Mage.Plugins/pom.xml +++ b/Mage.Plugins/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-root</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-plugins</artifactId> diff --git a/Mage.Server.Console/pom.xml b/Mage.Server.Console/pom.xml index 547a990f08..99eb5e2de2 100644 --- a/Mage.Server.Console/pom.xml +++ b/Mage.Server.Console/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-root</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <groupId>org.mage</groupId> diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml b/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml index 287354462e..5d995e5381 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-deck-constructed</artifactId> diff --git a/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml b/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml index 19b53474c1..78fd34bf6c 100644 --- a/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml +++ b/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-deck-limited</artifactId> diff --git a/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml index 62a989b098..0b1a9a5c22 100644 --- a/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-game-brawlduel</artifactId> diff --git a/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml index f2b97600f8..2d4503d4ea 100644 --- a/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-game-brawlfreeforall</artifactId> diff --git a/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml index cd785f4b49..6f5ed89727 100644 --- a/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-game-canadianhighlanderduel</artifactId> diff --git a/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml index 26a262184c..8058f31e8b 100644 --- a/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-game-commanderduel</artifactId> diff --git a/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml index 19b505125d..c1e880af34 100644 --- a/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-game-commanderfreeforall</artifactId> diff --git a/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml index 045eea0eeb..a594fc43ba 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-game-freeforall</artifactId> diff --git a/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml index 7db3a73717..f470d91e35 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-game-freeformcommanderfreeforall</artifactId> diff --git a/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml index de50441804..dd2baee2fc 100644 --- a/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-game-momirduel</artifactId> diff --git a/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml b/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml index c3e283c5a2..73bd0da03f 100644 --- a/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-game-momirfreeforall</artifactId> diff --git a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml index ce9eea9940..47296e7410 100644 --- a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId> diff --git a/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml index 5ee3091a35..dfab44f5c3 100644 --- a/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-game-tinyleadersduel</artifactId> diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml index 3554cbc99f..a01797f1c0 100644 --- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-game-twoplayerduel</artifactId> diff --git a/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml b/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml index 517e8282fd..835f1aa271 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-player-ai-draftbot</artifactId> diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml b/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml index 69c7bda0bb..b85644b4ee 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-player-ai-ma</artifactId> diff --git a/Mage.Server.Plugins/Mage.Player.AI/pom.xml b/Mage.Server.Plugins/Mage.Player.AI/pom.xml index b9f4cc1dd4..d8b40b7034 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AI/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-player-ai</artifactId> diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml b/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml index 735dc58d65..bacd02de91 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-player-ai-mcts</artifactId> diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml b/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml index 4fb64e9919..a8c6839a98 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-player-aiminimax</artifactId> diff --git a/Mage.Server.Plugins/Mage.Player.Human/pom.xml b/Mage.Server.Plugins/Mage.Player.Human/pom.xml index ef1db9b569..633eae49c0 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.Human/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-player-human</artifactId> diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml index ad331b12cc..c51329ccda 100644 --- a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-tournament-boosterdraft</artifactId> diff --git a/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml b/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml index c72e49e940..9d7a35c808 100644 --- a/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml +++ b/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-tournament-constructed</artifactId> diff --git a/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml b/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml index ff27f07fd6..1ee73bd18e 100644 --- a/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml +++ b/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-server-plugins</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-tournament-sealed</artifactId> diff --git a/Mage.Server.Plugins/pom.xml b/Mage.Server.Plugins/pom.xml index 0cab2b380b..46611f0d33 100644 --- a/Mage.Server.Plugins/pom.xml +++ b/Mage.Server.Plugins/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-root</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-server-plugins</artifactId> diff --git a/Mage.Server/pom.xml b/Mage.Server/pom.xml index 375392ae29..3f11bd456b 100644 --- a/Mage.Server/pom.xml +++ b/Mage.Server/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-root</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-server</artifactId> diff --git a/Mage.Sets/pom.xml b/Mage.Sets/pom.xml index 1410214a16..8beaf1af44 100644 --- a/Mage.Sets/pom.xml +++ b/Mage.Sets/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-root</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <groupId>org.mage</groupId> diff --git a/Mage.Stats/pom.xml b/Mage.Stats/pom.xml index 818eb3bdd3..2d0403d9c2 100644 --- a/Mage.Stats/pom.xml +++ b/Mage.Stats/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-root</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <groupId>org.mage</groupId> diff --git a/Mage.Tests/pom.xml b/Mage.Tests/pom.xml index e681102f7e..5ee48c61bb 100644 --- a/Mage.Tests/pom.xml +++ b/Mage.Tests/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-root</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-tests</artifactId> diff --git a/Mage.Updater/pom.xml b/Mage.Updater/pom.xml index 33fb497996..953864d647 100644 --- a/Mage.Updater/pom.xml +++ b/Mage.Updater/pom.xml @@ -5,7 +5,7 @@ <parent> <artifactId>mage-root</artifactId> <groupId>org.mage</groupId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/Mage.Verify/pom.xml b/Mage.Verify/pom.xml index c0cc0aae2b..2b5f9eeabd 100644 --- a/Mage.Verify/pom.xml +++ b/Mage.Verify/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-root</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage-verify</artifactId> @@ -49,7 +49,7 @@ <dependency> <groupId>org.mage</groupId> <artifactId>mage-client</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </dependency> </dependencies> diff --git a/Mage/pom.xml b/Mage/pom.xml index c17c46b9bb..55d268b455 100644 --- a/Mage/pom.xml +++ b/Mage/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>org.mage</groupId> <artifactId>mage-root</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> </parent> <artifactId>mage</artifactId> diff --git a/pom.xml b/pom.xml index 26f37804ca..75753c635b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ <groupId>org.mage</groupId> <artifactId>mage-root</artifactId> - <version>1.4.29</version> + <version>1.4.30</version> <packaging>pom</packaging> <name>Mage Root</name> <description>Mage Root POM</description> @@ -84,7 +84,7 @@ </repositories> <properties> - <mage-version>1.4.29</mage-version> + <mage-version>1.4.30</mage-version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> From 0c4784ab6c0962032b1363a49bcf7c56be1a4e69 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sat, 26 May 2018 23:15:58 -0400 Subject: [PATCH 130/154] Implemented Grothama, All-Devouring --- .../mage/cards/g/GrothamaAllDevouring.java | 244 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 25 +- 2 files changed, 257 insertions(+), 12 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/g/GrothamaAllDevouring.java diff --git a/Mage.Sets/src/mage/cards/g/GrothamaAllDevouring.java b/Mage.Sets/src/mage/cards/g/GrothamaAllDevouring.java new file mode 100644 index 0000000000..98ae4770fe --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GrothamaAllDevouring.java @@ -0,0 +1,244 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.WatcherScope; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.watchers.Watcher; + +/** + * + * @author TheElk801 + */ +public class GrothamaAllDevouring extends CardImpl { + + public GrothamaAllDevouring(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.WURM); + this.power = new MageInt(10); + this.toughness = new MageInt(8); + + // Other creatures have "Whenever this creature attacks, you may have it fight Grothama, All-Devouring." + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GrothamaAllDevouringGainAbilityEffect())); + + // When Grothama leaves the battlefield, each player draws cards equal to the amount of damage dealt to Grothama this turn by sources they controlled. + this.addAbility(new LeavesBattlefieldTriggeredAbility(new GrothamaAllDevouringDrawCardsEffect(), false), new GrothamaAllDevouringWatcher()); + } + + public GrothamaAllDevouring(final GrothamaAllDevouring card) { + super(card); + } + + @Override + public GrothamaAllDevouring copy() { + return new GrothamaAllDevouring(this); + } +} + +class GrothamaAllDevouringGainAbilityEffect extends GainAbilityAllEffect { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other creatures"); + + static { + filter.add(new AnotherPredicate()); + } + + GrothamaAllDevouringGainAbilityEffect() { + super(new AttacksTriggeredAbility( + new GrothamaAllDevouringFightEffect(null, null), true + ), Duration.WhileOnBattlefield, filter); + this.staticText = "Other creatures have \"Whenever this creature attacks, you may have it fight {this}.\""; + } + + GrothamaAllDevouringGainAbilityEffect(final GrothamaAllDevouringGainAbilityEffect effect) { + super(effect); + } + + @Override + public GrothamaAllDevouringGainAbilityEffect copy() { + return new GrothamaAllDevouringGainAbilityEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + return false; + } + ability = new AttacksTriggeredAbility(new GrothamaAllDevouringFightEffect(permanent.getId(), permanent.getName()), true); + return super.apply(game, source); + } +} + +class GrothamaAllDevouringFightEffect extends OneShotEffect { + + private final UUID fightId; + + GrothamaAllDevouringFightEffect(UUID fightId, String fightName) { + super(Outcome.Benefit); + this.fightId = fightId; + this.staticText = "you may have it fight " + fightName; + } + + GrothamaAllDevouringFightEffect(final GrothamaAllDevouringFightEffect effect) { + super(effect); + this.fightId = effect.fightId; + } + + @Override + public GrothamaAllDevouringFightEffect copy() { + return new GrothamaAllDevouringFightEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent grothama = game.getPermanent(fightId); + Permanent creature = game.getPermanent(source.getSourceId()); + if (grothama == null || creature == null) { + return false; + } + return grothama.fight(creature, source, game); + } +} + +class GrothamaAllDevouringDrawCardsEffect extends OneShotEffect { + + GrothamaAllDevouringDrawCardsEffect() { + super(Outcome.Benefit); + this.staticText = "each player draws cards equal to the amount of " + + "damage dealt to {this} this turn by sources they controlled."; + } + + GrothamaAllDevouringDrawCardsEffect(final GrothamaAllDevouringDrawCardsEffect effect) { + super(effect); + } + + @Override + public GrothamaAllDevouringDrawCardsEffect copy() { + return new GrothamaAllDevouringDrawCardsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + GrothamaAllDevouringWatcher watcher = (GrothamaAllDevouringWatcher) game.getState().getWatchers().get(GrothamaAllDevouringWatcher.class.getSimpleName()); + if (watcher == null) { + return false; + } + Map<UUID, Integer> damageMap = watcher.getDamageMap(new MageObjectReference(source.getSourceId(), source.getSourceObjectZoneChangeCounter() - 1, game)); + for (UUID playerId : game.getPlayerList()) { + Player player = game.getPlayer(playerId); + if (player != null) { + int toDraw = damageMap.getOrDefault(player.getId(), 0); + if (toDraw > 0) { + player.drawCards(toDraw, game); + } + } + } + return true; + } +} + +class GrothamaAllDevouringWatcher extends Watcher { + + Map<MageObjectReference, Map<UUID, Integer>> damageMap = new HashMap<>(); + + GrothamaAllDevouringWatcher() { + super(GrothamaAllDevouringWatcher.class.getSimpleName(), WatcherScope.GAME); + } + + GrothamaAllDevouringWatcher(final GrothamaAllDevouringWatcher watcher) { + super(watcher); + for (MageObjectReference mor : watcher.damageMap.keySet()) { + this.damageMap.putIfAbsent(mor, new HashMap<>()); + for (UUID key : watcher.damageMap.get(mor).keySet()) { + this.damageMap.get(mor).putIfAbsent(key, 0); + this.damageMap.get(mor).compute(key, (k, damage) -> damage + watcher.damageMap.get(mor).get(key)); + } + } + } + + @Override + public GrothamaAllDevouringWatcher copy() { + return new GrothamaAllDevouringWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() != GameEvent.EventType.DAMAGED_CREATURE) { + return; + } + Permanent damaged = game.getPermanentOrLKIBattlefield(event.getTargetId()); + if (damaged == null) { + return; + } + MageObjectReference mor = new MageObjectReference(damaged, game); + damageMap.putIfAbsent(mor, new HashMap<>()); + damageMap.get(mor).putIfAbsent(event.getPlayerId(), 0); + damageMap.get(mor).compute(event.getPlayerId(), (k, damage) -> damage + event.getAmount()); + } + + @Override + public void reset() { + super.reset(); + damageMap.clear(); + } + + public Map<UUID, Integer> getDamageMap(MageObjectReference mor) { + return damageMap.getOrDefault(mor, new HashMap<>()); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 8f2d6ee3db..56d7d58ece 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -59,13 +59,13 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Angelic Gift", 88, Rarity.COMMON, mage.cards.a.AngelicGift.class)); cards.add(new SetCardInfo("Apocalypse Hydra", 217, Rarity.RARE, mage.cards.a.ApocalypseHydra.class)); cards.add(new SetCardInfo("Archfiend of Despair", 44, Rarity.MYTHIC, mage.cards.a.ArchfiendOfDespair.class)); - cards.add(new SetCardInfo("Archon of Valor's Reach", 74, Rarity.RARE, mage.cards.a.ArchonOfValorsReach.class)); + cards.add(new SetCardInfo("Archon of Valor's Reach", 74, Rarity.RARE, mage.cards.a.ArchonOfValorsReach.class)); cards.add(new SetCardInfo("Arena Rector", 23, Rarity.MYTHIC, mage.cards.a.ArenaRector.class)); cards.add(new SetCardInfo("Assassin's Strike", 138, Rarity.UNCOMMON, mage.cards.a.AssassinsStrike.class)); cards.add(new SetCardInfo("Assassinate", 139, Rarity.COMMON, mage.cards.a.Assassinate.class)); cards.add(new SetCardInfo("Auger Spree", 218, Rarity.COMMON, mage.cards.a.AugerSpree.class)); - cards.add(new SetCardInfo("Aurora Champion", 24, Rarity.COMMON, mage.cards.a.AuroraChampion.class)); - cards.add(new SetCardInfo("Azra Bladeseeker", 55, Rarity.COMMON, mage.cards.a.AzraBladeseeker.class)); + cards.add(new SetCardInfo("Aurora Champion", 24, Rarity.COMMON, mage.cards.a.AuroraChampion.class)); + cards.add(new SetCardInfo("Azra Bladeseeker", 55, Rarity.COMMON, mage.cards.a.AzraBladeseeker.class)); cards.add(new SetCardInfo("Azra Oddsmaker", 75, Rarity.UNCOMMON, mage.cards.a.AzraOddsmaker.class)); cards.add(new SetCardInfo("Bathe in Dragonfire", 164, Rarity.COMMON, mage.cards.b.BatheInDragonfire.class)); cards.add(new SetCardInfo("Battle Mastery", 89, Rarity.UNCOMMON, mage.cards.b.BattleMastery.class)); @@ -83,8 +83,8 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); cards.add(new SetCardInfo("Brightling", 25, Rarity.MYTHIC, mage.cards.b.Brightling.class)); - cards.add(new SetCardInfo("Bring Down", 26, Rarity.UNCOMMON, mage.cards.b.BringDown.class)); - cards.add(new SetCardInfo("Bull-Rush Bruiser", 57, Rarity.COMMON, mage.cards.b.BullRushBruiser.class)); + cards.add(new SetCardInfo("Bring Down", 26, Rarity.UNCOMMON, mage.cards.b.BringDown.class)); + cards.add(new SetCardInfo("Bull-Rush Bruiser", 57, Rarity.COMMON, mage.cards.b.BullRushBruiser.class)); cards.add(new SetCardInfo("Call to Heel", 114, Rarity.COMMON, mage.cards.c.CallToHeel.class)); cards.add(new SetCardInfo("Canopy Spider", 191, Rarity.COMMON, mage.cards.c.CanopySpider.class)); cards.add(new SetCardInfo("Centaur Healer", 219, Rarity.COMMON, mage.cards.c.CentaurHealer.class)); @@ -102,7 +102,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Culling Dais", 233, Rarity.UNCOMMON, mage.cards.c.CullingDais.class)); cards.add(new SetCardInfo("Daggerback Basilisk", 194, Rarity.COMMON, mage.cards.d.DaggerbackBasilisk.class)); cards.add(new SetCardInfo("Daggerdrome Imp", 140, Rarity.COMMON, mage.cards.d.DaggerdromeImp.class)); - cards.add(new SetCardInfo("Decorated Champion", 69, Rarity.UNCOMMON, mage.cards.d.DecoratedChampion.class)); + cards.add(new SetCardInfo("Decorated Champion", 69, Rarity.UNCOMMON, mage.cards.d.DecoratedChampion.class)); cards.add(new SetCardInfo("Diabolic Intent", 141, Rarity.RARE, mage.cards.d.DiabolicIntent.class)); cards.add(new SetCardInfo("Dinrova Horror", 220, Rarity.UNCOMMON, mage.cards.d.DinrovaHorror.class)); cards.add(new SetCardInfo("Doomed Dissenter", 142, Rarity.COMMON, mage.cards.d.DoomedDissenter.class)); @@ -139,6 +139,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Gold-Forged Sentinel", 236, Rarity.UNCOMMON, mage.cards.g.GoldForgedSentinel.class)); cards.add(new SetCardInfo("Greater Good", 201, Rarity.RARE, mage.cards.g.GreaterGood.class)); cards.add(new SetCardInfo("Grotesque Mutation", 145, Rarity.COMMON, mage.cards.g.GrotesqueMutation.class)); + cards.add(new SetCardInfo("Grothama, All-Devouring", 71, Rarity.MYTHIC, mage.cards.g.GrothamaAllDevouring.class)); cards.add(new SetCardInfo("Gwafa Hazid, Profiteer", 223, Rarity.RARE, mage.cards.g.GwafaHazidProfiteer.class)); cards.add(new SetCardInfo("Hand of Silumgar", 146, Rarity.COMMON, mage.cards.h.HandOfSilumgar.class)); cards.add(new SetCardInfo("Hexplate Golem", 237, Rarity.COMMON, mage.cards.h.HexplateGolem.class)); @@ -173,7 +174,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Lore Weaver", 22, Rarity.UNCOMMON, mage.cards.l.LoreWeaver.class)); cards.add(new SetCardInfo("Loyal Pegasus", 97, Rarity.UNCOMMON, mage.cards.l.LoyalPegasus.class)); cards.add(new SetCardInfo("Luxury Suite", 82, Rarity.RARE, mage.cards.l.LuxurySuite.class)); - cards.add(new SetCardInfo("Magma Hellion", 61, Rarity.COMMON, mage.cards.m.MagmaHellion.class)); + cards.add(new SetCardInfo("Magma Hellion", 61, Rarity.COMMON, mage.cards.m.MagmaHellion.class)); cards.add(new SetCardInfo("Magmatic Force", 181, Rarity.RARE, mage.cards.m.MagmaticForce.class)); cards.add(new SetCardInfo("Magus of the Candelabra", 206, Rarity.RARE, mage.cards.m.MagusOfTheCandelabra.class)); cards.add(new SetCardInfo("Mangara of Corondor", 98, Rarity.RARE, mage.cards.m.MangaraOfCorondor.class)); @@ -189,7 +190,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Najeela, the Blade-Blossom", 62, Rarity.MYTHIC, mage.cards.n.NajeelaTheBladeBlossom.class)); cards.add(new SetCardInfo("Negate", 123, Rarity.COMMON, mage.cards.n.Negate.class)); cards.add(new SetCardInfo("Night Market Guard", 242, Rarity.COMMON, mage.cards.n.NightMarketGuard.class)); - cards.add(new SetCardInfo("Nimbus Champion", 37, Rarity.UNCOMMON, mage.cards.n.NimbusChampion.class)); + cards.add(new SetCardInfo("Nimbus Champion", 37, Rarity.UNCOMMON, mage.cards.n.NimbusChampion.class)); cards.add(new SetCardInfo("Nimbus of the Isles", 124, Rarity.COMMON, mage.cards.n.NimbusOfTheIsles.class)); cards.add(new SetCardInfo("Nirkana Revenant", 150, Rarity.MYTHIC, mage.cards.n.NirkanaRevenant.class)); cards.add(new SetCardInfo("Noosegraf Mob", 151, Rarity.RARE, mage.cards.n.NoosegrafMob.class)); @@ -258,7 +259,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Spellseeker", 41, Rarity.RARE, mage.cards.s.Spellseeker.class)); cards.add(new SetCardInfo("Spellweaver Duo", 42, Rarity.COMMON, mage.cards.s.SpellweaverDuo.class)); cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); - cards.add(new SetCardInfo("Stadium Vendors", 63, Rarity.COMMON, mage.cards.s.StadiumVendors.class)); + cards.add(new SetCardInfo("Stadium Vendors", 63, Rarity.COMMON, mage.cards.s.StadiumVendors.class)); cards.add(new SetCardInfo("Steppe Glider", 109, Rarity.UNCOMMON, mage.cards.s.SteppeGlider.class)); cards.add(new SetCardInfo("Stone Golem", 247, Rarity.COMMON, mage.cards.s.StoneGolem.class)); cards.add(new SetCardInfo("Stunning Reversal", 51, Rarity.MYTHIC, mage.cards.s.StunningReversal.class)); @@ -275,7 +276,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); cards.add(new SetCardInfo("Thunder Strike", 185, Rarity.COMMON, mage.cards.t.ThunderStrike.class)); cards.add(new SetCardInfo("Tidespout Tyrant", 134, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); - cards.add(new SetCardInfo("Together Forever", 32, Rarity.RARE, mage.cards.t.TogetherForever.class)); + cards.add(new SetCardInfo("Together Forever", 32, Rarity.RARE, mage.cards.t.TogetherForever.class)); cards.add(new SetCardInfo("Toothy, Imaginary Friend", 12, Rarity.RARE, mage.cards.t.ToothyImaginaryFriend.class)); cards.add(new SetCardInfo("Totally Lost", 135, Rarity.COMMON, mage.cards.t.TotallyLost.class)); cards.add(new SetCardInfo("True-Name Nemesis", 136, Rarity.MYTHIC, mage.cards.t.TrueNameNemesis.class)); @@ -283,7 +284,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Tyrant's Machine", 248, Rarity.COMMON, mage.cards.t.TyrantsMachine.class)); cards.add(new SetCardInfo("Unflinching Courage", 230, Rarity.UNCOMMON, mage.cards.u.UnflinchingCourage.class)); cards.add(new SetCardInfo("Urborg Drake", 231, Rarity.COMMON, mage.cards.u.UrborgDrake.class)); - cards.add(new SetCardInfo("Vampire Charmseeker", 78, Rarity.UNCOMMON, mage.cards.v.VampireCharmseeker.class)); + cards.add(new SetCardInfo("Vampire Charmseeker", 78, Rarity.UNCOMMON, mage.cards.v.VampireCharmseeker.class)); cards.add(new SetCardInfo("Veteran Explorer", 214, Rarity.UNCOMMON, mage.cards.v.VeteranExplorer.class)); cards.add(new SetCardInfo("Vigor", 215, Rarity.RARE, mage.cards.v.Vigor.class)); cards.add(new SetCardInfo("Virtus the Veiled", 7, Rarity.RARE, mage.cards.v.VirtusTheVeiled.class)); @@ -293,7 +294,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Will Kenrith", 1, Rarity.MYTHIC, mage.cards.w.WillKenrith.class)); cards.add(new SetCardInfo("Wrap in Flames", 188, Rarity.COMMON, mage.cards.w.WrapInFlames.class)); cards.add(new SetCardInfo("Yotian Soldier", 249, Rarity.COMMON, mage.cards.y.YotianSoldier.class)); - cards.add(new SetCardInfo("Zndrsplt's Judgment", 43, Rarity.RARE, mage.cards.z.ZndrspltsJudgment.class)); + cards.add(new SetCardInfo("Zndrsplt's Judgment", 43, Rarity.RARE, mage.cards.z.ZndrspltsJudgment.class)); cards.add(new SetCardInfo("Zndrsplt, Eye of Wisdom", 5, Rarity.RARE, mage.cards.z.ZndrspltEyeOfWisdom.class)); } } From fc4e51e355dcfd4dc647f4e835c72bbfa07af70a Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Sun, 27 May 2018 11:01:33 +0200 Subject: [PATCH 131/154] * Corrosive Ooze - Fixed a bug game breaking bug if it is in the deck. --- Mage.Sets/src/mage/cards/c/CorrosiveOoze.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java b/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java index ef43f7e358..7331702320 100644 --- a/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java +++ b/Mage.Sets/src/mage/cards/c/CorrosiveOoze.java @@ -199,9 +199,10 @@ class CorrosiveOozeCombatWatcher extends Watcher { } } } - if (game.getTurn().getPhaseType().equals(TurnPhase.COMBAT)) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { - if (((ZoneChangeEvent) event).getFromZone().equals(Zone.BATTLEFIELD)) { + + if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { + if (((ZoneChangeEvent) event).getFromZone().equals(Zone.BATTLEFIELD)) { + if (game.getTurn() != null && TurnPhase.COMBAT.equals(game.getTurn().getPhaseType())) { // Check if a previous blocked or blocked by creatures is leaving the battlefield for (Map.Entry<MageObjectReference, HashSet<MageObjectReference>> entry : oozeBlocksOrBlocked.entrySet()) { for (MageObjectReference mor : entry.getValue()) { From 73559fbdb5a8fd592232438c8bfdb444490cc21d Mon Sep 17 00:00:00 2001 From: L_J <Zzooouhh@users.noreply.github.com> Date: Sun, 27 May 2018 11:57:29 +0000 Subject: [PATCH 132/154] Implemented Thrilling Encore --- .../src/mage/cards/t/ThrillingEncore.java | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/ThrillingEncore.java diff --git a/Mage.Sets/src/mage/cards/t/ThrillingEncore.java b/Mage.Sets/src/mage/cards/t/ThrillingEncore.java new file mode 100644 index 0000000000..b6435f451b --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThrillingEncore.java @@ -0,0 +1,102 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.target.targetpointer.FixedTarget; +import mage.watchers.common.CardsPutIntoGraveyardWatcher; + +/** + * + * @author L_J + */ +public class ThrillingEncore extends CardImpl { + + public ThrillingEncore(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{B}"); + + // Put onto the battlefield under your control all creature cards in all graveyards that were put there from the battlefield this turn. + this.getSpellAbility().addEffect(new ThrillingEncoreEffect()); + this.getSpellAbility().addWatcher(new CardsPutIntoGraveyardWatcher()); + } + + public ThrillingEncore(final ThrillingEncore card) { + super(card); + } + + @Override + public ThrillingEncore copy() { + return new ThrillingEncore(this); + } +} + +class ThrillingEncoreEffect extends OneShotEffect { + + public ThrillingEncoreEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "Put onto the battlefield under your control all creature cards in all graveyards that were put there from the battlefield this turn"; + } + + public ThrillingEncoreEffect(final ThrillingEncoreEffect effect) { + super(effect); + } + + @Override + public ThrillingEncoreEffect copy() { + return new ThrillingEncoreEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + CardsPutIntoGraveyardWatcher watcher = (CardsPutIntoGraveyardWatcher) game.getState().getWatchers().get(CardsPutIntoGraveyardWatcher.class.getSimpleName()); + if (watcher != null) { + for (MageObjectReference mor : watcher.getCardsPutToGraveyardFromBattlefield()) { + if (game.getState().getZoneChangeCounter(mor.getSourceId()) == mor.getZoneChangeCounter()) { + Card card = mor.getCard(game); + if (card != null && card.isCreature()) { + Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect(); + effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); + effect.apply(game, source); + } + } + } + } + return true; + } +} From 21578709bc272a915a53afa47106608a07ae28c5 Mon Sep 17 00:00:00 2001 From: L_J <Zzooouhh@users.noreply.github.com> Date: Sun, 27 May 2018 11:58:50 +0000 Subject: [PATCH 133/154] Implemented Thrilling Encore --- Mage.Sets/src/mage/sets/Battlebond.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 56d7d58ece..5c735e6505 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -274,6 +274,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Tenacious Dead", 163, Rarity.UNCOMMON, mage.cards.t.TenaciousDead.class)); cards.add(new SetCardInfo("The Crowd Goes Wild", 68, Rarity.UNCOMMON, mage.cards.t.TheCrowdGoesWild.class)); cards.add(new SetCardInfo("Thrasher Brute", 52, Rarity.UNCOMMON, mage.cards.t.ThrasherBrute.class)); + cards.add(new SetCardInfo("Thrilling Encore", 53, Rarity.RARE, mage.cards.t.ThrillingEncore.class)); cards.add(new SetCardInfo("Thunder Strike", 185, Rarity.COMMON, mage.cards.t.ThunderStrike.class)); cards.add(new SetCardInfo("Tidespout Tyrant", 134, Rarity.RARE, mage.cards.t.TidespoutTyrant.class)); cards.add(new SetCardInfo("Together Forever", 32, Rarity.RARE, mage.cards.t.TogetherForever.class)); From c7f57d8c68221730d940d0fa17f63e30c1c239ec Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sun, 27 May 2018 10:40:57 -0400 Subject: [PATCH 134/154] Fixed implementation of team-controlled effects --- .../src/mage/cards/a/AuroraChampion.java | 8 +--- .../src/mage/cards/b/BullRushBruiser.java | 8 +--- .../src/mage/cards/d/DecoratedChampion.java | 8 +--- .../src/mage/cards/d/DwarvenLightsmith.java | 11 +---- .../src/mage/cards/k/KhorvathBrightflame.java | 11 +---- .../src/mage/cards/n/NimbusChampion.java | 11 +---- .../src/mage/cards/r/RushbladeCommander.java | 15 +------ Mage.Sets/src/mage/cards/s/SickleDancer.java | 8 +--- .../src/mage/cards/s/SylviaBrightspear.java | 11 +---- Mage.Sets/src/mage/cards/t/ThrasherBrute.java | 8 +--- .../mage/abilities/ActivatedAbilityImpl.java | 7 +++- .../java/mage/constants/TargetController.java | 2 +- .../common/FilterTeamCreaturePermanent.java | 41 ++++++++++++++++++ .../filter/common/FilterTeamPermanent.java | 42 +++++++++++++++++++ .../permanent/ControllerPredicate.java | 9 +++- 15 files changed, 116 insertions(+), 84 deletions(-) create mode 100644 Mage/src/main/java/mage/filter/common/FilterTeamCreaturePermanent.java create mode 100644 Mage/src/main/java/mage/filter/common/FilterTeamPermanent.java diff --git a/Mage.Sets/src/mage/cards/a/AuroraChampion.java b/Mage.Sets/src/mage/cards/a/AuroraChampion.java index cef9b795ba..4ff38a4637 100644 --- a/Mage.Sets/src/mage/cards/a/AuroraChampion.java +++ b/Mage.Sets/src/mage/cards/a/AuroraChampion.java @@ -38,11 +38,8 @@ import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.TargetController; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; +import mage.filter.common.FilterTeamPermanent; import mage.filter.predicate.permanent.AnotherPredicate; -import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.common.TargetCreaturePermanent; /** @@ -51,11 +48,10 @@ import mage.target.common.TargetCreaturePermanent; */ public class AuroraChampion extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent(SubType.WARRIOR, "another Warrior"); + private static final FilterTeamPermanent filter = new FilterTeamPermanent(SubType.WARRIOR, "another Warrior"); static { filter.add(new AnotherPredicate()); - filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); } public AuroraChampion(UUID ownerId, CardSetInfo setInfo) { diff --git a/Mage.Sets/src/mage/cards/b/BullRushBruiser.java b/Mage.Sets/src/mage/cards/b/BullRushBruiser.java index 0c0a3cb19e..7645a1a1d2 100644 --- a/Mage.Sets/src/mage/cards/b/BullRushBruiser.java +++ b/Mage.Sets/src/mage/cards/b/BullRushBruiser.java @@ -38,11 +38,8 @@ import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.TargetController; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; +import mage.filter.common.FilterTeamPermanent; import mage.filter.predicate.permanent.AnotherPredicate; -import mage.filter.predicate.permanent.ControllerPredicate; /** * @@ -50,11 +47,10 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class BullRushBruiser extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent(SubType.WARRIOR, "another Warrior"); + private static final FilterTeamPermanent filter = new FilterTeamPermanent(SubType.WARRIOR, "another Warrior"); static { filter.add(new AnotherPredicate()); - filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); } public BullRushBruiser(UUID ownerId, CardSetInfo setInfo) { diff --git a/Mage.Sets/src/mage/cards/d/DecoratedChampion.java b/Mage.Sets/src/mage/cards/d/DecoratedChampion.java index 13e38c2af8..603ec8f710 100644 --- a/Mage.Sets/src/mage/cards/d/DecoratedChampion.java +++ b/Mage.Sets/src/mage/cards/d/DecoratedChampion.java @@ -35,12 +35,9 @@ import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.TargetController; import mage.counters.CounterType; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; +import mage.filter.common.FilterTeamPermanent; import mage.filter.predicate.permanent.AnotherPredicate; -import mage.filter.predicate.permanent.ControllerPredicate; /** * @@ -48,11 +45,10 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class DecoratedChampion extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent(SubType.WARRIOR, "another Warrior"); + private static final FilterTeamPermanent filter = new FilterTeamPermanent(SubType.WARRIOR, "another Warrior"); static { filter.add(new AnotherPredicate()); - filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); } public DecoratedChampion(UUID ownerId, CardSetInfo setInfo) { diff --git a/Mage.Sets/src/mage/cards/d/DwarvenLightsmith.java b/Mage.Sets/src/mage/cards/d/DwarvenLightsmith.java index 49b5f81b0d..9738176fa4 100644 --- a/Mage.Sets/src/mage/cards/d/DwarvenLightsmith.java +++ b/Mage.Sets/src/mage/cards/d/DwarvenLightsmith.java @@ -37,10 +37,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.TargetController; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.common.FilterTeamCreaturePermanent; /** * @@ -48,11 +45,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class DwarvenLightsmith extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures your team controls"); - - static { - filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); - } + private static final FilterTeamCreaturePermanent filter = new FilterTeamCreaturePermanent("creatures your team controls"); public DwarvenLightsmith(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); diff --git a/Mage.Sets/src/mage/cards/k/KhorvathBrightflame.java b/Mage.Sets/src/mage/cards/k/KhorvathBrightflame.java index 62fba0471d..e5c8825752 100644 --- a/Mage.Sets/src/mage/cards/k/KhorvathBrightflame.java +++ b/Mage.Sets/src/mage/cards/k/KhorvathBrightflame.java @@ -41,11 +41,8 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.TargetController; import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.common.FilterTeamPermanent; /** * @@ -53,11 +50,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class KhorvathBrightflame extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent(SubType.KNIGHT, "Knights your team controls"); - - static { - filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); - } + private static final FilterTeamPermanent filter = new FilterTeamPermanent(SubType.KNIGHT, "Knights your team controls"); public KhorvathBrightflame(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}"); diff --git a/Mage.Sets/src/mage/cards/n/NimbusChampion.java b/Mage.Sets/src/mage/cards/n/NimbusChampion.java index 0e7f04dd2b..7271074f26 100644 --- a/Mage.Sets/src/mage/cards/n/NimbusChampion.java +++ b/Mage.Sets/src/mage/cards/n/NimbusChampion.java @@ -40,10 +40,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.TargetController; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.common.FilterTeamPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; @@ -83,11 +80,7 @@ public class NimbusChampion extends CardImpl { class NimbusChampionEffect extends OneShotEffect { - private static final FilterPermanent filter = new FilterPermanent(SubType.WARRIOR, "Warriors your team controls"); - - static { - filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); - } + private static final FilterTeamPermanent filter = new FilterTeamPermanent(SubType.WARRIOR, "Warriors your team controls"); NimbusChampionEffect() { super(Outcome.Benefit); diff --git a/Mage.Sets/src/mage/cards/r/RushbladeCommander.java b/Mage.Sets/src/mage/cards/r/RushbladeCommander.java index 1e9388bc9d..ecb45b5b26 100644 --- a/Mage.Sets/src/mage/cards/r/RushbladeCommander.java +++ b/Mage.Sets/src/mage/cards/r/RushbladeCommander.java @@ -37,12 +37,8 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.TargetController; import mage.constants.Zone; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.SubtypePredicate; -import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.common.FilterTeamPermanent; /** * @@ -50,14 +46,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class RushbladeCommander extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Warrior creatures your team controls"); - - static { - filter.add(Predicates.not( - new ControllerPredicate(TargetController.OPPONENT) - )); - filter.add(new SubtypePredicate(SubType.WARRIOR)); - } + private static final FilterTeamPermanent filter = new FilterTeamPermanent(SubType.WARRIOR, "Warriors your team controls"); public RushbladeCommander(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{R}"); diff --git a/Mage.Sets/src/mage/cards/s/SickleDancer.java b/Mage.Sets/src/mage/cards/s/SickleDancer.java index 86690e99b6..062c963613 100644 --- a/Mage.Sets/src/mage/cards/s/SickleDancer.java +++ b/Mage.Sets/src/mage/cards/s/SickleDancer.java @@ -38,11 +38,8 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.TargetController; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; +import mage.filter.common.FilterTeamPermanent; import mage.filter.predicate.permanent.AnotherPredicate; -import mage.filter.predicate.permanent.ControllerPredicate; /** * @@ -50,10 +47,9 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class SickleDancer extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.WARRIOR, "Warrior creature"); + private static final FilterTeamPermanent filter = new FilterTeamPermanent(SubType.WARRIOR, "Warrior creature"); static { - filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); filter.add(new AnotherPredicate()); } diff --git a/Mage.Sets/src/mage/cards/s/SylviaBrightspear.java b/Mage.Sets/src/mage/cards/s/SylviaBrightspear.java index 6a456de6b6..d62688412a 100644 --- a/Mage.Sets/src/mage/cards/s/SylviaBrightspear.java +++ b/Mage.Sets/src/mage/cards/s/SylviaBrightspear.java @@ -39,11 +39,8 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.TargetController; import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.common.FilterTeamPermanent; /** * @@ -51,11 +48,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class SylviaBrightspear extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent(SubType.DRAGON, "Dragons your team controls"); - - static { - filter.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); - } + private static final FilterTeamPermanent filter = new FilterTeamPermanent(SubType.DRAGON, "Dragons your team controls"); public SylviaBrightspear(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); diff --git a/Mage.Sets/src/mage/cards/t/ThrasherBrute.java b/Mage.Sets/src/mage/cards/t/ThrasherBrute.java index 12383777bc..07c628b6a7 100644 --- a/Mage.Sets/src/mage/cards/t/ThrasherBrute.java +++ b/Mage.Sets/src/mage/cards/t/ThrasherBrute.java @@ -37,11 +37,8 @@ import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.TargetController; import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.common.FilterTeamPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetOpponent; @@ -86,11 +83,10 @@ public class ThrasherBrute extends CardImpl { } } -class ThrasherBruteFilter extends FilterPermanent { +class ThrasherBruteFilter extends FilterTeamPermanent { ThrasherBruteFilter() { super(); - this.add(Predicates.not(new ControllerPredicate(TargetController.OPPONENT))); } ThrasherBruteFilter(final ThrasherBruteFilter effect) { diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java index 073a459688..f199003774 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java @@ -185,13 +185,16 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa switch (mayActivate) { case ANY: break; - case NOT_YOU: if (controlsAbility(playerId, game)) { return false; } break; - + case TEAM: + if (game.getPlayer(controllerId).hasOpponent(playerId, game)) { + return false; + } + break; case OPPONENT: if (!game.getPlayer(controllerId).hasOpponent(playerId, game)) { return false; diff --git a/Mage/src/main/java/mage/constants/TargetController.java b/Mage/src/main/java/mage/constants/TargetController.java index 82766cdbad..2236ebe464 100644 --- a/Mage/src/main/java/mage/constants/TargetController.java +++ b/Mage/src/main/java/mage/constants/TargetController.java @@ -6,5 +6,5 @@ package mage.constants; */ public enum TargetController { - ACTIVE, ANY, YOU, NOT_YOU, OPPONENT, OWNER, CONTROLLER_ATTACHED_TO, NEXT + ACTIVE, ANY, YOU, NOT_YOU, OPPONENT, TEAM, OWNER, CONTROLLER_ATTACHED_TO, NEXT } diff --git a/Mage/src/main/java/mage/filter/common/FilterTeamCreaturePermanent.java b/Mage/src/main/java/mage/filter/common/FilterTeamCreaturePermanent.java new file mode 100644 index 0000000000..7d6bb67c72 --- /dev/null +++ b/Mage/src/main/java/mage/filter/common/FilterTeamCreaturePermanent.java @@ -0,0 +1,41 @@ +package mage.filter.common; + +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.predicate.permanent.ControllerPredicate; + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +/** + * + * @author TheElk801 + */ +public class FilterTeamCreaturePermanent extends FilterCreaturePermanent { + + public FilterTeamCreaturePermanent() { + this("creature your team controls"); + } + + public FilterTeamCreaturePermanent(String name) { + super(name); + this.add(new ControllerPredicate(TargetController.TEAM)); + + } + + public FilterTeamCreaturePermanent(SubType subtype, String name) { + super(subtype, name); + this.add(new ControllerPredicate(TargetController.TEAM)); + } + + public FilterTeamCreaturePermanent(final FilterTeamCreaturePermanent filter) { + super(filter); + } + + @Override + public FilterTeamCreaturePermanent copy() { + return new FilterTeamCreaturePermanent(this); + } +} diff --git a/Mage/src/main/java/mage/filter/common/FilterTeamPermanent.java b/Mage/src/main/java/mage/filter/common/FilterTeamPermanent.java new file mode 100644 index 0000000000..445088e660 --- /dev/null +++ b/Mage/src/main/java/mage/filter/common/FilterTeamPermanent.java @@ -0,0 +1,42 @@ +package mage.filter.common; + +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.predicate.permanent.ControllerPredicate; + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +/** + * + * @author TheElk801 + */ +public class FilterTeamPermanent extends FilterPermanent { + + public FilterTeamPermanent() { + this("permanent your team controls"); + } + + public FilterTeamPermanent(String name) { + super(name); + this.add(new ControllerPredicate(TargetController.TEAM)); + + } + + public FilterTeamPermanent(SubType subtype, String name) { + super(subtype, name); + this.add(new ControllerPredicate(TargetController.TEAM)); + } + + public FilterTeamPermanent(final FilterTeamPermanent filter) { + super(filter); + } + + @Override + public FilterTeamPermanent copy() { + return new FilterTeamPermanent(this); + } +} 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 21234780d9..3cbe8a7258 100644 --- a/Mage/src/main/java/mage/filter/predicate/permanent/ControllerPredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/permanent/ControllerPredicate.java @@ -58,9 +58,14 @@ public class ControllerPredicate implements ObjectPlayerPredicate<ObjectPlayer<C return true; } break; + case TEAM: + if (!game.getPlayer(playerId).hasOpponent(object.getControllerId(), game)) { + return true; + } + break; case OPPONENT: - if (!object.getControllerId().equals(playerId) && - game.getPlayer(playerId).hasOpponent(object.getControllerId(), game)) { + if (!object.getControllerId().equals(playerId) + && game.getPlayer(playerId).hasOpponent(object.getControllerId(), game)) { return true; } break; From 9eb3da5c4651a1f8eb5da3256d9a43ff8dfb6afc Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sun, 27 May 2018 11:05:47 -0400 Subject: [PATCH 135/154] Implemented Regna's Sanction --- .../src/mage/cards/r/RegnasSanction.java | 114 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 115 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RegnasSanction.java diff --git a/Mage.Sets/src/mage/cards/r/RegnasSanction.java b/Mage.Sets/src/mage/cards/r/RegnasSanction.java new file mode 100644 index 0000000000..0918f99aad --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RegnasSanction.java @@ -0,0 +1,114 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TapAllEffect; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.ChooseFriendsAndFoes; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPermanent; + +/** + * + * @author TheElk801 + */ +public class RegnasSanction extends CardImpl { + + public RegnasSanction(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{W}"); + + // For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest. + this.getSpellAbility().addEffect(new RegnasSanctionEffect()); + } + + public RegnasSanction(final RegnasSanction card) { + super(card); + } + + @Override + public RegnasSanction copy() { + return new RegnasSanction(this); + } +} + +class RegnasSanctionEffect extends OneShotEffect { + + RegnasSanctionEffect() { + super(Outcome.Benefit); + this.staticText = "For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest"; + } + + RegnasSanctionEffect(final RegnasSanctionEffect effect) { + super(effect); + } + + @Override + public RegnasSanctionEffect copy() { + return new RegnasSanctionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + ChooseFriendsAndFoes choice = new ChooseFriendsAndFoes(); + if (!choice.chooseFriendOrFoe(controller, source, game)) { + return false; + } + FilterCreaturePermanent filterToTap = new FilterCreaturePermanent(); + for (Player player : choice.getFoes()) { + FilterCreaturePermanent filter = new FilterCreaturePermanent("untapped creature you control"); + filter.add(Predicates.not(new TappedPredicate())); + filter.add(new ControllerIdPredicate(player.getId())); + TargetPermanent target = new TargetPermanent(1, 1, filter, true); + if (player.choose(Outcome.Benefit, target, source.getSourceId(), game)) { + filterToTap.add(Predicates.not(new PermanentIdPredicate(target.getFirstTarget()))); + } + } + for (Player player : choice.getFriends()) { + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(new ControllerIdPredicate(player.getId())); + new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter).apply(game, source); + filterToTap.add(Predicates.not(new ControllerIdPredicate(player.getId()))); + } + return new TapAllEffect(filterToTap).apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 5c735e6505..425a75e573 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -223,6 +223,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Rebuke", 103, Rarity.COMMON, mage.cards.r.Rebuke.class)); cards.add(new SetCardInfo("Reckless Reveler", 183, Rarity.COMMON, mage.cards.r.RecklessReveler.class)); cards.add(new SetCardInfo("Reckless Scholar", 130, Rarity.UNCOMMON, mage.cards.r.RecklessScholar.class)); + cards.add(new SetCardInfo("Regna's Sanction", 30, Rarity.RARE, mage.cards.r.RegnasSanction.class)); cards.add(new SetCardInfo("Regna, the Redeemer", 3, Rarity.RARE, mage.cards.r.RegnaTheRedeemer.class)); cards.add(new SetCardInfo("Relentless Hunter", 226, Rarity.UNCOMMON, mage.cards.r.RelentlessHunter.class)); cards.add(new SetCardInfo("Return to the Earth", 210, Rarity.COMMON, mage.cards.r.ReturnToTheEarth.class)); From b5036e519ce9cf5480af538a247003e38ff78e26 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sun, 27 May 2018 11:27:43 -0400 Subject: [PATCH 136/154] Implemented Bonus Round --- Mage.Sets/src/mage/cards/b/BonusRound.java | 101 ++++++++++++++++++ .../src/mage/cards/t/TheMirariConjecture.java | 2 +- Mage.Sets/src/mage/sets/Battlebond.java | 1 + .../effects/common/CopyTargetSpellEffect.java | 13 ++- 4 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/b/BonusRound.java diff --git a/Mage.Sets/src/mage/cards/b/BonusRound.java b/Mage.Sets/src/mage/cards/b/BonusRound.java new file mode 100644 index 0000000000..2459c40d23 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BonusRound.java @@ -0,0 +1,101 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.effects.common.CopyTargetSpellEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class BonusRound extends CardImpl { + + public BonusRound(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}{R}"); + + // Until end of turn, whenever a player casts an instant or sorcery spell, that player copies it and may choose new targets for the copy. + this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new BonusRoundDelayedTriggeredAbility())); + } + + public BonusRound(final BonusRound card) { + super(card); + } + + @Override + public BonusRound copy() { + return new BonusRound(this); + } +} + +class BonusRoundDelayedTriggeredAbility extends DelayedTriggeredAbility { + + public BonusRoundDelayedTriggeredAbility() { + super(new CopyTargetSpellEffect(true, true), Duration.EndOfTurn, false); + } + + public BonusRoundDelayedTriggeredAbility(final BonusRoundDelayedTriggeredAbility ability) { + super(ability); + } + + @Override + public BonusRoundDelayedTriggeredAbility copy() { + return new BonusRoundDelayedTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (spell != null && (spell.isInstant() || spell.isSorcery())) { + this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId())); + return true; + } + return false; + } + + @Override + public String getRule() { + return "Until end of turn, whenever a player casts an instant or sorcery spell, " + + "that player copies it and may choose new targets for the copy"; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TheMirariConjecture.java b/Mage.Sets/src/mage/cards/t/TheMirariConjecture.java index 7cbe6a3c45..88528f2058 100644 --- a/Mage.Sets/src/mage/cards/t/TheMirariConjecture.java +++ b/Mage.Sets/src/mage/cards/t/TheMirariConjecture.java @@ -102,7 +102,7 @@ public class TheMirariConjecture extends CardImpl { class TheMirariConjectureDelayedTriggeredAbility extends DelayedTriggeredAbility { public TheMirariConjectureDelayedTriggeredAbility() { - super(new CopyTargetSpellEffect(), Duration.EndOfTurn, false); + super(new CopyTargetSpellEffect(true), Duration.EndOfTurn, false); } public TheMirariConjectureDelayedTriggeredAbility(final TheMirariConjectureDelayedTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 425a75e573..dee4add181 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -79,6 +79,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Blood Feud", 168, Rarity.UNCOMMON, mage.cards.b.BloodFeud.class)); cards.add(new SetCardInfo("Bloodborn Scoundrels", 45, Rarity.COMMON, mage.cards.b.BloodbornScoundrels.class)); cards.add(new SetCardInfo("Boldwyr Intimidator", 169, Rarity.UNCOMMON, mage.cards.b.BoldwyrIntimidator.class)); + cards.add(new SetCardInfo("Bonus Round", 56, Rarity.RARE, mage.cards.b.BonusRound.class)); cards.add(new SetCardInfo("Borderland Marauder", 170, Rarity.COMMON, mage.cards.b.BorderlandMarauder.class)); cards.add(new SetCardInfo("Bountiful Promenade", 81, Rarity.RARE, mage.cards.b.BountifulPromenade.class)); cards.add(new SetCardInfo("Bramble Sovereign", 65, Rarity.MYTHIC, mage.cards.b.BrambleSovereign.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CopyTargetSpellEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CopyTargetSpellEffect.java index 56d50b8c40..7382a19cc5 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CopyTargetSpellEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CopyTargetSpellEffect.java @@ -43,20 +43,27 @@ import mage.players.Player; */ public class CopyTargetSpellEffect extends OneShotEffect { - private boolean useLKI = false; + private final boolean useController; + private final boolean useLKI; public CopyTargetSpellEffect() { - super(Outcome.Copy); + this(false); } public CopyTargetSpellEffect(boolean useLKI) { + this(false, useLKI); + } + + public CopyTargetSpellEffect(boolean useController, boolean useLKI) { super(Outcome.Copy); + this.useController = useController; this.useLKI = useLKI; } public CopyTargetSpellEffect(final CopyTargetSpellEffect effect) { super(effect); this.useLKI = effect.useLKI; + this.useController = effect.useController; } @Override @@ -71,7 +78,7 @@ public class CopyTargetSpellEffect extends OneShotEffect { spell = (Spell) game.getLastKnownInformation(targetPointer.getFirst(game, source), Zone.STACK); } if (spell != null) { - StackObject newStackObject = spell.createCopyOnStack(game, source, source.getControllerId(), true); + StackObject newStackObject = spell.createCopyOnStack(game, source, useController ? spell.getControllerId() : source.getControllerId(), true); Player player = game.getPlayer(source.getControllerId()); if (player != null && newStackObject != null && newStackObject instanceof Spell) { String activateMessage = ((Spell) newStackObject).getActivatedMessage(game); From ea77ec0532e045c51f292d8ad244a9281c85455f Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sun, 27 May 2018 12:05:12 -0400 Subject: [PATCH 137/154] Implemented Khorvath's Fury --- Mage.Sets/src/mage/cards/k/KhorvathsFury.java | 115 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 116 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KhorvathsFury.java diff --git a/Mage.Sets/src/mage/cards/k/KhorvathsFury.java b/Mage.Sets/src/mage/cards/k/KhorvathsFury.java new file mode 100644 index 0000000000..a71fcd1092 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KhorvathsFury.java @@ -0,0 +1,115 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.k; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.ChooseFriendsAndFoes; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class KhorvathsFury extends CardImpl { + + public KhorvathsFury(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}"); + + // For each player, choose friend or foe. Each friend discards all cards from their hand, then draws that many cards plus one. Khorvath's Fury deals damage to each foe equal to the number of cards in their hand. + this.getSpellAbility().addEffect(new KhorvathsFuryEffect()); + } + + public KhorvathsFury(final KhorvathsFury card) { + super(card); + } + + @Override + public KhorvathsFury copy() { + return new KhorvathsFury(this); + } +} + +class KhorvathsFuryEffect extends OneShotEffect { + + KhorvathsFuryEffect() { + super(Outcome.Benefit); + this.staticText = "For each player, choose friend or foe. " + + "Each friend discards all cards from their hand, " + + "then draws that many cards plus one." + + " {this} deals damage to each foe equal to the number of cards in their hand"; + } + + KhorvathsFuryEffect(final KhorvathsFuryEffect effect) { + super(effect); + } + + @Override + public KhorvathsFuryEffect copy() { + return new KhorvathsFuryEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + ChooseFriendsAndFoes choice = new ChooseFriendsAndFoes(); + choice.chooseFriendOrFoe(controller, source, game); + Map<UUID, Integer> cardsToDraw = new HashMap<>(); + for (Player player : choice.getFriends()) { + if (player != null) { + int cardsInHand = player.getHand().size(); + player.discard(cardsInHand, false, source, game); + if (cardsInHand > 0) { + cardsToDraw.put(player.getId(), cardsInHand); + } + } + } + for (Player player : choice.getFriends()) { + if (player != null) { + player.drawCards(cardsToDraw.get(player.getId()) + 1, game); + } + } + for (Player player : choice.getFoes()) { + if (player != null) { + player.damage(player.getHand().size(), source.getSourceId(), game, false, true); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index dee4add181..1b9071933e 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -156,6 +156,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Jungle Wayfinder", 72, Rarity.COMMON, mage.cards.j.JungleWayfinder.class)); cards.add(new SetCardInfo("Karametra's Favor", 203, Rarity.UNCOMMON, mage.cards.k.KarametrasFavor.class)); cards.add(new SetCardInfo("Khorvath Brightflame", 9, Rarity.RARE, mage.cards.k.KhorvathBrightflame.class)); + cards.add(new SetCardInfo("Khorvath's Fury", 59, Rarity.RARE, mage.cards.k.KhorvathsFury.class)); cards.add(new SetCardInfo("Kiss of the Amesha", 225, Rarity.UNCOMMON, mage.cards.k.KissOfTheAmesha.class)); cards.add(new SetCardInfo("Kitesail Corsair", 120, Rarity.COMMON, mage.cards.k.KitesailCorsair.class)); cards.add(new SetCardInfo("Kor Spiritdancer", 93, Rarity.RARE, mage.cards.k.KorSpiritdancer.class)); From c7ba71745315f38fb2a1b84c7bcb2f4749803748 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sun, 27 May 2018 13:06:26 -0400 Subject: [PATCH 138/154] Fixed colorless commanders not being able to use a single type of basic land (fixes #4973) --- .../Mage.Deck.Constructed/src/mage/deck/Brawl.java | 6 ++++-- Mage/src/main/java/mage/filter/FilterMana.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) 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 846221fd23..b3bb4ee87f 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 @@ -149,10 +149,12 @@ public class Brawl extends Constructed { if (commanderColor.isGreen()) { colorIdentity.setGreen(true); } + if (commanderColor.isColorless()) { + colorIdentity.setColorless(true); + } } } - - List<String> basicsInDeck = new ArrayList<>(); + Set<String> basicsInDeck = new HashSet<>(); if (colorIdentity.isColorless()) { for (Card card : deck.getCards()) { if (basicLandNames.contains(card.getName())) { diff --git a/Mage/src/main/java/mage/filter/FilterMana.java b/Mage/src/main/java/mage/filter/FilterMana.java index 5deda8ce48..d942b6bd12 100644 --- a/Mage/src/main/java/mage/filter/FilterMana.java +++ b/Mage/src/main/java/mage/filter/FilterMana.java @@ -104,7 +104,7 @@ public class FilterMana implements Serializable { } public boolean isColorless() { - return colorless; + return !(white || blue || black || red || green) || colorless; } public void setColorless(boolean colorless) { From 79576472ae81507229591173d787e0a15ec50a2d Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sun, 27 May 2018 14:13:19 -0400 Subject: [PATCH 139/154] Implemented Runed Arch --- Mage.Sets/src/mage/cards/r/RunedArch.java | 89 +++++++++++++++++++++++ Mage.Sets/src/mage/sets/IceAge.java | 1 + 2 files changed, 90 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RunedArch.java diff --git a/Mage.Sets/src/mage/cards/r/RunedArch.java b/Mage.Sets/src/mage/cards/r/RunedArch.java new file mode 100644 index 0000000000..a511f4050b --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RunedArch.java @@ -0,0 +1,89 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Duration; +import mage.constants.TargetAdjustment; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.target.TargetPermanent; + +/** + * + * @author TheElk801 + */ +public class RunedArch extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("creatures with power 2 or less"); + + static { + filter.add(new CardTypePredicate(CardType.CREATURE)); + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3)); + } + + public RunedArch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + // Runed Arch enters the battlefield tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + + // {X}, {tap}, Sacrifice Runed Arch: X target creatures with power 2 or less are unblockable this turn. + Ability ability = new SimpleActivatedAbility( + new CantBeBlockedTargetEffect(Duration.EndOfGame) + .setText("X target creatures with power 2 or less can’t be blocked this turn."), + new ManaCostsImpl("{X}") + ); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjustment(TargetAdjustment.X_TARGETS); + this.addAbility(ability); + } + + public RunedArch(final RunedArch card) { + super(card); + } + + @Override + public RunedArch copy() { + return new RunedArch(this); + } +} diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 745eefad6f..664dbbd4aa 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -288,6 +288,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Rime Dryad", 260, Rarity.COMMON, mage.cards.r.RimeDryad.class)); cards.add(new SetCardInfo("Ritual of Subdual", 261, Rarity.RARE, mage.cards.r.RitualOfSubdual.class)); cards.add(new SetCardInfo("River Delta", 359, Rarity.RARE, mage.cards.r.RiverDelta.class)); + cards.add(new SetCardInfo("Runed Arch", 309, Rarity.RARE, mage.cards.r.RunedArch.class)); cards.add(new SetCardInfo("Sabretooth Tiger", 215, Rarity.COMMON, mage.cards.s.SabretoothTiger.class)); cards.add(new SetCardInfo("Scaled Wurm", 262, Rarity.COMMON, mage.cards.s.ScaledWurm.class)); cards.add(new SetCardInfo("Sea Spirit", 95, Rarity.UNCOMMON, mage.cards.s.SeaSpirit.class)); From 69b98faeebbcc414aefb0aa6a4d76b9012dc9d34 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sun, 27 May 2018 14:19:36 -0400 Subject: [PATCH 140/154] Implemented Purging Scythe --- Mage.Sets/src/mage/cards/p/PurgingScythe.java | 129 ++++++++++++++++++ Mage.Sets/src/mage/sets/UrzasSaga.java | 1 + 2 files changed, 130 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PurgingScythe.java diff --git a/Mage.Sets/src/mage/cards/p/PurgingScythe.java b/Mage.Sets/src/mage/cards/p/PurgingScythe.java new file mode 100644 index 0000000000..e64ce790c2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PurgingScythe.java @@ -0,0 +1,129 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ToughnessPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; + +/** + * + * @author TheElk801 + */ +public class PurgingScythe extends CardImpl { + + public PurgingScythe(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); + + // At the beginning of your upkeep, Purging Scythe deals 2 damage to the creature with the least toughness. If two or more creatures are tied for least toughness, you choose one of them. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new PurgingScytheEffect(), TargetController.YOU, false)); + } + + public PurgingScythe(final PurgingScythe card) { + super(card); + } + + @Override + public PurgingScythe copy() { + return new PurgingScythe(this); + } +} + +class PurgingScytheEffect extends OneShotEffect { + + public PurgingScytheEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "{this} deals 2 damage to the creature with the least toughness. " + + "If two or more creatures are tied for least toughness, you choose one of them"; + } + + public PurgingScytheEffect(final PurgingScytheEffect effect) { + super(effect); + } + + @Override + public PurgingScytheEffect copy() { + return new PurgingScytheEffect(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) { + int leastToughness = Integer.MAX_VALUE; + boolean multipleExist = false; + Permanent permanentToDamage = null; + for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURES, source.getControllerId(), game)) { + if (permanent.getToughness().getValue() < leastToughness) { + permanentToDamage = permanent; + leastToughness = permanent.getToughness().getValue(); + multipleExist = false; + } else { + if (permanent.getToughness().getValue() == leastToughness) { + multipleExist = true; + } + } + } + if (multipleExist) { + FilterCreaturePermanent filter = new FilterCreaturePermanent("one of the creatures with the least toughness"); + filter.add(new ToughnessPredicate(ComparisonType.EQUAL_TO, leastToughness)); + Target target = new TargetPermanent(filter); + target.setNotTarget(true); + if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) { + if (controller.choose(outcome, target, source.getSourceId(), game)) { + permanentToDamage = game.getPermanent(target.getFirstTarget()); + } + } + } + if (permanentToDamage != null) { + game.informPlayers(new StringBuilder(sourcePermanent.getName()).append(" chosen creature: ").append(permanentToDamage.getName()).toString()); + return permanentToDamage.damage(2, source.getSourceId(), game, false, true) > 0; + } + return true; + } + + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasSaga.java b/Mage.Sets/src/mage/sets/UrzasSaga.java index a434c412e4..6a8269dd23 100644 --- a/Mage.Sets/src/mage/sets/UrzasSaga.java +++ b/Mage.Sets/src/mage/sets/UrzasSaga.java @@ -263,6 +263,7 @@ public class UrzasSaga extends ExpansionSet { cards.add(new SetCardInfo("Presence of the Master", 32, Rarity.UNCOMMON, mage.cards.p.PresenceOfTheMaster.class)); cards.add(new SetCardInfo("Priest of Gix", 150, Rarity.UNCOMMON, mage.cards.p.PriestOfGix.class)); cards.add(new SetCardInfo("Priest of Titania", 270, Rarity.COMMON, mage.cards.p.PriestOfTitania.class)); + cards.add(new SetCardInfo("Purging Scythe", 308, Rarity.RARE, mage.cards.p.PurgingScythe.class)); cards.add(new SetCardInfo("Rain of Filth", 151, Rarity.UNCOMMON, mage.cards.r.RainOfFilth.class)); cards.add(new SetCardInfo("Rain of Salt", 206, Rarity.UNCOMMON, mage.cards.r.RainOfSalt.class)); cards.add(new SetCardInfo("Ravenous Skirge", 152, Rarity.COMMON, mage.cards.r.RavenousSkirge.class)); From b97a443a3723a64647d77f8f06e151851cdbd3f1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sun, 27 May 2018 15:47:46 -0400 Subject: [PATCH 141/154] Implemented Stolen Strategy --- .../src/mage/cards/s/StolenStrategy.java | 205 ++++++++++++++++++ Mage.Sets/src/mage/sets/Battlebond.java | 1 + 2 files changed, 206 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/StolenStrategy.java diff --git a/Mage.Sets/src/mage/cards/s/StolenStrategy.java b/Mage.Sets/src/mage/cards/s/StolenStrategy.java new file mode 100644 index 0000000000..d1a801c2e5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StolenStrategy.java @@ -0,0 +1,205 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.Objects; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.AsThoughManaEffect; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +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.ManaType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.ExileZone; +import mage.game.Game; +import mage.players.ManaPoolItem; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +/** + * + * @author TheElk801 + */ +public class StolenStrategy extends CardImpl { + + public StolenStrategy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{R}"); + + // At the beginning of your upkeep, exile the top card of each opponent's library. Until end of turn, you may cast nonland cards from among those exiled cards, and you may spend mana as though it were mana of any color to cast those spells. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new StolenStrategyEffect(), TargetController.YOU, false)); + } + + public StolenStrategy(final StolenStrategy card) { + super(card); + } + + @Override + public StolenStrategy copy() { + return new StolenStrategy(this); + } +} + +class StolenStrategyEffect extends OneShotEffect { + + public StolenStrategyEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "exile the top card of each opponent's library. " + + "Until end of turn, you may cast nonland cards from among those exiled cards, " + + "and you may spend mana as though it were mana of any color to cast those spells"; + } + + public StolenStrategyEffect(final StolenStrategyEffect effect) { + super(effect); + } + + @Override + public StolenStrategyEffect copy() { + return new StolenStrategyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + if (!controller.hasOpponent(playerId, game)) { + continue; + } + Player damagedPlayer = game.getPlayer(playerId); + if (damagedPlayer == null) { + continue; + } + MageObject sourceObject = game.getObject(source.getSourceId()); + UUID exileId = CardUtil.getCardExileZoneId(game, source); + Card card = damagedPlayer.getLibrary().getFromTop(game); + if (card != null) { + // move card to exile + controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); + // Add effects only if the card has a spellAbility (e.g. not for lands). + if (!card.isLand() && card.getSpellAbility() != null) { + // allow to cast the card + game.addEffect(new StolenStrategyCastFromExileEffect(card.getId(), exileId), source); + // and you may spend mana as though it were mana of any color to cast it + ContinuousEffect effect = new StolenStrategySpendAnyManaEffect(); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); + } + } + } + return true; + } +} + +class StolenStrategyCastFromExileEffect extends AsThoughEffectImpl { + + private UUID cardId; + private UUID exileId; + + public StolenStrategyCastFromExileEffect(UUID cardId, UUID exileId) { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); + staticText = "Until end of turn, you may cast that card and you may spend mana as though it were mana of any color to cast it"; + this.cardId = cardId; + this.exileId = exileId; + } + + public StolenStrategyCastFromExileEffect(final StolenStrategyCastFromExileEffect effect) { + super(effect); + this.cardId = effect.cardId; + this.exileId = effect.exileId; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public StolenStrategyCastFromExileEffect copy() { + return new StolenStrategyCastFromExileEffect(this); + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + if (sourceId.equals(cardId) && source.getControllerId().equals(affectedControllerId)) { + ExileZone exileZone = game.getState().getExile().getExileZone(exileId); + return exileZone != null && exileZone.contains(cardId); + } + return false; + } +} + +class StolenStrategySpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect { + + public StolenStrategySpendAnyManaEffect() { + super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.EndOfTurn, Outcome.Benefit); + staticText = "you may spend mana as though it were mana of any color to cast it"; + } + + public StolenStrategySpendAnyManaEffect(final StolenStrategySpendAnyManaEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public StolenStrategySpendAnyManaEffect copy() { + return new StolenStrategySpendAnyManaEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + return source.getControllerId().equals(affectedControllerId) + && Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget()) + && ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId) + && (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)) + && game.getState().getZone(objectId) == Zone.STACK; + } + + @Override + public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) { + return mana.getFirstAvailable(); + } + +} diff --git a/Mage.Sets/src/mage/sets/Battlebond.java b/Mage.Sets/src/mage/sets/Battlebond.java index 1b9071933e..e427435cfd 100644 --- a/Mage.Sets/src/mage/sets/Battlebond.java +++ b/Mage.Sets/src/mage/sets/Battlebond.java @@ -264,6 +264,7 @@ public class Battlebond extends ExpansionSet { cards.add(new SetCardInfo("Spire Garden", 85, Rarity.RARE, mage.cards.s.SpireGarden.class)); cards.add(new SetCardInfo("Stadium Vendors", 63, Rarity.COMMON, mage.cards.s.StadiumVendors.class)); cards.add(new SetCardInfo("Steppe Glider", 109, Rarity.UNCOMMON, mage.cards.s.SteppeGlider.class)); + cards.add(new SetCardInfo("Stolen Strategy", 64, Rarity.RARE, mage.cards.s.StolenStrategy.class)); cards.add(new SetCardInfo("Stone Golem", 247, Rarity.COMMON, mage.cards.s.StoneGolem.class)); cards.add(new SetCardInfo("Stunning Reversal", 51, Rarity.MYTHIC, mage.cards.s.StunningReversal.class)); cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); From 27ced167fb140115cb1f3c32f077145c1dc74dca Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Sun, 27 May 2018 23:47:57 +0200 Subject: [PATCH 142/154] * Added logic to add permitting object to play/cast events. --- .../java/mage/player/ai/ComputerPlayer.java | 33 +- .../mage/player/ai/GameStateEvaluator.java | 38 ++- .../src/mage/cards/a/AetherworksMarvel.java | 5 +- Mage.Sets/src/mage/cards/b/BrainInAJar.java | 3 +- .../src/mage/cards/b/BrilliantUltimatum.java | 5 +- Mage.Sets/src/mage/cards/b/BringToLight.java | 5 +- Mage.Sets/src/mage/cards/c/ChandraAblaze.java | 9 +- .../src/mage/cards/c/ChandraPyromaster.java | 7 +- .../mage/cards/c/ChandraTorchOfDefiance.java | 7 +- .../src/mage/cards/c/CharmedPendant.java | 4 +- Mage.Sets/src/mage/cards/c/Counterlash.java | 15 +- .../src/mage/cards/d/DarksteelGarrison.java | 9 +- .../mage/cards/d/DereviEmpyrialTactician.java | 6 +- .../src/mage/cards/d/DescendantsPath.java | 10 +- .../src/mage/cards/d/DiluvianPrimordial.java | 7 +- Mage.Sets/src/mage/cards/d/DjinnOfWishes.java | 9 +- Mage.Sets/src/mage/cards/d/DrainPower.java | 4 +- Mage.Sets/src/mage/cards/e/EliteArcanist.java | 14 +- .../src/mage/cards/e/EpicExperiment.java | 5 +- .../src/mage/cards/e/EtaliPrimalStorm.java | 7 +- Mage.Sets/src/mage/cards/e/EyeOfTheStorm.java | 3 +- Mage.Sets/src/mage/cards/g/Galvanoth.java | 3 +- .../src/mage/cards/g/GoblinDarkDwellers.java | 13 +- .../src/mage/cards/g/GreaterGargadon.java | 20 +- .../src/mage/cards/g/GreenbeltRampager.java | 24 +- Mage.Sets/src/mage/cards/g/Guile.java | 7 +- .../src/mage/cards/h/HarnessTheStorm.java | 5 +- .../src/mage/cards/h/HazoretsUndyingFury.java | 3 +- .../src/mage/cards/h/HellcarverDemon.java | 12 +- .../src/mage/cards/h/HordeOfNotions.java | 5 +- .../src/mage/cards/i/IsochronScepter.java | 5 +- .../src/mage/cards/i/IzzetChemister.java | 5 +- .../mage/cards/j/JaceArchitectOfThought.java | 5 +- .../src/mage/cards/j/JacesMindseeker.java | 5 +- .../mage/cards/j/JelevaNephaliasScourge.java | 5 +- .../src/mage/cards/k/KahoMinamoHistorian.java | 7 +- .../mage/cards/k/KnowledgeExploitation.java | 17 +- Mage.Sets/src/mage/cards/k/KnowledgePool.java | 5 +- .../src/mage/cards/l/LeafCrownedElder.java | 7 +- .../src/mage/cards/l/LionsEyeDiamond.java | 14 +- Mage.Sets/src/mage/cards/l/LivingLore.java | 3 +- .../src/mage/cards/m/MaelstromArchangel.java | 15 +- Mage.Sets/src/mage/cards/m/ManaCache.java | 13 +- Mage.Sets/src/mage/cards/m/Martyrdom.java | 4 +- .../mage/cards/m/MasterOfPredicaments.java | 7 +- Mage.Sets/src/mage/cards/m/MemoryPlunder.java | 9 +- Mage.Sets/src/mage/cards/m/Merseine.java | 18 +- .../src/mage/cards/m/MindclawShaman.java | 21 +- Mage.Sets/src/mage/cards/m/MindleechMass.java | 15 +- Mage.Sets/src/mage/cards/m/MindsDilation.java | 5 +- .../src/mage/cards/m/MizzixsMastery.java | 5 +- Mage.Sets/src/mage/cards/o/OmenMachine.java | 3 +- Mage.Sets/src/mage/cards/o/OracleOfBones.java | 11 +- .../src/mage/cards/p/PanopticMirror.java | 27 +- .../src/mage/cards/p/PossibilityStorm.java | 3 +- .../src/mage/cards/q/QasaliAmbusher.java | 21 +- .../mage/cards/r/RashmiEternitiesCrafter.java | 7 +- .../src/mage/cards/r/ReversalOfFortune.java | 24 +- Mage.Sets/src/mage/cards/r/RhysticCave.java | 4 +- .../src/mage/cards/s/ShellOfTheLastKappa.java | 3 +- .../src/mage/cards/s/SilentBladeOni.java | 7 +- Mage.Sets/src/mage/cards/s/SpellQueller.java | 11 +- Mage.Sets/src/mage/cards/s/Spellbinder.java | 11 +- Mage.Sets/src/mage/cards/s/Spellshift.java | 3 +- Mage.Sets/src/mage/cards/s/Spelltwine.java | 10 +- .../src/mage/cards/s/SpellweaverHelix.java | 43 +-- .../src/mage/cards/s/SpellweaverVolute.java | 3 +- .../src/mage/cards/s/SunbirdsInvocation.java | 3 +- Mage.Sets/src/mage/cards/s/Sunforger.java | 5 +- .../src/mage/cards/t/TalentOfTheTelepath.java | 5 +- .../src/mage/cards/t/ThunderbladeCharge.java | 3 +- .../src/mage/cards/t/TorrentialGearhulk.java | 5 +- .../src/mage/cards/t/ToshiroUmezawa.java | 3 +- .../src/mage/cards/t/TreasureKeeper.java | 3 +- Mage.Sets/src/mage/cards/t/TwinningGlass.java | 3 +- .../src/mage/cards/u/UnexpectedResults.java | 3 +- .../src/mage/cards/v/VillainousWealth.java | 3 +- .../src/mage/cards/w/WellOfKnowledge.java | 6 +- Mage.Sets/src/mage/cards/w/WildEvocation.java | 3 +- .../src/mage/cards/w/WildfireEternal.java | 5 +- .../src/mage/cards/w/WrexialTheRisenDeep.java | 3 +- .../cards/single/FiendOfTheShadowsTest.java | 2 + .../java/org/mage/test/player/TestPlayer.java | 10 +- .../java/org/mage/test/stub/PlayerStub.java | 5 +- .../java/mage/abilities/AbilitiesImpl.java | 2 +- .../java/mage/abilities/ActivatedAbility.java | 32 +- .../mage/abilities/ActivatedAbilityImpl.java | 28 +- .../java/mage/abilities/PlayLandAbility.java | 11 +- .../java/mage/abilities/SpellAbility.java | 24 +- .../mage/abilities/common/PassAbility.java | 17 +- .../abilities/costs/common/TapSourceCost.java | 2 +- .../costs/common/UntapSourceCost.java | 2 +- .../ConditionalGainActivatedAbility.java | 4 +- .../abilities/effects/ContinuousEffects.java | 20 +- .../CastCardFromOutsideTheGameEffect.java | 7 +- .../effects/common/CipherEffect.java | 3 +- .../effects/common/HideawayPlayEffect.java | 6 +- .../PlayTargetWithoutPayingManaEffect.java | 13 +- .../cost/CastWithoutPayingManaCostEffect.java | 3 +- .../AddConditionalManaOfAnyColorEffect.java | 12 +- .../mage/abilities/keyword/AssistAbility.java | 317 +++++++++--------- .../abilities/keyword/CascadeAbility.java | 3 +- .../abilities/keyword/ConvokeAbility.java | 2 +- .../mage/abilities/keyword/DelveAbility.java | 2 +- .../mage/abilities/keyword/EmergeAbility.java | 280 ++++++++-------- .../mage/abilities/keyword/EquipAbility.java | 12 +- .../keyword/EquipLegendaryAbility.java | 191 ++++++----- .../abilities/keyword/FlashbackAbility.java | 9 +- .../abilities/keyword/ForecastAbility.java | 12 +- .../abilities/keyword/ImproviseAbility.java | 3 +- .../abilities/keyword/MadnessAbility.java | 11 +- .../abilities/keyword/MiracleAbility.java | 7 +- .../abilities/keyword/ReboundAbility.java | 3 +- .../mage/abilities/keyword/RippleAbility.java | 3 +- .../keyword/SpliceOntoArcaneAbility.java | 96 +++--- .../mage/abilities/keyword/SurgeAbility.java | 4 +- .../abilities/keyword/SuspendAbility.java | 11 +- .../mana/ActivateOncePerTurnManaAbility.java | 2 +- .../mana/ActivatedManaAbilityImpl.java | 10 +- .../common/FilterCreatureForCombatBlock.java | 2 +- .../main/java/mage/game/events/GameEvent.java | 48 ++- .../mage/game/permanent/PermanentImpl.java | 16 +- Mage/src/main/java/mage/players/Player.java | 5 +- .../main/java/mage/players/PlayerImpl.java | 76 +++-- 124 files changed, 1095 insertions(+), 964 deletions(-) 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 e7f90f20c4..57def9ddfc 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 @@ -33,6 +33,7 @@ import java.util.*; import java.util.Map.Entry; import mage.ConditionalMana; import mage.MageObject; +import mage.MageObjectReference; import mage.Mana; import mage.abilities.*; import mage.abilities.costs.VariableCost; @@ -1027,7 +1028,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { findPlayables(game); if (!playableAbilities.isEmpty()) { for (ActivatedAbility ability : playableAbilities) { - if (ability.canActivate(playerId, game)) { + if (ability.canActivate(playerId, game).canActivate()) { if (ability.getEffects().hasOutcome(Outcome.PutLandInPlay)) { if (this.activateAbility(ability, game)) { return true; @@ -1058,7 +1059,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { if (game.getStack().isEmpty()) { if (!playableNonInstant.isEmpty()) { for (Card card : playableNonInstant) { - if (card.getSpellAbility().canActivate(playerId, game)) { + if (card.getSpellAbility().canActivate(playerId, game).canActivate()) { if (this.activateAbility(card.getSpellAbility(), game)) { return true; } @@ -1067,7 +1068,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { } if (!playableAbilities.isEmpty()) { for (ActivatedAbility ability : playableAbilities) { - if (ability.canActivate(playerId, game)) { + if (ability.canActivate(playerId, game).canActivate()) { if (!(ability.getEffects().get(0) instanceof BecomesCreatureSourceEffect)) { if (this.activateAbility(ability, game)) { return true; @@ -1187,7 +1188,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { for (Mana avail : available) { if (mana.enough(avail)) { SpellAbility ability = card.getSpellAbility(); - if (ability != null && ability.canActivate(playerId, game) + if (ability != null && ability.canActivate(playerId, game).canActivate() && game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) { if (card.getCardType().contains(CardType.INSTANT) || card.hasAbility(FlashAbility.getInstance().getId(), game)) { @@ -1204,7 +1205,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { } for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) { for (ActivatedAbility ability : permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) { - if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(playerId, game)) { + if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(playerId, game).canActivate()) { if (ability instanceof EquipAbility && permanent.getAttachedTo() != null) { continue; } @@ -1231,7 +1232,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { } for (Card card : graveyard.getCards(game)) { for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.GRAVEYARD)) { - if (ability.canActivate(playerId, game)) { + if (ability.canActivate(playerId, game).canActivate()) { ManaOptions abilityOptions = ability.getManaCosts().getOptions(); if (abilityOptions.isEmpty()) { playableAbilities.add(ability); @@ -1264,7 +1265,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { protected boolean playManaHandling(Ability ability, ManaCost unpaid, final Game game) { // log.info("paying for " + unpaid.getText()); - UUID spendAnyManaId = game.getContinuousEffects().asThough(ability.getSourceId(), AsThoughEffectType.SPEND_OTHER_MANA, ability, ability.getControllerId(), game); + MageObjectReference permittingObject = game.getContinuousEffects().asThough(ability.getSourceId(), AsThoughEffectType.SPEND_OTHER_MANA, ability, ability.getControllerId(), game); ManaCost cost; List<MageObject> producers; if (unpaid instanceof ManaCosts) { @@ -1308,7 +1309,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) { if (cost instanceof ColoredManaCost) { for (Mana netMana : manaAbility.getNetMana(game)) { - if (cost.testPay(netMana) || spendAnyManaId != null) { + if (cost.testPay(netMana) || permittingObject != null) { if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) { continue; } @@ -1323,7 +1324,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) { if (cost instanceof SnowManaCost) { for (Mana netMana : manaAbility.getNetMana(game)) { - if (cost.testPay(netMana) || spendAnyManaId != null) { + if (cost.testPay(netMana) || permittingObject != null) { if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) { continue; } @@ -1338,7 +1339,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) { if (cost instanceof HybridManaCost) { for (Mana netMana : manaAbility.getNetMana(game)) { - if (cost.testPay(netMana) || spendAnyManaId != null) { + if (cost.testPay(netMana) || permittingObject != null) { if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) { continue; } @@ -1353,7 +1354,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) { if (cost instanceof MonoHybridManaCost) { for (Mana netMana : manaAbility.getNetMana(game)) { - if (cost.testPay(netMana) || spendAnyManaId != null) { + if (cost.testPay(netMana) || permittingObject != null) { if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) { continue; } @@ -1368,7 +1369,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) { if (cost instanceof ColorlessManaCost) { for (Mana netMana : manaAbility.getNetMana(game)) { - if (cost.testPay(netMana) || spendAnyManaId != null) { + if (cost.testPay(netMana) || permittingObject != null) { if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) { continue; } @@ -1383,7 +1384,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { for (ActivatedManaAbilityImpl manaAbility : getManaAbilitiesSortedByManaCount(mageObject, game)) { if (cost instanceof GenericManaCost) { for (Mana netMana : manaAbility.getNetMana(game)) { - if (cost.testPay(netMana) || spendAnyManaId != null) { + if (cost.testPay(netMana) || permittingObject != null) { if (netMana instanceof ConditionalMana && !((ConditionalMana) netMana).apply(ability, game, getId(), cost)) { continue; } @@ -1397,7 +1398,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { } // pay phyrexian life costs if (cost instanceof PhyrexianManaCost) { - if (cost.pay(null, game, null, playerId, false, null) || spendAnyManaId != null) { + if (cost.pay(null, game, null, playerId, false, null) || permittingObject != null) { return true; } } @@ -2386,7 +2387,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { private void playRemoval(List<UUID> creatures, Game game) { for (UUID creatureId : creatures) { for (Card card : this.playableInstant) { - if (card.getSpellAbility().canActivate(playerId, game)) { + if (card.getSpellAbility().canActivate(playerId, game).canActivate()) { for (Effect effect : card.getSpellAbility().getEffects()) { if (effect.getOutcome() == Outcome.DestroyPermanent || effect.getOutcome() == Outcome.ReturnToHand) { if (card.getSpellAbility().getTargets().get(0).canTarget(creatureId, card.getSpellAbility(), game)) { @@ -2405,7 +2406,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { for (UUID creatureId : creatures) { Permanent creature = game.getPermanent(creatureId); for (Card card : this.playableInstant) { - if (card.getSpellAbility().canActivate(playerId, game)) { + if (card.getSpellAbility().canActivate(playerId, game).canActivate()) { for (Effect effect : card.getSpellAbility().getEffects()) { if (effect instanceof DamageTargetEffect) { if (card.getSpellAbility().getTargets().get(0).canTarget(creatureId, card.getSpellAbility(), game)) { diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java index df9e389d03..cc54d69012 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java @@ -25,17 +25,16 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.player.ai; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Zone; import mage.abilities.ActivatedAbility; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.TrampleAbility; import mage.abilities.mana.ActivatedManaAbilityImpl; +import mage.constants.CardType; +import mage.constants.Zone; import mage.counters.BoostCounter; import mage.counters.Counter; import mage.counters.CounterType; @@ -71,18 +70,20 @@ public final class GameStateEvaluator { Player player = game.getPlayer(playerId); Player opponent = game.getPlayer(game.getOpponents(playerId).iterator().next()); if (game.checkIfGameIsOver()) { - if (player.hasLost() || opponent.hasWon()) + if (player.hasLost() || opponent.hasWon()) { return LOSE_SCORE; - if (opponent.hasLost() || player.hasWon()) + } + if (opponent.hasLost() || player.hasWon()) { return WIN_SCORE; + } } int lifeScore = (player.getLife() - opponent.getLife()) * LIFE_FACTOR; int poisonScore = (opponent.getCounters().getCount(CounterType.POISON) - player.getCounters().getCount(CounterType.POISON)) * LIFE_FACTOR * 2; int permanentScore = 0; - for (Permanent permanent: game.getBattlefield().getAllActivePermanents(playerId)) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) { permanentScore += evaluatePermanent(permanent, game, ignoreTapped); } - for (Permanent permanent: game.getBattlefield().getAllActivePermanents(opponent.getId())) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(opponent.getId())) { permanentScore -= evaluatePermanent(permanent, game, ignoreTapped); } permanentScore *= PERMANENT_FACTOR; @@ -92,26 +93,29 @@ public final class GameStateEvaluator { handScore *= HAND_FACTOR; int score = lifeScore + poisonScore + permanentScore + handScore; - if (logger.isDebugEnabled()) + if (logger.isDebugEnabled()) { logger.debug("game state for player " + player.getName() + " evaluated to- lifeScore:" + lifeScore + " permanentScore:" + permanentScore + " handScore:" + handScore + " total:" + score); + } return score; } public static int evaluatePermanent(Permanent permanent, Game game, boolean ignoreTapped) { int value = 0; - if (ignoreTapped) + if (ignoreTapped) { value = 5; - else - value = permanent.isTapped()?4:5; + } else { + value = permanent.isTapped() ? 4 : 5; + } if (permanent.getCardType().contains(CardType.CREATURE)) { value += evaluateCreature(permanent, game) * CREATURE_FACTOR; } value += permanent.getAbilities().getActivatedManaAbilities(Zone.BATTLEFIELD).size(); - for (ActivatedAbility ability: permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) { - if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(ability.getControllerId(), game)) + for (ActivatedAbility ability : permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) { + if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(ability.getControllerId(), game).canActivate()) { value += ability.getEffects().size(); + } } - for (Counter counter: permanent.getCounters(game).values()) { + for (Counter counter : permanent.getCounters(game).values()) { if (!(counter instanceof BoostCounter)) { value += counter.getCount(); } @@ -133,9 +137,9 @@ public final class GameStateEvaluator { // value += 2; value += creature.getAbilities().getEvasionAbilities().size(); value += creature.getAbilities().getProtectionAbilities().size(); - value += creature.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId())?1:0; - value += creature.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId())?2:0; - value += creature.getAbilities().containsKey(TrampleAbility.getInstance().getId())?1:0; + value += creature.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId()) ? 1 : 0; + value += creature.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId()) ? 2 : 0; + value += creature.getAbilities().containsKey(TrampleAbility.getInstance().getId()) ? 1 : 0; return value; } diff --git a/Mage.Sets/src/mage/cards/a/AetherworksMarvel.java b/Mage.Sets/src/mage/cards/a/AetherworksMarvel.java index 2cef850445..5e51eb2518 100644 --- a/Mage.Sets/src/mage/cards/a/AetherworksMarvel.java +++ b/Mage.Sets/src/mage/cards/a/AetherworksMarvel.java @@ -29,6 +29,7 @@ package mage.cards.a; import java.util.Set; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -55,7 +56,7 @@ import mage.target.common.TargetCardInLibrary; public class AetherworksMarvel extends CardImpl { public AetherworksMarvel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); addSuperType(SuperType.LEGENDARY); // Whenever a permanent you control is put into a graveyard, you get {E}. @@ -105,7 +106,7 @@ class AetherworksMarvelEffect extends OneShotEffect { TargetCard target = new TargetCardInLibrary(0, 1, new FilterNonlandCard("card to cast without paying its mana cost")); if (controller.choose(Outcome.PlayForFree, cards, target, game)) { Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); - if (card != null && controller.cast(card.getSpellAbility(), game, true)) { + if (card != null && controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { cards.remove(card); } } diff --git a/Mage.Sets/src/mage/cards/b/BrainInAJar.java b/Mage.Sets/src/mage/cards/b/BrainInAJar.java index bf9b9a3a9c..912cb77a4d 100644 --- a/Mage.Sets/src/mage/cards/b/BrainInAJar.java +++ b/Mage.Sets/src/mage/cards/b/BrainInAJar.java @@ -28,6 +28,7 @@ package mage.cards.b; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.RemoveVariableCountersSourceCost; @@ -114,7 +115,7 @@ class BrainInAJarCastEffect extends OneShotEffect { controller.chooseTarget(outcome, target, source, game); Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } return true; diff --git a/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java b/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java index f91c2b7804..2071278bc9 100644 --- a/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java +++ b/Mage.Sets/src/mage/cards/b/BrilliantUltimatum.java @@ -31,6 +31,7 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.*; @@ -50,7 +51,7 @@ import mage.target.common.TargetOpponent; public class BrilliantUltimatum extends CardImpl { public BrilliantUltimatum(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{W}{W}{U}{U}{U}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}{W}{U}{U}{U}{B}{B}"); // Exile the top five cards of your library. An opponent separates those cards into two piles. You may play any number of cards from one of those piles without paying their mana costs. this.getSpellAbility().addEffect(new BrilliantUltimatumEffect()); @@ -136,7 +137,7 @@ class BrilliantUltimatumEffect extends OneShotEffect { TargetCard targetExiledCard = new TargetCard(Zone.EXILED, new FilterCard()); if (controller.chooseTarget(Outcome.PlayForFree, selectedPile, targetExiledCard, source, game)) { Card card = selectedPile.get(targetExiledCard.getFirstTarget(), game); - if (controller.playCard(card, game, true, true)) { + if (controller.playCard(card, game, true, true, new MageObjectReference(source.getSourceObject(game), game))) { selectedPileCards.remove(card); selectedPile.remove(card); } diff --git a/Mage.Sets/src/mage/cards/b/BringToLight.java b/Mage.Sets/src/mage/cards/b/BringToLight.java index 34fbe118fb..8ac6e6a55a 100644 --- a/Mage.Sets/src/mage/cards/b/BringToLight.java +++ b/Mage.Sets/src/mage/cards/b/BringToLight.java @@ -28,6 +28,7 @@ package mage.cards.b; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.dynamicvalue.common.ColorsOfManaSpentToCastCount; import mage.abilities.effects.OneShotEffect; @@ -54,7 +55,7 @@ import org.apache.log4j.Logger; public class BringToLight extends CardImpl { public BringToLight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}{U}"); // <i>Converge</i>-Search your library for a creature, instant, or sorcery card with converted mana // cost less than or equal to the number of colors of mana spent to cast Bring to Light, exile that card, @@ -108,7 +109,7 @@ class BringToLightEffect extends OneShotEffect { if (card != null) { if (controller.chooseUse(outcome, "Cast " + card.getName() + " without paying its mana cost?", source, game)) { if (card.getSpellAbility() != null) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } else { Logger.getLogger(BringToLightEffect.class).error("Bring to Light: spellAbility == null " + card.getName()); } diff --git a/Mage.Sets/src/mage/cards/c/ChandraAblaze.java b/Mage.Sets/src/mage/cards/c/ChandraAblaze.java index 912937767a..d2cb672265 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraAblaze.java +++ b/Mage.Sets/src/mage/cards/c/ChandraAblaze.java @@ -29,6 +29,7 @@ package mage.cards.c; import java.util.Set; import java.util.UUID; +import mage.MageObjectReference; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; @@ -41,8 +42,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.SuperType; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; @@ -51,8 +52,8 @@ import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetAnyTarget; +import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetDiscard; /** @@ -62,7 +63,7 @@ import mage.target.common.TargetDiscard; public class ChandraAblaze extends CardImpl { public ChandraAblaze(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{4}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{R}{R}"); this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.CHANDRA); @@ -198,7 +199,7 @@ class ChandraAblazeEffect5 extends OneShotEffect { if (player.choose(outcome, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - player.cast(card.getSpellAbility(), game, true); + player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); player.getGraveyard().remove(card); cards.remove(card); } diff --git a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java index 75c5b5f59f..c49eedb085 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java +++ b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java @@ -287,17 +287,18 @@ class ChandraPyromasterEffect3 extends OneShotEffect { if (controller.chooseTarget(Outcome.PlayForFree, cards, target, source, game)) { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { + MageObjectReference mor = new MageObjectReference(source.getSourceObject(game), game); if (controller.chooseUse(outcome, "Do you wish to cast copy 1 of " + card.getName(), source, game)) { Card copy1 = game.copyCard(card, source, source.getControllerId()); - controller.cast(copy1.getSpellAbility(), game, true); + controller.cast(copy1.getSpellAbility(), game, true, mor); } if (controller.chooseUse(outcome, "Do you wish to cast copy 2 of " + card.getName(), source, game)) { Card copy2 = game.copyCard(card, source, source.getControllerId()); - controller.cast(copy2.getSpellAbility(), game, true); + controller.cast(copy2.getSpellAbility(), game, true, mor); } if (controller.chooseUse(outcome, "Do you wish to cast copy 3 of " + card.getName(), source, game)) { Card copy3 = game.copyCard(card, source, source.getControllerId()); - controller.cast(copy3.getSpellAbility(), game, true); + controller.cast(copy3.getSpellAbility(), game, true, mor); } return true; } diff --git a/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java b/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java index 3b8f4c0adb..d004e96cea 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java +++ b/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java @@ -29,22 +29,23 @@ package mage.cards.c; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.Mana; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.mana.BasicManaEffect; import mage.abilities.effects.common.DamagePlayersEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.GetEmblemEffect; +import mage.abilities.effects.mana.BasicManaEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.TargetController; import mage.constants.Zone; @@ -120,7 +121,7 @@ class ChandraTorchOfDefianceEffect extends OneShotEffect { controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); if (!card.getManaCost().isEmpty()) { if (controller.chooseUse(Outcome.Benefit, "Cast the card? (You still pay the costs)", source, game) && !card.isLand()) { - exiledCardWasCast = controller.cast(card.getSpellAbility(), game, false); + exiledCardWasCast = controller.cast(card.getSpellAbility(), game, false, new MageObjectReference(source.getSourceObject(game), game)); } } if (!exiledCardWasCast) { diff --git a/Mage.Sets/src/mage/cards/c/CharmedPendant.java b/Mage.Sets/src/mage/cards/c/CharmedPendant.java index 325086fe56..f135dc3527 100644 --- a/Mage.Sets/src/mage/cards/c/CharmedPendant.java +++ b/Mage.Sets/src/mage/cards/c/CharmedPendant.java @@ -98,12 +98,12 @@ class CharmedPendantAbility extends ActivatedManaAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { Player player = game.getPlayer(playerId); if (player != null && !player.isInPayManaMode()) { // while paying the costs of a spell you cant activate this return super.canActivate(playerId, game); } - return false; + return ActivationStatus.getFalse(); } @Override diff --git a/Mage.Sets/src/mage/cards/c/Counterlash.java b/Mage.Sets/src/mage/cards/c/Counterlash.java index b1ad8d9225..e7ef1279a0 100644 --- a/Mage.Sets/src/mage/cards/c/Counterlash.java +++ b/Mage.Sets/src/mage/cards/c/Counterlash.java @@ -27,7 +27,11 @@ */ package mage.cards.c; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -45,10 +49,6 @@ import mage.players.Player; import mage.target.TargetSpell; import mage.target.common.TargetCardInHand; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - /** * * @author BetaSteward @@ -56,8 +56,7 @@ import java.util.UUID; public class Counterlash extends CardImpl { public Counterlash(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{U}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{U}{U}"); // Counter target spell. You may cast a nonland card in your hand that shares a card type with that spell without paying its mana cost. this.getSpellAbility().addTarget(new TargetSpell()); @@ -99,7 +98,7 @@ class CounterlashEffect extends OneShotEffect { if (player.chooseUse(Outcome.PutCardInPlay, "Cast a nonland card in your hand that shares a card type with that spell without paying its mana cost?", source, game)) { FilterCard filter = new FilterCard(); List<Predicate<MageObject>> types = new ArrayList<>(); - for (CardType type: stackObject.getCardType()) { + for (CardType type : stackObject.getCardType()) { if (type != CardType.LAND) { types.add(new CardTypePredicate(type)); } @@ -109,7 +108,7 @@ class CounterlashEffect extends OneShotEffect { if (player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { Card card = player.getHand().get(target.getFirstTarget(), game); if (card != null) { - player.cast(card.getSpellAbility(), game, true); + player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/d/DarksteelGarrison.java b/Mage.Sets/src/mage/cards/d/DarksteelGarrison.java index bdbba6de0a..472cd594df 100644 --- a/Mage.Sets/src/mage/cards/d/DarksteelGarrison.java +++ b/Mage.Sets/src/mage/cards/d/DarksteelGarrison.java @@ -112,14 +112,15 @@ class FortifyAbility extends ActivatedAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { - if (super.canActivate(playerId, game)) { + public ActivationStatus canActivate(UUID playerId, Game game) { + ActivationStatus activationStatus = super.canActivate(playerId, game); + if (activationStatus.canActivate()) { Permanent permanent = game.getPermanent(sourceId); if (permanent != null && permanent.hasSubtype(SubType.FORTIFICATION, game)) { - return true; + return activationStatus; } } - return false; + return ActivationStatus.getFalse(); } public FortifyAbility(final FortifyAbility ability) { diff --git a/Mage.Sets/src/mage/cards/d/DereviEmpyrialTactician.java b/Mage.Sets/src/mage/cards/d/DereviEmpyrialTactician.java index 2ac726055c..78a54e3007 100644 --- a/Mage.Sets/src/mage/cards/d/DereviEmpyrialTactician.java +++ b/Mage.Sets/src/mage/cards/d/DereviEmpyrialTactician.java @@ -41,8 +41,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.game.Game; @@ -139,10 +139,10 @@ class DereviEmpyrialTacticianAbility extends ActivatedAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { Zone currentZone = game.getState().getZone(this.getSourceId()); if (currentZone == null || currentZone != Zone.COMMAND) { - return false; + return ActivationStatus.getFalse(); } return super.canActivate(playerId, game); } diff --git a/Mage.Sets/src/mage/cards/d/DescendantsPath.java b/Mage.Sets/src/mage/cards/d/DescendantsPath.java index c1eabec49b..d1902d961f 100644 --- a/Mage.Sets/src/mage/cards/d/DescendantsPath.java +++ b/Mage.Sets/src/mage/cards/d/DescendantsPath.java @@ -29,6 +29,7 @@ package mage.cards.d; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -47,12 +48,12 @@ import mage.players.Player; /** * * @author noxx - + * */ public class DescendantsPath extends CardImpl { public DescendantsPath(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); // At the beginning of your upkeep, reveal the top card of your library. If it's a creature card that shares a creature type with a creature you control, you may cast that card without paying its mana cost. Otherwise, put that card on the bottom of your library. Ability ability = new BeginningOfUpkeepTriggeredAbility(new DescendantsPathEffect(), TargetController.YOU, false); @@ -99,7 +100,7 @@ class DescendantsPathEffect extends OneShotEffect { if (card.isCreature()) { FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); boolean found = false; - for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { if (card.shareSubtypes(permanent, game)) { found = true; break; @@ -108,7 +109,7 @@ class DescendantsPathEffect extends OneShotEffect { if (found) { game.informPlayers(sourceObject.getLogName() + ": Found a creature that shares a creature type with the revealed card."); if (controller.chooseUse(Outcome.Benefit, "Cast the card?", source, game)) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } else { game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " canceled casting the card."); controller.getLibrary().putOnBottom(card, game); @@ -128,4 +129,3 @@ class DescendantsPathEffect extends OneShotEffect { return false; } } - diff --git a/Mage.Sets/src/mage/cards/d/DiluvianPrimordial.java b/Mage.Sets/src/mage/cards/d/DiluvianPrimordial.java index 073afab433..57a81ea366 100644 --- a/Mage.Sets/src/mage/cards/d/DiluvianPrimordial.java +++ b/Mage.Sets/src/mage/cards/d/DiluvianPrimordial.java @@ -29,6 +29,7 @@ package mage.cards.d; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.ContinuousEffect; @@ -39,9 +40,9 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; @@ -63,7 +64,7 @@ import mage.target.targetpointer.FixedTarget; public class DiluvianPrimordial extends CardImpl { public DiluvianPrimordial(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{U}"); this.subtype.add(SubType.AVATAR); this.power = new MageInt(5); @@ -128,7 +129,7 @@ class DiluvianPrimordialEffect extends OneShotEffect { Card targetCard = game.getCard(target.getFirstTarget()); if (targetCard != null) { if (controller.chooseUse(outcome, "Cast " + targetCard.getLogName() + '?', source, game)) { - if (controller.cast(targetCard.getSpellAbility(), game, true)) { + if (controller.cast(targetCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { ContinuousEffect effect = new DiluvianPrimordialReplacementEffect(); effect.setTargetPointer(new FixedTarget(targetCard.getId(), game.getState().getZoneChangeCounter(targetCard.getId()))); game.addEffect(effect, source); diff --git a/Mage.Sets/src/mage/cards/d/DjinnOfWishes.java b/Mage.Sets/src/mage/cards/d/DjinnOfWishes.java index a6ca79ebae..e182723c98 100644 --- a/Mage.Sets/src/mage/cards/d/DjinnOfWishes.java +++ b/Mage.Sets/src/mage/cards/d/DjinnOfWishes.java @@ -30,6 +30,7 @@ package mage.cards.d; import java.util.UUID; import mage.MageInt; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -40,8 +41,8 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.*; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; @@ -56,7 +57,7 @@ public class DjinnOfWishes extends CardImpl { private static final String ruleText = "{this} enters the battlefield with three wish counters on it"; public DjinnOfWishes(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); this.subtype.add(SubType.DJINN); this.color.setBlue(true); @@ -103,8 +104,8 @@ class DjinnOfWishesEffect extends OneShotEffect { Cards cards = new CardsImpl(card); controller.revealCards(sourceObject.getIdName(), cards, game); if (!controller.chooseUse(Outcome.PlayForFree, "Play " + card.getName() + " without paying its mana cost?", source, game) - || !controller.playCard(card, game, true, true)) { - card.moveToZone(Zone.EXILED, source.getSourceId(), game, false); + || !controller.playCard(card, game, true, true, new MageObjectReference(source.getSourceObject(game), game))) { + controller.moveCards(card, Zone.EXILED, source, game); } return true; } diff --git a/Mage.Sets/src/mage/cards/d/DrainPower.java b/Mage.Sets/src/mage/cards/d/DrainPower.java index 8e81cc943c..474aa972db 100644 --- a/Mage.Sets/src/mage/cards/d/DrainPower.java +++ b/Mage.Sets/src/mage/cards/d/DrainPower.java @@ -102,7 +102,7 @@ class DrainPowerEffect extends OneShotEffect { List<Permanent> ignorePermanents = new ArrayList<>(); Map<Permanent, List<ActivatedManaAbilityImpl>> manaAbilitiesMap = new HashMap<>(); TargetPermanent target = null; - + while (true) { manaAbilitiesMap.clear(); for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, targetPlayer.getId(), game)) { @@ -112,7 +112,7 @@ class DrainPowerEffect extends OneShotEffect { for (Ability ability : permanent.getAbilities()) { if (ability instanceof ActivatedAbility && ability.getAbilityType() == AbilityType.MANA) { ActivatedManaAbilityImpl manaAbility = (ActivatedManaAbilityImpl) ability; - if (manaAbility != null && manaAbility.canActivate(targetPlayer.getId(), game)) { + if (manaAbility != null && manaAbility.canActivate(targetPlayer.getId(), game).canActivate()) { // canActivate can't check for mana abilities that require a mana cost, if the payment isn't possible (Cabal Coffers etc) // so it's necessary to filter them out manually - might be buggy in some fringe cases for (ManaCost manaCost : manaAbility.getManaCosts()) { diff --git a/Mage.Sets/src/mage/cards/e/EliteArcanist.java b/Mage.Sets/src/mage/cards/e/EliteArcanist.java index adced54e58..69b5f382d0 100644 --- a/Mage.Sets/src/mage/cards/e/EliteArcanist.java +++ b/Mage.Sets/src/mage/cards/e/EliteArcanist.java @@ -29,6 +29,7 @@ package mage.cards.e; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -40,8 +41,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -57,7 +58,7 @@ import mage.target.TargetCard; public class EliteArcanist extends CardImpl { public EliteArcanist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); @@ -79,7 +80,7 @@ public class EliteArcanist extends CardImpl { @Override public void adjustCosts(Ability ability, Game game) { - if(ability instanceof SimpleActivatedAbility){ + if (ability instanceof SimpleActivatedAbility) { Permanent sourcePermanent = game.getPermanent(ability.getSourceId()); if (sourcePermanent != null && sourcePermanent.getImprinted() != null && !sourcePermanent.getImprinted().isEmpty()) { Card imprintedInstant = game.getCard(sourcePermanent.getImprinted().get(0)); @@ -103,7 +104,8 @@ public class EliteArcanist extends CardImpl { class EliteArcanistImprintEffect extends OneShotEffect { private static final FilterCard filter = new FilterCard("instant card from your hand"); - static { + + static { filter.add(new CardTypePredicate(CardType.INSTANT)); } @@ -174,10 +176,10 @@ class EliteArcanistCopyEffect extends OneShotEffect { if (controller != null) { Card copiedCard = game.copyCard(imprintedInstant, source, source.getControllerId()); if (copiedCard != null) { - game.getExile().add(source.getSourceId(), "",copiedCard); + game.getExile().add(source.getSourceId(), "", copiedCard); game.getState().setZone(copiedCard.getId(), Zone.EXILED); if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) { - return controller.cast(copiedCard.getSpellAbility(), game, true); + return controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/e/EpicExperiment.java b/Mage.Sets/src/mage/cards/e/EpicExperiment.java index a387fb0656..98eed59786 100644 --- a/Mage.Sets/src/mage/cards/e/EpicExperiment.java +++ b/Mage.Sets/src/mage/cards/e/EpicExperiment.java @@ -29,6 +29,7 @@ package mage.cards.e; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.*; @@ -51,7 +52,7 @@ import mage.target.TargetCard; public class EpicExperiment extends CardImpl { public EpicExperiment(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{U}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}{R}"); // Exile the top X cards of your library. For each instant and sorcery card with // converted mana cost X or less among them, you may cast that card without paying @@ -105,7 +106,7 @@ class EpicExperimentEffect extends OneShotEffect { if (controller.choose(Outcome.PlayForFree, cardsToCast, targetCard, game)) { Card card = game.getCard(targetCard.getFirstTarget()); if (card != null) { - if (controller.cast(card.getSpellAbility(), game, true)) { + if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { cardsToCast.remove(card); } else { game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting."); diff --git a/Mage.Sets/src/mage/cards/e/EtaliPrimalStorm.java b/Mage.Sets/src/mage/cards/e/EtaliPrimalStorm.java index f48ef2ec72..1f8b98ef32 100644 --- a/Mage.Sets/src/mage/cards/e/EtaliPrimalStorm.java +++ b/Mage.Sets/src/mage/cards/e/EtaliPrimalStorm.java @@ -32,6 +32,7 @@ import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -41,8 +42,8 @@ import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.filter.FilterCard; @@ -127,7 +128,7 @@ class EtaliPrimalStormEffect extends OneShotEffect { cardsToCast.addAll(currentExiledCards); boolean alreadyCast = false; while (!cardsToCast.isEmpty()) { - if (!controller.chooseUse(Outcome.PlayForFree, "Cast a" + (alreadyCast ? "nother" : "" ) + " card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) { + if (!controller.chooseUse(Outcome.PlayForFree, "Cast a" + (alreadyCast ? "nother" : "") + " card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) { break; } TargetCard targetCard = new TargetCard(1, Zone.EXILED, new FilterCard("nonland card to cast for free")); @@ -135,7 +136,7 @@ class EtaliPrimalStormEffect extends OneShotEffect { alreadyCast = true; Card card = game.getCard(targetCard.getFirstTarget()); if (card != null) { - if (controller.cast(card.getSpellAbility(), game, true)) { + if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { cardsToCast.remove(card); } else { game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting."); diff --git a/Mage.Sets/src/mage/cards/e/EyeOfTheStorm.java b/Mage.Sets/src/mage/cards/e/EyeOfTheStorm.java index 8739f84300..2672e128c6 100644 --- a/Mage.Sets/src/mage/cards/e/EyeOfTheStorm.java +++ b/Mage.Sets/src/mage/cards/e/EyeOfTheStorm.java @@ -28,6 +28,7 @@ package mage.cards.e; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; @@ -180,7 +181,7 @@ class EyeOfTheStormEffect1 extends OneShotEffect { if (cardToCopy != null) { Card copy = game.copyCard(cardToCopy, source, source.getControllerId()); if (spellController.chooseUse(outcome, "Cast " + copy.getIdName() + " without paying mana cost?", source, game)) { - spellController.cast(copy.getSpellAbility(), game, true); + spellController.cast(copy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/g/Galvanoth.java b/Mage.Sets/src/mage/cards/g/Galvanoth.java index a8f996d0e4..9ba91c83f9 100644 --- a/Mage.Sets/src/mage/cards/g/Galvanoth.java +++ b/Mage.Sets/src/mage/cards/g/Galvanoth.java @@ -29,6 +29,7 @@ package mage.cards.g; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -86,7 +87,7 @@ class GalvanothEffect extends OneShotEffect { controller.lookAtCards(source, null, new CardsImpl(card), game); if (card.isInstant() || card.isSorcery()) { if (controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName() + " without paying its mana cost?", source, game)) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/g/GoblinDarkDwellers.java b/Mage.Sets/src/mage/cards/g/GoblinDarkDwellers.java index 31b558779c..bc7291219a 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinDarkDwellers.java +++ b/Mage.Sets/src/mage/cards/g/GoblinDarkDwellers.java @@ -29,6 +29,7 @@ package mage.cards.g; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.ContinuousEffect; @@ -39,10 +40,10 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.ComparisonType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterInstantOrSorceryCard; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; @@ -58,22 +59,22 @@ import mage.target.targetpointer.FixedTarget; * @author fireshoes */ public class GoblinDarkDwellers extends CardImpl { - + private static final FilterInstantOrSorceryCard filter = new FilterInstantOrSorceryCard("instant or sorcery card with converted mana cost 3 or less"); - + static { filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 4)); } public GoblinDarkDwellers(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); this.subtype.add(SubType.GOBLIN); this.power = new MageInt(4); this.toughness = new MageInt(4); // Menace this.addAbility(new MenaceAbility()); - + // When Goblin Dark-Dwellers enters the battlefield, you may cast target instant or sorcery card with converted mana cost 3 or less // from your graveyard without paying its mana cost. If that card would be put into your graveyard this turn, exile it instead. Ability ability = new EntersBattlefieldTriggeredAbility(new GoblinDarkDwellersEffect()); @@ -115,7 +116,7 @@ class GoblinDarkDwellersEffect extends OneShotEffect { Card card = game.getCard(this.getTargetPointer().getFirst(game, source)); if (card != null) { if (controller.chooseUse(outcome, "Cast " + card.getLogName() + '?', source, game)) { - if (controller.cast(card.getSpellAbility(), game, true)) { + if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { ContinuousEffect effect = new GoblinDarkDwellersReplacementEffect(card.getId()); effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId()))); game.addEffect(effect, source); diff --git a/Mage.Sets/src/mage/cards/g/GreaterGargadon.java b/Mage.Sets/src/mage/cards/g/GreaterGargadon.java index d7f6fd5b34..4a2ce4121d 100644 --- a/Mage.Sets/src/mage/cards/g/GreaterGargadon.java +++ b/Mage.Sets/src/mage/cards/g/GreaterGargadon.java @@ -53,10 +53,8 @@ import mage.target.common.TargetControlledPermanent; */ public class GreaterGargadon extends CardImpl { - - public GreaterGargadon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{9}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{9}{R}"); this.subtype.add(SubType.BEAST); this.power = new MageInt(9); @@ -78,14 +76,14 @@ public class GreaterGargadon extends CardImpl { } } - class GreaterGargadonAbility extends ActivatedAbilityImpl { - + private static final FilterControlledPermanent filter = new FilterControlledPermanent("artifact, creature, or land"); + static { filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.LAND))); } - + public GreaterGargadonAbility() { super(Zone.EXILED, new RemoveCounterSourceEffect(CounterType.TIME.createInstance()), new SacrificeTargetCost(new TargetControlledPermanent(filter))); } @@ -100,16 +98,14 @@ class GreaterGargadonAbility extends ActivatedAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { Card card = game.getCard(this.getSourceId()); - if(super.canActivate(playerId, game) && card != null && card.getCounters(game).getCount(CounterType.TIME) > 0){ - return true; + if (card == null || card.getCounters(game).getCount(CounterType.TIME) == 0) { + return ActivationStatus.getFalse(); } - return false; + return super.canActivate(playerId, game); } - - @Override public String getRule() { return super.getRule() + " Activate this ability only if Greater Gargadon is suspended."; diff --git a/Mage.Sets/src/mage/cards/g/GreenbeltRampager.java b/Mage.Sets/src/mage/cards/g/GreenbeltRampager.java index e7f78f9695..bedf23abc9 100644 --- a/Mage.Sets/src/mage/cards/g/GreenbeltRampager.java +++ b/Mage.Sets/src/mage/cards/g/GreenbeltRampager.java @@ -25,19 +25,19 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.g; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.PayEnergyCost; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; @@ -82,18 +82,18 @@ public class GreenbeltRampager extends CardImpl { @Override public boolean apply(Game game, Ability source) { - Permanent card = game.getPermanent(source.getSourceId()); - Player player = game.getPlayer(source.getControllerId()); - - if (card == null || player == null) return false; - - if (player.getCounters().getCount(CounterType.ENERGY) > 1) { - player.getCounters().removeCounter(CounterType.ENERGY, 2); - } else { - card.moveToZone(Zone.HAND, source.getSourceId(), game, true); - player.addCounters(CounterType.ENERGY.createInstance(), game); + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; } + if (!new PayEnergyCost(2).pay(source, game, source.getSourceId(), source.getControllerId(), true)) { + Permanent sourceObject = source.getSourcePermanentIfItStillExists(game); + if (sourceObject != null) { + controller.moveCards(sourceObject, Zone.HAND, source, game); + controller.addCounters(CounterType.ENERGY.createInstance(), game); + } + } return true; } diff --git a/Mage.Sets/src/mage/cards/g/Guile.java b/Mage.Sets/src/mage/cards/g/Guile.java index 33c35bd6b3..5684559d10 100644 --- a/Mage.Sets/src/mage/cards/g/Guile.java +++ b/Mage.Sets/src/mage/cards/g/Guile.java @@ -29,6 +29,7 @@ package mage.cards.g; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.PutIntoGraveFromAnywhereSourceTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -39,9 +40,9 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -57,7 +58,7 @@ import mage.players.Player; public class Guile extends CardImpl { public Guile(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}{U}"); this.subtype.add(SubType.ELEMENTAL); this.subtype.add(SubType.INCARNATION); this.power = new MageInt(6); @@ -113,7 +114,7 @@ class GuileReplacementEffect extends ReplacementEffectImpl { if (!spell.isCopy()) { Card spellCard = spell.getCard(); if (spellCard != null && controller.chooseUse(Outcome.PlayForFree, "Cast " + spellCard.getIdName() + " for free?", source, game)) { - controller.playCard(spellCard, game, true, true); + controller.playCard(spellCard, game, true, true, new MageObjectReference(source.getSourceObject(game), game)); } return true; } diff --git a/Mage.Sets/src/mage/cards/h/HarnessTheStorm.java b/Mage.Sets/src/mage/cards/h/HarnessTheStorm.java index 2af3d7ebf8..01d8ed1e99 100644 --- a/Mage.Sets/src/mage/cards/h/HarnessTheStorm.java +++ b/Mage.Sets/src/mage/cards/h/HarnessTheStorm.java @@ -28,6 +28,7 @@ package mage.cards.h; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.Effect; @@ -55,7 +56,7 @@ import mage.watchers.common.CastFromHandWatcher; public class HarnessTheStorm extends CardImpl { public HarnessTheStorm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); // Whenever you cast an instant or sorcery spell from your hand, you may cast target card with the same name as that spell from your graveyard. this.addAbility(new HarnessTheStormTriggeredAbility(new HarnessTheStormEffect(), @@ -132,7 +133,7 @@ class HarnessTheStormEffect extends OneShotEffect { Card card = controller.getGraveyard().get(getTargetPointer().getFirst(game, source), game); if (card != null) { if (controller.chooseUse(outcome, "Cast " + card.getIdName() + " from your graveyard?", source, game)) { - controller.cast(card.getSpellAbility(), game, false); + controller.cast(card.getSpellAbility(), game, false, new MageObjectReference(source.getSourceObject(game), game)); } } return true; diff --git a/Mage.Sets/src/mage/cards/h/HazoretsUndyingFury.java b/Mage.Sets/src/mage/cards/h/HazoretsUndyingFury.java index d8a68cf19d..4bbd487925 100644 --- a/Mage.Sets/src/mage/cards/h/HazoretsUndyingFury.java +++ b/Mage.Sets/src/mage/cards/h/HazoretsUndyingFury.java @@ -29,6 +29,7 @@ package mage.cards.h; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DontUntapInControllersUntapStepAllEffect; @@ -129,7 +130,7 @@ class HazoretsUndyingFuryEffect extends OneShotEffect { if (controller.choose(Outcome.PlayForFree, cardsToCast, targetCard, game)) { Card card = game.getCard(targetCard.getFirstTarget()); if (card != null) { - if (controller.cast(card.getSpellAbility(), game, true)) { + if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { cardsToCast.remove(card); } else { game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting."); diff --git a/Mage.Sets/src/mage/cards/h/HellcarverDemon.java b/Mage.Sets/src/mage/cards/h/HellcarverDemon.java index af8462e4b7..6fd523e7b9 100644 --- a/Mage.Sets/src/mage/cards/h/HellcarverDemon.java +++ b/Mage.Sets/src/mage/cards/h/HellcarverDemon.java @@ -32,21 +32,21 @@ import java.util.Objects; import java.util.Set; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.cards.CardsImpl; -import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -110,14 +110,14 @@ class HellcarverDemonEffect extends OneShotEffect { Set<Card> currentExiledCards = new HashSet<>(); currentExiledCards.addAll(controller.getLibrary().getTopCards(game, 6)); controller.moveCardsToExile(currentExiledCards, source, game, true, source.getSourceId(), sourceObject.getIdName()); - + // cast the possible cards without paying the mana Cards cardsToCast = new CardsImpl(); cardsToCast.addAll(currentExiledCards); boolean alreadyCast = false; while (!cardsToCast.isEmpty() && controller.canRespond()) { - if (!controller.chooseUse(outcome, "Cast a" + (alreadyCast ? "nother" : "" ) + " card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) { + if (!controller.chooseUse(outcome, "Cast a" + (alreadyCast ? "nother" : "") + " card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) { break; } TargetCard targetCard = new TargetCard(1, Zone.EXILED, new FilterCard("nonland card to cast for free")); @@ -125,7 +125,7 @@ class HellcarverDemonEffect extends OneShotEffect { alreadyCast = true; Card card = game.getCard(targetCard.getFirstTarget()); if (card != null) { - if (controller.cast(card.getSpellAbility(), game, true)) { + if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { cardsToCast.remove(card); } else { game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting."); diff --git a/Mage.Sets/src/mage/cards/h/HordeOfNotions.java b/Mage.Sets/src/mage/cards/h/HordeOfNotions.java index 641dcf7b2f..eacfd8f841 100644 --- a/Mage.Sets/src/mage/cards/h/HordeOfNotions.java +++ b/Mage.Sets/src/mage/cards/h/HordeOfNotions.java @@ -29,6 +29,7 @@ package mage.cards.h; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -59,7 +60,7 @@ public class HordeOfNotions extends CardImpl { } public HordeOfNotions(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}{U}{B}{R}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}{B}{R}{G}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.ELEMENTAL); this.power = new MageInt(5); @@ -110,7 +111,7 @@ class HordeOfNotionsEffect extends OneShotEffect { if (controller != null) { Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card != null && controller.chooseUse(outcome, "Play " + card.getName() + " from your graveyard for free?", source, game)) { - controller.playCard(card, game, true, true); + controller.playCard(card, game, true, true, new MageObjectReference(source.getSourceObject(game), game)); } return true; } diff --git a/Mage.Sets/src/mage/cards/i/IsochronScepter.java b/Mage.Sets/src/mage/cards/i/IsochronScepter.java index b7ac1defaf..ded92dd8df 100644 --- a/Mage.Sets/src/mage/cards/i/IsochronScepter.java +++ b/Mage.Sets/src/mage/cards/i/IsochronScepter.java @@ -28,6 +28,7 @@ package mage.cards.i; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -58,7 +59,7 @@ import org.apache.log4j.Logger; public class IsochronScepter extends CardImpl { public IsochronScepter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); // Imprint - When Isochron Scepter enters the battlefield, you may exile an instant card with converted mana cost 2 or less from your hand. this.addAbility(new EntersBattlefieldTriggeredAbility(new IsochronScepterImprintEffect(), true, "<i>Imprint — </i>")); @@ -162,7 +163,7 @@ class IsochronScepterCopyEffect extends OneShotEffect { game.getState().setZone(copiedCard.getId(), Zone.EXILED); if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) { if (copiedCard.getSpellAbility() != null) { - controller.cast(copiedCard.getSpellAbility(), game, true); + controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } else { Logger.getLogger(IsochronScepterCopyEffect.class).error("Isochron Scepter: spell ability == null " + copiedCard.getName()); } diff --git a/Mage.Sets/src/mage/cards/i/IzzetChemister.java b/Mage.Sets/src/mage/cards/i/IzzetChemister.java index 2663fc9d5a..1f004e586d 100644 --- a/Mage.Sets/src/mage/cards/i/IzzetChemister.java +++ b/Mage.Sets/src/mage/cards/i/IzzetChemister.java @@ -29,6 +29,7 @@ package mage.cards.i; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; @@ -43,8 +44,8 @@ import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.common.FilterOwnedCard; @@ -144,7 +145,7 @@ class IzzetChemisterCastFromExileEffect extends OneShotEffect { while (cardsToExile.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); cardsToExile.remove(card); } else { break OuterLoop; diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index c8fddaa7ac..493d171708 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -30,6 +30,7 @@ package mage.cards.j; import java.util.ArrayList; import java.util.Set; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; @@ -43,9 +44,9 @@ import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.filter.FilterCard; @@ -290,7 +291,7 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { while (jaceExileZone.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, jaceExileZone, target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - if (controller.cast(card.getSpellAbility(), game, true)) { + if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { game.getExile().removeCard(card, game); } } diff --git a/Mage.Sets/src/mage/cards/j/JacesMindseeker.java b/Mage.Sets/src/mage/cards/j/JacesMindseeker.java index 0df0bc549e..99b271b564 100644 --- a/Mage.Sets/src/mage/cards/j/JacesMindseeker.java +++ b/Mage.Sets/src/mage/cards/j/JacesMindseeker.java @@ -31,6 +31,7 @@ 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.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -41,8 +42,8 @@ import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.common.FilterInstantOrSorceryCard; @@ -132,7 +133,7 @@ class JaceMindseekerEffect extends OneShotEffect { && controller.choose(outcome, cardsToCast, target, game)) { Card card = cardsToCast.get(target.getFirstTarget(), game); if (card != null) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java b/Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java index 19aca22058..6fc77c87de 100644 --- a/Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java +++ b/Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java @@ -32,6 +32,7 @@ import java.util.Map; import java.util.UUID; import mage.MageInt; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -41,8 +42,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.WatcherScope; import mage.filter.common.FilterInstantOrSorceryCard; @@ -155,7 +156,7 @@ class JelevaNephaliasCastEffect extends OneShotEffect { if (controller.choose(Outcome.PlayForFree, exileZone, target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - return controller.cast(card.getSpellAbility(), game, true); + return controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/k/KahoMinamoHistorian.java b/Mage.Sets/src/mage/cards/k/KahoMinamoHistorian.java index e9d1f218fb..e55a525d10 100644 --- a/Mage.Sets/src/mage/cards/k/KahoMinamoHistorian.java +++ b/Mage.Sets/src/mage/cards/k/KahoMinamoHistorian.java @@ -30,6 +30,7 @@ package mage.cards.k; import java.util.UUID; import mage.MageInt; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -39,9 +40,9 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.SearchEffect; import mage.cards.*; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.ComparisonType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.filter.FilterCard; @@ -60,7 +61,7 @@ import mage.util.CardUtil; public class KahoMinamoHistorian extends CardImpl { public KahoMinamoHistorian(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); @@ -154,7 +155,7 @@ class KahoMinamoHistorianCastEffect extends OneShotEffect { if (!cards.isEmpty() && controller.choose(Outcome.PlayForFree, cards, target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } return true; diff --git a/Mage.Sets/src/mage/cards/k/KnowledgeExploitation.java b/Mage.Sets/src/mage/cards/k/KnowledgeExploitation.java index 366397c589..fd58a9ea36 100644 --- a/Mage.Sets/src/mage/cards/k/KnowledgeExploitation.java +++ b/Mage.Sets/src/mage/cards/k/KnowledgeExploitation.java @@ -28,6 +28,7 @@ package mage.cards.k; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.ProwlAbility; @@ -35,8 +36,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.common.FilterInstantOrSorceryCard; import mage.game.Game; import mage.players.Player; @@ -50,12 +51,12 @@ import mage.target.common.TargetOpponent; public class KnowledgeExploitation extends CardImpl { public KnowledgeExploitation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.TRIBAL,CardType.SORCERY},"{5}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.TRIBAL, CardType.SORCERY}, "{5}{U}{U}"); this.subtype.add(SubType.ROGUE); // Prowl {3}{U} this.addAbility(new ProwlAbility(this, "{3}{U}")); - + // Search target opponent's library for an instant or sorcery card. You may cast that card without paying its mana cost. Then that player shuffles their library. this.getSpellAbility().addEffect(new KnowledgeExploitationEffect()); this.getSpellAbility().addTarget(new TargetOpponent()); @@ -72,21 +73,21 @@ public class KnowledgeExploitation extends CardImpl { } class KnowledgeExploitationEffect extends OneShotEffect { - + KnowledgeExploitationEffect() { super(Outcome.Benefit); this.staticText = "Search target opponent's library for an instant or sorcery card. You may cast that card without paying its mana cost. Then that player shuffles their library"; } - + KnowledgeExploitationEffect(final KnowledgeExploitationEffect effect) { super(effect); } - + @Override public KnowledgeExploitationEffect copy() { return new KnowledgeExploitationEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -96,7 +97,7 @@ class KnowledgeExploitationEffect extends OneShotEffect { if (controller.searchLibrary(target, game, opponent.getId())) { Card card = opponent.getLibrary().remove(target.getFirstTarget(), game); if (card != null) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } opponent.shuffleLibrary(source, game); diff --git a/Mage.Sets/src/mage/cards/k/KnowledgePool.java b/Mage.Sets/src/mage/cards/k/KnowledgePool.java index 463766dc06..6c96e29546 100644 --- a/Mage.Sets/src/mage/cards/k/KnowledgePool.java +++ b/Mage.Sets/src/mage/cards/k/KnowledgePool.java @@ -29,6 +29,7 @@ package mage.cards.k; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -58,7 +59,7 @@ import mage.util.CardUtil; public class KnowledgePool extends CardImpl { public KnowledgePool(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{6}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}"); // Imprint - When Knowledge Pool enters the battlefield, each player exiles the top three cards of their library this.addAbility(new EntersBattlefieldTriggeredAbility(new KnowledgePoolEffect1(), false)); @@ -177,7 +178,7 @@ class KnowledgePoolEffect2 extends OneShotEffect { while (player.choose(Outcome.PlayForFree, game.getExile().getExileZone(exileZoneId), target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null && !card.getId().equals(spell.getSourceId())) { - return player.cast(card.getSpellAbility(), game, true); + return player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } target.clearChosen(); } diff --git a/Mage.Sets/src/mage/cards/l/LeafCrownedElder.java b/Mage.Sets/src/mage/cards/l/LeafCrownedElder.java index 0680363bb1..d552036578 100644 --- a/Mage.Sets/src/mage/cards/l/LeafCrownedElder.java +++ b/Mage.Sets/src/mage/cards/l/LeafCrownedElder.java @@ -29,6 +29,7 @@ package mage.cards.l; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.abilityword.KinshipAbility; import mage.abilities.effects.OneShotEffect; @@ -36,8 +37,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.players.Player; @@ -48,7 +49,7 @@ import mage.players.Player; public class LeafCrownedElder extends CardImpl { public LeafCrownedElder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); this.subtype.add(SubType.TREEFOLK); this.subtype.add(SubType.SHAMAN); @@ -88,7 +89,7 @@ class LeafCrownedElderPlayEffect extends OneShotEffect { Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (controller != null && card != null) { if (controller.chooseUse(Outcome.PlayForFree, "Play " + card.getIdName() + " without paying its mana cost?", source, game)) { - controller.playCard(card, game, true, true); + controller.playCard(card, game, true, true, new MageObjectReference(source.getSourceObject(game), game)); } return true; } diff --git a/Mage.Sets/src/mage/cards/l/LionsEyeDiamond.java b/Mage.Sets/src/mage/cards/l/LionsEyeDiamond.java index d979ec7ba1..b5bdce5cfb 100644 --- a/Mage.Sets/src/mage/cards/l/LionsEyeDiamond.java +++ b/Mage.Sets/src/mage/cards/l/LionsEyeDiamond.java @@ -1,4 +1,4 @@ - /* +/* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are @@ -49,7 +49,7 @@ import mage.players.Player; public class LionsEyeDiamond extends CardImpl { public LionsEyeDiamond(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{0}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{0}"); // Sacrifice Lion's Eye Diamond, Discard your hand: Add three mana of any one color. Activate this ability only any time you could cast an instant. this.addAbility(new LionsEyeDiamondAbility()); @@ -65,18 +65,17 @@ public class LionsEyeDiamond extends CardImpl { } } - class LionsEyeDiamondAbility extends ActivatedManaAbilityImpl { public LionsEyeDiamondAbility() { super(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(3), new SacrificeSourceCost()); this.addCost(new DiscardHandCost()); - this.netMana.add(new Mana(0,0,0,0,0,0,3, 0)); + this.netMana.add(new Mana(0, 0, 0, 0, 0, 0, 3, 0)); } public LionsEyeDiamondAbility(Zone zone, Mana mana, Cost cost) { super(zone, new BasicManaEffect(mana), cost); - + } public LionsEyeDiamondAbility(final LionsEyeDiamondAbility ability) { @@ -84,12 +83,12 @@ class LionsEyeDiamondAbility extends ActivatedManaAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { Player player = game.getPlayer(playerId); if (player != null && !player.isInPayManaMode()) { return super.canActivate(playerId, game); } - return false; + return ActivationStatus.getFalse(); } @Override @@ -102,4 +101,3 @@ class LionsEyeDiamondAbility extends ActivatedManaAbilityImpl { return super.getRule() + " Activate this ability only any time you could cast an instant."; } } - diff --git a/Mage.Sets/src/mage/cards/l/LivingLore.java b/Mage.Sets/src/mage/cards/l/LivingLore.java index f9ae3d30e3..f6c08cde9b 100644 --- a/Mage.Sets/src/mage/cards/l/LivingLore.java +++ b/Mage.Sets/src/mage/cards/l/LivingLore.java @@ -41,7 +41,6 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Layer; import mage.constants.Outcome; @@ -207,7 +206,7 @@ class LivingLoreSacrificeEffect extends OneShotEffect { } if (exiledCard != null) { if (exiledCard.getSpellAbility().canChooseTarget(game)) { - controller.cast(exiledCard.getSpellAbility(), game, true); + controller.cast(exiledCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/m/MaelstromArchangel.java b/Mage.Sets/src/mage/cards/m/MaelstromArchangel.java index 1c644aab71..720d4b2c32 100644 --- a/Mage.Sets/src/mage/cards/m/MaelstromArchangel.java +++ b/Mage.Sets/src/mage/cards/m/MaelstromArchangel.java @@ -29,6 +29,7 @@ package mage.cards.m; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -37,8 +38,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.common.FilterNonlandCard; import mage.game.Game; @@ -53,7 +54,7 @@ import mage.target.common.TargetCardInHand; public class MaelstromArchangel extends CardImpl { public MaelstromArchangel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}{U}{B}{R}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}{B}{R}{G}"); this.subtype.add(SubType.ANGEL); this.power = new MageInt(5); @@ -61,10 +62,10 @@ public class MaelstromArchangel extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); - + // Whenever Maelstrom Archangel deals combat damage to a player, you may cast a nonland card from your hand without paying its mana cost. this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new MaelstromArchangelCastEffect(), false)); - + } public MaelstromArchangel(final MaelstromArchangel card) { @@ -100,8 +101,8 @@ class MaelstromArchangelCastEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Target target = new TargetCardInHand(filter); - if (target.canChoose(source.getSourceId(), controller.getId(), game) && - controller.chooseUse(outcome, "Cast a nonland card from your hand without paying its mana cost?", source, game)) { + if (target.canChoose(source.getSourceId(), controller.getId(), game) + && controller.chooseUse(outcome, "Cast a nonland card from your hand without paying its mana cost?", source, game)) { Card cardToCast = null; boolean cancel = false; while (controller.canRespond() && !cancel) { @@ -115,7 +116,7 @@ class MaelstromArchangelCastEffect extends OneShotEffect { } } if (cardToCast != null) { - controller.cast(cardToCast.getSpellAbility(), game, true); + controller.cast(cardToCast.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } return true; diff --git a/Mage.Sets/src/mage/cards/m/ManaCache.java b/Mage.Sets/src/mage/cards/m/ManaCache.java index de03d528f3..07f4adf03b 100644 --- a/Mage.Sets/src/mage/cards/m/ManaCache.java +++ b/Mage.Sets/src/mage/cards/m/ManaCache.java @@ -65,7 +65,7 @@ public class ManaCache extends CardImpl { // At the beginning of each player's end step, put a charge counter on Mana Cache for each untapped land that player controls. TriggeredAbility ability = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of each player's end step", true, new ManaCacheEffect()); this.addAbility(ability); - + // Remove a charge counter from Mana Cache: Add {C}. Any player may activate this ability but only during their turn before the end step. this.addAbility(new ManaCacheManaAbility()); } @@ -83,6 +83,7 @@ public class ManaCache extends CardImpl { class ManaCacheEffect extends OneShotEffect { private static final FilterPermanent filter = new FilterControlledLandPermanent(); + static { filter.add(Predicates.not(new TappedPredicate())); } @@ -114,7 +115,7 @@ class ManaCacheManaAbility extends ActivatedManaAbilityImpl { public ManaCacheManaAbility() { super(Zone.BATTLEFIELD, new BasicManaEffect(Mana.ColorlessMana(1)), new RemoveCountersSourceCost(CounterType.CHARGE.createInstance(1))); - this.netMana.add(new Mana(0,0,0,0,0,0,0,1)); + this.netMana.add(new Mana(0, 0, 0, 0, 0, 0, 0, 1)); } public ManaCacheManaAbility(final ManaCacheManaAbility ability) { @@ -122,18 +123,18 @@ class ManaCacheManaAbility extends ActivatedManaAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { if (!super.hasMoreActivationsThisTurn(game) || !(condition == null || condition.apply(game, this))) { - return false; + return ActivationStatus.getFalse(); } Player player = game.getPlayer(playerId); if (player != null && playerId.equals(game.getActivePlayerId()) && game.getStep().getType().isBefore(PhaseStep.END_TURN)) { if (costs.canPay(this, sourceId, playerId, game)) { this.setControllerId(playerId); - return true; + return ActivationStatus.getTrue(); } } - return false; + return ActivationStatus.getFalse(); } @Override diff --git a/Mage.Sets/src/mage/cards/m/Martyrdom.java b/Mage.Sets/src/mage/cards/m/Martyrdom.java index d57ed53505..c6ad4435ed 100644 --- a/Mage.Sets/src/mage/cards/m/Martyrdom.java +++ b/Mage.Sets/src/mage/cards/m/Martyrdom.java @@ -126,7 +126,7 @@ class MartyrdomActivatedAbility extends ActivatedAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { if (playerId.equals(caster)) { Permanent permanent = game.getBattlefield().getPermanent(this.getSourceId()); if (permanent != null) { @@ -135,7 +135,7 @@ class MartyrdomActivatedAbility extends ActivatedAbilityImpl { } } } - return false; + return ActivationStatus.getFalse(); } @Override diff --git a/Mage.Sets/src/mage/cards/m/MasterOfPredicaments.java b/Mage.Sets/src/mage/cards/m/MasterOfPredicaments.java index 67edf0fb6e..a535a30581 100644 --- a/Mage.Sets/src/mage/cards/m/MasterOfPredicaments.java +++ b/Mage.Sets/src/mage/cards/m/MasterOfPredicaments.java @@ -29,6 +29,7 @@ package mage.cards.m; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -37,8 +38,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.FilterCard; import mage.game.Game; import mage.players.Player; @@ -52,7 +53,7 @@ import mage.target.common.TargetCardInHand; public class MasterOfPredicaments extends CardImpl { public MasterOfPredicaments(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); this.subtype.add(SubType.SPHINX); this.power = new MageInt(4); @@ -125,7 +126,7 @@ class MasterOfPredicamentsEffect extends OneShotEffect { // If the revealed card is a land, you can't cast it. So nothing happens } else { if (controller.chooseUse(outcome, "Cast " + cardFromHand.getName() + " without paying its mana cost?", source, game)) { - controller.cast(cardFromHand.getSpellAbility(), game, true); + controller.cast(cardFromHand.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } diff --git a/Mage.Sets/src/mage/cards/m/MemoryPlunder.java b/Mage.Sets/src/mage/cards/m/MemoryPlunder.java index 7eea6a6dc0..f6d4726edd 100644 --- a/Mage.Sets/src/mage/cards/m/MemoryPlunder.java +++ b/Mage.Sets/src/mage/cards/m/MemoryPlunder.java @@ -28,6 +28,7 @@ package mage.cards.m; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -49,6 +50,7 @@ import mage.target.common.TargetCardInOpponentsGraveyard; public class MemoryPlunder extends CardImpl { private static final FilterCard filter = new FilterCard("instant or sorcery card from an opponent's graveyard"); + static { filter.add(Predicates.or( new CardTypePredicate(CardType.INSTANT), @@ -56,8 +58,7 @@ public class MemoryPlunder extends CardImpl { } public MemoryPlunder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U/B}{U/B}{U/B}{U/B}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U/B}{U/B}{U/B}{U/B}"); // You may cast target instant or sorcery card from an opponent's graveyard without paying its mana cost. this.getSpellAbility().addEffect(new MemoryPlunderEffect()); @@ -96,8 +97,8 @@ class MemoryPlunderEffect extends OneShotEffect { Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card != null) { Player player = game.getPlayer(source.getControllerId()); - if (player != null && player.chooseUse(Outcome.Benefit, "Cast " + card.getName() +" without paying cost?", source, game)) { - player.cast(card.getSpellAbility(), game, true); + if (player != null && player.chooseUse(Outcome.Benefit, "Cast " + card.getName() + " without paying cost?", source, game)) { + player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } return false; diff --git a/Mage.Sets/src/mage/cards/m/Merseine.java b/Mage.Sets/src/mage/cards/m/Merseine.java index f9a7ffb438..9e74f0ed6b 100644 --- a/Mage.Sets/src/mage/cards/m/Merseine.java +++ b/Mage.Sets/src/mage/cards/m/Merseine.java @@ -33,9 +33,9 @@ import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.SourceHasCounterCondition; -import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect; import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; +import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; import mage.abilities.effects.common.AttachEffect; @@ -53,13 +53,13 @@ import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; /** - * + * * @author L_J */ public class Merseine extends CardImpl { public Merseine(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -74,9 +74,9 @@ public class Merseine extends CardImpl { this.addAbility(new EntersBattlefieldAbility(effect)); // Enchanted creature doesn't untap during its controller's untap step if Merseine has a net counter on it. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepEnchantedEffect(), - new SourceHasCounterCondition(CounterType.NET)).setText("Enchanted creature doesn't untap during its controller's untap step if Merseine has a net counter on it"))); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepEnchantedEffect(), + new SourceHasCounterCondition(CounterType.NET)).setText("Enchanted creature doesn't untap during its controller's untap step if Merseine has a net counter on it"))); + // Pay enchanted creature's mana cost: Remove a net counter from Merseine. Any player may activate this ability, but only if he or she controls the enchanted creature. SimpleActivatedAbility ability = new MerseineActivatedAbility(); ability.setMayActivate(TargetController.ANY); @@ -94,7 +94,7 @@ public class Merseine extends CardImpl { } class MerseineActivatedAbility extends SimpleActivatedAbility { - + public MerseineActivatedAbility() { super(Zone.BATTLEFIELD, new RemoveCounterSourceEffect(CounterType.NET.createInstance()), new MerseineCost()); } @@ -109,7 +109,7 @@ class MerseineActivatedAbility extends SimpleActivatedAbility { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { Permanent sourcePermanent = game.getBattlefield().getPermanent(this.getSourceId()); if (sourcePermanent != null) { Permanent attachedTo = game.getPermanent(sourcePermanent.getAttachedTo()); @@ -117,7 +117,7 @@ class MerseineActivatedAbility extends SimpleActivatedAbility { return super.canActivate(attachedTo.getControllerId(), game); } } - return false; + return ActivationStatus.getFalse(); } @Override diff --git a/Mage.Sets/src/mage/cards/m/MindclawShaman.java b/Mage.Sets/src/mage/cards/m/MindclawShaman.java index 343c7be305..2656e750f0 100644 --- a/Mage.Sets/src/mage/cards/m/MindclawShaman.java +++ b/Mage.Sets/src/mage/cards/m/MindclawShaman.java @@ -30,6 +30,7 @@ package mage.cards.m; import java.util.UUID; import mage.MageInt; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -37,8 +38,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; @@ -55,7 +56,7 @@ import mage.target.common.TargetOpponent; public class MindclawShaman extends CardImpl { public MindclawShaman(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); this.subtype.add(SubType.VIASHINO); this.subtype.add(SubType.SHAMAN); @@ -81,13 +82,13 @@ public class MindclawShaman extends CardImpl { class MindclawShamanEffect extends OneShotEffect { private static final FilterCard filter = new FilterCard("instant or sorcery card"); - + static { filter.add(Predicates.or( - new CardTypePredicate(CardType.INSTANT), - new CardTypePredicate(CardType.SORCERY))); + new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY))); } - + public MindclawShamanEffect() { super(Outcome.Discard); this.staticText = "target opponent reveals their hand. You may cast an instant or sorcery card from it without paying its mana cost"; @@ -106,7 +107,7 @@ class MindclawShamanEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player targetOpponent = game.getPlayer(source.getFirstTarget()); MageObject sourceObject = source.getSourceObject(game); - if (targetOpponent != null && sourceObject != null) { + if (targetOpponent != null && sourceObject != null) { if (!targetOpponent.getHand().isEmpty()) { targetOpponent.revealCards(sourceObject.getName(), targetOpponent.getHand(), game); Player controller = game.getPlayer(source.getControllerId()); @@ -117,9 +118,9 @@ class MindclawShamanEffect extends OneShotEffect { Card chosenCard = targetOpponent.getHand().get(target.getFirstTarget(), game); if (chosenCard != null) { if (controller.chooseUse(Outcome.Benefit, "Cast the chosen card?", source, game)) { - controller.cast(chosenCard.getSpellAbility(), game, true); + controller.cast(chosenCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } else { - game.informPlayers(sourceObject.getLogName() +": " + controller.getLogName() + " canceled casting the card."); + game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " canceled casting the card."); } } } @@ -129,4 +130,4 @@ class MindclawShamanEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/m/MindleechMass.java b/Mage.Sets/src/mage/cards/m/MindleechMass.java index a604d7764a..9778b112f6 100644 --- a/Mage.Sets/src/mage/cards/m/MindleechMass.java +++ b/Mage.Sets/src/mage/cards/m/MindleechMass.java @@ -29,6 +29,7 @@ package mage.cards.m; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -39,8 +40,8 @@ import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterNonlandCard; import mage.game.Game; @@ -54,7 +55,7 @@ import mage.target.TargetCard; public class MindleechMass extends CardImpl { public MindleechMass(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{U}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{U}{B}{B}"); this.subtype.add(SubType.HORROR); this.power = new MageInt(6); @@ -62,7 +63,7 @@ public class MindleechMass extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); - + // Whenever Mindleech Mass deals combat damage to a player, you may look at that player's hand. If you do, you may cast a nonland card in it without paying that card's mana cost. this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new MindleechMassEffect(), true, true)); } @@ -96,18 +97,18 @@ class MindleechMassEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source)); - Player you = game.getPlayer(source.getControllerId()); - if (opponent != null && you != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (opponent != null && controller != null) { Cards cardsInHand = new CardsImpl(); cardsInHand.addAll(opponent.getHand()); opponent.revealCards("Opponents hand", cardsInHand, game); if (!cardsInHand.isEmpty() && !cardsInHand.getCards(new FilterNonlandCard(), game).isEmpty()) { TargetCard target = new TargetCard(1, Zone.HAND, new FilterNonlandCard()); - if (you.chooseTarget(Outcome.PlayForFree, cardsInHand, target, source, game)) { + if (controller.chooseTarget(Outcome.PlayForFree, cardsInHand, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - you.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/m/MindsDilation.java b/Mage.Sets/src/mage/cards/m/MindsDilation.java index e19befd169..bbe23a80fb 100644 --- a/Mage.Sets/src/mage/cards/m/MindsDilation.java +++ b/Mage.Sets/src/mage/cards/m/MindsDilation.java @@ -30,6 +30,7 @@ package mage.cards.m; import java.util.List; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SpellCastOpponentTriggeredAbility; import mage.abilities.effects.Effect; @@ -55,7 +56,7 @@ import mage.watchers.common.SpellsCastWatcher; public class MindsDilation extends CardImpl { public MindsDilation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{5}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{U}{U}"); // Whenever an opponent casts their first spell each turn, that player exiles the top card of their library. If it's a nonland card, // you may cast it without paying its mana cost. @@ -138,7 +139,7 @@ class MindsDilationEffect extends OneShotEffect { if (card != null && opponent.moveCards(card, Zone.EXILED, source, game)) { if (!card.isLand()) { if (controller.chooseUse(outcome, "Cast " + card.getLogName() + " without paying its mana cost from exile?", source, game)) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/m/MizzixsMastery.java b/Mage.Sets/src/mage/cards/m/MizzixsMastery.java index fd3b892bd8..b2c167ca28 100644 --- a/Mage.Sets/src/mage/cards/m/MizzixsMastery.java +++ b/Mage.Sets/src/mage/cards/m/MizzixsMastery.java @@ -29,6 +29,7 @@ package mage.cards.m; import java.util.Set; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; @@ -106,7 +107,7 @@ class MizzixsMasteryEffect extends OneShotEffect { Card cardCopy = game.copyCard(card, source, source.getControllerId()); if (cardCopy.getSpellAbility().canChooseTarget(game) && controller.chooseUse(outcome, "Cast copy of " + card.getName() + " without paying its mana cost?", source, game)) { - controller.cast(cardCopy.getSpellAbility(), game, true); + controller.cast(cardCopy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } @@ -150,7 +151,7 @@ class MizzixsMasteryOverloadEffect extends OneShotEffect { if (controller.choose(outcome, copiedCards, targetCard, game)) { Card selectedCard = game.getCard(targetCard.getFirstTarget()); if (selectedCard != null && selectedCard.getSpellAbility().canChooseTarget(game)) { - if (controller.cast(selectedCard.getSpellAbility(), game, true)) { + if (controller.cast(selectedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { copiedCards.remove(selectedCard); } } diff --git a/Mage.Sets/src/mage/cards/o/OmenMachine.java b/Mage.Sets/src/mage/cards/o/OmenMachine.java index c8928fce4a..6843ae9df5 100644 --- a/Mage.Sets/src/mage/cards/o/OmenMachine.java +++ b/Mage.Sets/src/mage/cards/o/OmenMachine.java @@ -28,6 +28,7 @@ package mage.cards.o; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.BeginningOfDrawTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -126,7 +127,7 @@ class OmenMachineEffect2 extends OneShotEffect { if (card.isLand()) { player.moveCards(card, Zone.BATTLEFIELD, source, game); } else { - player.cast(card.getSpellAbility(), game, true); + player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } return true; diff --git a/Mage.Sets/src/mage/cards/o/OracleOfBones.java b/Mage.Sets/src/mage/cards/o/OracleOfBones.java index 607b7d4ae2..015687d597 100644 --- a/Mage.Sets/src/mage/cards/o/OracleOfBones.java +++ b/Mage.Sets/src/mage/cards/o/OracleOfBones.java @@ -29,6 +29,7 @@ package mage.cards.o; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -41,8 +42,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.common.FilterInstantOrSorceryCard; import mage.game.Game; @@ -57,7 +58,7 @@ import mage.target.common.TargetCardInHand; public class OracleOfBones extends CardImpl { public OracleOfBones(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); this.subtype.add(SubType.MINOTAUR); this.subtype.add(SubType.SHAMAN); @@ -107,8 +108,8 @@ class OracleOfBonesCastEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Target target = new TargetCardInHand(filter); - if (target.canChoose(source.getSourceId(), controller.getId(), game) && - controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", source, game)) { + if (target.canChoose(source.getSourceId(), controller.getId(), game) + && controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", source, game)) { Card cardToCast = null; boolean cancel = false; while (controller.canRespond() && !cancel) { @@ -122,7 +123,7 @@ class OracleOfBonesCastEffect extends OneShotEffect { } } if (cardToCast != null) { - controller.cast(cardToCast.getSpellAbility(), game, true); + controller.cast(cardToCast.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } return true; diff --git a/Mage.Sets/src/mage/cards/p/PanopticMirror.java b/Mage.Sets/src/mage/cards/p/PanopticMirror.java index c259a2c7bd..4be62fb3a7 100644 --- a/Mage.Sets/src/mage/cards/p/PanopticMirror.java +++ b/Mage.Sets/src/mage/cards/p/PanopticMirror.java @@ -28,6 +28,7 @@ package mage.cards.p; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -57,7 +58,7 @@ import mage.util.CardUtil; public class PanopticMirror extends CardImpl { public PanopticMirror(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); // Imprint - {X}, {tap}: You may exile an instant or sorcery card with converted mana cost X from your hand. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PanopticMirrorExileEffect(), new VariableManaCost()); @@ -114,7 +115,7 @@ class PanopticMirrorExileEffect extends OneShotEffect { if (card != null) { card.moveToExile(CardUtil.getCardExileZoneId(game, source), "Panoptic Mirror", source.getSourceId(), game); Permanent PanopticMirror = game.getPermanent(source.getSourceId()); - if(PanopticMirror != null){ + if (PanopticMirror != null) { PanopticMirror.imprint(card.getId(), game); } return true; @@ -149,31 +150,29 @@ class PanopticMirrorCastEffect extends OneShotEffect { } if (PanopticMirror != null && PanopticMirror.getImprinted() != null && !PanopticMirror.getImprinted().isEmpty() && controller != null) { CardsImpl cards = new CardsImpl(); - for(UUID uuid : PanopticMirror.getImprinted()){ + for (UUID uuid : PanopticMirror.getImprinted()) { Card card = game.getCard(uuid); - if(card != null){ - if(card.isSplitCard()){ - cards.add(((SplitCard)card).getLeftHalfCard()); - cards.add(((SplitCard)card).getRightHalfCard()); - } - else{ + if (card != null) { + if (card.isSplitCard()) { + cards.add(((SplitCard) card).getLeftHalfCard()); + cards.add(((SplitCard) card).getRightHalfCard()); + } else { cards.add(card); } } } Card cardToCopy; - if(cards.size() == 1){ + if (cards.size() == 1) { cardToCopy = cards.getCards(game).iterator().next(); - } - else{ + } else { TargetCard target = new TargetCard(1, Zone.EXILED, new FilterCard("card to copy")); controller.choose(Outcome.Copy, cards, target, game); cardToCopy = cards.get(target.getFirstTarget(), game); } - if(cardToCopy != null){ + if (cardToCopy != null) { Card copy = game.copyCard(cardToCopy, source, source.getControllerId()); if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) { - return controller.cast(copy.getSpellAbility(), game, true); + return controller.cast(copy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } return true; diff --git a/Mage.Sets/src/mage/cards/p/PossibilityStorm.java b/Mage.Sets/src/mage/cards/p/PossibilityStorm.java index 6ccd585beb..d99782e3a0 100644 --- a/Mage.Sets/src/mage/cards/p/PossibilityStorm.java +++ b/Mage.Sets/src/mage/cards/p/PossibilityStorm.java @@ -30,6 +30,7 @@ package mage.cards.p; import java.util.EnumSet; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; @@ -155,7 +156,7 @@ class PossibilityStormEffect extends OneShotEffect { && !card.isLand() && card.getSpellAbility().canChooseTarget(game)) { if (spellController.chooseUse(Outcome.PlayForFree, "Cast " + card.getLogName() + " without paying cost?", source, game)) { - spellController.cast(card.getSpellAbility(), game, true); + spellController.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } diff --git a/Mage.Sets/src/mage/cards/q/QasaliAmbusher.java b/Mage.Sets/src/mage/cards/q/QasaliAmbusher.java index 4ff501b423..1df9bc3a42 100644 --- a/Mage.Sets/src/mage/cards/q/QasaliAmbusher.java +++ b/Mage.Sets/src/mage/cards/q/QasaliAmbusher.java @@ -29,6 +29,7 @@ package mage.cards.q; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.ActivatedAbilityImpl; import mage.abilities.SpellAbility; @@ -52,7 +53,7 @@ import mage.players.Player; public class QasaliAmbusher extends CardImpl { public QasaliAmbusher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{W}"); this.subtype.add(SubType.CAT); this.subtype.add(SubType.WARRIOR); @@ -102,18 +103,16 @@ class QasaliAmbusherAbility extends ActivatedAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { - if (super.canActivate(playerId, game)) { - 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())) { - return true; - } + public ActivationStatus canActivate(UUID playerId, Game game) { + 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())) { + return super.canActivate(playerId, game); } } } - return false; + return ActivationStatus.getFalse(); } @Override @@ -151,7 +150,7 @@ class QasaliAmbusherEffect extends OneShotEffect { if (controller != null) { SpellAbility spellAbility = card.getSpellAbility(); spellAbility.clear(); - return controller.cast(spellAbility, game, true); + return controller.cast(spellAbility, game, true, new MageObjectReference(source.getSourceObject(game), game)); } } return false; diff --git a/Mage.Sets/src/mage/cards/r/RashmiEternitiesCrafter.java b/Mage.Sets/src/mage/cards/r/RashmiEternitiesCrafter.java index d9942e4b18..a0438b8eb5 100644 --- a/Mage.Sets/src/mage/cards/r/RashmiEternitiesCrafter.java +++ b/Mage.Sets/src/mage/cards/r/RashmiEternitiesCrafter.java @@ -30,6 +30,7 @@ package mage.cards.r; import java.util.List; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.Effect; @@ -39,8 +40,8 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.game.Game; @@ -56,7 +57,7 @@ import mage.watchers.common.SpellsCastWatcher; public class RashmiEternitiesCrafter extends CardImpl { public RashmiEternitiesCrafter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.ELF); this.subtype.add(SubType.DRUID); @@ -146,7 +147,7 @@ class RashmiEternitiesCrafterEffect extends OneShotEffect { || card.isLand() || card.getConvertedManaCost() >= (int) cmcObject || !controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName() + " without paying its mana cost?", source, game) - || !controller.cast(card.getSpellAbility(), game, true)) { + || !controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { controller.moveCards(card, Zone.HAND, source, game); } } diff --git a/Mage.Sets/src/mage/cards/r/ReversalOfFortune.java b/Mage.Sets/src/mage/cards/r/ReversalOfFortune.java index 1af82ceb56..d1d3e1e4ac 100644 --- a/Mage.Sets/src/mage/cards/r/ReversalOfFortune.java +++ b/Mage.Sets/src/mage/cards/r/ReversalOfFortune.java @@ -28,6 +28,7 @@ package mage.cards.r; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -51,8 +52,7 @@ import mage.target.common.TargetOpponent; public class ReversalOfFortune extends CardImpl { public ReversalOfFortune(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{R}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}"); // Target opponent reveals their hand. You may copy an instant or sorcery card in it. If you do, you may cast the copy without paying its mana cost. this.getSpellAbility().addEffect(new ReversalOfFortuneEffect()); @@ -69,7 +69,6 @@ public class ReversalOfFortune extends CardImpl { } } - class ReversalOfFortuneEffect extends OneShotEffect { public ReversalOfFortuneEffect() { @@ -88,28 +87,27 @@ class ReversalOfFortuneEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - + Player controller = game.getPlayer(source.getControllerId()); Player opponent = game.getPlayer(source.getFirstTarget()); if (controller != null && opponent != null) { // Target opponent reveals their hand - Cards revealedCards = new CardsImpl(); - revealedCards.addAll(opponent.getHand()); + Cards revealedCards = new CardsImpl(); + revealedCards.addAll(opponent.getHand()); opponent.revealCards("Reveal", revealedCards, game); - + //You may copy an instant or sorcery card in it - TargetCard target = new TargetCard(1, Zone.HAND, new FilterInstantOrSorceryCard()); + TargetCard target = new TargetCard(1, Zone.HAND, new FilterInstantOrSorceryCard()); target.setRequired(false); if (controller.choose(outcome, revealedCards, target, game)) { Card card = revealedCards.get((UUID) target.getFirstTarget(), game); //If you do, you may cast the copy without paying its mana cost - if(card != null){ + if (card != null) { Card copiedCard = game.copyCard(card, source, source.getControllerId()); if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) { - controller.cast(copiedCard.getSpellAbility(), game, true); + controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } - } - else{ + } else { return false; } } @@ -117,4 +115,4 @@ class ReversalOfFortuneEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/r/RhysticCave.java b/Mage.Sets/src/mage/cards/r/RhysticCave.java index bca1ff1151..9b2f08afe2 100644 --- a/Mage.Sets/src/mage/cards/r/RhysticCave.java +++ b/Mage.Sets/src/mage/cards/r/RhysticCave.java @@ -87,12 +87,12 @@ class RhysticCaveManaAbility extends ActivatedManaAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { Player player = game.getPlayer(playerId); if (player != null && !player.isInPayManaMode()) { return super.canActivate(playerId, game); } - return false; + return ActivationStatus.getFalse(); } @Override diff --git a/Mage.Sets/src/mage/cards/s/ShellOfTheLastKappa.java b/Mage.Sets/src/mage/cards/s/ShellOfTheLastKappa.java index dfaeef31dc..f5a93d049a 100644 --- a/Mage.Sets/src/mage/cards/s/ShellOfTheLastKappa.java +++ b/Mage.Sets/src/mage/cards/s/ShellOfTheLastKappa.java @@ -28,6 +28,7 @@ package mage.cards.s; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; @@ -157,7 +158,7 @@ class ShellOfTheLastKappaCastEffect extends OneShotEffect { Card card = game.getCard(target.getFirstTarget()); if (card != null) { game.getExile().removeCard(card, game); - return controller.cast(card.getSpellAbility(), game, true); + return controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/s/SilentBladeOni.java b/Mage.Sets/src/mage/cards/s/SilentBladeOni.java index 59b9ffce96..b8536d769b 100644 --- a/Mage.Sets/src/mage/cards/s/SilentBladeOni.java +++ b/Mage.Sets/src/mage/cards/s/SilentBladeOni.java @@ -29,6 +29,7 @@ package mage.cards.s; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -40,8 +41,8 @@ import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterNonlandCard; import mage.game.Game; @@ -55,7 +56,7 @@ import mage.target.TargetCard; public class SilentBladeOni extends CardImpl { public SilentBladeOni(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}{B}{B}"); this.subtype.add(SubType.DEMON); this.subtype.add(SubType.NINJA); @@ -107,7 +108,7 @@ class SilentBladeOniEffect extends OneShotEffect { if (controller.chooseTarget(outcome, cardsInHand, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } diff --git a/Mage.Sets/src/mage/cards/s/SpellQueller.java b/Mage.Sets/src/mage/cards/s/SpellQueller.java index 667e48e2ac..f629c5ce8f 100644 --- a/Mage.Sets/src/mage/cards/s/SpellQueller.java +++ b/Mage.Sets/src/mage/cards/s/SpellQueller.java @@ -31,6 +31,7 @@ import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.LeavesBattlefieldTriggeredAbility; @@ -42,9 +43,9 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.ComparisonType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.ExileZone; @@ -69,7 +70,7 @@ public class SpellQueller extends CardImpl { } public SpellQueller(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(2); this.toughness = new MageInt(3); @@ -160,13 +161,13 @@ class SpellQuellerLeavesEffect extends OneShotEffect { if (exile != null) { // null is valid if source left battlefield before enters the battlefield effect resolved Card card = null; Set<Card> exiledCards = exile.getCards(game); - if (exiledCards != null && !exiledCards.isEmpty()) { - card = exiledCards.iterator().next(); + if (exiledCards != null && !exiledCards.isEmpty()) { + card = exiledCards.iterator().next(); if (card != null) { Player cardOwner = game.getPlayer(card.getOwnerId()); if (cardOwner != null) { if (cardOwner.chooseUse(Outcome.PlayForFree, "Cast " + card.getLogName() + " without paying cost?", source, game)) { - cardOwner.cast(card.getSpellAbility(), game, true); + cardOwner.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/s/Spellbinder.java b/Mage.Sets/src/mage/cards/s/Spellbinder.java index 085fbde233..2c4ad87d73 100644 --- a/Mage.Sets/src/mage/cards/s/Spellbinder.java +++ b/Mage.Sets/src/mage/cards/s/Spellbinder.java @@ -28,6 +28,7 @@ package mage.cards.s; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -38,8 +39,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -60,12 +61,12 @@ import org.apache.log4j.Logger; public class Spellbinder extends CardImpl { public Spellbinder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); this.subtype.add(SubType.EQUIPMENT); // Imprint - When Spellbinder enters the battlefield, you may exile an instant card from your hand. this.addAbility(new EntersBattlefieldTriggeredAbility(new SpellbinderImprintEffect(), true, "<i>Imprint — </i>")); - + // Whenever equipped creature deals combat damage to a player, you may copy the exiled card. If you do, you may cast the copy without paying its mana cost. this.addAbility(new SpellbinderTriggeredAbility()); @@ -197,7 +198,7 @@ class SpellbinderCopyEffect extends OneShotEffect { game.getState().setZone(copiedCard.getId(), Zone.EXILED); if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) { if (copiedCard.getSpellAbility() != null) { - controller.cast(copiedCard.getSpellAbility(), game, true); + controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } else { Logger.getLogger(SpellbinderCopyEffect.class).error("Spellbinder: spell ability == null " + copiedCard.getName()); } @@ -210,4 +211,4 @@ class SpellbinderCopyEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/Spellshift.java b/Mage.Sets/src/mage/cards/s/Spellshift.java index bf93afa11c..4ffe8a3914 100644 --- a/Mage.Sets/src/mage/cards/s/Spellshift.java +++ b/Mage.Sets/src/mage/cards/s/Spellshift.java @@ -28,6 +28,7 @@ package mage.cards.s; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CounterTargetEffect; @@ -103,7 +104,7 @@ class SpellshiftEffect extends OneShotEffect { } spellController.revealCards(source, cardsToReveal, game); if (toCast != null && spellController.chooseUse(outcome, "Cast " + toCast.getLogName() + " without paying its mana cost?", source, game)) { - spellController.cast(toCast.getSpellAbility(), game, true); + spellController.cast(toCast.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } spellController.shuffleLibrary(source, game); return true; diff --git a/Mage.Sets/src/mage/cards/s/Spelltwine.java b/Mage.Sets/src/mage/cards/s/Spelltwine.java index bf0970a535..9b046706d2 100644 --- a/Mage.Sets/src/mage/cards/s/Spelltwine.java +++ b/Mage.Sets/src/mage/cards/s/Spelltwine.java @@ -28,6 +28,7 @@ package mage.cards.s; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileSpellEffect; @@ -65,7 +66,7 @@ public class Spelltwine extends CardImpl { } public Spelltwine(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{U}"); // Exile target instant or sorcery card from your graveyard and target instant or sorcery card from an opponent's graveyard. Copy those cards. Cast the copies if able without paying their mana costs. Exile Spelltwine. this.getSpellAbility().addEffect(new SpelltwineEffect()); @@ -109,18 +110,19 @@ class SpelltwineEffect extends OneShotEffect { controller.moveCards(cardTwo, Zone.EXILED, source, game); } boolean castCardOne = true; + MageObjectReference mor = new MageObjectReference(source.getSourceObject(game), game); if (cardOne != null && controller.chooseUse(Outcome.Neutral, "Cast the copy of " + cardOne.getName() + " first?", source, game)) { Card copyOne = game.copyCard(cardOne, source, controller.getId()); - controller.cast(copyOne.getSpellAbility(), game, true); + controller.cast(copyOne.getSpellAbility(), game, true, mor); castCardOne = false; } if (cardTwo != null) { Card copyTwo = game.copyCard(cardTwo, source, controller.getId()); - controller.cast(copyTwo.getSpellAbility(), game, true); + controller.cast(copyTwo.getSpellAbility(), game, true, mor); } if (cardOne != null && castCardOne) { Card copyOne = game.copyCard(cardOne, source, controller.getId()); - controller.cast(copyOne.getSpellAbility(), game, true); + controller.cast(copyOne.getSpellAbility(), game, true, mor); } return true; } diff --git a/Mage.Sets/src/mage/cards/s/SpellweaverHelix.java b/Mage.Sets/src/mage/cards/s/SpellweaverHelix.java index ce0feffb92..7fb05d33d4 100644 --- a/Mage.Sets/src/mage/cards/s/SpellweaverHelix.java +++ b/Mage.Sets/src/mage/cards/s/SpellweaverHelix.java @@ -28,6 +28,7 @@ package mage.cards.s; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -55,20 +56,21 @@ import mage.util.CardUtil; * @author emerald000 */ public class SpellweaverHelix extends CardImpl { - + private static final FilterCard filter = new FilterCard("sorcery cards from a single graveyard"); + static { filter.add(new CardTypePredicate(CardType.SORCERY)); } public SpellweaverHelix(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // Imprint - When Spellweaver Helix enters the battlefield, you may exile two target sorcery cards from a single graveyard. Ability ability = new EntersBattlefieldTriggeredAbility(new SpellweaverHelixImprintEffect(), true, "Imprint — "); ability.addTarget(new TargetCardInASingleGraveyard(2, 2, filter)); this.addAbility(ability); - + // Whenever a player casts a card, if it has the same name as one of the cards exiled with Spellweaver Helix, you may copy the other. If you do, you may cast the copy without paying its mana cost. this.addAbility(new SpellweaverHelixTriggeredAbility()); } @@ -84,21 +86,21 @@ public class SpellweaverHelix extends CardImpl { } class SpellweaverHelixImprintEffect extends OneShotEffect { - + SpellweaverHelixImprintEffect() { super(Outcome.Exile); this.staticText = "you may exile two target sorcery cards from a single graveyard"; } - + SpellweaverHelixImprintEffect(final SpellweaverHelixImprintEffect effect) { super(effect); } - + @Override public SpellweaverHelixImprintEffect copy() { return new SpellweaverHelixImprintEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -120,20 +122,20 @@ class SpellweaverHelixImprintEffect extends OneShotEffect { } class SpellweaverHelixTriggeredAbility extends TriggeredAbilityImpl { - + SpellweaverHelixTriggeredAbility() { super(Zone.BATTLEFIELD, new SpellweaverHelixCastEffect(), false); } - + SpellweaverHelixTriggeredAbility(final SpellweaverHelixTriggeredAbility ability) { super(ability); } - + @Override public SpellweaverHelixTriggeredAbility copy() { return new SpellweaverHelixTriggeredAbility(this); } - + @Override public boolean checkEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.SPELL_CAST; @@ -169,7 +171,7 @@ class SpellweaverHelixTriggeredAbility extends TriggeredAbilityImpl { } return false; } - + @Override public String getRule() { return "Whenever a player casts a card, if it has the same name as one of the cards exiled with Spellweaver Helix, you may copy the other. If you do, you may cast the copy without paying its mana cost."; @@ -177,28 +179,28 @@ class SpellweaverHelixTriggeredAbility extends TriggeredAbilityImpl { } class SpellweaverHelixCastEffect extends OneShotEffect { - + private String spellName = ""; - + SpellweaverHelixCastEffect() { super(Outcome.Benefit); this.staticText = "you may copy the other. If you do, you may cast the copy without paying its mana cost"; } - + SpellweaverHelixCastEffect(final SpellweaverHelixCastEffect effect) { super(effect); this.spellName = effect.spellName; } - + @Override public SpellweaverHelixCastEffect copy() { return new SpellweaverHelixCastEffect(this); } - + public void setSpellName(String spellName) { this.spellName = spellName; } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -211,12 +213,11 @@ class SpellweaverHelixCastEffect extends OneShotEffect { if (card != null) { if (!foundSpellWithSameName && card.getName().equals(spellName)) { foundSpellWithSameName = true; - } - else { + } else { if (controller.chooseUse(Outcome.Copy, "Copy " + card.getIdName(), source, game)) { Card copy = game.copyCard(card, source, source.getControllerId()); if (controller.chooseUse(Outcome.PlayForFree, "Cast " + copy.getIdName() + " without paying its mana cost?", source, game)) { - controller.cast(copy.getSpellAbility(), game, true); + controller.cast(copy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/s/SpellweaverVolute.java b/Mage.Sets/src/mage/cards/s/SpellweaverVolute.java index ea17f9d45c..d75eb814f1 100644 --- a/Mage.Sets/src/mage/cards/s/SpellweaverVolute.java +++ b/Mage.Sets/src/mage/cards/s/SpellweaverVolute.java @@ -28,6 +28,7 @@ package mage.cards.s; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -119,7 +120,7 @@ class SpellweaverVoluteEffect extends OneShotEffect { game.getState().setZone(copiedCard.getId(), Zone.GRAVEYARD); if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) { if (copiedCard.getSpellAbility() != null) { - controller.cast(copiedCard.getSpellAbility(), game, true); + controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } if (controller.moveCards(enchantedCard, Zone.EXILED, source, game)) { FilterCard filter = new FilterCard("instant card in a graveyard"); diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java index 1481a10263..176d66d9d2 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -29,6 +29,7 @@ package mage.cards.s; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.Effect; @@ -156,7 +157,7 @@ class SunbirdsInvocationEffect extends OneShotEffect { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { if (controller.chooseUse(Outcome.Benefit, "Cast " + card.getLogName() + " without paying its mana cost?", source, game)) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); cards.remove(card); } } diff --git a/Mage.Sets/src/mage/cards/s/Sunforger.java b/Mage.Sets/src/mage/cards/s/Sunforger.java index cd54573746..7013d39aaf 100644 --- a/Mage.Sets/src/mage/cards/s/Sunforger.java +++ b/Mage.Sets/src/mage/cards/s/Sunforger.java @@ -28,6 +28,7 @@ package mage.cards.s; import java.util.UUID; +import mage.MageObjectReference; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.SpellAbility; @@ -44,10 +45,10 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.ComparisonType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.Predicate; @@ -133,7 +134,7 @@ class SunforgerEffect extends OneShotEffect { UUID targetId = target.getFirstTarget(); Card card = game.getCard(targetId); if (card != null) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/t/TalentOfTheTelepath.java b/Mage.Sets/src/mage/cards/t/TalentOfTheTelepath.java index 68475d200c..be932551d2 100644 --- a/Mage.Sets/src/mage/cards/t/TalentOfTheTelepath.java +++ b/Mage.Sets/src/mage/cards/t/TalentOfTheTelepath.java @@ -30,6 +30,7 @@ package mage.cards.t; import java.util.Set; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.condition.common.SpellMasteryCondition; import mage.abilities.effects.OneShotEffect; @@ -55,7 +56,7 @@ import mage.target.common.TargetOpponent; public class TalentOfTheTelepath extends CardImpl { public TalentOfTheTelepath(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{U}"); // Target opponent reveals the top seven cards of their library. You may cast an instant or sorcery card from among them without paying its mana cost. Then that player puts the rest into their graveyard. // <i>Spell mastery</i> — If there are two or more instant and/or sorcery cards in your graveyard, you may cast up to two revealed instant and/or sorcery cards instead of one. @@ -127,7 +128,7 @@ class TalentOfTheTelepathEffect extends OneShotEffect { && controller.choose(outcome, cardsToCast, target, game)) { Card card = cardsToCast.get(target.getFirstTarget(), game); if (card != null) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); numberOfSpells--; cardsToCast.remove(card); allCards.remove(card); diff --git a/Mage.Sets/src/mage/cards/t/ThunderbladeCharge.java b/Mage.Sets/src/mage/cards/t/ThunderbladeCharge.java index 73f3e813c3..8760a683b5 100644 --- a/Mage.Sets/src/mage/cards/t/ThunderbladeCharge.java +++ b/Mage.Sets/src/mage/cards/t/ThunderbladeCharge.java @@ -28,6 +28,7 @@ package mage.cards.t; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.ControlledCreaturesDealCombatDamagePlayerTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -96,7 +97,7 @@ class ThunderbladeChargeCastEffect extends OneShotEffect { if (controller != null && sourceCard != null && Zone.GRAVEYARD == game.getState().getZone(sourceCard.getId())) { - controller.cast(sourceCard.getSpellAbility(), game, true); + controller.cast(sourceCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/t/TorrentialGearhulk.java b/Mage.Sets/src/mage/cards/t/TorrentialGearhulk.java index 838bf4f9ad..bdce562404 100644 --- a/Mage.Sets/src/mage/cards/t/TorrentialGearhulk.java +++ b/Mage.Sets/src/mage/cards/t/TorrentialGearhulk.java @@ -29,6 +29,7 @@ package mage.cards.t; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.ContinuousEffect; @@ -39,9 +40,9 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -115,7 +116,7 @@ class TorrentialGearhulkEffect extends OneShotEffect { Card card = game.getCard(this.getTargetPointer().getFirst(game, source)); if (card != null && card.getSpellAbility() != null) { if (controller.chooseUse(outcome, "Cast " + card.getLogName() + '?', source, game)) { - if (controller.cast(card.getSpellAbility(), game, true)) { + if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { ContinuousEffect effect = new TorrentialGearhulkReplacementEffect(card.getId()); effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId()))); game.addEffect(effect, source); diff --git a/Mage.Sets/src/mage/cards/t/ToshiroUmezawa.java b/Mage.Sets/src/mage/cards/t/ToshiroUmezawa.java index 5352b3dd2b..28e7381a39 100644 --- a/Mage.Sets/src/mage/cards/t/ToshiroUmezawa.java +++ b/Mage.Sets/src/mage/cards/t/ToshiroUmezawa.java @@ -29,6 +29,7 @@ package mage.cards.t; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -115,7 +116,7 @@ class ToshiroUmezawaEffect extends OneShotEffect { if (controller != null) { Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card != null) { - controller.cast(card.getSpellAbility(), game, false); + controller.cast(card.getSpellAbility(), game, false, new MageObjectReference(source.getSourceObject(game), game)); game.addEffect(new ToshiroUmezawaReplacementEffect(card.getId()), source); } } diff --git a/Mage.Sets/src/mage/cards/t/TreasureKeeper.java b/Mage.Sets/src/mage/cards/t/TreasureKeeper.java index ada27fe5b9..6c748828ee 100644 --- a/Mage.Sets/src/mage/cards/t/TreasureKeeper.java +++ b/Mage.Sets/src/mage/cards/t/TreasureKeeper.java @@ -29,6 +29,7 @@ package mage.cards.t; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.DiesTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -97,7 +98,7 @@ class TreasureKeeperEffect extends OneShotEffect { } controller.revealCards(source, toReveal, game); if (nonLandCard != null && controller.chooseUse(outcome, "Cast " + nonLandCard.getLogName() + "without paying its mana cost?", source, game)) { - controller.cast(nonLandCard.getSpellAbility(), game, true); + controller.cast(nonLandCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); toReveal.remove(nonLandCard); } controller.putCardsOnBottomOfLibrary(toReveal, game, source, false); diff --git a/Mage.Sets/src/mage/cards/t/TwinningGlass.java b/Mage.Sets/src/mage/cards/t/TwinningGlass.java index 687ecc7ab7..f0748923a7 100644 --- a/Mage.Sets/src/mage/cards/t/TwinningGlass.java +++ b/Mage.Sets/src/mage/cards/t/TwinningGlass.java @@ -29,6 +29,7 @@ package mage.cards.t; import java.util.List; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; @@ -121,7 +122,7 @@ class TwinningGlassEffect extends OneShotEffect { Card chosenCard = game.getCard(target.getFirstTarget()); if (chosenCard != null) { if (controller.chooseUse(outcome, "Cast the card without paying mana cost?", source, game)) { - return controller.cast(chosenCard.getSpellAbility(), game, true); + return controller.cast(chosenCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } diff --git a/Mage.Sets/src/mage/cards/u/UnexpectedResults.java b/Mage.Sets/src/mage/cards/u/UnexpectedResults.java index 7b2fc87093..c4d95769dd 100644 --- a/Mage.Sets/src/mage/cards/u/UnexpectedResults.java +++ b/Mage.Sets/src/mage/cards/u/UnexpectedResults.java @@ -28,6 +28,7 @@ package mage.cards.u; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -126,7 +127,7 @@ class UnexpectedResultEffect extends OneShotEffect { } } else { if (controller.chooseUse(outcome, new StringBuilder("Cast ").append(card.getName()).append(" without paying its mana cost?").toString(), source, game)) { - return controller.cast(card.getSpellAbility(), game, true); + return controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } return true; diff --git a/Mage.Sets/src/mage/cards/v/VillainousWealth.java b/Mage.Sets/src/mage/cards/v/VillainousWealth.java index f33f371f90..632a61bd86 100644 --- a/Mage.Sets/src/mage/cards/v/VillainousWealth.java +++ b/Mage.Sets/src/mage/cards/v/VillainousWealth.java @@ -29,6 +29,7 @@ package mage.cards.v; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.*; @@ -110,7 +111,7 @@ class VillainousWealthEffect extends OneShotEffect { while (cardsToExile.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); cardsToExile.remove(card); } else { break OuterLoop; diff --git a/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java b/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java index 6a18a11d47..065b0b931f 100644 --- a/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java +++ b/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java @@ -89,14 +89,14 @@ class WellOfKnowledgeConditionalActivatedAbility extends ActivatedAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { if (condition.apply(game, this) && costs.canPay(this, sourceId, playerId, game) && game.getActivePlayerId().equals(playerId)) { this.activatorId = playerId; - return true; + return ActivationStatus.getTrue(); } - return false; + return ActivationStatus.getFalse(); } diff --git a/Mage.Sets/src/mage/cards/w/WildEvocation.java b/Mage.Sets/src/mage/cards/w/WildEvocation.java index ef18829166..f9442a56b9 100644 --- a/Mage.Sets/src/mage/cards/w/WildEvocation.java +++ b/Mage.Sets/src/mage/cards/w/WildEvocation.java @@ -29,6 +29,7 @@ package mage.cards.w; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -96,7 +97,7 @@ class WildEvocationEffect extends OneShotEffect { player.moveCards(card, Zone.BATTLEFIELD, source, game); } else if (card.getSpellAbility() != null && card.getSpellAbility().getTargets().canChoose(player.getId(), game)) { - player.cast(card.getSpellAbility(), game, true); + player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } else { game.informPlayers(GameLog.getColoredObjectName(card) + " can't be cast now by " + player.getLogName()); } diff --git a/Mage.Sets/src/mage/cards/w/WildfireEternal.java b/Mage.Sets/src/mage/cards/w/WildfireEternal.java index c489232bbd..40d3ea4c1f 100644 --- a/Mage.Sets/src/mage/cards/w/WildfireEternal.java +++ b/Mage.Sets/src/mage/cards/w/WildfireEternal.java @@ -29,6 +29,7 @@ package mage.cards.w; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.AttacksAndIsNotBlockedTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -37,8 +38,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.common.FilterInstantOrSorceryCard; import mage.game.Game; @@ -104,7 +105,7 @@ class WildfireEternalCastEffect extends OneShotEffect { controller.chooseTarget(outcome, target, source, game); Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } return true; diff --git a/Mage.Sets/src/mage/cards/w/WrexialTheRisenDeep.java b/Mage.Sets/src/mage/cards/w/WrexialTheRisenDeep.java index a98bd2de1e..b9ec932e4a 100644 --- a/Mage.Sets/src/mage/cards/w/WrexialTheRisenDeep.java +++ b/Mage.Sets/src/mage/cards/w/WrexialTheRisenDeep.java @@ -29,6 +29,7 @@ package mage.cards.w; import java.util.UUID; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -119,7 +120,7 @@ class WrexialEffect extends OneShotEffect { if (controller.chooseTarget(Outcome.PlayForFree, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); game.addEffect(new WrexialReplacementEffect(card.getId()), source); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/FiendOfTheShadowsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/FiendOfTheShadowsTest.java index 9c5b8ca20e..bdde801cd4 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/FiendOfTheShadowsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/FiendOfTheShadowsTest.java @@ -39,6 +39,8 @@ public class FiendOfTheShadowsTest extends CardTestPlayerBase { @Test public void testCardExile1() { + // Whenever Fiend of the Shadows deals combat damage to a player, that player exiles a card from their hand. You may play that card for as long as it remains exiled. + // Sacrifice a Human: Regenerate Fiend of the Shadows. addCard(Zone.BATTLEFIELD, playerA, "Fiend of the Shadows"); removeAllCardsFromHand(playerB); addCard(Zone.HAND, playerB, "Swamp"); diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 627f093064..78f47f0315 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -495,7 +495,7 @@ public class TestPlayer implements Player { List<Permanent> manaPermsWithCost = computerPlayer.getAvailableManaProducersWithCost(game); for (Permanent perm : manaPermsWithCost) { for (ActivatedManaAbilityImpl manaAbility : perm.getAbilities().getAvailableActivatedManaAbilities(Zone.BATTLEFIELD, game)) { - if (manaAbility.toString().startsWith(groups[0]) && manaAbility.canActivate(computerPlayer.getId(), game)) { + if (manaAbility.toString().startsWith(groups[0]) && manaAbility.canActivate(computerPlayer.getId(), game).canActivate()) { Ability newManaAbility = manaAbility.copy(); computerPlayer.activateAbility((ActivatedAbility) newManaAbility, game); actions.remove(action); @@ -1598,13 +1598,13 @@ public class TestPlayer implements Player { } @Override - public boolean cast(SpellAbility ability, Game game, boolean noMana) { - return computerPlayer.cast(ability, game, noMana); + public boolean cast(SpellAbility ability, Game game, boolean noMana, MageObjectReference reference) { + return computerPlayer.cast(ability, game, noMana, reference); } @Override - public boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming) { - return computerPlayer.playCard(card, game, noMana, ignoreTiming); + public boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming, MageObjectReference reference) { + return computerPlayer.playCard(card, game, noMana, ignoreTiming, reference); } @Override diff --git a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java index 79da1b98fa..2b79823cf4 100644 --- a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java +++ b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java @@ -30,6 +30,7 @@ package org.mage.test.stub; import java.io.Serializable; import java.util.*; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.*; import mage.abilities.costs.AlternativeSourceCosts; import mage.abilities.costs.Cost; @@ -564,7 +565,7 @@ public class PlayerStub implements Player { } @Override - public boolean cast(SpellAbility ability, Game game, boolean noMana) { + public boolean cast(SpellAbility ability, Game game, boolean noMana, MageObjectReference reference) { return false; } @@ -619,7 +620,7 @@ public class PlayerStub implements Player { } @Override - public boolean playCard(Card card, Game game, boolean noMana, boolean checkTiming) { + public boolean playCard(Card card, Game game, boolean noMana, boolean checkTiming, MageObjectReference reference) { return false; } diff --git a/Mage/src/main/java/mage/abilities/AbilitiesImpl.java b/Mage/src/main/java/mage/abilities/AbilitiesImpl.java index 4b99d2d8ed..8e79524bf5 100644 --- a/Mage/src/main/java/mage/abilities/AbilitiesImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilitiesImpl.java @@ -157,7 +157,7 @@ public class AbilitiesImpl<T extends Ability> extends ArrayList<T> implements Ab return stream() .filter(ability -> ability instanceof ActivatedManaAbilityImpl) .filter(ability -> ability.getZone().match(zone)) - .filter(ability -> (((ActivatedManaAbilityImpl) ability).canActivate(ability.getControllerId(), game))) + .filter(ability -> (((ActivatedManaAbilityImpl) ability).canActivate(ability.getControllerId(), game).canActivate())) .map(ability -> (ActivatedManaAbilityImpl) ability) .collect(Collectors.toCollection(AbilitiesImpl::new)); diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbility.java b/Mage/src/main/java/mage/abilities/ActivatedAbility.java index b8d15bffcd..22e9f8ecb3 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbility.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbility.java @@ -28,6 +28,7 @@ package mage.abilities; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.mana.ManaOptions; import mage.constants.TargetController; import mage.game.Game; @@ -38,9 +39,36 @@ import mage.game.Game; */ public interface ActivatedAbility extends Ability { - boolean canActivate(UUID playerId, Game game); + final public class ActivationStatus { - public void setMayActivate(TargetController mayActivate); + private final boolean canActivate; + private final MageObjectReference permittingObject; + + public ActivationStatus(boolean canActivate, MageObjectReference permittingObject) { + this.canActivate = canActivate; + this.permittingObject = permittingObject; + } + + public boolean canActivate() { + return canActivate; + } + + public MageObjectReference getPermittingObject() { + return permittingObject; + } + + public static ActivationStatus getFalse() { + return new ActivationStatus(false, null); + } + + public static ActivationStatus getTrue() { + return new ActivationStatus(true, null); + } + } + + ActivationStatus canActivate(UUID playerId, Game game); // has to return a reference to the permitting ability/source + + void setMayActivate(TargetController mayActivate); /** * Returns the minimal possible cost for what the ability can be activated diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java index f199003774..aaa4eeffd2 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java @@ -29,6 +29,7 @@ package mage.abilities; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.condition.Condition; import mage.abilities.costs.Cost; import mage.abilities.costs.Costs; @@ -177,38 +178,39 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa public abstract ActivatedAbilityImpl copy(); @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { //20091005 - 602.2 if (!(hasMoreActivationsThisTurn(game) && (condition == null || condition.apply(game, this)))) { - return false; + return ActivationStatus.getFalse(); } switch (mayActivate) { case ANY: break; + case NOT_YOU: if (controlsAbility(playerId, game)) { - return false; + return ActivationStatus.getFalse(); } break; case TEAM: if (game.getPlayer(controllerId).hasOpponent(playerId, game)) { - return false; + return ActivationStatus.getFalse(); } break; case OPPONENT: if (!game.getPlayer(controllerId).hasOpponent(playerId, game)) { - return false; + return ActivationStatus.getFalse(); } break; case OWNER: Permanent permanent = game.getPermanent(getSourceId()); if (!permanent.getOwnerId().equals(playerId)) { - return false; + return ActivationStatus.getFalse(); } break; case YOU: if (!controlsAbility(playerId, game)) { - return false; + return ActivationStatus.getFalse(); } break; case CONTROLLER_ATTACHED_TO: @@ -219,17 +221,17 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa break; } } - return false; + return ActivationStatus.getFalse(); } //20091005 - 602.5d/602.5e - if (timing == TimingRule.INSTANT || game.canPlaySorcery(playerId) - || null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_AS_INSTANT, this, controllerId, game)) { + MageObjectReference permittingObject = game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_AS_INSTANT, this, controllerId, game); + if (timing == TimingRule.INSTANT || game.canPlaySorcery(playerId) || null != permittingObject) { if (costs.canPay(this, sourceId, playerId, game) && canChooseTarget(game)) { this.activatorId = playerId; - return true; + return new ActivationStatus(true, permittingObject); } } - return false; + return ActivationStatus.getFalse(); } @Override @@ -310,10 +312,12 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa return false; } + @Override public void setMaxActivationsPerTurn(int maxActivationsPerTurn) { this.maxActivationsPerTurn = maxActivationsPerTurn; } + @Override public int getMaxActivationsPerTurn(Game game) { return maxActivationsPerTurn; } diff --git a/Mage/src/main/java/mage/abilities/PlayLandAbility.java b/Mage/src/main/java/mage/abilities/PlayLandAbility.java index 5aa10fb6cd..65d6a17b11 100644 --- a/Mage/src/main/java/mage/abilities/PlayLandAbility.java +++ b/Mage/src/main/java/mage/abilities/PlayLandAbility.java @@ -28,6 +28,7 @@ package mage.abilities; import java.util.UUID; +import mage.MageObjectReference; import mage.constants.AbilityType; import mage.constants.AsThoughEffectType; import mage.constants.Zone; @@ -50,13 +51,13 @@ public class PlayLandAbility extends ActivatedAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { - if (!controlsAbility(playerId, game) - && null == game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, playerId, game)) { - return false; + public ActivationStatus canActivate(UUID playerId, Game game) { + MageObjectReference permittingObject = game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, playerId, game); + if (!controlsAbility(playerId, game) && null == permittingObject) { + return ActivationStatus.getFalse(); } //20091005 - 114.2a - return game.getActivePlayerId().equals(playerId) && game.getPlayer(playerId).canPlayLand() && game.canPlaySorcery(playerId); + return new ActivationStatus(game.getActivePlayerId().equals(playerId) && game.getPlayer(playerId).canPlayLand() && game.canPlaySorcery(playerId), permittingObject); } @Override diff --git a/Mage/src/main/java/mage/abilities/SpellAbility.java b/Mage/src/main/java/mage/abilities/SpellAbility.java index 84491fb009..00c2144b06 100644 --- a/Mage/src/main/java/mage/abilities/SpellAbility.java +++ b/Mage/src/main/java/mage/abilities/SpellAbility.java @@ -29,6 +29,7 @@ package mage.abilities; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.costs.Cost; import mage.abilities.costs.VariableCost; import mage.abilities.costs.mana.ManaCost; @@ -91,48 +92,49 @@ public class SpellAbility extends ActivatedAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { if (null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game) // check this first to allow Offering in main phase || this.spellCanBeActivatedRegularlyNow(playerId, game)) { if (spellAbilityType == SpellAbilityType.SPLIT || spellAbilityType == SpellAbilityType.SPLIT_AFTERMATH) { - return false; + return ActivationStatus.getFalse(); } // fix for Gitaxian Probe and casting opponent's spells - if (null == game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, playerId, game)) { + 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))) { - return false; + return ActivationStatus.getFalse(); } } // Check if rule modifying events prevent to cast the spell in check playable mode if (this.isCheckPlayableMode()) { if (game.getContinuousEffects().preventedByRuleModification( GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, this.getId(), this.getSourceId(), playerId), this, game, true)) { - return false; + return ActivationStatus.getFalse(); } } // Alternate spell abilities (Flashback, Overload) can't be cast with no mana to pay option if (getSpellAbilityType() == SpellAbilityType.BASE_ALTERNATE) { Player player = game.getPlayer(playerId); if (player != null && getSourceId().equals(player.getCastSourceIdWithAlternateMana())) { - return false; + return ActivationStatus.getFalse(); } } if (costs.canPay(this, sourceId, controllerId, game)) { if (getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED) { SplitCard splitCard = (SplitCard) game.getCard(getSourceId()); if (splitCard != null) { - return (splitCard.getLeftHalfCard().getSpellAbility().canChooseTarget(game) - && splitCard.getRightHalfCard().getSpellAbility().canChooseTarget(game)); + return new ActivationStatus(splitCard.getLeftHalfCard().getSpellAbility().canChooseTarget(game) + && splitCard.getRightHalfCard().getSpellAbility().canChooseTarget(game), null); } - return false; + return ActivationStatus.getFalse(); } else { - return canChooseTarget(game); + return new ActivationStatus(canChooseTarget(game), permittingSource); } } } - return false; + return ActivationStatus.getFalse(); } @Override diff --git a/Mage/src/main/java/mage/abilities/common/PassAbility.java b/Mage/src/main/java/mage/abilities/common/PassAbility.java index 1c64b2a05c..9220ecfdc7 100644 --- a/Mage/src/main/java/mage/abilities/common/PassAbility.java +++ b/Mage/src/main/java/mage/abilities/common/PassAbility.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,18 +20,17 @@ * 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.common; import java.util.UUID; -import mage.constants.Zone; import mage.abilities.ActivatedAbilityImpl; import mage.abilities.effects.common.PassEffect; +import mage.constants.Zone; import mage.game.Game; /** @@ -55,8 +54,8 @@ public class PassAbility extends ActivatedAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { - return true; + public ActivationStatus canActivate(UUID playerId, Game game) { + return ActivationStatus.getTrue(); } @Override diff --git a/Mage/src/main/java/mage/abilities/costs/common/TapSourceCost.java b/Mage/src/main/java/mage/abilities/costs/common/TapSourceCost.java index d127b66491..c321bcc54e 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/TapSourceCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/TapSourceCost.java @@ -63,7 +63,7 @@ public class TapSourceCost extends CostImpl { Permanent permanent = game.getPermanent(sourceId); if (permanent != null) { return !permanent.isTapped() - && (permanent.canTap() || null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_HASTE, controllerId, game)); + && (permanent.canTap() || null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_HASTE, ability, controllerId, game)); } return false; } diff --git a/Mage/src/main/java/mage/abilities/costs/common/UntapSourceCost.java b/Mage/src/main/java/mage/abilities/costs/common/UntapSourceCost.java index 15af412080..f1fce810e5 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/UntapSourceCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/UntapSourceCost.java @@ -62,7 +62,7 @@ public class UntapSourceCost extends CostImpl { public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { Permanent permanent = game.getPermanent(sourceId); if (permanent != null) { - return permanent.isTapped() && (permanent.canTap() || null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_HASTE, controllerId, game)); + return permanent.isTapped() && (permanent.canTap() || null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_HASTE, ability, controllerId, game)); } return false; } diff --git a/Mage/src/main/java/mage/abilities/decorator/ConditionalGainActivatedAbility.java b/Mage/src/main/java/mage/abilities/decorator/ConditionalGainActivatedAbility.java index 41660dda3e..deedcca446 100644 --- a/Mage/src/main/java/mage/abilities/decorator/ConditionalGainActivatedAbility.java +++ b/Mage/src/main/java/mage/abilities/decorator/ConditionalGainActivatedAbility.java @@ -82,9 +82,9 @@ public class ConditionalGainActivatedAbility extends ActivatedAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { if (!condition.apply(game, this)) { - return false; + return ActivationStatus.getFalse(); } return super.canActivate(playerId, game); } diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java index 880e67ad44..cd4a15c37e 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java @@ -32,6 +32,7 @@ import java.util.*; import java.util.Map.Entry; import java.util.stream.Collectors; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.*; import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect; import mage.abilities.effects.common.continuous.CommanderReplacementEffect; @@ -502,19 +503,6 @@ public class ContinuousEffects implements Serializable { return spliceEffects; } - /** - * - * @param objectId - * @param type - * @param controllerId - * @param game - * @return sourceId of the permitting effect if any exists otherwise returns - * null - */ - public UUID asThough(UUID objectId, AsThoughEffectType type, UUID controllerId, Game game) { - return asThough(objectId, type, null, controllerId, game); - } - /** * * @param objectId @@ -525,17 +513,17 @@ public class ContinuousEffects implements Serializable { * @return sourceId of the permitting effect if any exists otherwise returns * null */ - public UUID asThough(UUID objectId, AsThoughEffectType type, Ability affectedAbility, UUID controllerId, Game game) { + public MageObjectReference asThough(UUID objectId, AsThoughEffectType type, Ability affectedAbility, UUID controllerId, Game game) { List<AsThoughEffect> asThoughEffectsList = getApplicableAsThoughEffects(type, game); for (AsThoughEffect effect : asThoughEffectsList) { Set<Ability> abilities = asThoughEffectsMap.get(type).getAbility(effect.getId()); for (Ability ability : abilities) { if (affectedAbility == null) { if (effect.applies(objectId, ability, controllerId, game)) { - return ability.getSourceId(); + return new MageObjectReference(ability.getSourceObject(game), game); } } else if (effect.applies(objectId, affectedAbility, ability, game)) { - return ability.getSourceId(); + return new MageObjectReference(ability.getSourceObject(game), game); } } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CastCardFromOutsideTheGameEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CastCardFromOutsideTheGameEffect.java index c8e1052d3a..eb4a8df758 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CastCardFromOutsideTheGameEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CastCardFromOutsideTheGameEffect.java @@ -28,6 +28,7 @@ package mage.abilities.effects.common; import java.util.Set; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -88,7 +89,7 @@ public class CastCardFromOutsideTheGameEffect extends OneShotEffect { } return false; } - + Cards filteredCards = new CardsImpl(); for (Card card : filtered) { filteredCards.add(card.getId()); @@ -98,7 +99,7 @@ public class CastCardFromOutsideTheGameEffect extends OneShotEffect { if (player.choose(Outcome.Benefit, filteredCards, target, game)) { Card card = player.getSideboard().get(target.getFirstTarget(), game); if (card != null) { - player.cast(card.getSpellAbility(), game, true); + player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } } @@ -106,4 +107,4 @@ public class CastCardFromOutsideTheGameEffect extends OneShotEffect { return true; } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/CipherEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CipherEffect.java index bd4dc4146f..9d66979137 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CipherEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CipherEffect.java @@ -28,6 +28,7 @@ package mage.abilities.effects.common; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; @@ -151,7 +152,7 @@ class CipherStoreEffect extends OneShotEffect { } ability.getEffects().remove(cipherEffect); if (ability instanceof SpellAbility) { - controller.cast(ability, game, true); + controller.cast(ability, game, true, new MageObjectReference(source.getSourceObject(game), game)); } } 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 8fed10126d..94a428f49b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/HideawayPlayEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/HideawayPlayEffect.java @@ -27,6 +27,8 @@ */ package mage.abilities.effects.common; +import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -36,8 +38,6 @@ import mage.game.Game; import mage.players.Player; import mage.util.CardUtil; -import java.util.UUID; - /** * @author LevelX2 * @@ -82,7 +82,7 @@ public class HideawayPlayEffect extends OneShotEffect { } } - if (!controller.playCard(card, game, true, true)) { + if (!controller.playCard(card, game, true, true, new MageObjectReference(source.getSourceObject(game), game))) { if (card.getZoneChangeCounter(game) == zcc) { card.setFaceDown(true, game); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PlayTargetWithoutPayingManaEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PlayTargetWithoutPayingManaEffect.java index 08612e5e18..8b3356482d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PlayTargetWithoutPayingManaEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PlayTargetWithoutPayingManaEffect.java @@ -24,16 +24,16 @@ * 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.constants.Outcome; -import mage.constants.Zone; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; import mage.players.Player; import mage.target.Target; @@ -62,7 +62,7 @@ public class PlayTargetWithoutPayingManaEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Card target = (Card) game.getObject(source.getFirstTarget()); if (controller != null && target != null) { - return controller.cast(target.getSpellAbility(), game, true); + return controller.cast(target.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } return false; } @@ -74,8 +74,7 @@ public class PlayTargetWithoutPayingManaEffect extends OneShotEffect { Target target = mode.getTargets().get(0); if (mode.getTargets().get(0).getZone() == Zone.HAND) { sb.append("you may put ").append(target.getTargetName()).append(" from your hand onto the battlefield"); - } - else { + } else { sb.append("you may cast target ").append(target.getTargetName()).append(" without paying its mana cost"); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/cost/CastWithoutPayingManaCostEffect.java b/Mage/src/main/java/mage/abilities/effects/common/cost/CastWithoutPayingManaCostEffect.java index c389ece434..43c43b1cf1 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/cost/CastWithoutPayingManaCostEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/cost/CastWithoutPayingManaCostEffect.java @@ -27,6 +27,7 @@ */ package mage.abilities.effects.common.cost; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -101,7 +102,7 @@ public class CastWithoutPayingManaCostEffect extends OneShotEffect { } } if (cardToCast != null) { - controller.cast(cardToCast.getSpellAbility(), game, true); + controller.cast(cardToCast.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } return true; diff --git a/Mage/src/main/java/mage/abilities/effects/mana/AddConditionalManaOfAnyColorEffect.java b/Mage/src/main/java/mage/abilities/effects/mana/AddConditionalManaOfAnyColorEffect.java index 8cdb5f5027..359171a0ab 100644 --- a/Mage/src/main/java/mage/abilities/effects/mana/AddConditionalManaOfAnyColorEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/mana/AddConditionalManaOfAnyColorEffect.java @@ -38,12 +38,15 @@ import mage.choices.ChoiceColor; import mage.game.Game; import mage.players.Player; import mage.util.CardUtil; +import org.apache.log4j.Logger; /** * @author noxx */ public class AddConditionalManaOfAnyColorEffect extends ManaEffect { + private static final Logger logger = Logger.getLogger(AddConditionalManaOfAnyColorEffect.class); + private final DynamicValue amount; private final ConditionalManaBuilder manaBuilder; private final boolean oneChoice; @@ -87,8 +90,13 @@ public class AddConditionalManaOfAnyColorEffect extends ManaEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - checkToFirePossibleEvents(getMana(game, source), game, source); - controller.getManaPool().addMana(getMana(game, source), game, source); + Mana mana = getMana(game, source); + if (mana != null) { + checkToFirePossibleEvents(mana, game, source); + controller.getManaPool().addMana(mana, game, source); + } else { + logger.error("There was no mana created: " + source.getSourceObject(game).getName() + " - Ability: " + source.getRule()); + } return true; } return false; diff --git a/Mage/src/main/java/mage/abilities/keyword/AssistAbility.java b/Mage/src/main/java/mage/abilities/keyword/AssistAbility.java index f56fd58e58..f1ebade552 100644 --- a/Mage/src/main/java/mage/abilities/keyword/AssistAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/AssistAbility.java @@ -1,158 +1,159 @@ -/* - * 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.keyword; - -import mage.Mana; -import mage.abilities.Ability; -import mage.abilities.SpecialAction; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.Cost; -import mage.abilities.costs.mana.AlternateManaPaymentAbility; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.costs.mana.ManaCost; -import mage.abilities.effects.OneShotEffect; -import mage.constants.AbilityType; -import mage.constants.ManaType; -import mage.constants.Outcome; -import mage.constants.TargetController; -import mage.constants.Zone; -import mage.filter.FilterPlayer; -import mage.filter.predicate.other.PlayerPredicate; -import mage.game.Game; -import mage.players.ManaPool; -import mage.players.Player; -import mage.target.Target; -import mage.target.TargetPlayer; - -/* - * @author emerald000 - */ -public class AssistAbility extends SimpleStaticAbility implements AlternateManaPaymentAbility { - - private static final FilterPlayer filter = new FilterPlayer("another player"); - static { - filter.add(new PlayerPredicate(TargetController.NOT_YOU)); - } - - public AssistAbility() { - super(Zone.STACK, null); - this.setRuleAtTheTop(true); - } - - public AssistAbility(final AssistAbility ability) { - super(ability); - } - - @Override - public AssistAbility copy() { - return new AssistAbility(this); - } - - @Override - public void addSpecialAction(Ability source, Game game, ManaCost unpaid) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null - && source.getAbilityType() == AbilityType.SPELL - && unpaid.getMana().getGeneric() >= 1 - && game.getState().getValue(source.getSourceId().toString() + game.getState().getZoneChangeCounter(source.getSourceId())) == null) { - SpecialAction specialAction = new AssistSpecialAction(unpaid); - specialAction.setControllerId(source.getControllerId()); - specialAction.setSourceId(source.getSourceId()); - Target target = new TargetPlayer(1, 1, true, filter); - specialAction.addTarget(target); - if (specialAction.canActivate(source.getControllerId(), game)) { - game.getState().getSpecialActions().add(specialAction); - } - } - } - - @Override - public String getRule() { - return "Assist <i>(Another player can help pay the generic mana of this spell's cost.)</i>"; - } -} - -class AssistSpecialAction extends SpecialAction { - - AssistSpecialAction(ManaCost unpaid) { - super(Zone.ALL, true); - setRuleVisible(false); - this.addEffect(new AssistEffect(unpaid)); - } - - AssistSpecialAction(final AssistSpecialAction ability) { - super(ability); - } - - @Override - public AssistSpecialAction copy() { - return new AssistSpecialAction(this); - } -} - -class AssistEffect extends OneShotEffect { - - private final ManaCost unpaid; - - AssistEffect(ManaCost unpaid) { - super(Outcome.Benefit); - this.unpaid = unpaid; - this.staticText = "Assist <i>(Another player can help pay the generic mana of this spell's cost.)</i>"; - } - - AssistEffect(final AssistEffect effect) { - super(effect); - this.unpaid = effect.unpaid; - } - - @Override - public AssistEffect copy() { - return new AssistEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); - if (controller != null && targetPlayer != null) { - int amountToPay = targetPlayer.announceXMana(0, unpaid.getMana().getGeneric(), "How much mana to pay?", game, source); - if (amountToPay > 0) { - Cost cost = new GenericManaCost(amountToPay); - if (cost.pay(source, game, source.getSourceId(), targetPlayer.getId(), false)) { - ManaPool manaPool = controller.getManaPool(); - manaPool.addMana(Mana.ColorlessMana(amountToPay), game, source); - manaPool.unlockManaType(ManaType.COLORLESS); - game.informPlayers(targetPlayer.getLogName() + " paid " + amountToPay + " mana."); - game.getState().setValue(source.getSourceId().toString() + game.getState().getZoneChangeCounter(source.getSourceId()), true); - } - } - return true; - } - return false; - } -} +/* + * 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.keyword; + +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.SpecialAction; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.mana.AlternateManaPaymentAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.mana.ManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.constants.AbilityType; +import mage.constants.ManaType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPlayer; +import mage.filter.predicate.other.PlayerPredicate; +import mage.game.Game; +import mage.players.ManaPool; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPlayer; + +/* + * @author emerald000 + */ +public class AssistAbility extends SimpleStaticAbility implements AlternateManaPaymentAbility { + + private static final FilterPlayer filter = new FilterPlayer("another player"); + + static { + filter.add(new PlayerPredicate(TargetController.NOT_YOU)); + } + + public AssistAbility() { + super(Zone.STACK, null); + this.setRuleAtTheTop(true); + } + + public AssistAbility(final AssistAbility ability) { + super(ability); + } + + @Override + public AssistAbility copy() { + return new AssistAbility(this); + } + + @Override + public void addSpecialAction(Ability source, Game game, ManaCost unpaid) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null + && source.getAbilityType() == AbilityType.SPELL + && unpaid.getMana().getGeneric() >= 1 + && game.getState().getValue(source.getSourceId().toString() + game.getState().getZoneChangeCounter(source.getSourceId())) == null) { + SpecialAction specialAction = new AssistSpecialAction(unpaid); + specialAction.setControllerId(source.getControllerId()); + specialAction.setSourceId(source.getSourceId()); + Target target = new TargetPlayer(1, 1, true, filter); + specialAction.addTarget(target); + if (specialAction.canActivate(source.getControllerId(), game).canActivate()) { + game.getState().getSpecialActions().add(specialAction); + } + } + } + + @Override + public String getRule() { + return "Assist <i>(Another player can help pay the generic mana of this spell's cost.)</i>"; + } +} + +class AssistSpecialAction extends SpecialAction { + + AssistSpecialAction(ManaCost unpaid) { + super(Zone.ALL, true); + setRuleVisible(false); + this.addEffect(new AssistEffect(unpaid)); + } + + AssistSpecialAction(final AssistSpecialAction ability) { + super(ability); + } + + @Override + public AssistSpecialAction copy() { + return new AssistSpecialAction(this); + } +} + +class AssistEffect extends OneShotEffect { + + private final ManaCost unpaid; + + AssistEffect(ManaCost unpaid) { + super(Outcome.Benefit); + this.unpaid = unpaid; + this.staticText = "Assist <i>(Another player can help pay the generic mana of this spell's cost.)</i>"; + } + + AssistEffect(final AssistEffect effect) { + super(effect); + this.unpaid = effect.unpaid; + } + + @Override + public AssistEffect copy() { + return new AssistEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); + if (controller != null && targetPlayer != null) { + int amountToPay = targetPlayer.announceXMana(0, unpaid.getMana().getGeneric(), "How much mana to pay?", game, source); + if (amountToPay > 0) { + Cost cost = new GenericManaCost(amountToPay); + if (cost.pay(source, game, source.getSourceId(), targetPlayer.getId(), false)) { + ManaPool manaPool = controller.getManaPool(); + manaPool.addMana(Mana.ColorlessMana(amountToPay), game, source); + manaPool.unlockManaType(ManaType.COLORLESS); + game.informPlayers(targetPlayer.getLogName() + " paid " + amountToPay + " mana."); + game.getState().setValue(source.getSourceId().toString() + game.getState().getZoneChangeCounter(source.getSourceId()), true); + } + } + return true; + } + return false; + } +} diff --git a/Mage/src/main/java/mage/abilities/keyword/CascadeAbility.java b/Mage/src/main/java/mage/abilities/keyword/CascadeAbility.java index 4c59a83013..25044b2db9 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CascadeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/CascadeAbility.java @@ -27,6 +27,7 @@ */ package mage.abilities.keyword; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.OneShotEffect; @@ -124,7 +125,7 @@ class CascadeEffect extends OneShotEffect { if (card != null) { if (controller.chooseUse(outcome, "Use cascade effect on " + card.getLogName() + '?', source, game)) { - controller.cast(card.getSpellAbility(), game, true); + controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); } } // Move the remaining cards to the buttom of the library in a random order diff --git a/Mage/src/main/java/mage/abilities/keyword/ConvokeAbility.java b/Mage/src/main/java/mage/abilities/keyword/ConvokeAbility.java index 2f0b744d3a..6cf6978858 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ConvokeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ConvokeAbility.java @@ -145,7 +145,7 @@ public class ConvokeAbility extends SimpleStaticAbility implements AlternateMana Target target = new TargetControlledCreaturePermanent(1, 1, filter, true); target.setTargetName("creature to convoke"); specialAction.addTarget(target); - if (specialAction.canActivate(source.getControllerId(), game)) { + if (specialAction.canActivate(source.getControllerId(), game).canActivate()) { game.getState().getSpecialActions().add(specialAction); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/DelveAbility.java b/Mage/src/main/java/mage/abilities/keyword/DelveAbility.java index 97c03922d1..59071c3471 100644 --- a/Mage/src/main/java/mage/abilities/keyword/DelveAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/DelveAbility.java @@ -110,7 +110,7 @@ public class DelveAbility extends SimpleStaticAbility implements AlternateManaPa } specialAction.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard( 0, Math.min(controller.getGraveyard().size(), unpaidAmount), new FilterCard(), true))); - if (specialAction.canActivate(source.getControllerId(), game)) { + if (specialAction.canActivate(source.getControllerId(), game).canActivate()) { game.getState().getSpecialActions().add(specialAction); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java b/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java index ce1c24afdd..8dea409e83 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java @@ -1,140 +1,140 @@ -/* - * 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.keyword; - -import java.util.UUID; -import mage.Mana; -import mage.abilities.SpellAbility; -import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.costs.mana.ManaCost; -import mage.abilities.costs.mana.ManaCosts; -import mage.abilities.mana.ManaOptions; -import mage.cards.Card; -import mage.constants.Outcome; -import mage.constants.SpellAbilityType; -import mage.constants.Zone; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.predicate.mageobject.CardIdPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.TargetPermanent; -import mage.target.common.TargetControlledCreaturePermanent; -import mage.util.CardUtil; - -/** - * - * @author emerald000 - */ -public class EmergeAbility extends SpellAbility { - - private final ManaCosts<ManaCost> emergeCost; - - public EmergeAbility(Card card, ManaCosts<ManaCost> emergeCost) { - super(emergeCost, card.getName() + " with emerge", Zone.HAND, SpellAbilityType.BASE_ALTERNATE); - this.getCosts().addAll(card.getSpellAbility().getCosts().copy()); - this.getEffects().addAll(card.getSpellAbility().getEffects().copy()); - this.getTargets().addAll(card.getSpellAbility().getTargets().copy()); - this.timing = card.getSpellAbility().getTiming(); - this.setRuleAtTheTop(true); - this.emergeCost = emergeCost.copy(); - } - - public EmergeAbility(final EmergeAbility ability) { - super(ability); - this.emergeCost = ability.emergeCost.copy(); - } - - @Override - public boolean canActivate(UUID playerId, Game game) { - if (super.canActivate(playerId, game)) { - Player controller = game.getPlayer(this.getControllerId()); - if (controller != null) { - for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), this.getControllerId(), this.getSourceId(), game)) { - ManaCost costToPay = CardUtil.reduceCost(emergeCost.copy(), creature.getConvertedManaCost()); - if (costToPay.canPay(this, this.getSourceId(), this.getControllerId(), game)) { - return true; - } - } - } - } - return false; - } - - @Override - public ManaOptions getMinimumCostToActivate(UUID playerId, Game game) { - int maxCMC = 0; - for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), playerId, this.getSourceId(), game)) { - int cmc = creature.getConvertedManaCost(); - if (cmc > maxCMC) { - maxCMC = cmc; - } - } - ManaOptions manaOptions = super.getMinimumCostToActivate(playerId, game); - for (Mana mana : manaOptions) { - if (mana.getGeneric() > maxCMC) { - mana.setGeneric(mana.getGeneric() - maxCMC); - } else { - mana.setGeneric(0); - } - } - return manaOptions; - } - - @Override - public boolean activate(Game game, boolean noMana) { - Player controller = game.getPlayer(this.getControllerId()); - if (controller != null) { - TargetPermanent target = new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("creature to sacrifice for emerge")); - if (controller.choose(Outcome.Sacrifice, target, this.getSourceId(), game)) { - Permanent creature = game.getPermanent(target.getFirstTarget()); - CardUtil.reduceCost(this, creature.getConvertedManaCost()); - FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(creature.getLogName()); - filter.add(new CardIdPredicate(creature.getId())); - this.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); - return super.activate(game, false); - } - } - return false; - } - - @Override - public EmergeAbility copy() { - return new EmergeAbility(this); - } - - @Override - public String getRule(boolean all) { - return getRule(); - } - - @Override - public String getRule() { - return "Emerge " + emergeCost.getText() + " <i>(You may cast this spell by sacrificing a creature and paying the emerge cost reduced by that creature's converted mana cost.)</i>"; - } -} +/* + * 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.keyword; + +import java.util.UUID; +import mage.Mana; +import mage.abilities.SpellAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.mana.ManaCost; +import mage.abilities.costs.mana.ManaCosts; +import mage.abilities.mana.ManaOptions; +import mage.cards.Card; +import mage.constants.Outcome; +import mage.constants.SpellAbilityType; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.CardIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.util.CardUtil; + +/** + * + * @author emerald000 + */ +public class EmergeAbility extends SpellAbility { + + private final ManaCosts<ManaCost> emergeCost; + + public EmergeAbility(Card card, ManaCosts<ManaCost> emergeCost) { + super(emergeCost, card.getName() + " with emerge", Zone.HAND, SpellAbilityType.BASE_ALTERNATE); + this.getCosts().addAll(card.getSpellAbility().getCosts().copy()); + this.getEffects().addAll(card.getSpellAbility().getEffects().copy()); + this.getTargets().addAll(card.getSpellAbility().getTargets().copy()); + this.timing = card.getSpellAbility().getTiming(); + this.setRuleAtTheTop(true); + this.emergeCost = emergeCost.copy(); + } + + public EmergeAbility(final EmergeAbility ability) { + super(ability); + this.emergeCost = ability.emergeCost.copy(); + } + + @Override + public ActivationStatus canActivate(UUID playerId, Game game) { + if (super.canActivate(playerId, game).canActivate()) { + Player controller = game.getPlayer(this.getControllerId()); + if (controller != null) { + for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), this.getControllerId(), this.getSourceId(), game)) { + ManaCost costToPay = CardUtil.reduceCost(emergeCost.copy(), creature.getConvertedManaCost()); + if (costToPay.canPay(this, this.getSourceId(), this.getControllerId(), game)) { + return ActivationStatus.getTrue(); + } + } + } + } + return ActivationStatus.getFalse(); + } + + @Override + public ManaOptions getMinimumCostToActivate(UUID playerId, Game game) { + int maxCMC = 0; + for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), playerId, this.getSourceId(), game)) { + int cmc = creature.getConvertedManaCost(); + if (cmc > maxCMC) { + maxCMC = cmc; + } + } + ManaOptions manaOptions = super.getMinimumCostToActivate(playerId, game); + for (Mana mana : manaOptions) { + if (mana.getGeneric() > maxCMC) { + mana.setGeneric(mana.getGeneric() - maxCMC); + } else { + mana.setGeneric(0); + } + } + return manaOptions; + } + + @Override + public boolean activate(Game game, boolean noMana) { + Player controller = game.getPlayer(this.getControllerId()); + if (controller != null) { + TargetPermanent target = new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("creature to sacrifice for emerge")); + if (controller.choose(Outcome.Sacrifice, target, this.getSourceId(), game)) { + Permanent creature = game.getPermanent(target.getFirstTarget()); + CardUtil.reduceCost(this, creature.getConvertedManaCost()); + FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(creature.getLogName()); + filter.add(new CardIdPredicate(creature.getId())); + this.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); + return super.activate(game, false); + } + } + return false; + } + + @Override + public EmergeAbility copy() { + return new EmergeAbility(this); + } + + @Override + public String getRule(boolean all) { + return getRule(); + } + + @Override + public String getRule() { + return "Emerge " + emergeCost.getText() + " <i>(You may cast this spell by sacrificing a creature and paying the emerge cost reduced by that creature's converted mana cost.)</i>"; + } +} diff --git a/Mage/src/main/java/mage/abilities/keyword/EquipAbility.java b/Mage/src/main/java/mage/abilities/keyword/EquipAbility.java index f6ae708cf9..8fc907d4eb 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EquipAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EquipAbility.java @@ -27,6 +27,7 @@ */ package mage.abilities.keyword; +import java.util.UUID; import mage.abilities.ActivatedAbilityImpl; import mage.abilities.costs.Cost; import mage.abilities.effects.common.AttachEffect; @@ -39,8 +40,6 @@ import mage.game.permanent.Permanent; import mage.target.Target; import mage.target.common.TargetControlledCreaturePermanent; -import java.util.UUID; - /** * @author BetaSteward_at_googlemail.com */ @@ -57,14 +56,15 @@ public class EquipAbility extends ActivatedAbilityImpl { } @Override - public boolean canActivate(UUID playerId, Game game) { - if (super.canActivate(playerId, game)) { + public ActivationStatus canActivate(UUID playerId, Game game) { + ActivationStatus activationStatus = super.canActivate(playerId, game); + if (activationStatus.canActivate()) { Permanent permanent = game.getPermanent(sourceId); if (permanent != null && permanent.hasSubtype(SubType.EQUIPMENT, game)) { - return true; + return activationStatus; } } - return false; + return activationStatus; } public EquipAbility(final EquipAbility ability) { diff --git a/Mage/src/main/java/mage/abilities/keyword/EquipLegendaryAbility.java b/Mage/src/main/java/mage/abilities/keyword/EquipLegendaryAbility.java index 585a357713..8ea4c9ef44 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EquipLegendaryAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EquipLegendaryAbility.java @@ -1,96 +1,95 @@ -/* - * 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.keyword; - -import mage.abilities.ActivatedAbilityImpl; -import mage.abilities.costs.Cost; -import mage.abilities.effects.common.AttachEffect; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.TimingRule; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.Target; -import mage.target.common.TargetControlledCreaturePermanent; - -import java.util.UUID; -import mage.constants.SuperType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.predicate.mageobject.SupertypePredicate; - -/** - * @author Rystan - */ -public class EquipLegendaryAbility extends ActivatedAbilityImpl { - - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("legendary creature you control"); - - static { - filter.add(new SupertypePredicate(SuperType.LEGENDARY)); - } - - public EquipLegendaryAbility(Outcome outcome, Cost cost) { - this(outcome, cost, new TargetControlledCreaturePermanent(filter)); - } - - public EquipLegendaryAbility(Outcome outcome, Cost cost, Target target) { - super(Zone.BATTLEFIELD, new AttachEffect(outcome, "Equip"), cost); - this.addTarget(target); - this.timing = TimingRule.SORCERY; - } - - @Override - public boolean canActivate(UUID playerId, Game game) { - if (super.canActivate(playerId, game)) { - Permanent permanent = game.getPermanent(sourceId); - if (permanent != null && permanent.hasSubtype(SubType.EQUIPMENT, game)) { - return true; - } - } - return false; - } - - public EquipLegendaryAbility(final EquipLegendaryAbility ability) { - super(ability); - } - - @Override - public EquipLegendaryAbility copy() { - return new EquipLegendaryAbility(this); - } - - @Override - public String getRule() { - return "Equip legendary creature " + costs.getText() + - manaCosts.getText() + " (" + manaCosts.getText() + - ": <i>Attach to target legendary creature you control. Equip only as a sorcery.)</i>"; - } - -} +/* + * 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.keyword; + +import java.util.UUID; +import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.costs.Cost; +import mage.abilities.effects.common.AttachEffect; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.TimingRule; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.Target; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * @author Rystan + */ +public class EquipLegendaryAbility extends ActivatedAbilityImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("legendary creature you control"); + + static { + filter.add(new SupertypePredicate(SuperType.LEGENDARY)); + } + + public EquipLegendaryAbility(Outcome outcome, Cost cost) { + this(outcome, cost, new TargetControlledCreaturePermanent(filter)); + } + + public EquipLegendaryAbility(Outcome outcome, Cost cost, Target target) { + super(Zone.BATTLEFIELD, new AttachEffect(outcome, "Equip"), cost); + this.addTarget(target); + this.timing = TimingRule.SORCERY; + } + + @Override + public ActivationStatus canActivate(UUID playerId, Game game) { + ActivationStatus activationStatus = super.canActivate(playerId, game); + if (activationStatus.canActivate()) { + Permanent permanent = game.getPermanent(sourceId); + if (permanent != null && permanent.hasSubtype(SubType.EQUIPMENT, game)) { + return activationStatus; + } + } + return activationStatus; + } + + public EquipLegendaryAbility(final EquipLegendaryAbility ability) { + super(ability); + } + + @Override + public EquipLegendaryAbility copy() { + return new EquipLegendaryAbility(this); + } + + @Override + public String getRule() { + return "Equip legendary creature " + costs.getText() + + manaCosts.getText() + " (" + manaCosts.getText() + + ": <i>Attach to target legendary creature you control. Equip only as a sorcery.)</i>"; + } + +} diff --git a/Mage/src/main/java/mage/abilities/keyword/FlashbackAbility.java b/Mage/src/main/java/mage/abilities/keyword/FlashbackAbility.java index 13f489dd36..f7d7fbe069 100644 --- a/Mage/src/main/java/mage/abilities/keyword/FlashbackAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/FlashbackAbility.java @@ -83,13 +83,14 @@ public class FlashbackAbility extends SpellAbility { } @Override - public boolean canActivate(UUID playerId, Game game) { - if (super.canActivate(playerId, game)) { + public ActivationStatus canActivate(UUID playerId, Game game) { + ActivationStatus activationStatus = super.canActivate(playerId, game); + if (activationStatus.canActivate()) { Card card = game.getCard(getSourceId()); if (card != null) { // Cards with no Mana Costs cant't be flashbacked (e.g. Ancestral Vision) if (card.getManaCost().isEmpty()) { - return false; + return ActivationStatus.getFalse(); } // Flashback can never cast a split card by Fuse, because Fuse only works from hand if (card.isSplitCard()) { @@ -102,7 +103,7 @@ public class FlashbackAbility extends SpellAbility { return card.getSpellAbility().canActivate(playerId, game); } } - return false; + return activationStatus; } @Override diff --git a/Mage/src/main/java/mage/abilities/keyword/ForecastAbility.java b/Mage/src/main/java/mage/abilities/keyword/ForecastAbility.java index fdbfe871ff..2d3a2fbf2d 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ForecastAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ForecastAbility.java @@ -43,10 +43,10 @@ import mage.game.Game; * * 702.56b A forecast ability may be activated only during the upkeep step of * the card's owner and only once each turn. The controller of the forecast - * ability reveals the card with that ability from their hand as the - * ability is activated. That player plays with that card revealed in their - * hand until it leaves the player's hand or until a step or phase that isn't an - * upkeep step begins, whichever comes first. + * ability reveals the card with that ability from their hand as the ability is + * activated. That player plays with that card revealed in their hand until it + * leaves the player's hand or until a step or phase that isn't an upkeep step + * begins, whichever comes first. * * @author LevelX2 * @@ -68,11 +68,11 @@ public class ForecastAbility extends LimitedTimesPerTurnActivatedAbility { } @Override - public boolean canActivate(UUID playerId, Game game) { + 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()) { - return false; + return ActivationStatus.getFalse(); } return super.canActivate(playerId, game); } diff --git a/Mage/src/main/java/mage/abilities/keyword/ImproviseAbility.java b/Mage/src/main/java/mage/abilities/keyword/ImproviseAbility.java index 738537f59d..f3a9f36d65 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ImproviseAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ImproviseAbility.java @@ -6,7 +6,6 @@ package mage.abilities.keyword; import java.util.UUID; - import mage.Mana; import mage.abilities.Ability; import mage.abilities.SpecialAction; @@ -69,7 +68,7 @@ public class ImproviseAbility extends SimpleStaticAbility implements AlternateMa Target target = new TargetControlledPermanent(1, unpaid.getMana().getGeneric(), filter, true); target.setTargetName("artifact to Improvise"); specialAction.addTarget(target); - if (specialAction.canActivate(source.getControllerId(), game)) { + if (specialAction.canActivate(source.getControllerId(), game).canActivate()) { game.getState().getSpecialActions().add(specialAction); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/MadnessAbility.java b/Mage/src/main/java/mage/abilities/keyword/MadnessAbility.java index 44153d7f32..b07de0e0b0 100644 --- a/Mage/src/main/java/mage/abilities/keyword/MadnessAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/MadnessAbility.java @@ -2,6 +2,7 @@ package mage.abilities.keyword; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; @@ -33,10 +34,10 @@ import mage.players.Player; * first ability is applied. * * "Madness [cost]" means "If a player would discard this card, that player - * discards it, but may exile it instead of putting it into their - * graveyard" and "When this card is exiled this way, its owner may cast it by - * paying [cost] rather than paying its mana cost. If that player doesn't, he or - * she puts this card into their graveyard. + * discards it, but may exile it instead of putting it into their graveyard" and + * "When this card is exiled this way, its owner may cast it by paying [cost] + * rather than paying its mana cost. If that player doesn't, he or she puts this + * card into their graveyard. * * 702.33b. Casting a spell using its madness ability follows the rules for * paying alternative costs in rules 601.2b and 601.2e-g. @@ -219,7 +220,7 @@ class MadnessCastEffect extends OneShotEffect { castByMadness.setSpellAbilityCastMode(SpellAbilityCastMode.MADNESS); costRef.clear(); costRef.add(madnessCost); - boolean result = owner.cast(castByMadness, game, false); + boolean result = owner.cast(castByMadness, game, false, new MageObjectReference(source.getSourceObject(game), game)); return result; } diff --git a/Mage/src/main/java/mage/abilities/keyword/MiracleAbility.java b/Mage/src/main/java/mage/abilities/keyword/MiracleAbility.java index ed50e9b7b0..5cc3b7f606 100644 --- a/Mage/src/main/java/mage/abilities/keyword/MiracleAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/MiracleAbility.java @@ -27,6 +27,7 @@ */ package mage.abilities.keyword; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.TriggeredAbilityImpl; @@ -52,8 +53,8 @@ import mage.watchers.common.MiracleWatcher; * cost." * * 702.92b If a player chooses to reveal a card using its miracle ability, he or - * she plays with that card revealed until that card leaves their hand, - * that ability resolves, or that ability otherwise leaves the stack. + * she plays with that card revealed until that card leaves their hand, that + * ability resolves, or that ability otherwise leaves the stack. * * You can cast a card for its miracle cost only as the miracle triggered * ability resolves. If you don't want to cast it at that time (or you can't @@ -172,7 +173,7 @@ class MiracleEffect extends OneShotEffect { // replace with the new cost costRef.clear(); costRef.add(miracleCosts); - controller.cast(abilityToCast, game, false); + controller.cast(abilityToCast, game, false, new MageObjectReference(source.getSourceObject(game), game)); return true; } return false; diff --git a/Mage/src/main/java/mage/abilities/keyword/ReboundAbility.java b/Mage/src/main/java/mage/abilities/keyword/ReboundAbility.java index 17bcf1d600..6766d6d53a 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ReboundAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ReboundAbility.java @@ -28,6 +28,7 @@ package mage.abilities.keyword; import java.util.UUID; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.SpellAbility; @@ -206,7 +207,7 @@ class ReboundCastSpellFromExileEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (player != null && reboundCard != null) { SpellAbility ability = reboundCard.getSpellAbility(); - player.cast(ability, game, true); + player.cast(ability, game, true, new MageObjectReference(source.getSourceObject(game), game)); zone.remove(reboundCard.getId()); return true; } diff --git a/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java b/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java index 80bab29d56..8dbd4b8e92 100644 --- a/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java @@ -1,6 +1,7 @@ package mage.abilities.keyword; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.OneShotEffect; @@ -103,7 +104,7 @@ class RippleEffect extends OneShotEffect { while (player.canRespond() && cards.count(sameNameFilter, game) > 0 && player.choose(Outcome.PlayForFree, cards, target1, game)) { Card card = cards.get(target1.getFirstTarget(), game); if (card != null) { - player.cast(card.getSpellAbility(), game, true); + player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); cards.remove(card); } target1.clearChosen(); diff --git a/Mage/src/main/java/mage/abilities/keyword/SpliceOntoArcaneAbility.java b/Mage/src/main/java/mage/abilities/keyword/SpliceOntoArcaneAbility.java index 0a4f96049b..9932427baf 100644 --- a/Mage/src/main/java/mage/abilities/keyword/SpliceOntoArcaneAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/SpliceOntoArcaneAbility.java @@ -27,6 +27,7 @@ */ package mage.abilities.keyword; +import java.util.Iterator; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.SpellAbility; @@ -42,63 +43,66 @@ import mage.game.Game; import mage.game.stack.Spell; import mage.players.Player; -import java.util.Iterator; - - /** * 702.45. Splice * - * 702.45a Splice is a static ability that functions while a card is in your hand. - * "Splice onto [subtype] [cost]" means "You may reveal this card from your hand - * as you cast a [subtype] spell. If you do, copy this card's text box onto that - * spell and pay [cost] as an additional cost to cast that spell." Paying a card's - * splice cost follows the rules for paying additional costs in rules 601.2b and - * 601.2e-g. + * 702.45a Splice is a static ability that functions while a card is in your + * hand. "Splice onto [subtype] [cost]" means "You may reveal this card from + * your hand as you cast a [subtype] spell. If you do, copy this card's text box + * onto that spell and pay [cost] as an additional cost to cast that spell." + * Paying a card's splice cost follows the rules for paying additional costs in + * rules 601.2b and 601.2e-g. * - * Example: Since the card with splice remains in the player's hand, it can later - * be cast normally or spliced onto another spell. It can even be discarded to pay - * a "discard a card" cost of the spell it's spliced onto. + * Example: Since the card with splice remains in the player's hand, it can + * later be cast normally or spliced onto another spell. It can even be + * discarded to pay a "discard a card" cost of the spell it's spliced onto. * - * 702.45b You can't choose to use a splice ability if you can't make the required - * choices (targets, etc.) for that card's instructions. You can't splice any one - * card onto the same spell more than once. If you're splicing more than one card - * onto a spell, reveal them all at once and choose the order in which their - * instructions will be followed. The instructions on the main spell have to be - * followed first. + * 702.45b You can't choose to use a splice ability if you can't make the + * required choices (targets, etc.) for that card's instructions. You can't + * splice any one card onto the same spell more than once. If you're splicing + * more than one card onto a spell, reveal them all at once and choose the order + * in which their instructions will be followed. The instructions on the main + * spell have to be followed first. * - * 702.45c The spell has the characteristics of the main spell, plus the text boxes - * of each of the spliced cards. The spell doesn't gain any other characteristics - * (name, mana cost, color, supertypes, card types, subtypes, etc.) of the spliced - * cards. Text copied onto the spell that refers to a card by name refers to the spell - * on the stack, not the card from which the text was copied. + * 702.45c The spell has the characteristics of the main spell, plus the text + * boxes of each of the spliced cards. The spell doesn't gain any other + * characteristics (name, mana cost, color, supertypes, card types, subtypes, + * etc.) of the spliced cards. Text copied onto the spell that refers to a card + * by name refers to the spell on the stack, not the card from which the text + * was copied. * - * Example: Glacial Ray is a red card with splice onto Arcane that reads, "Glacial - * Ray deals 2 damage to any target." Suppose Glacial Ray is spliced - * onto Reach Through Mists, a blue spell. The spell is still blue, and Reach Through - * Mists deals the damage. This means that the ability can target a creature with - * protection from red and deal 2 damage to that creature. + * Example: Glacial Ray is a red card with splice onto Arcane that reads, + * "Glacial Ray deals 2 damage to any target." Suppose Glacial Ray is spliced + * onto Reach Through Mists, a blue spell. The spell is still blue, and Reach + * Through Mists deals the damage. This means that the ability can target a + * creature with protection from red and deal 2 damage to that creature. * - * 702.45d Choose targets for the added text normally (see rule 601.2c). Note that a - * spell with one or more targets will be countered if all of its targets are illegal - * on resolution. + * 702.45d Choose targets for the added text normally (see rule 601.2c). Note + * that a spell with one or more targets will be countered if all of its targets + * are illegal on resolution. * - * 702.45e The spell loses any splice changes once it leaves the stack (for example, - * when it's countered, it's exiled, or it resolves). + * 702.45e The spell loses any splice changes once it leaves the stack (for + * example, when it's countered, it's exiled, or it resolves). * - * Rulings + * Rulings * - * You must reveal all of the cards you intend to splice at the same time. Each individual card can only be spliced once onto a spell. - * If you have more than one card with the same name in your hand, you may splice both of them onto the spell. - * A card with a splice ability can't be spliced onto itself because the spell is on the stack (and not in your hand) when you reveal the cards you want to splice onto it. - * The target for a card that's spliced onto a spell may be the same as the target chosen for the original spell or for another spliced-on card. (A recent change to the targeting rules allows this, but most other cards are unaffected by the change.) - * If you splice a targeted card onto an untargeted spell, the entire spell will be countered if the target isn't legal when the spell resolves. - * If you splice an untargeted card onto a targeted spell, the entire spell will be countered if the target isn't legal when the spell resolves. - * A spell is countered on resolution only if *all* of its targets are illegal (or the spell is countered by an effect). + * You must reveal all of the cards you intend to splice at the same time. Each + * individual card can only be spliced once onto a spell. If you have more than + * one card with the same name in your hand, you may splice both of them onto + * the spell. A card with a splice ability can't be spliced onto itself because + * the spell is on the stack (and not in your hand) when you reveal the cards + * you want to splice onto it. The target for a card that's spliced onto a spell + * may be the same as the target chosen for the original spell or for another + * spliced-on card. (A recent change to the targeting rules allows this, but + * most other cards are unaffected by the change.) If you splice a targeted card + * onto an untargeted spell, the entire spell will be countered if the target + * isn't legal when the spell resolves. If you splice an untargeted card onto a + * targeted spell, the entire spell will be countered if the target isn't legal + * when the spell resolves. A spell is countered on resolution only if *all* of + * its targets are illegal (or the spell is countered by an effect). * * @author LevelX2 */ - - public class SpliceOntoArcaneAbility extends SimpleStaticAbility { private static final String KEYWORD_TEXT = "Splice onto Arcane"; @@ -134,8 +138,8 @@ public class SpliceOntoArcaneAbility extends SimpleStaticAbility { @Override public String getRule() { StringBuilder sb = new StringBuilder(); - sb.append(KEYWORD_TEXT).append(nonManaCosts?"-":" "); - sb.append(spliceCosts.getText()).append(nonManaCosts?". ":" "); + sb.append(KEYWORD_TEXT).append(nonManaCosts ? "-" : " "); + sb.append(spliceCosts.getText()).append(nonManaCosts ? ". " : " "); sb.append("<i>(As you cast an Arcane spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell.)</i>"); return sb.toString(); } @@ -193,7 +197,7 @@ class SpliceOntoArcaneEffect extends SpliceCardEffectImpl { if (card.getManaCost().isEmpty()) { // e.g. Evermind return card.getSpellAbility().spellCanBeActivatedRegularlyNow(source.getControllerId(), game); } else { - return card.getSpellAbility().canActivate(source.getControllerId(), game); + return card.getSpellAbility().canActivate(source.getControllerId(), game).canActivate(); } } return false; diff --git a/Mage/src/main/java/mage/abilities/keyword/SurgeAbility.java b/Mage/src/main/java/mage/abilities/keyword/SurgeAbility.java index d03a394d6b..041331417c 100644 --- a/Mage/src/main/java/mage/abilities/keyword/SurgeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/SurgeAbility.java @@ -66,7 +66,7 @@ public class SurgeAbility extends SpellAbility { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { // check if controller or teammate has already cast a spell this turn CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName()); if (watcher != null) { @@ -81,7 +81,7 @@ public class SurgeAbility extends SpellAbility { } } } - return false; + return ActivationStatus.getFalse(); } @Override diff --git a/Mage/src/main/java/mage/abilities/keyword/SuspendAbility.java b/Mage/src/main/java/mage/abilities/keyword/SuspendAbility.java index b19ca7db21..11a9163cb5 100644 --- a/Mage/src/main/java/mage/abilities/keyword/SuspendAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/SuspendAbility.java @@ -31,6 +31,7 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.SpecialAction; import mage.abilities.TriggeredAbilityImpl; @@ -228,16 +229,16 @@ public class SuspendAbility extends SpecialAction { } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { if (game.getState().getZone(getSourceId()) != Zone.HAND) { // Supend can only be activated from hand - return false; + return ActivationStatus.getFalse(); } MageObject object = game.getObject(sourceId); - return (object.isInstant() + return new ActivationStatus(object.isInstant() || object.hasAbility(FlashAbility.getInstance().getId(), game) || null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game) - || game.canPlaySorcery(playerId)); + || game.canPlaySorcery(playerId), null); } @Override @@ -376,7 +377,7 @@ class SuspendPlayCardEffect extends OneShotEffect { card.getAbilities().removeAll(abilitiesToRemove); } // cast the card for free - if (player.cast(card.getSpellAbility(), game, true)) { + if (player.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { if (card.isCreature()) { ContinuousEffect effect = new GainHasteEffect(); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game) + 1)); diff --git a/Mage/src/main/java/mage/abilities/mana/ActivateOncePerTurnManaAbility.java b/Mage/src/main/java/mage/abilities/mana/ActivateOncePerTurnManaAbility.java index d647995c9b..623e8d51c0 100644 --- a/Mage/src/main/java/mage/abilities/mana/ActivateOncePerTurnManaAbility.java +++ b/Mage/src/main/java/mage/abilities/mana/ActivateOncePerTurnManaAbility.java @@ -58,7 +58,7 @@ public class ActivateOncePerTurnManaAbility extends ActivatedManaAbilityImpl { @Override public boolean activate(Game game, boolean noMana) { - if (canActivate(this.controllerId, game)) { + if (canActivate(this.controllerId, game).canActivate()) { return super.activate(game, noMana); } return false; diff --git a/Mage/src/main/java/mage/abilities/mana/ActivatedManaAbilityImpl.java b/Mage/src/main/java/mage/abilities/mana/ActivatedManaAbilityImpl.java index eb065d6927..6b95b9685e 100644 --- a/Mage/src/main/java/mage/abilities/mana/ActivatedManaAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/mana/ActivatedManaAbilityImpl.java @@ -69,21 +69,21 @@ public abstract class ActivatedManaAbilityImpl extends ActivatedAbilityImpl impl } @Override - public boolean canActivate(UUID playerId, Game game) { + public ActivationStatus canActivate(UUID playerId, Game game) { if (!super.hasMoreActivationsThisTurn(game) || !(condition == null || condition.apply(game, this))) { - return false; + return ActivationStatus.getFalse(); } if (!controlsAbility(playerId, game)) { - return false; + return ActivationStatus.getFalse(); } if (timing == TimingRule.SORCERY && !game.canPlaySorcery(playerId) && null == game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_AS_INSTANT, this, controllerId, game)) { - return false; + return ActivationStatus.getFalse(); } // check if player is in the process of playing spell costs and he is no longer allowed to use activated mana abilities (e.g. because he started to use improvise) //20091005 - 605.3a - return costs.canPay(this, sourceId, controllerId, game); + return new ActivationStatus(costs.canPay(this, sourceId, controllerId, game), null); } diff --git a/Mage/src/main/java/mage/filter/common/FilterCreatureForCombatBlock.java b/Mage/src/main/java/mage/filter/common/FilterCreatureForCombatBlock.java index f4e35180ca..99d99fd8a0 100644 --- a/Mage/src/main/java/mage/filter/common/FilterCreatureForCombatBlock.java +++ b/Mage/src/main/java/mage/filter/common/FilterCreatureForCombatBlock.java @@ -61,7 +61,7 @@ class BlockTappedPredicate implements Predicate<Permanent> { @Override public boolean apply(Permanent input, Game game) { - return !input.isTapped() || null != game.getState().getContinuousEffects().asThough(input.getId(), AsThoughEffectType.BLOCK_TAPPED, input.getControllerId(), game); + return !input.isTapped() || null != game.getState().getContinuousEffects().asThough(input.getId(), AsThoughEffectType.BLOCK_TAPPED, null, input.getControllerId(), game); } @Override diff --git a/Mage/src/main/java/mage/game/events/GameEvent.java b/Mage/src/main/java/mage/game/events/GameEvent.java index cee8547a81..33a8a29080 100644 --- a/Mage/src/main/java/mage/game/events/GameEvent.java +++ b/Mage/src/main/java/mage/game/events/GameEvent.java @@ -31,6 +31,7 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import mage.MageObjectReference; import mage.constants.Zone; /** @@ -48,6 +49,7 @@ public class GameEvent implements Serializable { protected String data; protected Zone zone; protected List<UUID> appliedEffects = new ArrayList<>(); + protected MageObjectReference reference; // e.g. the permitting object for casting a spell from non hand zone protected UUID customEventType = null; public enum EventType { @@ -232,7 +234,7 @@ public class GameEvent implements Serializable { FLIP_COIN, COIN_FLIPPED, SCRY, FATESEAL, ROLL_DICE, DICE_ROLLED, ROLL_PLANAR_DIE, PLANAR_DIE_ROLLED, - PLANESWALK, PLANESWALKED, + PLANESWALK, PLANESWALKED, PAID_CUMULATIVE_UPKEEP, DIDNT_PAY_CUMULATIVE_UPKEEP, //permanent events @@ -334,21 +336,14 @@ public class GameEvent implements Serializable { CUSTOM_EVENT } - private GameEvent(EventType type, UUID customEventType, - UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag) { - this.type = type; - this.customEventType = customEventType; - this.targetId = targetId; - this.sourceId = sourceId; - this.amount = amount; - this.playerId = playerId; - this.flag = flag; - } - public GameEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId) { this(type, null, targetId, sourceId, playerId, 0, false); } + public GameEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId, MageObjectReference reference) { + this(type, null, targetId, sourceId, playerId, 0, false, reference); + } + public GameEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag) { this(type, null, targetId, sourceId, playerId, amount, flag); } @@ -369,6 +364,10 @@ public class GameEvent implements Serializable { return new GameEvent(type, targetId, sourceId, playerId); } + public static GameEvent getEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId, MageObjectReference reference) { + return new GameEvent(type, targetId, sourceId, playerId, reference); + } + public static GameEvent getEvent(EventType type, UUID targetId, UUID playerId) { return new GameEvent(type, targetId, null, playerId); } @@ -399,6 +398,23 @@ public class GameEvent implements Serializable { return event; } + private GameEvent(EventType type, UUID customEventType, + UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag) { + this(type, customEventType, targetId, sourceId, playerId, amount, flag, null); + } + + private GameEvent(EventType type, UUID customEventType, + UUID targetId, UUID sourceId, UUID playerId, int amount, boolean flag, MageObjectReference reference) { + this.type = type; + this.customEventType = customEventType; + this.targetId = targetId; + this.sourceId = sourceId; + this.amount = amount; + this.playerId = playerId; + this.flag = flag; + this.reference = reference; + } + public EventType getType() { return type; } @@ -455,6 +471,14 @@ public class GameEvent implements Serializable { this.zone = zone; } + public MageObjectReference getAdditionalReference() { + return reference; + } + + public void setAdditionalReference(MageObjectReference additionalReference) { + this.reference = additionalReference; + } + /** * used to store which replacement effects were already applied to an event * or or any modified events that may replace it diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index 1f6eeacb01..e033640c13 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java @@ -935,20 +935,20 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { public boolean canBeTargetedBy(MageObject source, UUID sourceControllerId, Game game) { if (source != null) { if (abilities.containsKey(ShroudAbility.getInstance().getId())) { - if (null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.SHROUD, sourceControllerId, game)) { + if (null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.SHROUD, null, sourceControllerId, game)) { return false; } } if (abilities.containsKey(HexproofAbility.getInstance().getId())) { if (game.getPlayer(this.getControllerId()).hasOpponent(sourceControllerId, game) - && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, sourceControllerId, game)) { + && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, null, sourceControllerId, game)) { return false; } } if (abilities.containsKey(HexproofFromBlackAbility.getInstance().getId())) { if (game.getPlayer(this.getControllerId()).hasOpponent(sourceControllerId, game) - && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, sourceControllerId, game) + && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, null, sourceControllerId, game) && source.getColor(game).isBlack()) { return false; } @@ -956,7 +956,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { if (abilities.containsKey(HexproofFromWhiteAbility.getInstance().getId())) { if (game.getPlayer(this.getControllerId()).hasOpponent(sourceControllerId, game) - && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, sourceControllerId, game) + && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, null, sourceControllerId, game) && source.getColor(game).isWhite()) { return false; } @@ -1096,7 +1096,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { @Override public boolean canAttackInPrinciple(UUID defenderId, Game game) { if (hasSummoningSickness() - && null == game.getContinuousEffects().asThough(this.objectId, AsThoughEffectType.ATTACK_AS_HASTE, this.getControllerId(), game)) { + && null == game.getContinuousEffects().asThough(this.objectId, AsThoughEffectType.ATTACK_AS_HASTE, null, this.getControllerId(), game)) { return false; } //20101001 - 508.1c @@ -1116,7 +1116,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { } return !abilities.containsKey(DefenderAbility.getInstance().getId()) - || null != game.getContinuousEffects().asThough(this.objectId, AsThoughEffectType.ATTACK, this.getControllerId(), game); + || null != game.getContinuousEffects().asThough(this.objectId, AsThoughEffectType.ATTACK, null, this.getControllerId(), game); } private boolean canAttackCheckRestrictionEffects(UUID defenderId, Game game) { @@ -1136,7 +1136,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { @Override public boolean canBlock(UUID attackerId, Game game) { - if (tapped && null == game.getState().getContinuousEffects().asThough(this.getId(), AsThoughEffectType.BLOCK_TAPPED, this.getControllerId(), game)) { + if (tapped && null == game.getState().getContinuousEffects().asThough(this.getId(), AsThoughEffectType.BLOCK_TAPPED, null, this.getControllerId(), game)) { return false; } Permanent attacker = game.getPermanent(attackerId); @@ -1169,7 +1169,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { @Override public boolean canBlockAny(Game game) { - if (tapped && null == game.getState().getContinuousEffects().asThough(this.getId(), AsThoughEffectType.BLOCK_TAPPED, this.getControllerId(), game)) { + if (tapped && null == game.getState().getContinuousEffects().asThough(this.getId(), AsThoughEffectType.BLOCK_TAPPED, null, this.getControllerId(), game)) { return false; } diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java index b2510b262f..d8d7e36ce5 100644 --- a/Mage/src/main/java/mage/players/Player.java +++ b/Mage/src/main/java/mage/players/Player.java @@ -36,6 +36,7 @@ import java.util.Set; import java.util.UUID; import mage.MageItem; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Abilities; import mage.abilities.Ability; import mage.abilities.ActivatedAbility; @@ -359,7 +360,7 @@ public interface Player extends MageItem, Copyable<Player> { int drawCards(int num, Game game, List<UUID> appliedEffects); - boolean cast(SpellAbility ability, Game game, boolean noMana); + boolean cast(SpellAbility ability, Game game, boolean noMana, MageObjectReference reference); SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana); @@ -399,7 +400,7 @@ public interface Player extends MageItem, Copyable<Player> { * to be the turn of the player playing that card. * @return */ - boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming); + boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming, MageObjectReference reference); /** * diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index bdb8a60a3e..9ba76bbb6f 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -33,8 +33,10 @@ import java.util.*; import java.util.Map.Entry; import mage.ConditionalMana; import mage.MageObject; +import mage.MageObjectReference; import mage.Mana; import mage.abilities.*; +import mage.abilities.ActivatedAbility.ActivationStatus; import mage.abilities.common.PassAbility; import mage.abilities.common.WhileSearchingPlayFromLibraryAbility; import mage.abilities.common.delayed.AtTheEndOfTurnStepPostDelayedTriggeredAbility; @@ -610,7 +612,7 @@ public abstract class PlayerImpl implements Player, Serializable { } if (abilities.containsKey(HexproofAbility.getInstance().getId())) { if (sourceControllerId != null && this.hasOpponent(sourceControllerId, game) - && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, this.getId(), game)) { + && null == game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, null, this.getId(), game)) { return false; } } @@ -1010,7 +1012,7 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming) { + public boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming, MageObjectReference reference) { if (card == null) { return false; } @@ -1018,7 +1020,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (card.isLand()) { result = playLand(card, game, ignoreTiming); } else { - result = cast(card.getSpellAbility(), game, noMana); + result = cast(card.getSpellAbility(), game, noMana, reference); } if (!result) { game.informPlayer(this, "You can't play " + card.getIdName() + '.'); @@ -1027,7 +1029,7 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public boolean cast(SpellAbility ability, Game game, boolean noMana) { + public boolean cast(SpellAbility ability, Game game, boolean noMana, MageObjectReference permittingObject) { if (game == null || ability == null) { return false; } @@ -1046,7 +1048,7 @@ public abstract class PlayerImpl implements Player, Serializable { } Card card = game.getCard(ability.getSourceId()); if (card != null) { - if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getId(), ability.getSourceId(), playerId), ability)) { + if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getId(), ability.getSourceId(), playerId, permittingObject), ability)) { int bookmark = game.bookmarkState(); Zone fromZone = game.getState().getZone(card.getMainCard().getId()); card.cast(game, fromZone, ability, playerId); @@ -1074,10 +1076,10 @@ public abstract class PlayerImpl implements Player, Serializable { } } setCastSourceIdWithAlternateMana(null, null, null); - GameEvent event = GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, spell.getSpellAbility().getId(), spell.getSpellAbility().getSourceId(), playerId); + GameEvent event = GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, spell.getSpellAbility().getId(), spell.getSpellAbility().getSourceId(), playerId, permittingObject); game.fireEvent(event); if (spell.activate(game, noMana)) { - event = GameEvent.getEvent(GameEvent.EventType.SPELL_CAST, spell.getSpellAbility().getId(), spell.getSpellAbility().getSourceId(), playerId); + event = GameEvent.getEvent(GameEvent.EventType.SPELL_CAST, spell.getSpellAbility().getId(), spell.getSpellAbility().getSourceId(), playerId, permittingObject); event.setZone(fromZone); game.fireEvent(event); if (!game.isSimulation()) { @@ -1116,7 +1118,7 @@ public abstract class PlayerImpl implements Player, Serializable { SpellAbility spellAbility = new SpellAbility(null, "", game.getState().getZone(card.getId()), SpellAbilityType.FACE_DOWN_CREATURE); spellAbility.setControllerId(this.getId()); spellAbility.setSourceId(card.getId()); - if (cast(spellAbility, game, false)) { + if (cast(spellAbility, game, false, null)) { return true; } } @@ -1124,17 +1126,18 @@ public abstract class PlayerImpl implements Player, Serializable { return false; } //20091005 - 114.2a - if (!ignoreTiming && !playLandAbility.canActivate(this.playerId, game)) { + ActivationStatus activationStatus = playLandAbility.canActivate(this.playerId, game); + if (!ignoreTiming && !activationStatus.canActivate()) { return false; } //20091005 - 305.1 - if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), card.getId(), playerId))) { + if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), card.getId(), playerId, activationStatus.getPermittingObject()))) { // int bookmark = game.bookmarkState(); - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), card.getId(), playerId)); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), card.getId(), playerId, activationStatus.getPermittingObject())); if (moveCards(card, Zone.BATTLEFIELD, playLandAbility, game, false, false, false, null)) { landsPlayed++; - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED, card.getId(), card.getId(), playerId)); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED, card.getId(), card.getId(), playerId, activationStatus.getPermittingObject())); game.fireInformEvent(getLogName() + " plays " + card.getLogName()); // game.removeBookmark(bookmark); resetStoredBookmark(game); // prevent undo after playing a land @@ -1239,7 +1242,8 @@ public abstract class PlayerImpl implements Player, Serializable { Card card = game.getCard(ability.getSourceId()); result = playLand(card, game, false); } else { - if (!ability.canActivate(this.playerId, game)) { + ActivationStatus activationStatus = ability.canActivate(this.playerId, game); + if (!activationStatus.canActivate()) { return false; } @@ -1251,7 +1255,7 @@ public abstract class PlayerImpl implements Player, Serializable { result = playManaAbility((ActivatedManaAbilityImpl) ability.copy(), game); break; case SPELL: - result = cast((SpellAbility) ability.copy(), game, false); + result = cast((SpellAbility) ability.copy(), game, false, activationStatus.getPermittingObject()); break; default: result = playAbility(ability.copy(), game); @@ -1357,7 +1361,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (ability.getZone().match(zone)) { if (ability instanceof ActivatedAbility) { if (ability instanceof ActivatedManaAbilityImpl) { - if (((ActivatedAbility) ability).canActivate(playerId, game)) { + if (((ActivatedAbility) ability).canActivate(playerId, game).canActivate()) { output.put(ability.getId(), (ActivatedAbility) ability); } } else if (canPlay(((ActivatedAbility) ability), availableMana, object, game)) { @@ -1379,19 +1383,19 @@ public abstract class PlayerImpl implements Player, Serializable { if (Zone.GRAVEYARD == zone && canPlayCardsFromGraveyard()) { for (ActivatedAbility ability : candidateAbilites.getPlayableAbilities(Zone.HAND)) { if (canUse || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) { - if (ability.canActivate(playerId, game)) { + if (ability.canActivate(playerId, game).canActivate()) { output.put(ability.getId(), ability); } } } } if (zone != Zone.BATTLEFIELD - && null != game.getContinuousEffects().asThough(object.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, this.getId(), game)) { + && null != game.getContinuousEffects().asThough(object.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, this.getId(), game)) { for (Ability ability : candidateAbilites) { if (canUse || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) { ability.setControllerId(this.getId()); if (ability instanceof ActivatedAbility && ability.getZone().match(Zone.HAND) - && ((ActivatedAbility) ability).canActivate(playerId, game)) { + && ((ActivatedAbility) ability).canActivate(playerId, game).canActivate()) { output.put(ability.getId(), (ActivatedAbility) ability); } } @@ -1439,7 +1443,7 @@ public abstract class PlayerImpl implements Player, Serializable { flashbackAbility.setControllerId(card.getOwnerId()); flashbackAbility.setSpellAbilityType(SpellAbilityType.SPLIT_LEFT); flashbackAbility.setAbilityName(((SplitCard) card).getLeftHalfCard().getName()); - if (flashbackAbility.canActivate(playerId, game)) { + if (flashbackAbility.canActivate(playerId, game).canActivate()) { useable.put(flashbackAbility.getId(), flashbackAbility); } // Right Half @@ -1452,7 +1456,7 @@ public abstract class PlayerImpl implements Player, Serializable { flashbackAbility.setControllerId(card.getOwnerId()); flashbackAbility.setSpellAbilityType(SpellAbilityType.SPLIT_RIGHT); flashbackAbility.setAbilityName(((SplitCard) card).getRightHalfCard().getName()); - if (flashbackAbility.canActivate(playerId, game)) { + if (flashbackAbility.canActivate(playerId, game).canActivate()) { useable.put(flashbackAbility.getId(), flashbackAbility); } @@ -1469,7 +1473,7 @@ public abstract class PlayerImpl implements Player, Serializable { boolean canUse = !(object instanceof Permanent) || ((Permanent) object).canUseActivatedAbilities(game); for (ActivatedManaAbilityImpl ability : object.getAbilities().getActivatedManaAbilities(zone)) { if (canUse || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) { - if (ability.canActivate(playerId, game)) { + if (ability.canActivate(playerId, game).canActivate()) { useable.put(ability.getId(), ability); } } @@ -2477,7 +2481,7 @@ public abstract class PlayerImpl implements Player, Serializable { Card card = game.getCard(entry.getKey()); if (card != null) { // TODO: fix costs (why is Panglacial Wurm automatically accepting payment?) - player.cast(card.getSpellAbility(), game, false); + player.cast(card.getSpellAbility(), game, false, null); } chooseCard.clearChoice(); libraryCastableCardTracker.clear(); @@ -2633,7 +2637,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (canUse == null) { canUse = permanent.canUseActivatedAbilities(game); } - if (canUse && ability.canActivate(playerId, game)) { + if (canUse && ability.canActivate(playerId, game).canActivate()) { canAdd = true; if (!ability.getManaCosts().isEmpty()) { withCost = true; @@ -2677,7 +2681,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (canUse == null) { canUse = permanent.canUseActivatedAbilities(game); } - if (canUse && ability.canActivate(playerId, game)) { + if (canUse && ability.canActivate(playerId, game).canActivate()) { canAdd = true; } } @@ -2692,7 +2696,7 @@ public abstract class PlayerImpl implements Player, Serializable { canAdd = false; break; } - if (ability.canActivate(playerId, game)) { + if (ability.canActivate(playerId, game).canActivate()) { canAdd = true; } } @@ -2712,7 +2716,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (canUse == null) { canUse = permanent.canUseActivatedAbilities(game); } - if (canUse && ability.canActivate(playerId, game) && !ability.getManaCosts().isEmpty()) { + if (canUse && ability.canActivate(playerId, game).canActivate() && !ability.getManaCosts().isEmpty()) { result.add(permanent); break; } @@ -2732,7 +2736,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (!(ability instanceof ActivatedManaAbilityImpl)) { ActivatedAbility copy = ability.copy(); copy.setCheckPlayableMode(); // prevents from endless loops for asking player to use effects by checking this mode - if (!copy.canActivate(playerId, game)) { + if (!copy.canActivate(playerId, game).canActivate()) { return false; } if (available != null) { @@ -2765,10 +2769,10 @@ public abstract class PlayerImpl implements Player, Serializable { if (available == null) { return true; } - UUID spendAnyManaSourceId = game.getContinuousEffects().asThough(ability.getSourceId(), AsThoughEffectType.SPEND_OTHER_MANA, ability, ability.getControllerId(), game); + MageObjectReference permittingObject = game.getContinuousEffects().asThough(ability.getSourceId(), AsThoughEffectType.SPEND_OTHER_MANA, ability, ability.getControllerId(), game); for (Mana mana : abilityOptions) { for (Mana avail : available) { - if (spendAnyManaSourceId != null && mana.count() <= avail.count()) { + if (permittingObject != null && mana.count() <= avail.count()) { return true; } if (mana.enough(avail)) { // here we need to check if spend mana as though allow to pay the mana cost @@ -2893,13 +2897,13 @@ public abstract class PlayerImpl implements Player, Serializable { } private void getPlayableFromGraveyardCard(Game game, Card card, Abilities<Ability> candidateAbilities, ManaOptions availableMana, List<Ability> output) { - UUID asThoughtCastSourceId = game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, this.getId(), game); + MageObjectReference permittingObject = game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, this.getId(), game); for (ActivatedAbility ability : candidateAbilities.getActivatedAbilities(Zone.ALL)) { boolean possible = false; if (ability.getZone().match(Zone.GRAVEYARD)) { possible = true; } else if (ability.getZone().match(Zone.HAND) && (ability instanceof SpellAbility || ability instanceof PlayLandAbility)) { - if (asThoughtCastSourceId != null || canPlayCardsFromGraveyard()) { + if (permittingObject != null || canPlayCardsFromGraveyard()) { possible = true; } } @@ -2968,12 +2972,12 @@ public abstract class PlayerImpl implements Player, Serializable { } for (ExileZone exile : game.getExile().getExileZones()) { for (Card card : exile.getCards(game)) { - if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, this.getId(), game)) { + if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, this.getId(), game)) { for (Ability ability : card.getAbilities()) { if (ability.getZone().match(Zone.HAND)) { ability.setControllerId(this.getId()); // controller must be set for case owner != caster if (ability instanceof ActivatedAbility) { - if (((ActivatedAbility) ability).canActivate(playerId, game)) { + if (((ActivatedAbility) ability).canActivate(playerId, game).canActivate()) { playable.add(ability); } } @@ -2986,7 +2990,7 @@ public abstract class PlayerImpl implements Player, Serializable { // Check to play revealed cards for (Cards cards : game.getState().getRevealed().values()) { for (Card card : cards.getCards(game)) { - if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, this.getId(), game)) { + if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, this.getId(), game)) { for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) { if (ability instanceof SpellAbility || ability instanceof PlayLandAbility) { playable.add(ability); @@ -3001,7 +3005,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (player != null) { if (/*player.isTopCardRevealed() &&*/player.getLibrary().hasCards()) { Card card = player.getLibrary().getFromTop(game); - if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, getId(), game)) { + if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, getId(), game)) { for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) { if (ability instanceof SpellAbility || ability instanceof PlayLandAbility) { playable.add(ability); @@ -3354,7 +3358,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean lookAtFaceDownCard(Card card, Game game ) { - if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.LOOK_AT_FACE_DOWN, this.getId(), game)) { + if (null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.LOOK_AT_FACE_DOWN, card.getSpellAbility(), this.getId(), game)) { if (chooseUse(Outcome.Benefit, "Look at that card?", null, game)) { Cards cards = new CardsImpl(card); this.lookAtCards(getName() + " - " + sdf.format(System.currentTimeMillis()), cards, game); From 496609e7a0df7d15da13f002bcd2548e153188fe Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Sun, 27 May 2018 23:49:17 +0200 Subject: [PATCH 143/154] * Muldrotha, the Gravetide - Fixed a problem that the cast usage was checked by player instead by source (fixes #4969). --- .../mage/cards/m/MuldrothaTheGravetide.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MuldrothaTheGravetide.java b/Mage.Sets/src/mage/cards/m/MuldrothaTheGravetide.java index 1a74f79d8b..ec6ca9ab4e 100644 --- a/Mage.Sets/src/mage/cards/m/MuldrothaTheGravetide.java +++ b/Mage.Sets/src/mage/cards/m/MuldrothaTheGravetide.java @@ -33,6 +33,7 @@ import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.AsThoughEffectImpl; @@ -118,7 +119,8 @@ class MuldrothaTheGravetideCastFromGraveyardEffect extends AsThoughEffectImpl { if (mageObject != null && watcher != null) { for (CardType cardType : mageObject.getCardType()) { if (cardType.isPermanentType()) { - if (!watcher.permanentTypePlayedFromGraveyard(affectedControllerId, cardType)) { + MageObjectReference mor = new MageObjectReference(source.getSourceObject(game), game); + if (!watcher.permanentTypePlayedFromGraveyard(mor, cardType)) { return true; } } @@ -136,10 +138,12 @@ class MuldrothaTheGravetideCastFromGraveyardEffect extends AsThoughEffectImpl { */ class MuldrothaTheGravetideWatcher extends Watcher { - // final HashMap<MageObjectReference, Set<CardType>> playerPlayedPermanentTypes = new HashMap<>(); // source that played permanent types from graveyard - final HashMap<UUID, Set<CardType>> playerPlayedPermanentTypes = new HashMap<>(); // player that played permanent types from graveyard + final HashMap<MageObjectReference, Set<CardType>> sourcePlayedPermanentTypes = new HashMap<>(); // source that played permanent types from graveyard + // final HashMap<UUID, Set<CardType>> playerPlayedPermanentTypes = new HashMap<>(); // player that played permanent types from graveyard // 4/27/2018 If multiple effects allow you to play a card from your graveyard, such as those of Gisa and Geralf and Karador, // Ghost Chieftain, you must announce which permission you’re using as you begin to play the card. + // 4/27/2018: If you play a card from your graveyard and then have a new Muldrotha come under your control in the same turn, + // you may play another card of that type from your graveyard that turn. private Zone fromZone; public MuldrothaTheGravetideWatcher() { @@ -148,7 +152,7 @@ class MuldrothaTheGravetideWatcher extends Watcher { public MuldrothaTheGravetideWatcher(final MuldrothaTheGravetideWatcher watcher) { super(watcher); - playerPlayedPermanentTypes.putAll(watcher.playerPlayedPermanentTypes); + sourcePlayedPermanentTypes.putAll(watcher.sourcePlayedPermanentTypes); } @Override @@ -174,7 +178,7 @@ class MuldrothaTheGravetideWatcher extends Watcher { } private void addPermanentTypes(GameEvent event, Card mageObject, Game game) { - if (mageObject != null) { + if (mageObject != null && event.getAdditionalReference() != null) { UUID playerId = null; if (mageObject instanceof Spell) { playerId = ((Spell) mageObject).getControllerId(); @@ -182,10 +186,10 @@ class MuldrothaTheGravetideWatcher extends Watcher { playerId = ((Permanent) mageObject).getControllerId(); } if (playerId != null) { - Set<CardType> permanentTypes = playerPlayedPermanentTypes.get(playerId); + Set<CardType> permanentTypes = sourcePlayedPermanentTypes.get(event.getAdditionalReference()); if (permanentTypes == null) { permanentTypes = EnumSet.noneOf(CardType.class); - playerPlayedPermanentTypes.put(playerId, permanentTypes); + sourcePlayedPermanentTypes.put(event.getAdditionalReference(), permanentTypes); } Set<CardType> typesNotCast = EnumSet.noneOf(CardType.class); for (CardType cardType : mageObject.getCardType()) { @@ -226,12 +230,12 @@ class MuldrothaTheGravetideWatcher extends Watcher { @Override public void reset() { - playerPlayedPermanentTypes.clear(); + sourcePlayedPermanentTypes.clear(); super.reset(); } - public boolean permanentTypePlayedFromGraveyard(UUID playerId, CardType cardType) { - Set<CardType> permanentTypes = playerPlayedPermanentTypes.get(playerId); + public boolean permanentTypePlayedFromGraveyard(MageObjectReference sourceMor, CardType cardType) { + Set<CardType> permanentTypes = sourcePlayedPermanentTypes.get(sourceMor); if (permanentTypes != null) { return permanentTypes.contains(cardType); } From 1f522f874aa2006c7d816e81c72e2b14644c036a Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Sun, 27 May 2018 23:55:25 +0200 Subject: [PATCH 144/154] xmage 1.4.30V1 --- Mage.Common/src/main/java/mage/utils/MageVersion.java | 2 +- Mage/src/main/java/mage/cards/repository/CardRepository.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java index c4e991fa49..9018b512ce 100644 --- a/Mage.Common/src/main/java/mage/utils/MageVersion.java +++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java @@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable<MageVersion> { 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 = "V0"; + public final static String MAGE_VERSION_MINOR_PATCH = "V1"; public final static String MAGE_VERSION_INFO = ""; private final int major; diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index 8f3a18fcfc..f17117374a 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -58,7 +58,7 @@ public enum CardRepository { // raise this if db structure was changed private static final long CARD_DB_VERSION = 51; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 110; + private static final long CARD_CONTENT_VERSION = 111; private Dao<CardInfo, Object> cardDao; private Set<String> classNames; From ea0a677e46bd8bed9608f214043d9890a26ceb1d Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Sun, 27 May 2018 22:06:01 -0400 Subject: [PATCH 145/154] Fixed Angel of Glory's Rise not bringing back Humans --- Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java b/Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java index 39355c6b02..220642f70f 100644 --- a/Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java +++ b/Mage.Sets/src/mage/cards/a/AngelOfGlorysRise.java @@ -103,7 +103,7 @@ class AngelOfGlorysRiseEffect extends OneShotEffect { controller.moveCards(toExile, Zone.EXILED, source, game); FilterCreatureCard filterHuman = new FilterCreatureCard(); filterHuman.add(new SubtypePredicate(SubType.HUMAN)); - controller.moveCards(controller.getGraveyard().getCards(filterHuman, game), Zone.GRAVEYARD, source, game); + controller.moveCards(controller.getGraveyard().getCards(filterHuman, game), Zone.BATTLEFIELD, source, game); } return true; } From 2d92d9be41c0c11b203fcd32c6e293f0510ea7ba Mon Sep 17 00:00:00 2001 From: Michael Simons <rystan@gmail.com> Date: Mon, 28 May 2018 01:16:48 -0400 Subject: [PATCH 146/154] Update TriumphOfFerocity.java static ruleText passed to ConditionalTriggeredAbility was leaving off the initial triggering condition when building rule text. --- Mage.Sets/src/mage/cards/t/TriumphOfFerocity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/t/TriumphOfFerocity.java b/Mage.Sets/src/mage/cards/t/TriumphOfFerocity.java index 177822ac17..9a7d3cd0bc 100644 --- a/Mage.Sets/src/mage/cards/t/TriumphOfFerocity.java +++ b/Mage.Sets/src/mage/cards/t/TriumphOfFerocity.java @@ -43,7 +43,7 @@ import mage.constants.TargetController; */ public class TriumphOfFerocity extends CardImpl { - private static final String ruleText = "draw a card if you control the creature with the greatest power or tied for the greatest power"; + private static final String ruleText = "At the beginning of your upkeep, draw a card if you control the creature with the greatest power or tied for the greatest power"; public TriumphOfFerocity(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{G}"); From a21496ef5f544971dfd294ed8fa9bd98e7fc55f0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 28 May 2018 14:08:13 -0400 Subject: [PATCH 147/154] Fixed Will Kenrith first ability duration and second ability not working --- Mage.Sets/src/mage/cards/w/WillKenrith.java | 13 +++++-------- .../common/cost/SpellsCostReductionAllEffect.java | 11 +++++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/w/WillKenrith.java b/Mage.Sets/src/mage/cards/w/WillKenrith.java index ce133b91d6..bb40bd41ed 100644 --- a/Mage.Sets/src/mage/cards/w/WillKenrith.java +++ b/Mage.Sets/src/mage/cards/w/WillKenrith.java @@ -32,7 +32,6 @@ import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.CanBeYourCommanderAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardTargetEffect; @@ -51,7 +50,6 @@ import mage.constants.Outcome; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; -import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; import mage.game.command.emblems.WillKenrithEmblem; import mage.target.TargetPlayer; @@ -72,11 +70,11 @@ public class WillKenrith extends CardImpl { // +2: Until your next turn, up to two target creatures each have base power and toughness 0/3 and lose all abilities. Ability ability = new LoyaltyAbility( - new SetPowerToughnessTargetEffect(0, 3, Duration.EndOfTurn) - .setText("until end of turn, up to two target creatures each have base power and toughness 0/3"), + new SetPowerToughnessTargetEffect(0, 3, Duration.UntilYourNextTurn) + .setText("until your next turn, up to two target creatures each have base power and toughness 0/3"), 2 ); - ability.addEffect(new LoseAllAbilitiesTargetEffect(Duration.EndOfTurn) + ability.addEffect(new LoseAllAbilitiesTargetEffect(Duration.UntilYourNextTurn) .setText("and lose all abilities") ); ability.addTarget(new TargetCreaturePermanent(0, 2)); @@ -144,10 +142,9 @@ class WillKenrithCostReductionEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - FilterCard filter2 = filter.copy(); - filter2.add(new ControllerIdPredicate(source.getFirstTarget())); - ContinuousEffect effect = new SpellsCostReductionAllEffect(filter2, 2); + SpellsCostReductionAllEffect effect = new SpellsCostReductionAllEffect(filter, 2); effect.setDuration(Duration.UntilYourNextTurn); + effect.setControllerId(source.getFirstTarget()); game.addEffect(effect, source); return true; } 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 3f07900238..dcd2bea04d 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 @@ -29,6 +29,7 @@ package mage.abilities.effects.common.cost; import java.util.LinkedHashSet; import java.util.Set; +import java.util.UUID; import mage.Mana; import mage.abilities.Ability; import mage.abilities.ActivatedAbility; @@ -54,6 +55,7 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl { private int amount; private final boolean upTo; private boolean onlyControlled; + private UUID controllerId; public SpellsCostReductionAllEffect(int amount) { this(new FilterCard("Spells"), amount); @@ -74,6 +76,7 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl { this.upTo = upTo; this.onlyControlled = onlyControlled; this.staticText = filter.getMessage() + " cost " + (upTo ? "up to " : "") + '{' + amount + "} less to cast"; + this.controllerId = null; } protected SpellsCostReductionAllEffect(final SpellsCostReductionAllEffect effect) { @@ -82,6 +85,7 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl { this.amount = effect.amount; this.upTo = effect.upTo; this.onlyControlled = effect.onlyControlled; + this.controllerId = effect.controllerId; } @Override @@ -145,6 +149,9 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl { if (onlyControlled && !abilityToModify.getControllerId().equals(source.getControllerId())) { return false; } + if (controllerId != null && !abilityToModify.getControllerId().equals(controllerId)) { + return false; + } if (abilityToModify instanceof SpellAbility) { Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); if (spell != null) { @@ -158,6 +165,10 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl { return false; } + public void setControllerId(UUID controllerId) { + this.controllerId = controllerId; + } + @Override public SpellsCostReductionAllEffect copy() { return new SpellsCostReductionAllEffect(this); From 00b4d8d482842e7f7cd2c61114f08a6b9fca622e Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 28 May 2018 14:11:16 -0400 Subject: [PATCH 148/154] fixed The Ur-Dragon only allowing lands to be put into play --- Mage.Sets/src/mage/cards/t/TheUrDragon.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/t/TheUrDragon.java b/Mage.Sets/src/mage/cards/t/TheUrDragon.java index f0380b3be9..a8b349383e 100644 --- a/Mage.Sets/src/mage/cards/t/TheUrDragon.java +++ b/Mage.Sets/src/mage/cards/t/TheUrDragon.java @@ -44,7 +44,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.FilterCard; -import mage.filter.StaticFilters; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.game.events.GameEvent; @@ -207,7 +206,7 @@ class TheUrDragonEffect extends OneShotEffect { if (attackingDragons > 0) { controller.drawCards(attackingDragons, game); } - return new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A).apply(game, source); + return new PutCardFromHandOntoBattlefieldEffect().apply(game, source); } } return false; From b217f86553e02a1fe55a856e4f8410f02905fce8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 28 May 2018 14:18:23 -0400 Subject: [PATCH 149/154] Fixed Matter Reshaper not working --- .../src/mage/cards/m/MatterReshaper.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MatterReshaper.java b/Mage.Sets/src/mage/cards/m/MatterReshaper.java index e1e8536734..3ece476ef7 100644 --- a/Mage.Sets/src/mage/cards/m/MatterReshaper.java +++ b/Mage.Sets/src/mage/cards/m/MatterReshaper.java @@ -91,17 +91,18 @@ class MatterReshaperEffect extends OneShotEffect { if (controller != null) { Card card = controller.getLibrary().getFromTop(game); if (card == null) { - controller.revealCards(source, new CardsImpl(card), game); - FilterPermanentCard filter = new FilterPermanentCard("permanent card with converted mana cost 3 or less"); - filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 4)); - if (filter.match(card, game)) { - if (controller.chooseUse(Outcome.PutCardInPlay, "Put " + card.getName() + " onto the battlefield (otherwise put in hand)?", source, game)) { - controller.moveCards(card, Zone.BATTLEFIELD, source, game); - return true; - } - } - controller.moveCards(card, Zone.HAND, source, game); + return false; } + controller.revealCards(source, new CardsImpl(card), game); + FilterPermanentCard filter = new FilterPermanentCard("permanent card with converted mana cost 3 or less"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 4)); + if (filter.match(card, game)) { + if (controller.chooseUse(Outcome.PutCardInPlay, "Put " + card.getName() + " onto the battlefield (otherwise put in hand)?", source, game)) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + return true; + } + } + controller.moveCards(card, Zone.HAND, source, game); return true; } return false; From 1fe4d59f6adbf4be53da199e8c8a339be094f6a5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 28 May 2018 14:29:32 -0400 Subject: [PATCH 150/154] fixed Obzedat, Ghost Council not gaining haste when it comes back --- .../src/mage/cards/o/ObzedatGhostCouncil.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/o/ObzedatGhostCouncil.java b/Mage.Sets/src/mage/cards/o/ObzedatGhostCouncil.java index c0c17aab26..eb642b5ed9 100644 --- a/Mage.Sets/src/mage/cards/o/ObzedatGhostCouncil.java +++ b/Mage.Sets/src/mage/cards/o/ObzedatGhostCouncil.java @@ -34,12 +34,13 @@ import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.LoseLifeTargetEffect; -import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.HasteAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -51,6 +52,7 @@ import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetOpponent; +import mage.target.targetpointer.FixedTarget; /** * @@ -69,10 +71,10 @@ public class ObzedatGhostCouncil extends CardImpl { //When Obzedat, Ghost Council enters the battlefield, target opponent loses 2 life and you gain 2 life. Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(2)); - ability.addEffect(new GainLifeEffect(2)); + ability.addEffect(new GainLifeEffect(2).setText("and you gain 2 life")); ability.addTarget(new TargetOpponent()); this.addAbility(ability); - //At the beginning of your end step you may exile Obzedat. If you do, return it to the battlefield under it's owner's control at the beginning of your next upkeep. It gains haste. + //At the beginning of your end step you may exile Obzedat. If you do, return it to the battlefield under its owner's control at the beginning of your next upkeep. It gains haste. Ability ability2 = new BeginningOfYourEndStepTriggeredAbility(new ObzedatGhostCouncilExileSourceEffect(), true); ability2.addEffect(new CreateDelayedTriggeredAbilityEffect(new BeginningOfYourUpkeepdelayTriggeredAbility())); this.addAbility(ability2); @@ -92,7 +94,7 @@ class ObzedatGhostCouncilExileSourceEffect extends OneShotEffect { public ObzedatGhostCouncilExileSourceEffect() { super(Outcome.Exile); - staticText = "Exile {this}"; + staticText = "exile {this}"; } public ObzedatGhostCouncilExileSourceEffect(final ObzedatGhostCouncilExileSourceEffect effect) { @@ -119,7 +121,6 @@ class BeginningOfYourUpkeepdelayTriggeredAbility extends DelayedTriggeredAbility public BeginningOfYourUpkeepdelayTriggeredAbility() { this(new ObzedatGhostCouncilReturnEffect(), TargetController.YOU); - this.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.Custom)); } public BeginningOfYourUpkeepdelayTriggeredAbility(Effect effect, TargetController targetController) { @@ -147,7 +148,7 @@ class BeginningOfYourUpkeepdelayTriggeredAbility extends DelayedTriggeredAbility @Override public String getRule() { - return "If you do, return it to the battlefield under it's owner's control at the beginning of your next upkeep. It gains haste"; + return "If you do, return it to the battlefield under its owner's control at the beginning of your next upkeep. It gains haste"; } } @@ -174,8 +175,11 @@ class ObzedatGhostCouncilReturnEffect extends OneShotEffect { // return it from every public zone - http://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/magic-rulings-archives/513186-obzedat-gc-as-edh-commander if (zone != Zone.BATTLEFIELD && zone != Zone.LIBRARY && zone != Zone.HAND) { Player owner = game.getPlayer(card.getOwnerId()); - if (owner != null) { - owner.moveCards(card, Zone.BATTLEFIELD, source, game); + if (owner != null && owner.moveCards(card, Zone.BATTLEFIELD, source, game)) { + Permanent permanent = game.getPermanent(card.getId()); + ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); } } return true; From ae5bccebfa3f282b272f66dfdd9901710bcfccae Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 28 May 2018 14:49:30 -0400 Subject: [PATCH 151/154] Fixed Sakura-Tribe Scout only allowing basic lands --- Mage.Sets/src/mage/cards/s/SakuraTribeScout.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SakuraTribeScout.java b/Mage.Sets/src/mage/cards/s/SakuraTribeScout.java index 5e297bd67e..b13362dfd7 100644 --- a/Mage.Sets/src/mage/cards/s/SakuraTribeScout.java +++ b/Mage.Sets/src/mage/cards/s/SakuraTribeScout.java @@ -55,8 +55,11 @@ public class SakuraTribeScout extends CardImpl { this.toughness = new MageInt(1); // {tap}: You may put a land card from your hand onto the battlefield. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new TapSourceCost())); + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A), + new TapSourceCost() + )); } public SakuraTribeScout(final SakuraTribeScout card) { From 2f0f71d3e93628546d613edc6a183223d18d72e2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 28 May 2018 15:11:00 -0400 Subject: [PATCH 152/154] Fixed some errors from b28bf51, did some refactoring --- Mage.Sets/src/mage/cards/a/AinokGuide.java | 2 +- .../src/mage/cards/a/ArmillarySphere.java | 2 +- .../src/mage/cards/a/AttuneWithAether.java | 2 +- .../src/mage/cards/b/BeneathTheSands.java | 2 +- .../src/mage/cards/b/BlightedWoodland.java | 2 +- .../src/mage/cards/b/BorderlandExplorer.java | 2 +- .../src/mage/cards/b/BorderlandRanger.java | 2 +- Mage.Sets/src/mage/cards/b/Bossk.java | 2 +- .../src/mage/cards/b/BoundlessRealms.java | 2 +- .../src/mage/cards/b/BraidwoodSextant.java | 2 +- .../src/mage/cards/b/BudokaGardener.java | 2 +- Mage.Sets/src/mage/cards/b/BurnishedHart.java | 2 +- Mage.Sets/src/mage/cards/c/CaravanVigil.java | 2 +- .../src/mage/cards/c/CentaurRootcaster.java | 2 +- .../src/mage/cards/c/CivicWayfinder.java | 2 +- .../src/mage/cards/c/CollectiveVoyage.java | 2 +- Mage.Sets/src/mage/cards/c/CopperGnomes.java | 8 ++++-- Mage.Sets/src/mage/cards/c/Cultivate.java | 2 +- .../src/mage/cards/d/DawntreaderElk.java | 2 +- .../src/mage/cards/d/DeepReconnaissance.java | 2 +- Mage.Sets/src/mage/cards/d/Dermoplasm.java | 2 +- .../src/mage/cards/d/DiligentFarmhand.java | 2 +- .../src/mage/cards/d/DreamscapeArtist.java | 2 +- Mage.Sets/src/mage/cards/e/EdgeOfAutumn.java | 2 +- .../src/mage/cards/e/ElfhameSanctuary.java | 2 +- Mage.Sets/src/mage/cards/e/ElvishPioneer.java | 2 +- .../src/mage/cards/e/EmbodimentOfSpring.java | 2 +- .../src/mage/cards/e/EvolutionCharm.java | 2 +- Mage.Sets/src/mage/cards/e/EvolvingWilds.java | 2 +- .../src/mage/cards/e/ExplodingBorders.java | 2 +- Mage.Sets/src/mage/cards/f/FarWanderings.java | 4 +-- Mage.Sets/src/mage/cards/f/FarhavenElf.java | 2 +- .../src/mage/cards/f/FertileThicket.java | 2 +- Mage.Sets/src/mage/cards/f/Fertilid.java | 2 +- Mage.Sets/src/mage/cards/f/FieldOfRuin.java | 2 +- .../src/mage/cards/f/FirebrandRanger.java | 2 +- .../src/mage/cards/f/FontOfFertility.java | 2 +- Mage.Sets/src/mage/cards/f/ForkInTheRoad.java | 2 +- .../src/mage/cards/f/FrenziedTilling.java | 2 +- Mage.Sets/src/mage/cards/f/FromTheAshes.java | 2 +- Mage.Sets/src/mage/cards/f/FrontierGuide.java | 2 +- Mage.Sets/src/mage/cards/g/GhostQuarter.java | 2 +- Mage.Sets/src/mage/cards/g/Greenseeker.java | 2 +- .../src/mage/cards/g/GrowFromTheAshes.java | 4 +-- Mage.Sets/src/mage/cards/g/GrowthSpasm.java | 2 +- Mage.Sets/src/mage/cards/h/Harrow.java | 2 +- Mage.Sets/src/mage/cards/h/HarvestSeason.java | 2 +- Mage.Sets/src/mage/cards/h/HarvestWurm.java | 2 +- .../src/mage/cards/h/HauntingEchoes.java | 2 +- Mage.Sets/src/mage/cards/h/HermitDruid.java | 2 +- .../src/mage/cards/h/HorizonSpellbomb.java | 2 +- .../src/mage/cards/i/IthorianInitiate.java | 2 +- .../src/mage/cards/j/JourneyOfDiscovery.java | 2 +- .../src/mage/cards/j/JourneyersKite.java | 2 +- .../src/mage/cards/j/JungleWayfinder.java | 2 +- .../mage/cards/k/KhalniHeartExpedition.java | 2 +- Mage.Sets/src/mage/cards/k/KodamasReach.java | 2 +- Mage.Sets/src/mage/cards/k/KrosanTusker.java | 2 +- .../src/mage/cards/k/KrosanWayfarer.java | 2 +- Mage.Sets/src/mage/cards/l/LandTax.java | 2 +- Mage.Sets/src/mage/cards/l/LayOfTheLand.java | 2 +- Mage.Sets/src/mage/cards/l/LlanowarScout.java | 2 +- Mage.Sets/src/mage/cards/l/LoamLarva.java | 2 +- Mage.Sets/src/mage/cards/m/MapTheWastes.java | 2 +- .../src/mage/cards/m/MycosynthWellspring.java | 4 +-- .../src/mage/cards/n/NaturalBalance.java | 2 +- .../src/mage/cards/n/NaturalConnection.java | 2 +- Mage.Sets/src/mage/cards/n/NewFrontiers.java | 2 +- .../src/mage/cards/n/NissaWorldwaker.java | 2 +- .../src/mage/cards/n/NissasExpedition.java | 2 +- Mage.Sets/src/mage/cards/n/NissasRenewal.java | 2 +- .../src/mage/cards/o/OashraCultivator.java | 2 +- Mage.Sets/src/mage/cards/o/OathOfLieges.java | 2 +- Mage.Sets/src/mage/cards/o/OnduGiant.java | 2 +- Mage.Sets/src/mage/cards/o/OneWithNature.java | 2 +- Mage.Sets/src/mage/cards/o/OrdealOfNylea.java | 2 +- Mage.Sets/src/mage/cards/p/PathToExile.java | 2 +- Mage.Sets/src/mage/cards/p/Peregrination.java | 2 +- Mage.Sets/src/mage/cards/p/PilgrimsEye.java | 2 +- Mage.Sets/src/mage/cards/p/PlanarBirth.java | 2 +- Mage.Sets/src/mage/cards/p/PrimalDruid.java | 2 +- Mage.Sets/src/mage/cards/p/PrimalGrowth.java | 4 +-- .../src/mage/cards/q/QuirionTrailblazer.java | 2 +- Mage.Sets/src/mage/cards/r/RampantGrowth.java | 2 +- .../src/mage/cards/r/RangingRaptors.java | 2 +- Mage.Sets/src/mage/cards/r/RenegadeMap.java | 2 +- Mage.Sets/src/mage/cards/r/Renewal.java | 2 +- Mage.Sets/src/mage/cards/r/RitesOfSpring.java | 2 +- .../src/mage/cards/r/RuinInTheirWake.java | 2 +- .../src/mage/cards/s/SakuraTribeElder.java | 2 +- .../src/mage/cards/s/SearchForTomorrow.java | 2 +- .../src/mage/cards/s/SeekTheHorizon.java | 2 +- .../src/mage/cards/s/SettleTheWreckage.java | 2 +- Mage.Sets/src/mage/cards/s/SilkwingScout.java | 2 +- .../mage/cards/s/SilvergladePathfinder.java | 2 +- .../src/mage/cards/s/SkitteringSurveyor.java | 2 +- .../src/mage/cards/s/SkyshroudRanger.java | 7 ++++-- .../src/mage/cards/s/SolemnSimulacrum.java | 2 +- Mage.Sets/src/mage/cards/s/SpringMind.java | 2 +- .../src/mage/cards/s/SproutingVines.java | 2 +- .../src/mage/cards/s/SurveyorsScope.java | 2 +- Mage.Sets/src/mage/cards/s/SwellOfGrowth.java | 2 +- .../src/mage/cards/s/SwordOfTheAnimist.java | 2 +- Mage.Sets/src/mage/cards/s/SylvanRanger.java | 2 +- .../src/mage/cards/t/TerminalMoraine.java | 2 +- .../src/mage/cards/t/TerrainGenerator.java | 2 +- .../src/mage/cards/t/TerramorphicExpanse.java | 2 +- .../src/mage/cards/t/ThaumaticCompass.java | 2 +- .../src/mage/cards/t/ThawingGlaciers.java | 2 +- .../mage/cards/t/ThunderherdMigration.java | 2 +- .../src/mage/cards/t/TrailOfMystery.java | 2 +- .../src/mage/cards/t/TravelersAmulet.java | 2 +- .../src/mage/cards/t/TraverseTheOutlands.java | 2 +- .../mage/cards/t/TraverseTheUlvenwald.java | 2 +- Mage.Sets/src/mage/cards/u/UntamedWilds.java | 2 +- .../src/mage/cards/v/VerdantConfluence.java | 2 +- .../src/mage/cards/v/VerdantCrescendo.java | 2 +- .../src/mage/cards/v/VeteranExplorer.java | 2 +- .../src/mage/cards/v/ViridianEmissary.java | 2 +- Mage.Sets/src/mage/cards/w/WalkingAtlas.java | 7 ++++-- Mage.Sets/src/mage/cards/w/WanderersTwig.java | 2 +- .../src/mage/cards/w/WarpedLandscape.java | 2 +- Mage.Sets/src/mage/cards/w/WaveOfVitriol.java | 2 +- .../src/mage/cards/w/WayfarersBauble.java | 2 +- .../src/mage/cards/w/WildFieldScarecrow.java | 2 +- Mage.Sets/src/mage/cards/w/WildWanderer.java | 2 +- Mage.Sets/src/mage/cards/y/YavimayaElder.java | 2 +- .../src/mage/cards/y/YavimayaGranger.java | 2 +- .../keyword/BasicLandcyclingAbility.java | 2 +- .../main/java/mage/filter/StaticFilters.java | 25 ++++++++++--------- 130 files changed, 159 insertions(+), 148 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AinokGuide.java b/Mage.Sets/src/mage/cards/a/AinokGuide.java index c10ee0eb52..82a2359253 100644 --- a/Mage.Sets/src/mage/cards/a/AinokGuide.java +++ b/Mage.Sets/src/mage/cards/a/AinokGuide.java @@ -62,7 +62,7 @@ public class AinokGuide extends CardImpl { // * Search your library for a basic land card, reveal it, then shuffle your library and put that card on top of it. Mode mode = new Mode(); - mode.getEffects().add(new SearchLibraryPutOnLibraryEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true)); + mode.getEffects().add(new SearchLibraryPutOnLibraryEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true)); ability.addMode(mode); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/a/ArmillarySphere.java b/Mage.Sets/src/mage/cards/a/ArmillarySphere.java index eae283df7f..7100a3280a 100644 --- a/Mage.Sets/src/mage/cards/a/ArmillarySphere.java +++ b/Mage.Sets/src/mage/cards/a/ArmillarySphere.java @@ -53,7 +53,7 @@ public class ArmillarySphere extends CardImpl { // {2}, {tap}, Sacrifice Armillary Sphere: Search your library for up to two basic land cards, reveal them, and put them into your hand. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND), true, true), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/a/AttuneWithAether.java b/Mage.Sets/src/mage/cards/a/AttuneWithAether.java index a3f254b1d2..f38e80a800 100644 --- a/Mage.Sets/src/mage/cards/a/AttuneWithAether.java +++ b/Mage.Sets/src/mage/cards/a/AttuneWithAether.java @@ -48,7 +48,7 @@ public class AttuneWithAether extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{G}"); // Search you library for a basic land card, reveal it, put it into your hand, then shuffle your library. You get {E}{E}. - Effect effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true); + Effect effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, StaticFilters.FILTER_CARD_BASIC_LAND), true); effect.setText("Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new GetEnergyCountersControllerEffect(2)); diff --git a/Mage.Sets/src/mage/cards/b/BeneathTheSands.java b/Mage.Sets/src/mage/cards/b/BeneathTheSands.java index 22a6c604ee..ad1c3c5374 100644 --- a/Mage.Sets/src/mage/cards/b/BeneathTheSands.java +++ b/Mage.Sets/src/mage/cards/b/BeneathTheSands.java @@ -48,7 +48,7 @@ public class BeneathTheSands extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}"); // Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true)); // Cycling {2} this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); diff --git a/Mage.Sets/src/mage/cards/b/BlightedWoodland.java b/Mage.Sets/src/mage/cards/b/BlightedWoodland.java index 5a3646604b..218314fade 100644 --- a/Mage.Sets/src/mage/cards/b/BlightedWoodland.java +++ b/Mage.Sets/src/mage/cards/b/BlightedWoodland.java @@ -57,7 +57,7 @@ public class BlightedWoodland extends CardImpl { // {3}{G}, {T}, Sacrifice Blighted Woodland: Search your library for up to two basic land cards and put them onto the battlefield tapped. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND), true, true), new ManaCostsImpl<>("{3}{G}")); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/b/BorderlandExplorer.java b/Mage.Sets/src/mage/cards/b/BorderlandExplorer.java index 97f800e510..2aa8623640 100644 --- a/Mage.Sets/src/mage/cards/b/BorderlandExplorer.java +++ b/Mage.Sets/src/mage/cards/b/BorderlandExplorer.java @@ -135,7 +135,7 @@ class BorderlandExplorerEffect extends OneShotEffect { if (player != null) { Cards cardsPlayer = cardsToDiscard.get(playerId); if (cardsPlayer != null && !cardsPlayer.isEmpty()) { - TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND); if (player.searchLibrary(target, game)) { if (!target.getTargets().isEmpty()) { Cards cards = new CardsImpl(target.getTargets()); diff --git a/Mage.Sets/src/mage/cards/b/BorderlandRanger.java b/Mage.Sets/src/mage/cards/b/BorderlandRanger.java index acb1503878..a6f4e907b0 100644 --- a/Mage.Sets/src/mage/cards/b/BorderlandRanger.java +++ b/Mage.Sets/src/mage/cards/b/BorderlandRanger.java @@ -53,7 +53,7 @@ public class BorderlandRanger extends CardImpl { this.toughness = new MageInt(2); // When Borderland Ranger enters the battlefield, you may search your library for a basic land card, reveal it, and put it into your hand. If you do, shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true), true)); } public BorderlandRanger(final BorderlandRanger card) { diff --git a/Mage.Sets/src/mage/cards/b/Bossk.java b/Mage.Sets/src/mage/cards/b/Bossk.java index 676b9ea513..042c0f9c0e 100644 --- a/Mage.Sets/src/mage/cards/b/Bossk.java +++ b/Mage.Sets/src/mage/cards/b/Bossk.java @@ -70,7 +70,7 @@ public class Bossk extends CardImpl { this.addAbility(new BosskTriggeredAbility()); // <i>Bounty</i> — Whenever a creature an opponent controls with a bounty counter on it dies, you may search your library for a basic land card, reveal it, and put it in to your hand. If you do, shuffle your library. - this.addAbility(new BountyAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), true)); + this.addAbility(new BountyAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true), true)); } public Bossk(final Bossk card) { diff --git a/Mage.Sets/src/mage/cards/b/BoundlessRealms.java b/Mage.Sets/src/mage/cards/b/BoundlessRealms.java index 03f8188e68..8f714f9328 100644 --- a/Mage.Sets/src/mage/cards/b/BoundlessRealms.java +++ b/Mage.Sets/src/mage/cards/b/BoundlessRealms.java @@ -95,7 +95,7 @@ class BoundlessRealmsEffect extends OneShotEffect { filter.add(new ControllerPredicate(TargetController.YOU)); int amount = new PermanentsOnBattlefieldCount(filter).calculate(game, source, this); - TargetCardInLibrary target = new TargetCardInLibrary(0, amount, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, amount, StaticFilters.FILTER_CARD_BASIC_LAND); if (controller.searchLibrary(target, game)) { controller.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null); } diff --git a/Mage.Sets/src/mage/cards/b/BraidwoodSextant.java b/Mage.Sets/src/mage/cards/b/BraidwoodSextant.java index 11ceac2232..dfd0215d8d 100644 --- a/Mage.Sets/src/mage/cards/b/BraidwoodSextant.java +++ b/Mage.Sets/src/mage/cards/b/BraidwoodSextant.java @@ -53,7 +53,7 @@ public class BraidwoodSextant extends CardImpl { // {2}, {tap}, Sacrifice Braidwood Sextant: Search your library for a basic land card, reveal that card, and put it into your hand. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND), true, true), new ManaCostsImpl("{2}")); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/b/BudokaGardener.java b/Mage.Sets/src/mage/cards/b/BudokaGardener.java index d76d6ef12a..a8dbb239a4 100644 --- a/Mage.Sets/src/mage/cards/b/BudokaGardener.java +++ b/Mage.Sets/src/mage/cards/b/BudokaGardener.java @@ -64,7 +64,7 @@ public class BudokaGardener extends CardImpl { this.flipCardName = "Dokai, Weaver of Life"; // {T}: You may put a land card from your hand onto the battlefield. If you control ten or more lands, flip Budoka Gardener. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A), new TapSourceCost()); ability.addEffect(new BudokaGardenerEffect()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BurnishedHart.java b/Mage.Sets/src/mage/cards/b/BurnishedHart.java index 2b4bbe8910..3b874a5fa9 100644 --- a/Mage.Sets/src/mage/cards/b/BurnishedHart.java +++ b/Mage.Sets/src/mage/cards/b/BurnishedHart.java @@ -59,7 +59,7 @@ public class BurnishedHart extends CardImpl { // {3}, Sacrifice Burnished Hart: Search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle your library. Ability ability = new SimpleActivatedAbility( Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0,2, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0,2, StaticFilters.FILTER_CARD_BASIC_LAND), true, true), new GenericManaCost(3)); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/c/CaravanVigil.java b/Mage.Sets/src/mage/cards/c/CaravanVigil.java index 019d270320..64348b912e 100644 --- a/Mage.Sets/src/mage/cards/c/CaravanVigil.java +++ b/Mage.Sets/src/mage/cards/c/CaravanVigil.java @@ -88,7 +88,7 @@ class CaravanVigilEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); if (sourceObject != null && controller != null) { - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); if (controller.searchLibrary(target, game)) { Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); if (card != null) { diff --git a/Mage.Sets/src/mage/cards/c/CentaurRootcaster.java b/Mage.Sets/src/mage/cards/c/CentaurRootcaster.java index b175792f0c..f7a7acc551 100644 --- a/Mage.Sets/src/mage/cards/c/CentaurRootcaster.java +++ b/Mage.Sets/src/mage/cards/c/CentaurRootcaster.java @@ -54,7 +54,7 @@ public class CentaurRootcaster extends CardImpl { // Whenever Centaur Rootcaster deals combat damage to a player, you may search your library for a basic land card and put that card onto the battlefield tapped. If you do, shuffle your library. this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND), true, true), true)); } diff --git a/Mage.Sets/src/mage/cards/c/CivicWayfinder.java b/Mage.Sets/src/mage/cards/c/CivicWayfinder.java index 414602e160..383999b13e 100644 --- a/Mage.Sets/src/mage/cards/c/CivicWayfinder.java +++ b/Mage.Sets/src/mage/cards/c/CivicWayfinder.java @@ -55,7 +55,7 @@ public class CivicWayfinder extends CardImpl { this.toughness = new MageInt(2); // When Civic Wayfinder enters the battlefield, you may search your library for a basic land card, reveal it, and put it into your hand. If you do, shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true), true)); } public CivicWayfinder(final CivicWayfinder card) { diff --git a/Mage.Sets/src/mage/cards/c/CollectiveVoyage.java b/Mage.Sets/src/mage/cards/c/CollectiveVoyage.java index bd26b4b556..6ed0936d24 100644 --- a/Mage.Sets/src/mage/cards/c/CollectiveVoyage.java +++ b/Mage.Sets/src/mage/cards/c/CollectiveVoyage.java @@ -101,7 +101,7 @@ class CollectiveVoyageEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - TargetCardInLibrary target = new TargetCardInLibrary(0, xSum, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, xSum, StaticFilters.FILTER_CARD_BASIC_LAND); if (player.searchLibrary(target, game)) { player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, true, null); player.shuffleLibrary(source, game); diff --git a/Mage.Sets/src/mage/cards/c/CopperGnomes.java b/Mage.Sets/src/mage/cards/c/CopperGnomes.java index 29254ffc22..8f51b13542 100644 --- a/Mage.Sets/src/mage/cards/c/CopperGnomes.java +++ b/Mage.Sets/src/mage/cards/c/CopperGnomes.java @@ -39,7 +39,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterArtifactCard; +import mage.filter.StaticFilters; /** * @@ -54,7 +54,11 @@ public class CopperGnomes extends CardImpl { this.toughness = new MageInt(1); // {4}, Sacrifice Copper Gnomes: You may put an artifact card from your hand onto the battlefield. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutCardFromHandOntoBattlefieldEffect(new FilterArtifactCard()), new ManaCostsImpl("{4}")); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_ARTIFACT_AN), + new ManaCostsImpl("{4}") + ); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/Cultivate.java b/Mage.Sets/src/mage/cards/c/Cultivate.java index 2959af31e4..baf0d2346f 100644 --- a/Mage.Sets/src/mage/cards/c/Cultivate.java +++ b/Mage.Sets/src/mage/cards/c/Cultivate.java @@ -92,7 +92,7 @@ class CultivateEffect extends OneShotEffect { if (controller == null || sourceObject == null) { return false; } - TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND); if (controller.searchLibrary(target, game)) { if (!target.getTargets().isEmpty()) { Cards revealed = new CardsImpl(target.getTargets()); diff --git a/Mage.Sets/src/mage/cards/d/DawntreaderElk.java b/Mage.Sets/src/mage/cards/d/DawntreaderElk.java index 23f52358dd..e5ca3853a7 100644 --- a/Mage.Sets/src/mage/cards/d/DawntreaderElk.java +++ b/Mage.Sets/src/mage/cards/d/DawntreaderElk.java @@ -58,7 +58,7 @@ public class DawntreaderElk extends CardImpl { // {G}, Sacrifice Dawntreader Elk: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new ColoredManaCost(ColoredManaSymbol.G)); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/d/DeepReconnaissance.java b/Mage.Sets/src/mage/cards/d/DeepReconnaissance.java index 63077883d9..73721b3160 100644 --- a/Mage.Sets/src/mage/cards/d/DeepReconnaissance.java +++ b/Mage.Sets/src/mage/cards/d/DeepReconnaissance.java @@ -50,7 +50,7 @@ public class DeepReconnaissance extends CardImpl { // Search your library for a basic land card and put that card onto the battlefield tapped. Then shuffle your library. - this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true)); // Flashback {4}{G} this.addAbility(new FlashbackAbility(new ManaCostsImpl("{4}{G}"), TimingRule.SORCERY)); } diff --git a/Mage.Sets/src/mage/cards/d/Dermoplasm.java b/Mage.Sets/src/mage/cards/d/Dermoplasm.java index 441aeac1c0..0801ca0c50 100644 --- a/Mage.Sets/src/mage/cards/d/Dermoplasm.java +++ b/Mage.Sets/src/mage/cards/d/Dermoplasm.java @@ -103,7 +103,7 @@ class DermoplasmEffect extends OneShotEffect { Permanent thisCreature = game.getPermanent(source.getId()); FilterCreatureCard filter = new FilterCreatureCard("a creature card with a morph ability"); filter.add(new AbilityPredicate(MorphAbility.class)); - Effect effect = new PutCardFromHandOntoBattlefieldEffect(new FilterCreatureCard(filter)); + Effect effect = new PutCardFromHandOntoBattlefieldEffect(filter); if (effect.apply(game, source)) { if (thisCreature != null) { effect = new ReturnToHandTargetEffect(); diff --git a/Mage.Sets/src/mage/cards/d/DiligentFarmhand.java b/Mage.Sets/src/mage/cards/d/DiligentFarmhand.java index 3544c95618..71394eccfb 100644 --- a/Mage.Sets/src/mage/cards/d/DiligentFarmhand.java +++ b/Mage.Sets/src/mage/cards/d/DiligentFarmhand.java @@ -59,7 +59,7 @@ public class DiligentFarmhand extends CardImpl { this.toughness = new MageInt(1); // {1}{G}, Sacrifice Diligent Farmhand: Search your library for a basic land card and put that card onto the battlefield tapped. Then shuffle your library. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), new ManaCostsImpl("{1}{G}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new ManaCostsImpl("{1}{G}")); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); // If Diligent Farmhand is in a graveyard, effects from spells named Muscle Burst count it as a card named Muscle Burst. diff --git a/Mage.Sets/src/mage/cards/d/DreamscapeArtist.java b/Mage.Sets/src/mage/cards/d/DreamscapeArtist.java index fd547265f2..d21b3c960b 100644 --- a/Mage.Sets/src/mage/cards/d/DreamscapeArtist.java +++ b/Mage.Sets/src/mage/cards/d/DreamscapeArtist.java @@ -62,7 +62,7 @@ public class DreamscapeArtist extends CardImpl { this.toughness = new MageInt(1); // {2}{U}, {tap}, Discard a card, Sacrifice a land: Search your library for up to two basic land cards and put them onto the battlefield. Then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND); Ability ability = new SimpleActivatedAbility( Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(target, false, Outcome.PutLandInPlay), diff --git a/Mage.Sets/src/mage/cards/e/EdgeOfAutumn.java b/Mage.Sets/src/mage/cards/e/EdgeOfAutumn.java index 659752daf1..07d2ddae89 100644 --- a/Mage.Sets/src/mage/cards/e/EdgeOfAutumn.java +++ b/Mage.Sets/src/mage/cards/e/EdgeOfAutumn.java @@ -57,7 +57,7 @@ public class EdgeOfAutumn extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}"); // If you control four or fewer lands, search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.FEWER_THAN, 5), "If you control four or fewer lands, search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library.")); diff --git a/Mage.Sets/src/mage/cards/e/ElfhameSanctuary.java b/Mage.Sets/src/mage/cards/e/ElfhameSanctuary.java index 300c6b5625..27487a21fb 100644 --- a/Mage.Sets/src/mage/cards/e/ElfhameSanctuary.java +++ b/Mage.Sets/src/mage/cards/e/ElfhameSanctuary.java @@ -54,7 +54,7 @@ public class ElfhameSanctuary extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}"); // At the beginning of your upkeep, you may search your library for a basic land card, reveal that card, and put it into your hand. If you do, you skip your draw step this turn and shuffle your library. - Ability ability = new BeginningOfUpkeepTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD)), TargetController.YOU, true); + Ability ability = new BeginningOfUpkeepTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND)), TargetController.YOU, true); ability.addEffect(new SkipDrawStepThisTurn()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/e/ElvishPioneer.java b/Mage.Sets/src/mage/cards/e/ElvishPioneer.java index f9bbb4e051..c07c27fc1c 100644 --- a/Mage.Sets/src/mage/cards/e/ElvishPioneer.java +++ b/Mage.Sets/src/mage/cards/e/ElvishPioneer.java @@ -52,7 +52,7 @@ public class ElvishPioneer extends CardImpl { this.toughness = new MageInt(1); // When Elvish Pioneer enters the battlefield, you may put a basic land card from your hand onto the battlefield tapped. - this.addAbility(new EntersBattlefieldTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A, false, true), false)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_BASIC_LAND_A, false, true), false)); } public ElvishPioneer(final ElvishPioneer card) { diff --git a/Mage.Sets/src/mage/cards/e/EmbodimentOfSpring.java b/Mage.Sets/src/mage/cards/e/EmbodimentOfSpring.java index 6c34b5fde2..d9462056ac 100644 --- a/Mage.Sets/src/mage/cards/e/EmbodimentOfSpring.java +++ b/Mage.Sets/src/mage/cards/e/EmbodimentOfSpring.java @@ -58,7 +58,7 @@ public class EmbodimentOfSpring extends CardImpl { // {1}{G}, {T}, Sacrifice Embodiment of Spring: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new ManaCostsImpl("{1}{G}")); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/e/EvolutionCharm.java b/Mage.Sets/src/mage/cards/e/EvolutionCharm.java index 59d192d18d..9e2a3cafc1 100644 --- a/Mage.Sets/src/mage/cards/e/EvolutionCharm.java +++ b/Mage.Sets/src/mage/cards/e/EvolutionCharm.java @@ -53,7 +53,7 @@ public class EvolutionCharm extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); // Choose one - Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library; - this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND), true, true)); // or return target creature card from your graveyard to your hand; Mode mode = new Mode(); diff --git a/Mage.Sets/src/mage/cards/e/EvolvingWilds.java b/Mage.Sets/src/mage/cards/e/EvolvingWilds.java index 13c09f8abd..2f511a0fa4 100644 --- a/Mage.Sets/src/mage/cards/e/EvolvingWilds.java +++ b/Mage.Sets/src/mage/cards/e/EvolvingWilds.java @@ -53,7 +53,7 @@ public class EvolvingWilds extends CardImpl { // {T}, Sacrifice Evolving Wilds: Search your library for a basic land card and put it onto the battlefield tapped. Then shuffle your library. Ability ability = new SimpleActivatedAbility( Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/e/ExplodingBorders.java b/Mage.Sets/src/mage/cards/e/ExplodingBorders.java index 4b963ef0dd..aa54d973f5 100644 --- a/Mage.Sets/src/mage/cards/e/ExplodingBorders.java +++ b/Mage.Sets/src/mage/cards/e/ExplodingBorders.java @@ -49,7 +49,7 @@ public class ExplodingBorders extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}{G}"); // Domain - Search your library for a basic land card, put that card onto the battlefield tapped, then shuffle your library. Exploding Borders deals X damage to target player, where X is the number of basic land types among lands you control. - this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true)); this.getSpellAbility().addEffect(new DamageTargetEffect(new DomainValue())); this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker()); } diff --git a/Mage.Sets/src/mage/cards/f/FarWanderings.java b/Mage.Sets/src/mage/cards/f/FarWanderings.java index 95f0f581c1..02f896ce22 100644 --- a/Mage.Sets/src/mage/cards/f/FarWanderings.java +++ b/Mage.Sets/src/mage/cards/f/FarWanderings.java @@ -52,8 +52,8 @@ public class FarWanderings extends CardImpl { // Search your library for a basic land card, put that card onto the battlefield tapped, then shuffle your library. // Threshold - If seven or more cards are in your graveyard, instead search your library for up to three basic land cards, put them onto the battlefield tapped, then shuffle your library. Effect effect = new ConditionalOneShotEffect( - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 3, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 3, StaticFilters.FILTER_CARD_BASIC_LAND), true, true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND), true, true), new CardsInControllerGraveCondition(7), "Search your library for a basic land card, put that card onto the battlefield tapped, then shuffle your library.<br/><br/><i>Threshold</i> — If seven or more cards are in your graveyard, instead search your library for up to three basic land cards, put them onto the battlefield tapped, then shuffle your library."); this.getSpellAbility().addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/f/FarhavenElf.java b/Mage.Sets/src/mage/cards/f/FarhavenElf.java index ca27b784fa..a553e8a8b9 100644 --- a/Mage.Sets/src/mage/cards/f/FarhavenElf.java +++ b/Mage.Sets/src/mage/cards/f/FarhavenElf.java @@ -54,7 +54,7 @@ public class FarhavenElf extends CardImpl { this.toughness = new MageInt(1); // When Farhaven Elf enters the battlefield, you may search your library for a basic land card and put it onto the battlefield tapped. If you do, shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, false), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, false), true)); } public FarhavenElf(final FarhavenElf card) { diff --git a/Mage.Sets/src/mage/cards/f/FertileThicket.java b/Mage.Sets/src/mage/cards/f/FertileThicket.java index 3ce1452b43..38db74db69 100644 --- a/Mage.Sets/src/mage/cards/f/FertileThicket.java +++ b/Mage.Sets/src/mage/cards/f/FertileThicket.java @@ -100,7 +100,7 @@ class FertileThicketEffect extends OneShotEffect { Cards cards = new CardsImpl(); cards.addAll(controller.getLibrary().getTopCards(game, 5)); controller.lookAtCards(sourceObject.getIdName(), cards, game); - TargetCard target = new TargetCard(0, 1, Zone.LIBRARY, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCard target = new TargetCard(0, 1, Zone.LIBRARY, StaticFilters.FILTER_CARD_BASIC_LAND); controller.chooseTarget(outcome, cards, target, source, game); Cards cardsRevealed = new CardsImpl(target.getTargets()); if (!cardsRevealed.isEmpty()) { diff --git a/Mage.Sets/src/mage/cards/f/Fertilid.java b/Mage.Sets/src/mage/cards/f/Fertilid.java index 4faa9ee5ce..50378d6bc9 100644 --- a/Mage.Sets/src/mage/cards/f/Fertilid.java +++ b/Mage.Sets/src/mage/cards/f/Fertilid.java @@ -64,7 +64,7 @@ public class Fertilid extends CardImpl { // {1}{G}, Remove a +1/+1 counter from Fertilid: Target player searches their library for a basic land card and puts it onto the battlefield tapped. Then that player shuffles their library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInPlayTargetPlayerEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), new ManaCostsImpl("{1}{G}")); + new SearchLibraryPutInPlayTargetPlayerEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true), new ManaCostsImpl("{1}{G}")); ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance(1))); ability.addTarget(new TargetPlayer()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/f/FieldOfRuin.java b/Mage.Sets/src/mage/cards/f/FieldOfRuin.java index 50015b83c7..43c345fb93 100644 --- a/Mage.Sets/src/mage/cards/f/FieldOfRuin.java +++ b/Mage.Sets/src/mage/cards/f/FieldOfRuin.java @@ -115,7 +115,7 @@ class FieldOfRuinEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND); if (player.searchLibrary(target, game)) { player.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); player.shuffleLibrary(source, game); diff --git a/Mage.Sets/src/mage/cards/f/FirebrandRanger.java b/Mage.Sets/src/mage/cards/f/FirebrandRanger.java index c46cbf97cc..4ce9fd1daa 100644 --- a/Mage.Sets/src/mage/cards/f/FirebrandRanger.java +++ b/Mage.Sets/src/mage/cards/f/FirebrandRanger.java @@ -56,7 +56,7 @@ public class FirebrandRanger extends CardImpl { // {G}, {T}: You may put a basic land card from your hand onto the battlefield. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new ManaCostsImpl("{G}")); + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_BASIC_LAND_A), new ManaCostsImpl("{G}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/FontOfFertility.java b/Mage.Sets/src/mage/cards/f/FontOfFertility.java index 2087d7ef02..0fc54d5335 100644 --- a/Mage.Sets/src/mage/cards/f/FontOfFertility.java +++ b/Mage.Sets/src/mage/cards/f/FontOfFertility.java @@ -53,7 +53,7 @@ public class FontOfFertility extends CardImpl { // {1}{G}, Sacrifice Font of Fertility: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(target, true, true, Outcome.PutLandInPlay), new ManaCostsImpl("{1}{G}")); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/f/ForkInTheRoad.java b/Mage.Sets/src/mage/cards/f/ForkInTheRoad.java index e0f73b462b..9e6b4b0782 100644 --- a/Mage.Sets/src/mage/cards/f/ForkInTheRoad.java +++ b/Mage.Sets/src/mage/cards/f/ForkInTheRoad.java @@ -91,7 +91,7 @@ class ForkInTheRoadEffect extends OneShotEffect { if (controller == null || sourceObject == null) { return false; } - TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND); if (controller.searchLibrary(target, game)) { if (!target.getTargets().isEmpty()) { Cards revealed = new CardsImpl(); diff --git a/Mage.Sets/src/mage/cards/f/FrenziedTilling.java b/Mage.Sets/src/mage/cards/f/FrenziedTilling.java index 5cc63a5d5c..f0e1f7c3dd 100644 --- a/Mage.Sets/src/mage/cards/f/FrenziedTilling.java +++ b/Mage.Sets/src/mage/cards/f/FrenziedTilling.java @@ -51,7 +51,7 @@ public class FrenziedTilling extends CardImpl { // Destroy target land. Search your library for a basic land card and put that card onto the battlefield tapped. Then shuffle your library. this.getSpellAbility().addEffect(new DestroyTargetEffect()); this.getSpellAbility().addTarget(new TargetLandPermanent()); - this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true)); } public FrenziedTilling(final FrenziedTilling card) { diff --git a/Mage.Sets/src/mage/cards/f/FromTheAshes.java b/Mage.Sets/src/mage/cards/f/FromTheAshes.java index 1ee3f3f0db..d99ddbdcfa 100644 --- a/Mage.Sets/src/mage/cards/f/FromTheAshes.java +++ b/Mage.Sets/src/mage/cards/f/FromTheAshes.java @@ -106,7 +106,7 @@ class FromTheAshesEffect extends OneShotEffect { for (Map.Entry<UUID, Integer> entry : playerAmount.entrySet()) { Player player = game.getPlayer(entry.getKey()); if (player != null && player.chooseUse(outcome, "Search your library for up to " + entry.getValue() + " basic land card(s) to put it onto the battlefield?", source, game)) { - TargetCardInLibrary target = new TargetCardInLibrary(0, entry.getValue(), StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, entry.getValue(), StaticFilters.FILTER_CARD_BASIC_LAND); if (player.searchLibrary(target, game)) { if (!target.getTargets().isEmpty()) { player.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); diff --git a/Mage.Sets/src/mage/cards/f/FrontierGuide.java b/Mage.Sets/src/mage/cards/f/FrontierGuide.java index f8fe545043..4425668924 100644 --- a/Mage.Sets/src/mage/cards/f/FrontierGuide.java +++ b/Mage.Sets/src/mage/cards/f/FrontierGuide.java @@ -58,7 +58,7 @@ public class FrontierGuide extends CardImpl { //{3}{G}, {T}: Search your library for a basic land card and put it onto the battlefield tapped. Then shuffle your library. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new ManaCostsImpl("{3}{G}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/g/GhostQuarter.java b/Mage.Sets/src/mage/cards/g/GhostQuarter.java index c5ab33cb78..9452a3cd9a 100644 --- a/Mage.Sets/src/mage/cards/g/GhostQuarter.java +++ b/Mage.Sets/src/mage/cards/g/GhostQuarter.java @@ -100,7 +100,7 @@ class GhostQuarterEffect extends OneShotEffect { if (permanent != null) { Player controller = game.getPlayer(permanent.getControllerId()); if (controller.chooseUse(Outcome.PutLandInPlay, "Do you wish to search for a basic land, put it onto the battlefield and then shuffle your library?", source, game)) { - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); if (controller.searchLibrary(target, game)) { Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); if (card != null) { diff --git a/Mage.Sets/src/mage/cards/g/Greenseeker.java b/Mage.Sets/src/mage/cards/g/Greenseeker.java index 4b873b29bb..7880b802b7 100644 --- a/Mage.Sets/src/mage/cards/g/Greenseeker.java +++ b/Mage.Sets/src/mage/cards/g/Greenseeker.java @@ -59,7 +59,7 @@ public class Greenseeker extends CardImpl { // {G}, {tap}, Discard a card: Search your library for a basic land card, reveal it, and put it into your hand. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, StaticFilters.FILTER_CARD_BASIC_LAND), true, true), new ManaCostsImpl("{G}")); ability.addCost(new TapSourceCost()); ability.addCost(new DiscardCardCost()); diff --git a/Mage.Sets/src/mage/cards/g/GrowFromTheAshes.java b/Mage.Sets/src/mage/cards/g/GrowFromTheAshes.java index ee002dc954..169abf5689 100644 --- a/Mage.Sets/src/mage/cards/g/GrowFromTheAshes.java +++ b/Mage.Sets/src/mage/cards/g/GrowFromTheAshes.java @@ -52,8 +52,8 @@ public class GrowFromTheAshes extends CardImpl { // Search you library for a basic land card, put it onto the battlefield, then shuffle your library. If this spell was kicked, instead search your library for two basic land cards, put them onto the battlefield, then shuffle your library. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD), false, true), - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD), false, true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND), false, true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND), false, true), KickedCondition.instance, "Search your library for a basic land card, put it onto the battlefield, then shuffle your library. If this spell was kicked, instead search your library for two basic land cards, put them onto the battlefield, then shuffle your library.")); } diff --git a/Mage.Sets/src/mage/cards/g/GrowthSpasm.java b/Mage.Sets/src/mage/cards/g/GrowthSpasm.java index 9dec125ecd..c33498a399 100644 --- a/Mage.Sets/src/mage/cards/g/GrowthSpasm.java +++ b/Mage.Sets/src/mage/cards/g/GrowthSpasm.java @@ -48,7 +48,7 @@ public class GrowthSpasm extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{G}"); - this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true)); this.getSpellAbility().addEffect(new CreateTokenEffect(new EldraziSpawnToken())); } diff --git a/Mage.Sets/src/mage/cards/h/Harrow.java b/Mage.Sets/src/mage/cards/h/Harrow.java index 84b94e7e8b..deecc7d175 100644 --- a/Mage.Sets/src/mage/cards/h/Harrow.java +++ b/Mage.Sets/src/mage/cards/h/Harrow.java @@ -55,7 +55,7 @@ public class Harrow extends CardImpl { this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("land")))); // Search your library for up to two basic land cards and put them onto the battlefield. Then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND); this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(target, false, Outcome.PutLandInPlay)); } diff --git a/Mage.Sets/src/mage/cards/h/HarvestSeason.java b/Mage.Sets/src/mage/cards/h/HarvestSeason.java index 696bc1b356..8425bda1d5 100644 --- a/Mage.Sets/src/mage/cards/h/HarvestSeason.java +++ b/Mage.Sets/src/mage/cards/h/HarvestSeason.java @@ -98,7 +98,7 @@ class HarvestSeasonEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - TargetCardInLibrary target = new TargetCardInLibrary(0, new PermanentsOnBattlefieldCount(filter).calculate(game, source, this), StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, new PermanentsOnBattlefieldCount(filter).calculate(game, source, this), StaticFilters.FILTER_CARD_BASIC_LAND); if (controller.searchLibrary(target, game)) { controller.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null); } diff --git a/Mage.Sets/src/mage/cards/h/HarvestWurm.java b/Mage.Sets/src/mage/cards/h/HarvestWurm.java index aa7e3ef1d5..5390578f81 100644 --- a/Mage.Sets/src/mage/cards/h/HarvestWurm.java +++ b/Mage.Sets/src/mage/cards/h/HarvestWurm.java @@ -53,7 +53,7 @@ public class HarvestWurm extends CardImpl { this.toughness = new MageInt(2); // When Harvest Wurm enters the battlefield, sacrifice it unless you return a basic land card from your graveyard to your hand. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandFromGraveyardCost(new TargetCardInYourGraveyard(StaticFilters.FILTER_BASIC_LAND_CARD))))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandFromGraveyardCost(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_BASIC_LAND))))); } public HarvestWurm(final HarvestWurm card) { diff --git a/Mage.Sets/src/mage/cards/h/HauntingEchoes.java b/Mage.Sets/src/mage/cards/h/HauntingEchoes.java index 1273169ae7..af5d82bb83 100644 --- a/Mage.Sets/src/mage/cards/h/HauntingEchoes.java +++ b/Mage.Sets/src/mage/cards/h/HauntingEchoes.java @@ -86,7 +86,7 @@ class HauntingEchoesEffect extends OneShotEffect { Player targetPlayer = game.getPlayer(source.getFirstTarget()); if (targetPlayer != null) { for (Card card : targetPlayer.getGraveyard().getCards(game)) { - if (!StaticFilters.FILTER_BASIC_LAND_CARD.match(card, game)) { + if (!StaticFilters.FILTER_CARD_BASIC_LAND.match(card, game)) { card.moveToExile(null, "", source.getSourceId(), game); FilterCard filterCard = new FilterCard("cards named " + card.getName()); diff --git a/Mage.Sets/src/mage/cards/h/HermitDruid.java b/Mage.Sets/src/mage/cards/h/HermitDruid.java index 940ea218ae..a86dd61e35 100644 --- a/Mage.Sets/src/mage/cards/h/HermitDruid.java +++ b/Mage.Sets/src/mage/cards/h/HermitDruid.java @@ -57,7 +57,7 @@ public class HermitDruid extends CardImpl { this.toughness = new MageInt(1); // {G}, {tap}: Reveal cards from the top of your library until you reveal a basic land card. Put that card into your hand and all other cards revealed this way into your graveyard. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RevealCardsFromLibraryUntilEffect(StaticFilters.FILTER_BASIC_LAND_CARD, Zone.HAND, Zone.GRAVEYARD), new ManaCostsImpl("{G}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RevealCardsFromLibraryUntilEffect(StaticFilters.FILTER_CARD_BASIC_LAND, Zone.HAND, Zone.GRAVEYARD), new ManaCostsImpl("{G}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HorizonSpellbomb.java b/Mage.Sets/src/mage/cards/h/HorizonSpellbomb.java index 641053abec..e5005ff78d 100644 --- a/Mage.Sets/src/mage/cards/h/HorizonSpellbomb.java +++ b/Mage.Sets/src/mage/cards/h/HorizonSpellbomb.java @@ -55,7 +55,7 @@ public class HorizonSpellbomb extends CardImpl { // {2}, {tap}, Sacrifice Horizon Spellbomb: Search your library for a basic land card, reveal it, and put it into your hand. Then shuffle your library. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new ManaCostsImpl("{2}")); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/i/IthorianInitiate.java b/Mage.Sets/src/mage/cards/i/IthorianInitiate.java index e3bcf12b88..84bfaa67b9 100644 --- a/Mage.Sets/src/mage/cards/i/IthorianInitiate.java +++ b/Mage.Sets/src/mage/cards/i/IthorianInitiate.java @@ -55,7 +55,7 @@ public class IthorianInitiate extends CardImpl { this.toughness = new MageInt(1); // When Ithorian Initiate enters the battlefield, you may search your library for a basic land, reveal it, and put it into your hand. If you do shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true), true)); // Meditate {1}{G} this.addAbility(new MeditateAbility(new ManaCostsImpl("{1}{G}"))); diff --git a/Mage.Sets/src/mage/cards/j/JourneyOfDiscovery.java b/Mage.Sets/src/mage/cards/j/JourneyOfDiscovery.java index cc59dbc579..459bf94786 100644 --- a/Mage.Sets/src/mage/cards/j/JourneyOfDiscovery.java +++ b/Mage.Sets/src/mage/cards/j/JourneyOfDiscovery.java @@ -50,7 +50,7 @@ public class JourneyOfDiscovery extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{G}"); // Choose one - Search your library for up to two basic land cards, reveal them, put them into your hand, then shuffle your library; - this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD))); + this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND))); // or you may play up to two additional lands this turn. Mode mode = new Mode(); diff --git a/Mage.Sets/src/mage/cards/j/JourneyersKite.java b/Mage.Sets/src/mage/cards/j/JourneyersKite.java index 9da9498574..7f508ace00 100644 --- a/Mage.Sets/src/mage/cards/j/JourneyersKite.java +++ b/Mage.Sets/src/mage/cards/j/JourneyersKite.java @@ -54,7 +54,7 @@ public class JourneyersKite extends CardImpl { // {3}, {tap}: Search your library for a basic land card, reveal it, and put it into your hand. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new GenericManaCost(3)); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/j/JungleWayfinder.java b/Mage.Sets/src/mage/cards/j/JungleWayfinder.java index 76e3d659ef..7fd8972954 100644 --- a/Mage.Sets/src/mage/cards/j/JungleWayfinder.java +++ b/Mage.Sets/src/mage/cards/j/JungleWayfinder.java @@ -96,7 +96,7 @@ class JungleWayfinderEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND); if (player.chooseUse(Outcome.Benefit, "Search your library for a card to put into your hand?", source, game)) { player.searchLibrary(target, game); for (UUID cardId : target.getTargets()) { diff --git a/Mage.Sets/src/mage/cards/k/KhalniHeartExpedition.java b/Mage.Sets/src/mage/cards/k/KhalniHeartExpedition.java index 304dc4661b..413fba14ae 100644 --- a/Mage.Sets/src/mage/cards/k/KhalniHeartExpedition.java +++ b/Mage.Sets/src/mage/cards/k/KhalniHeartExpedition.java @@ -56,7 +56,7 @@ public class KhalniHeartExpedition extends CardImpl { this.addAbility(new LandfallAbility(new AddCountersSourceEffect(CounterType.QUEST.createInstance()), true)); - TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND); SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(target, true, Outcome.PutLandInPlay), new RemoveCountersSourceCost(CounterType.QUEST.createInstance(3))); diff --git a/Mage.Sets/src/mage/cards/k/KodamasReach.java b/Mage.Sets/src/mage/cards/k/KodamasReach.java index ae900512f9..e2ebc75442 100644 --- a/Mage.Sets/src/mage/cards/k/KodamasReach.java +++ b/Mage.Sets/src/mage/cards/k/KodamasReach.java @@ -93,7 +93,7 @@ class KodamasReachEffect extends OneShotEffect { if (controller == null || sourceObject == null) { return false; } - TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND); if (controller.searchLibrary(target, game)) { if (!target.getTargets().isEmpty()) { Cards revealed = new CardsImpl(); diff --git a/Mage.Sets/src/mage/cards/k/KrosanTusker.java b/Mage.Sets/src/mage/cards/k/KrosanTusker.java index 8bfa0b8f7a..2fdfe0c3a6 100644 --- a/Mage.Sets/src/mage/cards/k/KrosanTusker.java +++ b/Mage.Sets/src/mage/cards/k/KrosanTusker.java @@ -59,7 +59,7 @@ public class KrosanTusker extends CardImpl { this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}{G}"))); // When you cycle Krosan Tusker, you may search your library for a basic land card, reveal that card, put it into your hand, then shuffle your library. this.addAbility(new CycleTriggeredAbility( - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true), true)); } diff --git a/Mage.Sets/src/mage/cards/k/KrosanWayfarer.java b/Mage.Sets/src/mage/cards/k/KrosanWayfarer.java index bbe0b97502..565a5d0a72 100644 --- a/Mage.Sets/src/mage/cards/k/KrosanWayfarer.java +++ b/Mage.Sets/src/mage/cards/k/KrosanWayfarer.java @@ -54,7 +54,7 @@ public class KrosanWayfarer extends CardImpl { // Sacrifice Krosan Wayfarer: You may put a land card from your hand onto the battlefield. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new SacrificeSourceCost())); + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_BASIC_LAND_A), new SacrificeSourceCost())); } public KrosanWayfarer(final KrosanWayfarer card) { diff --git a/Mage.Sets/src/mage/cards/l/LandTax.java b/Mage.Sets/src/mage/cards/l/LandTax.java index f89e94e6b2..47a91b8f63 100644 --- a/Mage.Sets/src/mage/cards/l/LandTax.java +++ b/Mage.Sets/src/mage/cards/l/LandTax.java @@ -51,7 +51,7 @@ public class LandTax extends CardImpl { // At the beginning of your upkeep, if an opponent controls more lands than you, you may search your library for up to three basic land cards, reveal them, and put them into your hand. If you do, shuffle your library. this.addAbility(new ConditionalTriggeredAbility( - new BeginningOfUpkeepTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 3, StaticFilters.FILTER_BASIC_LAND_CARD), true), TargetController.YOU, true), + new BeginningOfUpkeepTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 3, StaticFilters.FILTER_CARD_BASIC_LAND), true), TargetController.YOU, true), new OpponentControlsMoreCondition(StaticFilters.FILTER_LANDS), "At the beginning of your upkeep, if an opponent controls more lands than you, you may search your library for up to three basic land cards, reveal them, and put them into your hand. If you do, shuffle your library" )); diff --git a/Mage.Sets/src/mage/cards/l/LayOfTheLand.java b/Mage.Sets/src/mage/cards/l/LayOfTheLand.java index deb608fa06..cb09a432f9 100644 --- a/Mage.Sets/src/mage/cards/l/LayOfTheLand.java +++ b/Mage.Sets/src/mage/cards/l/LayOfTheLand.java @@ -47,7 +47,7 @@ public class LayOfTheLand extends CardImpl { // Search your library for a basic land card, reveal that card, and put it into your hand. Then shuffle your library. - this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, StaticFilters.FILTER_CARD_BASIC_LAND), true)); } public LayOfTheLand(final LayOfTheLand card) { diff --git a/Mage.Sets/src/mage/cards/l/LlanowarScout.java b/Mage.Sets/src/mage/cards/l/LlanowarScout.java index 46332c0816..c7b135070c 100644 --- a/Mage.Sets/src/mage/cards/l/LlanowarScout.java +++ b/Mage.Sets/src/mage/cards/l/LlanowarScout.java @@ -55,7 +55,7 @@ public class LlanowarScout extends CardImpl { // {T}: You may put a land card from your hand onto the battlefield. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new TapSourceCost())); + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_BASIC_LAND_A), new TapSourceCost())); } public LlanowarScout(final LlanowarScout card) { diff --git a/Mage.Sets/src/mage/cards/l/LoamLarva.java b/Mage.Sets/src/mage/cards/l/LoamLarva.java index 38e0791954..3cd2e93aba 100644 --- a/Mage.Sets/src/mage/cards/l/LoamLarva.java +++ b/Mage.Sets/src/mage/cards/l/LoamLarva.java @@ -52,7 +52,7 @@ public class LoamLarva extends CardImpl { this.toughness = new MageInt(3); // When Loam Larva enters the battlefield, you may search your library for a basic land card, reveal it, then shuffle your library and put that card on top of it. - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutOnLibraryEffect(target, true, true), true)); } diff --git a/Mage.Sets/src/mage/cards/m/MapTheWastes.java b/Mage.Sets/src/mage/cards/m/MapTheWastes.java index 463fdb0b46..4541db0d23 100644 --- a/Mage.Sets/src/mage/cards/m/MapTheWastes.java +++ b/Mage.Sets/src/mage/cards/m/MapTheWastes.java @@ -47,7 +47,7 @@ public class MapTheWastes extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{G}"); // Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(target, true)); // Bolster 1. diff --git a/Mage.Sets/src/mage/cards/m/MycosynthWellspring.java b/Mage.Sets/src/mage/cards/m/MycosynthWellspring.java index ea6f5545a5..178b7ce803 100644 --- a/Mage.Sets/src/mage/cards/m/MycosynthWellspring.java +++ b/Mage.Sets/src/mage/cards/m/MycosynthWellspring.java @@ -49,8 +49,8 @@ public class MycosynthWellspring extends CardImpl { // When Mycosynth Wellspring enters the battlefield or is put into a graveyard from the battlefield, // you may search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), true)); - this.addAbility(new DiesTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true), true)); + this.addAbility(new DiesTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true), true)); } public MycosynthWellspring(final MycosynthWellspring card) { diff --git a/Mage.Sets/src/mage/cards/n/NaturalBalance.java b/Mage.Sets/src/mage/cards/n/NaturalBalance.java index 834c375146..ff03401069 100644 --- a/Mage.Sets/src/mage/cards/n/NaturalBalance.java +++ b/Mage.Sets/src/mage/cards/n/NaturalBalance.java @@ -117,7 +117,7 @@ public class NaturalBalance extends CardImpl { int amount = 5 - landCount; if (landCount < 5 && player.chooseUse(outcome, "Search your library for up to " + amount + " basic land cards and put them onto the battlefield?", source, game)) { // Select lands and put them onto battlefield - TargetCardInLibrary target = new TargetCardInLibrary(0, amount, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, amount, StaticFilters.FILTER_CARD_BASIC_LAND); if (player.searchLibrary(target, game)) { player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game); } diff --git a/Mage.Sets/src/mage/cards/n/NaturalConnection.java b/Mage.Sets/src/mage/cards/n/NaturalConnection.java index 8ab4262067..6c5875c578 100644 --- a/Mage.Sets/src/mage/cards/n/NaturalConnection.java +++ b/Mage.Sets/src/mage/cards/n/NaturalConnection.java @@ -46,7 +46,7 @@ public class NaturalConnection extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{G}"); // Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(target, true)); } diff --git a/Mage.Sets/src/mage/cards/n/NewFrontiers.java b/Mage.Sets/src/mage/cards/n/NewFrontiers.java index 9311f5aad7..3cf779e08f 100644 --- a/Mage.Sets/src/mage/cards/n/NewFrontiers.java +++ b/Mage.Sets/src/mage/cards/n/NewFrontiers.java @@ -89,7 +89,7 @@ class NewFrontiersEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null && player.chooseUse(outcome, "Search your library for up to " + amount + " basic lands?", source, game)) { - TargetCardInLibrary target = new TargetCardInLibrary(0, amount, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, amount, StaticFilters.FILTER_CARD_BASIC_LAND); if (player.searchLibrary(target, game)) { player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null); player.shuffleLibrary(source, game); diff --git a/Mage.Sets/src/mage/cards/n/NissaWorldwaker.java b/Mage.Sets/src/mage/cards/n/NissaWorldwaker.java index 2962d44c1c..c36cbb0c66 100644 --- a/Mage.Sets/src/mage/cards/n/NissaWorldwaker.java +++ b/Mage.Sets/src/mage/cards/n/NissaWorldwaker.java @@ -115,7 +115,7 @@ class NissaWorldwakerSearchEffect extends OneShotEffect { if (controller == null) { return false; } - TargetCardInLibrary target = new TargetCardInLibrary(0, Integer.MAX_VALUE, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD_BASIC_LAND); if (controller.searchLibrary(target, game)) { if (!target.getTargets().isEmpty()) { for (UUID cardId : target.getTargets()) { diff --git a/Mage.Sets/src/mage/cards/n/NissasExpedition.java b/Mage.Sets/src/mage/cards/n/NissasExpedition.java index c37b21c72a..7625fd7769 100644 --- a/Mage.Sets/src/mage/cards/n/NissasExpedition.java +++ b/Mage.Sets/src/mage/cards/n/NissasExpedition.java @@ -50,7 +50,7 @@ public class NissasExpedition extends CardImpl { // Convoke this.addAbility(new ConvokeAbility()); // Search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle your library. - this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0,2, StaticFilters.FILTER_BASIC_LAND_CARD), true, true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0,2, StaticFilters.FILTER_CARD_BASIC_LAND), true, true)); } public NissasExpedition(final NissasExpedition card) { diff --git a/Mage.Sets/src/mage/cards/n/NissasRenewal.java b/Mage.Sets/src/mage/cards/n/NissasRenewal.java index 1d03a039ae..01d57cf739 100644 --- a/Mage.Sets/src/mage/cards/n/NissasRenewal.java +++ b/Mage.Sets/src/mage/cards/n/NissasRenewal.java @@ -47,7 +47,7 @@ public class NissasRenewal extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{G}"); // Search your library for up to three basic land cards, put them onto the battlefield tapped, then shuffle your library. You gain 7 life. - this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 3, StaticFilters.FILTER_BASIC_LAND_CARD), true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 3, StaticFilters.FILTER_CARD_BASIC_LAND), true)); this.getSpellAbility().addEffect(new GainLifeEffect(7)); } diff --git a/Mage.Sets/src/mage/cards/o/OashraCultivator.java b/Mage.Sets/src/mage/cards/o/OashraCultivator.java index e488ab21e1..2b3a280810 100644 --- a/Mage.Sets/src/mage/cards/o/OashraCultivator.java +++ b/Mage.Sets/src/mage/cards/o/OashraCultivator.java @@ -61,7 +61,7 @@ public class OashraCultivator extends CardImpl { // {2}{G}, {T}, Sacrifice Oashra Cultivator: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new ManaCostsImpl("{2}{G}")); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/o/OathOfLieges.java b/Mage.Sets/src/mage/cards/o/OathOfLieges.java index c8d6524d4b..4e02349814 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfLieges.java +++ b/Mage.Sets/src/mage/cards/o/OathOfLieges.java @@ -119,7 +119,7 @@ class OathOfLiegesEffect extends OneShotEffect { Player activePlayer = game.getPlayer(game.getActivePlayerId()); if (activePlayer != null) { if (activePlayer.chooseUse(outcome, "Search your library for a basic land card, put that card onto the battlefield, then shuffle your library?", source, game)) { - Effect effect = new SearchLibraryPutInPlayTargetPlayerEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), false, true, Outcome.PutLandInPlay, true); + Effect effect = new SearchLibraryPutInPlayTargetPlayerEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), false, true, Outcome.PutLandInPlay, true); effect.setTargetPointer(new FixedTarget(game.getActivePlayerId())); return effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/o/OnduGiant.java b/Mage.Sets/src/mage/cards/o/OnduGiant.java index c4704c1f78..cc2ae77ab4 100644 --- a/Mage.Sets/src/mage/cards/o/OnduGiant.java +++ b/Mage.Sets/src/mage/cards/o/OnduGiant.java @@ -54,7 +54,7 @@ public class OnduGiant extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(4); - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), true)); } public OnduGiant(final OnduGiant card) { diff --git a/Mage.Sets/src/mage/cards/o/OneWithNature.java b/Mage.Sets/src/mage/cards/o/OneWithNature.java index 6f4e7097f9..a77b992b31 100644 --- a/Mage.Sets/src/mage/cards/o/OneWithNature.java +++ b/Mage.Sets/src/mage/cards/o/OneWithNature.java @@ -64,7 +64,7 @@ public class OneWithNature extends CardImpl { // Whenever enchanted creature deals combat damage to a player, you may search your library for a basic land card, put that card onto the battlefield tapped, then shuffle your library. ability = new DealsDamageToAPlayerAttachedTriggeredAbility( - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, Outcome.PutLandInPlay) + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, Outcome.PutLandInPlay) .setText("you may search your library for a basic land card, put that card onto the battlefield tapped, then shuffle your library."), "enchanted creature", true, false, true, TargetController.ANY); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/o/OrdealOfNylea.java b/Mage.Sets/src/mage/cards/o/OrdealOfNylea.java index dbae6b1ee9..271de1056d 100644 --- a/Mage.Sets/src/mage/cards/o/OrdealOfNylea.java +++ b/Mage.Sets/src/mage/cards/o/OrdealOfNylea.java @@ -76,7 +76,7 @@ public class OrdealOfNylea extends CardImpl { this.addAbility(ability); // When you sacrifice Ordeal of Nylea, search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle your library. ability = new SacrificeSourceTriggeredAbility( - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0,2, StaticFilters.FILTER_BASIC_LAND_CARD),true, true),false); + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0,2, StaticFilters.FILTER_CARD_BASIC_LAND),true, true),false); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PathToExile.java b/Mage.Sets/src/mage/cards/p/PathToExile.java index 72969a0217..3432b01dec 100644 --- a/Mage.Sets/src/mage/cards/p/PathToExile.java +++ b/Mage.Sets/src/mage/cards/p/PathToExile.java @@ -94,7 +94,7 @@ class PathToExileEffect extends OneShotEffect { // if the zone change to exile gets replaced does not prevent the target controller to be able to search controller.moveCardToExileWithInfo(permanent, null, "", source.getSourceId(), game, Zone.BATTLEFIELD, true); if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for a basic land card?", source, game)) { - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); if (player.searchLibrary(target, game)) { Card card = player.getLibrary().getCard(target.getFirstTarget(), game); if (card != null) { diff --git a/Mage.Sets/src/mage/cards/p/Peregrination.java b/Mage.Sets/src/mage/cards/p/Peregrination.java index a11a67e2e0..a91e3cd916 100644 --- a/Mage.Sets/src/mage/cards/p/Peregrination.java +++ b/Mage.Sets/src/mage/cards/p/Peregrination.java @@ -96,7 +96,7 @@ class PeregrinationEffect extends OneShotEffect { if (controller == null || sourceObject == null) { return false; } - TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND); if (controller.searchLibrary(target, game)) { if (!target.getTargets().isEmpty()) { Cards revealed = new CardsImpl(); diff --git a/Mage.Sets/src/mage/cards/p/PilgrimsEye.java b/Mage.Sets/src/mage/cards/p/PilgrimsEye.java index 23a024d07e..4e6e17c23a 100644 --- a/Mage.Sets/src/mage/cards/p/PilgrimsEye.java +++ b/Mage.Sets/src/mage/cards/p/PilgrimsEye.java @@ -66,7 +66,7 @@ public class PilgrimsEye extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Pilgrim's Eye enters the battlefield, you may search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true), true)); } public PilgrimsEye (final PilgrimsEye card) { diff --git a/Mage.Sets/src/mage/cards/p/PlanarBirth.java b/Mage.Sets/src/mage/cards/p/PlanarBirth.java index cefcddc2b5..704a4bc329 100644 --- a/Mage.Sets/src/mage/cards/p/PlanarBirth.java +++ b/Mage.Sets/src/mage/cards/p/PlanarBirth.java @@ -89,7 +89,7 @@ class PlanarBirthEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - toBattlefield.addAll(player.getGraveyard().getCards(StaticFilters.FILTER_BASIC_LAND_CARD, source.getSourceId(), controller.getId(), game)); + toBattlefield.addAll(player.getGraveyard().getCards(StaticFilters.FILTER_CARD_BASIC_LAND, source.getSourceId(), controller.getId(), game)); } } controller.moveCards(toBattlefield.getCards(game), Zone.BATTLEFIELD, source, game, true, false, true, null); diff --git a/Mage.Sets/src/mage/cards/p/PrimalDruid.java b/Mage.Sets/src/mage/cards/p/PrimalDruid.java index f733fb87c4..25c27dce08 100644 --- a/Mage.Sets/src/mage/cards/p/PrimalDruid.java +++ b/Mage.Sets/src/mage/cards/p/PrimalDruid.java @@ -54,7 +54,7 @@ public class PrimalDruid extends CardImpl { this.toughness = new MageInt(3); // When Primal Druid dies, you may search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - Effect effect = new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true); + Effect effect = new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true); effect.setText("you may search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library"); this.addAbility(new DiesTriggeredAbility(effect, true)); diff --git a/Mage.Sets/src/mage/cards/p/PrimalGrowth.java b/Mage.Sets/src/mage/cards/p/PrimalGrowth.java index 3a3d9531e3..b9adcb99b1 100644 --- a/Mage.Sets/src/mage/cards/p/PrimalGrowth.java +++ b/Mage.Sets/src/mage/cards/p/PrimalGrowth.java @@ -55,8 +55,8 @@ public class PrimalGrowth extends CardImpl { // Search your library for a basic land card, put that card onto the battlefield, then shuffle your library. If Primal Growth was kicked, instead search your library for up to two basic land cards, put them onto the battlefield, then shuffle your library. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD), false, true), - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD), false, true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND), false, true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND), false, true), KickedCondition.instance, "Search your library for a basic land card, put that card onto the battlefield, then shuffle your library. If this spell was kicked, instead search your library for up to two basic land cards, put them onto the battlefield, then shuffle your library")); } diff --git a/Mage.Sets/src/mage/cards/q/QuirionTrailblazer.java b/Mage.Sets/src/mage/cards/q/QuirionTrailblazer.java index ee26c88734..a05013d654 100644 --- a/Mage.Sets/src/mage/cards/q/QuirionTrailblazer.java +++ b/Mage.Sets/src/mage/cards/q/QuirionTrailblazer.java @@ -52,7 +52,7 @@ public class QuirionTrailblazer extends CardImpl { this.toughness = new MageInt(2); // When Quirion Trailblazer enters the battlefield, you may search your library for a basic land card and put that card onto the battlefield tapped. If you do, shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true), true)); } public QuirionTrailblazer(final QuirionTrailblazer card) { diff --git a/Mage.Sets/src/mage/cards/r/RampantGrowth.java b/Mage.Sets/src/mage/cards/r/RampantGrowth.java index 820cc70aa0..2192fbb9fa 100644 --- a/Mage.Sets/src/mage/cards/r/RampantGrowth.java +++ b/Mage.Sets/src/mage/cards/r/RampantGrowth.java @@ -47,7 +47,7 @@ public class RampantGrowth extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{G}"); // Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true)); } public RampantGrowth(final RampantGrowth card) { diff --git a/Mage.Sets/src/mage/cards/r/RangingRaptors.java b/Mage.Sets/src/mage/cards/r/RangingRaptors.java index 8044e9a590..50e25b040b 100644 --- a/Mage.Sets/src/mage/cards/r/RangingRaptors.java +++ b/Mage.Sets/src/mage/cards/r/RangingRaptors.java @@ -56,7 +56,7 @@ public class RangingRaptors extends CardImpl { // Enrage - Whenever Ranging Raptors is dealt damage, you may search your library for a basic land card, put it onto the battlefield, then shuffle your library. Ability ability = new DealtDamageToSourceTriggeredAbility( Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), true, true); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/r/RenegadeMap.java b/Mage.Sets/src/mage/cards/r/RenegadeMap.java index c6ca3d2dc5..cbd69eca24 100644 --- a/Mage.Sets/src/mage/cards/r/RenegadeMap.java +++ b/Mage.Sets/src/mage/cards/r/RenegadeMap.java @@ -57,7 +57,7 @@ public class RenegadeMap extends CardImpl { // {T}, Sacrifice Renegade Map: Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. Ability ability = new SimpleActivatedAbility( Zone.BATTLEFIELD, - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new TapSourceCost() ); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/r/Renewal.java b/Mage.Sets/src/mage/cards/r/Renewal.java index fd68f49fc8..5a73cf2350 100644 --- a/Mage.Sets/src/mage/cards/r/Renewal.java +++ b/Mage.Sets/src/mage/cards/r/Renewal.java @@ -55,7 +55,7 @@ public class Renewal extends CardImpl { this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); // Search your library for a basic land card and put that card onto the battlefield. Then shuffle your library. - this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD))); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND))); // Draw a card at the beginning of the next turn's upkeep. this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(new DrawCardSourceControllerEffect(1)), false)); diff --git a/Mage.Sets/src/mage/cards/r/RitesOfSpring.java b/Mage.Sets/src/mage/cards/r/RitesOfSpring.java index f755fc271f..c2fc9ba86b 100644 --- a/Mage.Sets/src/mage/cards/r/RitesOfSpring.java +++ b/Mage.Sets/src/mage/cards/r/RitesOfSpring.java @@ -100,7 +100,7 @@ class RitesOfSpringEffect extends OneShotEffect { } game.applyEffects(); return new SearchLibraryPutInHandEffect( - new TargetCardInLibrary(0, numDiscarded, StaticFilters.FILTER_BASIC_LAND_CARD), true, true) + new TargetCardInLibrary(0, numDiscarded, StaticFilters.FILTER_CARD_BASIC_LAND), true, true) .apply(game, source); } return false; diff --git a/Mage.Sets/src/mage/cards/r/RuinInTheirWake.java b/Mage.Sets/src/mage/cards/r/RuinInTheirWake.java index 8344776c74..f70551d759 100644 --- a/Mage.Sets/src/mage/cards/r/RuinInTheirWake.java +++ b/Mage.Sets/src/mage/cards/r/RuinInTheirWake.java @@ -96,7 +96,7 @@ class RuinInTheirWakeEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); if (controller != null && sourceObject != null) { - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); if (controller.searchLibrary(target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/cards/s/SakuraTribeElder.java b/Mage.Sets/src/mage/cards/s/SakuraTribeElder.java index eeb180cff7..e4b62a9d46 100644 --- a/Mage.Sets/src/mage/cards/s/SakuraTribeElder.java +++ b/Mage.Sets/src/mage/cards/s/SakuraTribeElder.java @@ -55,7 +55,7 @@ public class SakuraTribeElder extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(1); - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(target, true, Outcome.PutLandInPlay), new SacrificeSourceCost())); } diff --git a/Mage.Sets/src/mage/cards/s/SearchForTomorrow.java b/Mage.Sets/src/mage/cards/s/SearchForTomorrow.java index 63d164834f..7f3d1559af 100644 --- a/Mage.Sets/src/mage/cards/s/SearchForTomorrow.java +++ b/Mage.Sets/src/mage/cards/s/SearchForTomorrow.java @@ -50,7 +50,7 @@ public class SearchForTomorrow extends CardImpl { // Search your library for a basic land card and put it onto the battlefield. Then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(target, false, Outcome.PutLandInPlay)); // Suspend 2-{G} diff --git a/Mage.Sets/src/mage/cards/s/SeekTheHorizon.java b/Mage.Sets/src/mage/cards/s/SeekTheHorizon.java index 94a9bdf8fb..3738785891 100644 --- a/Mage.Sets/src/mage/cards/s/SeekTheHorizon.java +++ b/Mage.Sets/src/mage/cards/s/SeekTheHorizon.java @@ -46,7 +46,7 @@ public class SeekTheHorizon extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}"); // Search your library for up to three basic land cards, reveal them, and put them into your hand. Then shuffle your library. - this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 3, StaticFilters.FILTER_BASIC_LAND_CARD), true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 3, StaticFilters.FILTER_CARD_BASIC_LAND), true)); } public SeekTheHorizon(final SeekTheHorizon card) { diff --git a/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java b/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java index 704c74f141..0c011300ec 100644 --- a/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java +++ b/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java @@ -105,7 +105,7 @@ class SettleTheWreckageEffect extends OneShotEffect { } } controller.moveCards(toExile, Zone.EXILED, source, game); - TargetCardInLibrary target = new TargetCardInLibrary(0, attackers, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, attackers, StaticFilters.FILTER_CARD_BASIC_LAND); if (player.chooseUse(Outcome.Benefit, "Search for up to " + attackers + " basic land" + ((attackers == 1) ? "" : "s") + "?", source, game) && player.searchLibrary(target, game)) { player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null); player.shuffleLibrary(source, game); diff --git a/Mage.Sets/src/mage/cards/s/SilkwingScout.java b/Mage.Sets/src/mage/cards/s/SilkwingScout.java index 46f03ad004..06f3b731d3 100644 --- a/Mage.Sets/src/mage/cards/s/SilkwingScout.java +++ b/Mage.Sets/src/mage/cards/s/SilkwingScout.java @@ -62,7 +62,7 @@ public class SilkwingScout extends CardImpl { // {G}, Sacrifice Silkwing Scout: Search your library for a basic land card and put that card onto the battlefield tapped. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND), true, true), new ManaCostsImpl("{G}")); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/s/SilvergladePathfinder.java b/Mage.Sets/src/mage/cards/s/SilvergladePathfinder.java index 2a2591bebf..5a76daeb89 100644 --- a/Mage.Sets/src/mage/cards/s/SilvergladePathfinder.java +++ b/Mage.Sets/src/mage/cards/s/SilvergladePathfinder.java @@ -59,7 +59,7 @@ public class SilvergladePathfinder extends CardImpl { // {1}{G}, {tap}, Discard a card: Search your library for a basic land card and put that card onto the battlefield tapped. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND), true, true), new ManaCostsImpl("{1}{G}")); ability.addCost(new TapSourceCost()); ability.addCost(new DiscardCardCost()); diff --git a/Mage.Sets/src/mage/cards/s/SkitteringSurveyor.java b/Mage.Sets/src/mage/cards/s/SkitteringSurveyor.java index 143aef6e9e..4630a9a7d9 100644 --- a/Mage.Sets/src/mage/cards/s/SkitteringSurveyor.java +++ b/Mage.Sets/src/mage/cards/s/SkitteringSurveyor.java @@ -52,7 +52,7 @@ public class SkitteringSurveyor extends CardImpl { this.toughness = new MageInt(2); // When Skittering Surveyor enters the battlefield, you may search your library for a basic land, reveal it, put it into your hand, then shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true), true)); } public SkitteringSurveyor(final SkitteringSurveyor card) { diff --git a/Mage.Sets/src/mage/cards/s/SkyshroudRanger.java b/Mage.Sets/src/mage/cards/s/SkyshroudRanger.java index 614b015bf3..5998a57b64 100644 --- a/Mage.Sets/src/mage/cards/s/SkyshroudRanger.java +++ b/Mage.Sets/src/mage/cards/s/SkyshroudRanger.java @@ -53,8 +53,11 @@ public class SkyshroudRanger extends CardImpl { this.toughness = new MageInt(1); // {tap}: You may put a land card from your hand onto the battlefield. Activate this ability only any time you could cast a sorcery. - this.addAbility(new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, - new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new TapSourceCost())); + this.addAbility(new ActivateAsSorceryActivatedAbility( + Zone.BATTLEFIELD, + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A), + new TapSourceCost() + )); } diff --git a/Mage.Sets/src/mage/cards/s/SolemnSimulacrum.java b/Mage.Sets/src/mage/cards/s/SolemnSimulacrum.java index 0f1722f45a..361e41bc81 100644 --- a/Mage.Sets/src/mage/cards/s/SolemnSimulacrum.java +++ b/Mage.Sets/src/mage/cards/s/SolemnSimulacrum.java @@ -51,7 +51,7 @@ public class SolemnSimulacrum extends CardImpl { this.subtype.add(SubType.GOLEM); this.power = new MageInt(2); this.toughness = new MageInt(2); - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), true)); this.addAbility(new DiesTriggeredAbility(new DrawCardSourceControllerEffect(1), true)); } diff --git a/Mage.Sets/src/mage/cards/s/SpringMind.java b/Mage.Sets/src/mage/cards/s/SpringMind.java index 52512b3167..7d6f666f3b 100644 --- a/Mage.Sets/src/mage/cards/s/SpringMind.java +++ b/Mage.Sets/src/mage/cards/s/SpringMind.java @@ -50,7 +50,7 @@ public class SpringMind extends SplitCard { // Spring // Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - getLeftHalfCard().getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true)); + getLeftHalfCard().getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true)); // Mind // Aftermath diff --git a/Mage.Sets/src/mage/cards/s/SproutingVines.java b/Mage.Sets/src/mage/cards/s/SproutingVines.java index 47008a8758..ef5e005ea0 100644 --- a/Mage.Sets/src/mage/cards/s/SproutingVines.java +++ b/Mage.Sets/src/mage/cards/s/SproutingVines.java @@ -48,7 +48,7 @@ public class SproutingVines extends CardImpl { // Search your library for a basic land card, reveal that card, and put it into your hand. Then shuffle your library. - this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, StaticFilters.FILTER_CARD_BASIC_LAND), true)); // Storm this.addAbility(new StormAbility()); } diff --git a/Mage.Sets/src/mage/cards/s/SurveyorsScope.java b/Mage.Sets/src/mage/cards/s/SurveyorsScope.java index 988c0fc694..816aaccd08 100644 --- a/Mage.Sets/src/mage/cards/s/SurveyorsScope.java +++ b/Mage.Sets/src/mage/cards/s/SurveyorsScope.java @@ -102,7 +102,7 @@ class SurveyorsScopeEffect extends OneShotEffect { } game.informPlayers(new StringBuilder("Surveyor's Scope: X = ").append(numberOfLands).toString()); // 10/17/2013 If no players control at least two more lands than you when the ability resolves, you’ll still search and shuffle your library. - return new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, numberOfLands, StaticFilters.FILTER_BASIC_LAND_CARD)).apply(game, source); + return new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, numberOfLands, StaticFilters.FILTER_CARD_BASIC_LAND)).apply(game, source); } return false; } diff --git a/Mage.Sets/src/mage/cards/s/SwellOfGrowth.java b/Mage.Sets/src/mage/cards/s/SwellOfGrowth.java index 8710a17a82..ab6a76bbce 100644 --- a/Mage.Sets/src/mage/cards/s/SwellOfGrowth.java +++ b/Mage.Sets/src/mage/cards/s/SwellOfGrowth.java @@ -49,7 +49,7 @@ public class SwellOfGrowth extends CardImpl { // Target creature gets +2/+2 until end of turn. You may put a land card from your hand onto the battlefield. this.getSpellAbility().addEffect(new BoostTargetEffect(2, 2, Duration.EndOfTurn)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addEffect(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A)); + this.getSpellAbility().addEffect(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A)); } public SwellOfGrowth(final SwellOfGrowth card) { diff --git a/Mage.Sets/src/mage/cards/s/SwordOfTheAnimist.java b/Mage.Sets/src/mage/cards/s/SwordOfTheAnimist.java index 0cdac1dc97..8446790b6b 100644 --- a/Mage.Sets/src/mage/cards/s/SwordOfTheAnimist.java +++ b/Mage.Sets/src/mage/cards/s/SwordOfTheAnimist.java @@ -60,7 +60,7 @@ public class SwordOfTheAnimist extends CardImpl { // Equipped creature gets +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1))); // Whenever equipped creature attacks, you may search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); this.addAbility(new AttacksAttachedTriggeredAbility(new SearchLibraryPutInPlayEffect(target, true), true)); // Equip {2} this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); diff --git a/Mage.Sets/src/mage/cards/s/SylvanRanger.java b/Mage.Sets/src/mage/cards/s/SylvanRanger.java index 115a918c22..03d3193d7d 100644 --- a/Mage.Sets/src/mage/cards/s/SylvanRanger.java +++ b/Mage.Sets/src/mage/cards/s/SylvanRanger.java @@ -55,7 +55,7 @@ public class SylvanRanger extends CardImpl { this.toughness = new MageInt(1); // When Sylvan Ranger enters the battlefield, you may search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); } diff --git a/Mage.Sets/src/mage/cards/t/TerminalMoraine.java b/Mage.Sets/src/mage/cards/t/TerminalMoraine.java index 4f960ddd4d..c7c7c5fe9b 100644 --- a/Mage.Sets/src/mage/cards/t/TerminalMoraine.java +++ b/Mage.Sets/src/mage/cards/t/TerminalMoraine.java @@ -55,7 +55,7 @@ public class TerminalMoraine extends CardImpl { // {tap}: Add {C}. this.addAbility(new ColorlessManaAbility()); // {2}, {tap}, Sacrifice Terminal Moraine: Search your library for a basic land card and put that card onto the battlefield tapped. Then shuffle your library. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true), new ManaCostsImpl<>("{2}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true), new ManaCostsImpl<>("{2}")); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/t/TerrainGenerator.java b/Mage.Sets/src/mage/cards/t/TerrainGenerator.java index 91447add72..49a0c67b56 100644 --- a/Mage.Sets/src/mage/cards/t/TerrainGenerator.java +++ b/Mage.Sets/src/mage/cards/t/TerrainGenerator.java @@ -54,7 +54,7 @@ public class TerrainGenerator extends CardImpl { // {2}, {T}: You may put a basic land card from your hand onto the battlefield tapped. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A, false, true), new ManaCostsImpl("{2}")); + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_BASIC_LAND_A, false, true), new ManaCostsImpl("{2}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TerramorphicExpanse.java b/Mage.Sets/src/mage/cards/t/TerramorphicExpanse.java index 5a4239c092..f648cbb369 100644 --- a/Mage.Sets/src/mage/cards/t/TerramorphicExpanse.java +++ b/Mage.Sets/src/mage/cards/t/TerramorphicExpanse.java @@ -52,7 +52,7 @@ public class TerramorphicExpanse extends CardImpl { Ability ability = new SimpleActivatedAbility( Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java b/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java index e8272c8103..59ebbb0df8 100644 --- a/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java +++ b/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java @@ -63,7 +63,7 @@ public class ThaumaticCompass extends CardImpl { // {3}, {T}: Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new GenericManaCost(3)); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/t/ThawingGlaciers.java b/Mage.Sets/src/mage/cards/t/ThawingGlaciers.java index e955749cce..e05b3c8863 100644 --- a/Mage.Sets/src/mage/cards/t/ThawingGlaciers.java +++ b/Mage.Sets/src/mage/cards/t/ThawingGlaciers.java @@ -59,7 +59,7 @@ public class ThawingGlaciers extends CardImpl { this.addAbility(new EntersBattlefieldTappedAbility()); // {1}, {tap}: Search your library for a basic land card, put that card onto the battlefield tapped, then shuffle your library. Return Thawing Glaciers to its owner's hand at the beginning of the next cleanup step. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, Outcome.PutLandInPlay), new GenericManaCost(1)); + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, Outcome.PutLandInPlay), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextCleanupDelayedTriggeredAbility(new ReturnToHandSourceEffect(true)))); diff --git a/Mage.Sets/src/mage/cards/t/ThunderherdMigration.java b/Mage.Sets/src/mage/cards/t/ThunderherdMigration.java index 8ab1747664..4ed7784f4c 100644 --- a/Mage.Sets/src/mage/cards/t/ThunderherdMigration.java +++ b/Mage.Sets/src/mage/cards/t/ThunderherdMigration.java @@ -64,7 +64,7 @@ public class ThunderherdMigration extends CardImpl { "reveal a Dinosaur card from your hand or pay {1}")); // Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true)); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true)); } public ThunderherdMigration(final ThunderherdMigration card) { diff --git a/Mage.Sets/src/mage/cards/t/TrailOfMystery.java b/Mage.Sets/src/mage/cards/t/TrailOfMystery.java index 3a9aac7773..61c04e8537 100644 --- a/Mage.Sets/src/mage/cards/t/TrailOfMystery.java +++ b/Mage.Sets/src/mage/cards/t/TrailOfMystery.java @@ -60,7 +60,7 @@ public class TrailOfMystery extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}"); // Whenever a face-down creature enters the battlefield under your control, you may search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. - Effect effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0,1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true); + Effect effect = new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0,1, StaticFilters.FILTER_CARD_BASIC_LAND), true, true); this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, effect, filter, true)); // Whenever a permanent you control is turned face up, if it's a creature, it gets +2/+2 until end of turn. diff --git a/Mage.Sets/src/mage/cards/t/TravelersAmulet.java b/Mage.Sets/src/mage/cards/t/TravelersAmulet.java index d0ec05f768..8458523413 100644 --- a/Mage.Sets/src/mage/cards/t/TravelersAmulet.java +++ b/Mage.Sets/src/mage/cards/t/TravelersAmulet.java @@ -51,7 +51,7 @@ public class TravelersAmulet extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}"); // {1}, Sacrifice Traveler's Amulet: Search your library for a basic land card, reveal it, and put it into your hand. Then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInHandEffect(target, true), new GenericManaCost(1)); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/t/TraverseTheOutlands.java b/Mage.Sets/src/mage/cards/t/TraverseTheOutlands.java index 1e5a20f88f..a7db4d9d73 100644 --- a/Mage.Sets/src/mage/cards/t/TraverseTheOutlands.java +++ b/Mage.Sets/src/mage/cards/t/TraverseTheOutlands.java @@ -103,7 +103,7 @@ class TraverseTheOutlandsEffect extends OneShotEffect { } } - TargetCardInLibrary target = new TargetCardInLibrary(0, amount, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, amount, StaticFilters.FILTER_CARD_BASIC_LAND); if (controller.searchLibrary(target, game)) { controller.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null); } diff --git a/Mage.Sets/src/mage/cards/t/TraverseTheUlvenwald.java b/Mage.Sets/src/mage/cards/t/TraverseTheUlvenwald.java index ed2a85b152..cdef618d39 100644 --- a/Mage.Sets/src/mage/cards/t/TraverseTheUlvenwald.java +++ b/Mage.Sets/src/mage/cards/t/TraverseTheUlvenwald.java @@ -59,7 +59,7 @@ public class TraverseTheUlvenwald extends CardImpl { // Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, StaticFilters.FILTER_CARD_BASIC_LAND), true), new InvertCondition(DeliriumCondition.instance), "Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library.")); diff --git a/Mage.Sets/src/mage/cards/u/UntamedWilds.java b/Mage.Sets/src/mage/cards/u/UntamedWilds.java index 349fd36a89..f3ae958504 100644 --- a/Mage.Sets/src/mage/cards/u/UntamedWilds.java +++ b/Mage.Sets/src/mage/cards/u/UntamedWilds.java @@ -47,7 +47,7 @@ public class UntamedWilds extends CardImpl { // Search your library for a basic land card and put that card onto the battlefield. Then shuffle your library. - this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD))); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND))); } public UntamedWilds(final UntamedWilds card) { diff --git a/Mage.Sets/src/mage/cards/v/VerdantConfluence.java b/Mage.Sets/src/mage/cards/v/VerdantConfluence.java index fcefaf301f..049b1b6d5b 100644 --- a/Mage.Sets/src/mage/cards/v/VerdantConfluence.java +++ b/Mage.Sets/src/mage/cards/v/VerdantConfluence.java @@ -68,7 +68,7 @@ public class VerdantConfluence extends CardImpl { this.getSpellAbility().getModes().addMode(mode); // Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); mode = new Mode(); mode.getEffects().add(new SearchLibraryPutInPlayEffect(target, true)); this.getSpellAbility().getModes().addMode(mode); diff --git a/Mage.Sets/src/mage/cards/v/VerdantCrescendo.java b/Mage.Sets/src/mage/cards/v/VerdantCrescendo.java index f5ef749dbe..6d26500305 100644 --- a/Mage.Sets/src/mage/cards/v/VerdantCrescendo.java +++ b/Mage.Sets/src/mage/cards/v/VerdantCrescendo.java @@ -55,7 +55,7 @@ public class VerdantCrescendo extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}"); // Search your library for a basic land card and put it onto the battlefield tapped. - this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, false)); + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, false)); // Search your library and graveyard for a card named Nissa, Nature's Artisan, reveal it, and put it into your hand. Then shuffle your library. this.getSpellAbility().addEffect(new SearchLibraryGraveyardPutInHandEffect(filter, true)); diff --git a/Mage.Sets/src/mage/cards/v/VeteranExplorer.java b/Mage.Sets/src/mage/cards/v/VeteranExplorer.java index 63ff8fce33..9a1a5aca2b 100644 --- a/Mage.Sets/src/mage/cards/v/VeteranExplorer.java +++ b/Mage.Sets/src/mage/cards/v/VeteranExplorer.java @@ -116,7 +116,7 @@ class VeteranExplorerEffect extends OneShotEffect { private void chooseAndSearchLibrary(List<Player> usingPlayers, Player player, Ability source, Game game) { if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for up to two basic land cards and put them onto the battlefield?", source, game)) { usingPlayers.add(player); - TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND); if (player.searchLibrary(target, game)) { if (!target.getTargets().isEmpty()) { player.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); diff --git a/Mage.Sets/src/mage/cards/v/ViridianEmissary.java b/Mage.Sets/src/mage/cards/v/ViridianEmissary.java index 117bdec706..b54b29c5c2 100644 --- a/Mage.Sets/src/mage/cards/v/ViridianEmissary.java +++ b/Mage.Sets/src/mage/cards/v/ViridianEmissary.java @@ -54,7 +54,7 @@ public class ViridianEmissary extends CardImpl { this.toughness = new MageInt(1); // When Viridian Emissary dies, you may search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - this.addAbility(new DiesTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), true)); + this.addAbility(new DiesTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), true)); } public ViridianEmissary(final ViridianEmissary card) { diff --git a/Mage.Sets/src/mage/cards/w/WalkingAtlas.java b/Mage.Sets/src/mage/cards/w/WalkingAtlas.java index 7b04146037..5a5874f694 100644 --- a/Mage.Sets/src/mage/cards/w/WalkingAtlas.java +++ b/Mage.Sets/src/mage/cards/w/WalkingAtlas.java @@ -52,8 +52,11 @@ public class WalkingAtlas extends CardImpl { this.toughness = new MageInt(1); // {tap}: You may put a land card from your hand onto the battlefield. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_BASIC_LAND_CARD_A), new TapSourceCost())); + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_LAND_A), + new TapSourceCost() + )); } public WalkingAtlas(final WalkingAtlas card) { diff --git a/Mage.Sets/src/mage/cards/w/WanderersTwig.java b/Mage.Sets/src/mage/cards/w/WanderersTwig.java index f756f2884c..4ce79f23d3 100644 --- a/Mage.Sets/src/mage/cards/w/WanderersTwig.java +++ b/Mage.Sets/src/mage/cards/w/WanderersTwig.java @@ -52,7 +52,7 @@ public class WanderersTwig extends CardImpl { // {1}, Sacrifice Wanderer's Twig: Search your library for a basic land card, reveal it, and put it into your hand. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new GenericManaCost(1)); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/w/WarpedLandscape.java b/Mage.Sets/src/mage/cards/w/WarpedLandscape.java index 5e08d2219f..ca3db5e816 100644 --- a/Mage.Sets/src/mage/cards/w/WarpedLandscape.java +++ b/Mage.Sets/src/mage/cards/w/WarpedLandscape.java @@ -57,7 +57,7 @@ public class WarpedLandscape extends CardImpl { // {2}, {T}, Sacrifice Warped Landscape: Search your library for a basic land card and put it onto the battlefield tapped. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND), true, true), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/w/WaveOfVitriol.java b/Mage.Sets/src/mage/cards/w/WaveOfVitriol.java index ab3e045108..3707d0e0ff 100644 --- a/Mage.Sets/src/mage/cards/w/WaveOfVitriol.java +++ b/Mage.Sets/src/mage/cards/w/WaveOfVitriol.java @@ -125,7 +125,7 @@ class WaveOfVitriolEffect extends OneShotEffect { Set<Player> playersToShuffle = new LinkedHashSet<>(); for (Map.Entry<Player, Integer> entry : sacrificedLands.entrySet()) { if (entry.getKey().chooseUse(Outcome.PutLandInPlay, "Search your library for up to " + entry.getValue() + " basic lands?", source, game)) { - TargetCardInLibrary target = new TargetCardInLibrary(0, entry.getValue(), StaticFilters.FILTER_BASIC_LAND_CARD); + TargetCardInLibrary target = new TargetCardInLibrary(0, entry.getValue(), StaticFilters.FILTER_CARD_BASIC_LAND); if (entry.getKey().searchLibrary(target, game)) { if (!target.getTargets().isEmpty()) { toBattlefield.addAll(target.getTargets()); diff --git a/Mage.Sets/src/mage/cards/w/WayfarersBauble.java b/Mage.Sets/src/mage/cards/w/WayfarersBauble.java index 1d219a10d0..0a976a28ad 100644 --- a/Mage.Sets/src/mage/cards/w/WayfarersBauble.java +++ b/Mage.Sets/src/mage/cards/w/WayfarersBauble.java @@ -53,7 +53,7 @@ public class WayfarersBauble extends CardImpl { // {2}, {tap}, Sacrifice Wayfarer's Bauble: Search your library for a basic land card and put that card onto the battlefield tapped. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD),true, true, Outcome.PutLandInPlay), new GenericManaCost(2)); + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND),true, true, Outcome.PutLandInPlay), new GenericManaCost(2)); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/w/WildFieldScarecrow.java b/Mage.Sets/src/mage/cards/w/WildFieldScarecrow.java index a12e1b938e..a8dc9317b7 100644 --- a/Mage.Sets/src/mage/cards/w/WildFieldScarecrow.java +++ b/Mage.Sets/src/mage/cards/w/WildFieldScarecrow.java @@ -61,7 +61,7 @@ public class WildFieldScarecrow extends CardImpl { // {2}, Sacrifice Wild-Field Scarecrow: Search your library for up to two basic land cards, reveal them, and put them into your hand. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND), true, true), new GenericManaCost(2)); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/w/WildWanderer.java b/Mage.Sets/src/mage/cards/w/WildWanderer.java index 65c5c2329e..5f5a4e92fd 100644 --- a/Mage.Sets/src/mage/cards/w/WildWanderer.java +++ b/Mage.Sets/src/mage/cards/w/WildWanderer.java @@ -53,7 +53,7 @@ public class WildWanderer extends CardImpl { this.toughness = new MageInt(2); // When Wild Wanderer enters the battlefield, you may search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true, true))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true))); } public WildWanderer(final WildWanderer card) { diff --git a/Mage.Sets/src/mage/cards/y/YavimayaElder.java b/Mage.Sets/src/mage/cards/y/YavimayaElder.java index 923032b126..05a35ce9fe 100644 --- a/Mage.Sets/src/mage/cards/y/YavimayaElder.java +++ b/Mage.Sets/src/mage/cards/y/YavimayaElder.java @@ -60,7 +60,7 @@ public class YavimayaElder extends CardImpl { this.toughness = new MageInt(1); // When Yavimaya Elder dies, you may search your library for up to two basic land cards, reveal them, and put them into your hand. If you do, shuffle your library. - this.addAbility(new DiesTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_BASIC_LAND_CARD), true), true)); + this.addAbility(new DiesTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND), true), true)); // {2}, Sacrifice Yavimaya Elder: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new GenericManaCost(2)); ability.addCost(new SacrificeSourceCost()); diff --git a/Mage.Sets/src/mage/cards/y/YavimayaGranger.java b/Mage.Sets/src/mage/cards/y/YavimayaGranger.java index 466d8a128f..7c9b230c90 100644 --- a/Mage.Sets/src/mage/cards/y/YavimayaGranger.java +++ b/Mage.Sets/src/mage/cards/y/YavimayaGranger.java @@ -57,7 +57,7 @@ public class YavimayaGranger extends CardImpl { this.addAbility(new EchoAbility("{2}{G}")); //When Yavimaya Granger enters the battlefield, you may search your library for a basic land card, //put that card onto the battlefield tapped, then shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), true)); } public YavimayaGranger(final YavimayaGranger card) { diff --git a/Mage/src/main/java/mage/abilities/keyword/BasicLandcyclingAbility.java b/Mage/src/main/java/mage/abilities/keyword/BasicLandcyclingAbility.java index 8565a5a42a..3066bacda7 100644 --- a/Mage/src/main/java/mage/abilities/keyword/BasicLandcyclingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/BasicLandcyclingAbility.java @@ -39,7 +39,7 @@ public class BasicLandcyclingAbility extends CyclingAbility{ private static final String text = "Basic landcycling"; public BasicLandcyclingAbility(ManaCosts costs) { - super(costs, StaticFilters.FILTER_BASIC_LAND_CARD, text); + super(costs, StaticFilters.FILTER_CARD_BASIC_LAND, text); } public BasicLandcyclingAbility(final BasicLandcyclingAbility ability) { diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 3fca15f61e..4e9531e8c7 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -101,6 +101,19 @@ public final class StaticFilters { static { FILTER_CARD_LAND_A.setLockedFilter(true); } + + public static final FilterBasicLandCard FILTER_CARD_BASIC_LAND = new FilterBasicLandCard(); + + static { + FILTER_CARD_BASIC_LAND.setLockedFilter(true); + } + + public static final FilterBasicLandCard FILTER_CARD_BASIC_LAND_A = new FilterBasicLandCard("a basic land card"); + + static { + FILTER_CARD_BASIC_LAND_A.setLockedFilter(true); + } + public static final FilterNonlandCard FILTER_CARD_NON_LAND = new FilterNonlandCard(); static { @@ -299,18 +312,6 @@ public final class StaticFilters { FILTER_LANDS_NONBASIC.setLockedFilter(true); } - public static final FilterBasicLandCard FILTER_BASIC_LAND_CARD = new FilterBasicLandCard(); - - static { - FILTER_BASIC_LAND_CARD.setLockedFilter(true); - } - - public static final FilterBasicLandCard FILTER_BASIC_LAND_CARD_A = new FilterBasicLandCard("a basic land card"); - - static { - FILTER_BASIC_LAND_CARD_A.setLockedFilter(true); - } - // Used for sacrifice targets that don't need the "you control" text public static final FilterControlledLandPermanent FILTER_CONTROLLED_LAND_SHORT_TEXT = new FilterControlledLandPermanent("a land"); From c8d58efa7ff36a0d1a1a975e6856a4e98b8a5ce8 Mon Sep 17 00:00:00 2001 From: Evan Kranzler <theelk801@gmail.com> Date: Mon, 28 May 2018 15:53:46 -0400 Subject: [PATCH 153/154] Fixed effects that use opponents' life loss, including Rakdos, Lord of Riots and Neheb the Eternal --- .../java/mage/watchers/common/PlayerLostLifeWatcher.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Mage/src/main/java/mage/watchers/common/PlayerLostLifeWatcher.java b/Mage/src/main/java/mage/watchers/common/PlayerLostLifeWatcher.java index bd4ca446a8..69d7dcec4e 100644 --- a/Mage/src/main/java/mage/watchers/common/PlayerLostLifeWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/PlayerLostLifeWatcher.java @@ -34,6 +34,7 @@ import java.util.UUID; import mage.constants.WatcherScope; import mage.game.Game; import mage.game.events.GameEvent; +import mage.players.Player; import mage.watchers.Watcher; /* @@ -81,8 +82,9 @@ public class PlayerLostLifeWatcher extends Watcher { public int getAllOppLifeLost(UUID playerId, Game game) { int amount = 0; for (UUID opponentId : this.amountOfLifeLostThisTurn.keySet()) { - if (game.getOpponents(playerId).contains(opponentId)) { - amount += this.amountOfLifeLostThisTurn.get(playerId); + Player opponent = game.getPlayer(opponentId); + if (opponent != null && opponent.hasOpponent(playerId, game)) { + amount += this.amountOfLifeLostThisTurn.getOrDefault(opponentId, 0); } } return amount; From 33e03ce04b4bc5b326a458b0ebd5255aa97c0416 Mon Sep 17 00:00:00 2001 From: LevelX2 <ludwig.hirth@online.de> Date: Mon, 28 May 2018 23:53:47 +0200 Subject: [PATCH 154/154] * Chrome Mox - Fixed wrong netMana handling, that produced too much mana. --- Mage.Sets/src/mage/cards/c/ChromeMox.java | 43 +++++++++++++++++++---- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/ChromeMox.java b/Mage.Sets/src/mage/cards/c/ChromeMox.java index b560592dc7..dede2ed60d 100644 --- a/Mage.Sets/src/mage/cards/c/ChromeMox.java +++ b/Mage.Sets/src/mage/cards/c/ChromeMox.java @@ -27,6 +27,7 @@ */ package mage.cards.c; +import java.util.ArrayList; import java.util.List; import java.util.UUID; import mage.MageObject; @@ -67,7 +68,7 @@ public class ChromeMox extends CardImpl { // Imprint - When Chrome Mox enters the battlefield, you may exile a nonartifact, nonland card from your hand. this.addAbility(new EntersBattlefieldTriggeredAbility(new ChromeMoxEffect(), true)); - // {tap}: Add one mana of any of the exiled card's colors. + // {T}: Add one mana of any of the exiled card's colors. this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new ChromeMoxManaEffect(), new TapSourceCost())); } @@ -150,16 +151,47 @@ class ChromeMoxManaEffect extends ManaEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { checkToFirePossibleEvents(getMana(game, source), game, source); - player.getManaPool().addMana(getMana(game, source), game, source); + controller.getManaPool().addMana(getMana(game, source), game, source); return true; } return false; } + @Override + public List<Mana> getNetMana(Game game, Ability source) { + List<Mana> netMana = new ArrayList<>(); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + List<UUID> imprinted = permanent.getImprinted(); + if (!imprinted.isEmpty()) { + Card imprintedCard = game.getCard(imprinted.get(0)); + if (imprintedCard != null) { + ObjectColor color = imprintedCard.getColor(game); + if (color.isBlack()) { + netMana.add(Mana.BlackMana(1)); + } + if (color.isRed()) { + netMana.add(Mana.RedMana(1)); + } + if (color.isBlue()) { + netMana.add(Mana.BlueMana(1)); + } + if (color.isGreen()) { + netMana.add(Mana.GreenMana(1)); + } + if (color.isWhite()) { + netMana.add(Mana.WhiteMana(1)); + } + } + } + } + return netMana; + } + @Override public Mana produceMana(boolean netMana, Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); @@ -214,9 +246,6 @@ class ChromeMoxManaEffect extends ManaEffect { case "White": player.getManaPool().addMana(Mana.WhiteMana(1), game, source); break; - case "Colorless": - player.getManaPool().addMana(Mana.ColorlessMana(1), game, source); - break; default: break; }