diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form index 4b0dae2a96c..3b146fe8bc0 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form @@ -324,10 +324,12 @@ - - - - + + + + + + @@ -347,6 +349,7 @@ + @@ -360,8 +363,7 @@ - - + @@ -372,32 +374,29 @@ - - + - - - + @@ -414,7 +413,7 @@ - + @@ -424,29 +423,51 @@ - - - + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -463,7 +484,7 @@ - + diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java index 3fb22126d24..7e5203a75e1 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java @@ -92,6 +92,118 @@ public class ConnectDialog extends MageDialog { // last settings for reconnect MagePreferences.saveLastServer(); } + + private void setServerSettings(String address, String port, boolean needRegistration) { + this.txtServer.setText(address); + this.txtPort.setText(port); + this.txtUserName.setText(MagePreferences.getUserName(address)); + if (needRegistration) { + this.txtPassword.setText(MagePreferences.getPassword(address)); + } else { + this.txtPassword.setText(""); + } + } + + private void chooseAndSetServerSettingsFromOther() { + BufferedReader in = null; + Writer output = null; + try { + String serverUrl = PreferencesDialog.getCachedValue(KEY_CONNECTION_URL_SERVER_LIST, "http://xmage.de/files/server-list.txt"); + if (serverUrl.contains("xmage.info/files/")) { + serverUrl = serverUrl.replace("xmage.info/files/", "xmage.de/files/"); // replace old URL if still saved + PreferencesDialog.saveValue(KEY_CONNECTION_URL_SERVER_LIST, serverUrl); + } + URL serverListURL = new URL(serverUrl); + + Connection.ProxyType configProxyType = Connection.ProxyType.valueByText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_TYPE, "None")); + Proxy p = null; + Proxy.Type type = Proxy.Type.DIRECT; + switch (configProxyType) { + case HTTP: + type = Proxy.Type.HTTP; + break; + case SOCKS: + type = Proxy.Type.SOCKS; + break; + case NONE: + default: + p = Proxy.NO_PROXY; + break; + } + + if (p == null || !p.equals(Proxy.NO_PROXY)) { + try { + String address = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_ADDRESS, ""); + Integer port = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_PORT, "80")); + p = new Proxy(type, new InetSocketAddress(address, port)); + } catch (Exception ex) { + throw new RuntimeException("Gui_DownloadPictures : error 1 - " + ex); + } + } + + if (p == null) { + JOptionPane.showMessageDialog(null, "Couldn't configure Proxy object!", "Error", JOptionPane.ERROR_MESSAGE); + return; + } + + boolean URLNotFound = false; + try { + in = new BufferedReader(new InputStreamReader(serverListURL.openConnection(p).getInputStream())); + } catch (SocketTimeoutException | FileNotFoundException | UnknownHostException ex) { + logger.warn("Could not read serverlist from: " + serverListURL.toString()); + File f = new File("serverlist.txt"); + if (f.exists() && !f.isDirectory()) { + logger.info("Using buffered serverlist: serverlist.txt"); + URLNotFound = true; + in = new BufferedReader(new FileReader("serverlist.txt")); + } + } + List servers = new ArrayList<>(); + if (in != null) { + + if (!URLNotFound) { + // write serverlist to be able to read if URL is not available + File file = new File("serverlist.txt"); + if (file.exists() && !file.isDirectory()) { + file.delete(); + } + output = new BufferedWriter(new FileWriter(file)); + } + + String inputLine; + while ((inputLine = in.readLine()) != null) { + logger.debug("Found server: " + inputLine); + servers.add(inputLine); + if (output != null) { + output.append(inputLine).append('\n'); + + } + } + } + if (servers.isEmpty()) { + JOptionPane.showMessageDialog(null, "Couldn't find any server."); + return; + } + + String selectedServer = (String) JOptionPane.showInputDialog(null, + "Choose XMage Public Server:", "Input", + JOptionPane.INFORMATION_MESSAGE, null, servers.toArray(), + servers.get(0)); + if (selectedServer != null) { + String[] params = selectedServer.split(":"); + if (params.length == 3) { + setServerSettings(params[1], params[2], true); + } else { + JOptionPane.showMessageDialog(null, "Wrong server data format."); + } + } + } catch (Exception ex) { + logger.error(ex, ex); + } finally { + StreamUtils.closeQuietly(in); + StreamUtils.closeQuietly(output); + } + } /** * This method is called from within the constructor to initialize the form. @@ -127,6 +239,7 @@ public class ConnectDialog extends MageDialog { btnFindBeta = new javax.swing.JButton(); btnFindUs = new javax.swing.JButton(); btnFindOther = new javax.swing.JButton(); + btnFindEU = new javax.swing.JButton(); panelServer = new javax.swing.JPanel(); txtServer = new javax.swing.JTextField(); txtPort = new javax.swing.JTextField(); @@ -242,31 +355,27 @@ public class ConnectDialog extends MageDialog { btnFindMain.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/de.png"))); // NOI18N btnFindMain.setText("X"); - btnFindMain.setToolTipText("Connect to xmage.de (Europe, most popular, registration needs)"); - btnFindMain.setActionCommand("connectXmageDe"); + btnFindMain.setToolTipText("Connect to xmage.de (first Europe server, most popular, registration needs)"); btnFindMain.setAlignmentY(0.0F); btnFindMain.setMargin(new java.awt.Insets(2, 2, 2, 2)); btnFindMain.setMaximumSize(new java.awt.Dimension(42, 23)); btnFindMain.setMinimumSize(new java.awt.Dimension(42, 23)); - btnFindMain.setName("connectXmageDeBtn"); // NOI18N btnFindMain.setPreferredSize(new java.awt.Dimension(23, 23)); btnFindMain.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - connectXmageDe(evt); + btnFindMainActionPerformed(evt); } }); btnFindLocal.setText("LOCAL, AI"); btnFindLocal.setToolTipText("Connect to localhost, AI enabled (run local server from launcher)"); - btnFindLocal.setActionCommand("connectLocalhost"); btnFindLocal.setAlignmentY(0.0F); btnFindLocal.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); btnFindLocal.setMargin(new java.awt.Insets(2, 2, 2, 2)); - btnFindLocal.setName("connectLocalhostBtn"); // NOI18N btnFindLocal.setPreferredSize(new java.awt.Dimension(23, 23)); btnFindLocal.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - connectLocalhost(evt); + btnFindLocalActionPerformed(evt); } }); @@ -278,31 +387,42 @@ public class ConnectDialog extends MageDialog { btnFindBeta.setPreferredSize(new java.awt.Dimension(23, 23)); btnFindBeta.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - btnFindBetaconnectLocalhost(evt); + btnFindBetaActionPerformed(evt); } }); btnFindUs.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/us.png"))); // NOI18N btnFindUs.setText("US"); btnFindUs.setToolTipText("Connect to us.xmage.today (USA, use any username without registration)"); - btnFindUs.setActionCommand("connectXmageus"); btnFindUs.setAlignmentY(0.0F); btnFindUs.setMargin(new java.awt.Insets(2, 2, 2, 2)); - btnFindUs.setName("connectXmageusBtn"); // NOI18N btnFindUs.setPreferredSize(new java.awt.Dimension(23, 23)); btnFindUs.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - connectXmageus(evt); + btnFindUsActionPerformed(evt); } }); - btnFindOther.setText("Other servers..."); + btnFindOther.setText("Other..."); btnFindOther.setToolTipText("Choose server from full servers list"); btnFindOther.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnFindOther.setName("findServerBtn"); // NOI18N btnFindOther.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { - findPublicServerActionPerformed(evt); + btnFindOtherActionPerformed(evt); + } + }); + + btnFindEU.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/europeanunion.png"))); // NOI18N + btnFindEU.setText("EU"); + btnFindEU.setToolTipText("Connect to eu.xmage.today (second Europe server, use any username without registration)"); + btnFindEU.setAlignmentY(0.0F); + btnFindEU.setMargin(new java.awt.Insets(2, 2, 2, 2)); + btnFindEU.setMaximumSize(new java.awt.Dimension(42, 23)); + btnFindEU.setMinimumSize(new java.awt.Dimension(42, 23)); + btnFindEU.setPreferredSize(new java.awt.Dimension(23, 23)); + btnFindEU.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnFindEUActionPerformed(evt); } }); @@ -312,9 +432,11 @@ public class ConnectDialog extends MageDialog { panelFastLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(panelFastLayout.createSequentialGroup() .addGap(0, 0, 0) - .addComponent(btnFindMain, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(btnFindMain, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnFindUs, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(btnFindEU, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnFindUs, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnFindBeta, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -332,7 +454,8 @@ public class ConnectDialog extends MageDialog { .addComponent(btnFindLocal, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(btnFindUs, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(btnFindBeta, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(btnFindOther, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(btnFindOther, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(btnFindEU, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(0, 0, 0)) ); @@ -368,7 +491,7 @@ public class ConnectDialog extends MageDialog { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnCheckStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 205, Short.MAX_VALUE) + .addComponent(btnCheckStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(0, 0, 0)) ); panelServerLayout.setVerticalGroup( @@ -615,110 +738,7 @@ public class ConnectDialog extends MageDialog { }//GEN-LAST:event_chkAutoConnectActionPerformed private void findPublicServerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed - BufferedReader in = null; - Writer output = null; - try { - String serverUrl = PreferencesDialog.getCachedValue(KEY_CONNECTION_URL_SERVER_LIST, "http://xmage.de/files/server-list.txt"); - if (serverUrl.contains("xmage.info/files/")) { - serverUrl = serverUrl.replace("xmage.info/files/", "xmage.de/files/"); // replace old URL if still saved - PreferencesDialog.saveValue(KEY_CONNECTION_URL_SERVER_LIST, serverUrl); - } - URL serverListURL = new URL(serverUrl); - - Connection.ProxyType configProxyType = Connection.ProxyType.valueByText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_TYPE, "None")); - Proxy p = null; - Proxy.Type type = Proxy.Type.DIRECT; - switch (configProxyType) { - case HTTP: - type = Proxy.Type.HTTP; - break; - case SOCKS: - type = Proxy.Type.SOCKS; - break; - case NONE: - default: - p = Proxy.NO_PROXY; - break; - } - - if (p == null || !p.equals(Proxy.NO_PROXY)) { - try { - String address = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_ADDRESS, ""); - Integer port = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_PROXY_PORT, "80")); - p = new Proxy(type, new InetSocketAddress(address, port)); - } catch (Exception ex) { - throw new RuntimeException("Gui_DownloadPictures : error 1 - " + ex); - } - } - - if (p == null) { - JOptionPane.showMessageDialog(null, "Couldn't configure Proxy object!", "Error", JOptionPane.ERROR_MESSAGE); - return; - } - - boolean URLNotFound = false; - try { - in = new BufferedReader(new InputStreamReader(serverListURL.openConnection(p).getInputStream())); - } catch (SocketTimeoutException | FileNotFoundException | UnknownHostException ex) { - logger.warn("Could not read serverlist from: " + serverListURL.toString()); - File f = new File("serverlist.txt"); - if (f.exists() && !f.isDirectory()) { - logger.info("Using buffered serverlist: serverlist.txt"); - URLNotFound = true; - in = new BufferedReader(new FileReader("serverlist.txt")); - } - } - List servers = new ArrayList<>(); - if (in != null) { - - if (!URLNotFound) { - // write serverlist to be able to read if URL is not available - File file = new File("serverlist.txt"); - if (file.exists() && !file.isDirectory()) { - file.delete(); - } - output = new BufferedWriter(new FileWriter(file)); - } - - String inputLine; - while ((inputLine = in.readLine()) != null) { - logger.debug("Found server: " + inputLine); - servers.add(inputLine); - if (output != null) { - output.append(inputLine).append('\n'); - - } - } - } - if (servers.isEmpty()) { - JOptionPane.showMessageDialog(null, "Couldn't find any server."); - return; - } - - String selectedServer = (String) JOptionPane.showInputDialog(null, - "Choose XMage Public Server:", "Input", - JOptionPane.INFORMATION_MESSAGE, null, servers.toArray(), - servers.get(0)); - if (selectedServer != null) { - String[] params = selectedServer.split(":"); - if (params.length == 3) { - String serverAddress = params[1]; - this.txtServer.setText(serverAddress); - this.txtPort.setText(params[2]); - // Update userName and password according to the chosen server. - this.txtUserName.setText(MagePreferences.getUserName(serverAddress)); - this.txtPassword.setText(MagePreferences.getPassword(serverAddress)); - } else { - JOptionPane.showMessageDialog(null, "Wrong server data format."); - } - } - - } catch (Exception ex) { - logger.error(ex, ex); - } finally { - StreamUtils.closeQuietly(in); - StreamUtils.closeQuietly(output); - } + }//GEN-LAST:event_jButton1ActionPerformed private void jProxySettingsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jProxySettingsButtonActionPerformed @@ -786,10 +806,6 @@ public class ConnectDialog extends MageDialog { doFastFlagSearch(); }//GEN-LAST:event_btnFlagSearchActionPerformed - private void btnFindBetaconnectLocalhost(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindBetaconnectLocalhost - connectBeta(evt); - }//GEN-LAST:event_btnFindBetaconnectLocalhost - private void btnCheckStatusActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckStatusActionPerformed if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { try { @@ -804,6 +820,30 @@ public class ConnectDialog extends MageDialog { MageFrame.getInstance().showWhatsNewDialog(true); }//GEN-LAST:event_btnWhatsNewActionPerformed + private void btnFindMainActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindMainActionPerformed + setServerSettings("xmage.de", "17171", true); + }//GEN-LAST:event_btnFindMainActionPerformed + + private void btnFindEUActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindEUActionPerformed + setServerSettings("eu.xmage.today", "17171", false); + }//GEN-LAST:event_btnFindEUActionPerformed + + private void btnFindUsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindUsActionPerformed + setServerSettings("us.xmage.today", "17171", false); + }//GEN-LAST:event_btnFindUsActionPerformed + + private void btnFindBetaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindBetaActionPerformed + setServerSettings("beta.xmage.today", "17171", false); + }//GEN-LAST:event_btnFindBetaActionPerformed + + private void btnFindLocalActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindLocalActionPerformed + setServerSettings("localhost", "17171", false); + }//GEN-LAST:event_btnFindLocalActionPerformed + + private void btnFindOtherActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindOtherActionPerformed + chooseAndSetServerSettingsFromOther(); + }//GEN-LAST:event_btnFindOtherActionPerformed + private void doFastFlagSearch() { Choice choice = new ChoiceImpl(false); @@ -852,6 +892,7 @@ public class ConnectDialog extends MageDialog { private javax.swing.JButton btnCheckStatus; private javax.swing.JButton btnConnect; private javax.swing.JButton btnFindBeta; + private javax.swing.JButton btnFindEU; private javax.swing.JButton btnFindLocal; private javax.swing.JButton btnFindMain; private javax.swing.JButton btnFindOther; diff --git a/Mage.Client/src/main/java/mage/client/dialog/TestCardRenderDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TestCardRenderDialog.java index ad92e560e66..25a5da5b836 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/TestCardRenderDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/TestCardRenderDialog.java @@ -400,7 +400,7 @@ class TestGame extends GameImpl { private int numPlayers; public TestGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 60); } public TestGame(final TestGame game) { 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 375ebd8e1eb..c80b87a4ae3 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -582,6 +582,7 @@ public class TablesPanel extends javax.swing.JPanel { Dimension newDimension = new Dimension((int) jPanelBottom.getPreferredSize().getWidth(), GUISizeHelper.menuFont.getSize() + 28); jPanelBottom.setMinimumSize(newDimension); jPanelBottom.setPreferredSize(newDimension); + buttonWhatsNew.setFont(GUISizeHelper.menuFont); buttonNextMessage.setFont(GUISizeHelper.menuFont); labelMessageHeader.setFont(new Font(GUISizeHelper.menuFont.getName(), Font.BOLD, GUISizeHelper.menuFont.getSize())); labelMessageText.setFont(GUISizeHelper.menuFont); @@ -1569,7 +1570,7 @@ public class TablesPanel extends javax.swing.JPanel { jPanelBottom.setPreferredSize(new java.awt.Dimension(516, 37)); jPanelBottom.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT)); - buttonWhatsNew.setText("Show that's new"); + buttonWhatsNew.setText("Show what's new"); buttonWhatsNew.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); buttonWhatsNew.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); buttonWhatsNew.setOpaque(false); 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 f62801a02f9..e656b53d870 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 @@ -151,7 +151,7 @@ public class Brawl extends Constructed { for (Ability ability : companion.getAbilities()) { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; - if (!companionAbility.isLegal(cards)) { + if (!companionAbility.isLegal(cards, getDeckMinSize())) { invalid.put(companion.getName(), "Deck invalid for companion"); valid = false; } 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 8836549e401..3a9b104f3a9 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 @@ -234,7 +234,7 @@ public class Commander extends Constructed { for (Ability ability : companion.getAbilities()) { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; - if (!companionAbility.isLegal(cards)) { + if (!companionAbility.isLegal(cards, getDeckMinSize())) { invalid.put(companion.getName(), "Deck invalid for companion"); valid = false; } 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 d53dd54dd6f..f66405d36b0 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 @@ -158,7 +158,7 @@ public class FreeformCommander extends Constructed { for (Ability ability : companion.getAbilities()) { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; - if (!companionAbility.isLegal(cards)) { + if (!companionAbility.isLegal(cards, getDeckMinSize())) { invalid.put(companion.getName(), "Deck invalid for companion"); valid = false; } 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 967578f66be..ceff69fd1fb 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 @@ -189,7 +189,7 @@ public class PennyDreadfulCommander extends Constructed { for (Ability ability : companion.getAbilities()) { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; - if (!companionAbility.isLegal(cards)) { + if (!companionAbility.isLegal(cards, getDeckMinSize())) { invalid.put(companion.getName(), "Deck invalid for companion"); valid = false; } diff --git a/Mage.Server.Plugins/Mage.Game.BrawlDuel/src/mage/game/BrawlDuel.java b/Mage.Server.Plugins/Mage.Game.BrawlDuel/src/mage/game/BrawlDuel.java index 8aa8ba425e7..50ef2e4dab8 100644 --- a/Mage.Server.Plugins/Mage.Game.BrawlDuel/src/mage/game/BrawlDuel.java +++ b/Mage.Server.Plugins/Mage.Game.BrawlDuel/src/mage/game/BrawlDuel.java @@ -10,7 +10,7 @@ import mage.game.mulligan.Mulligan; public class BrawlDuel extends GameCommanderImpl { public BrawlDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 60); } public BrawlDuel(final BrawlDuel game) { diff --git a/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/src/mage/game/BrawlFreeForAll.java b/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/src/mage/game/BrawlFreeForAll.java index 29cc7f22e07..6b5f1db755a 100644 --- a/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/src/mage/game/BrawlFreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/src/mage/game/BrawlFreeForAll.java @@ -17,7 +17,7 @@ public class BrawlFreeForAll extends GameCommanderImpl { private int numPlayers; public BrawlFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 60); } public BrawlFreeForAll(final BrawlFreeForAll game) { diff --git a/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuel.java b/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuel.java index 6e5df00b828..f8afcb93dfe 100644 --- a/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuel.java +++ b/Mage.Server.Plugins/Mage.Game.CommanderDuel/src/mage/game/CommanderDuel.java @@ -10,7 +10,7 @@ import mage.game.mulligan.Mulligan; public class CommanderDuel extends GameCommanderImpl { public CommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 100); } public CommanderDuel(final CommanderDuel game) { diff --git a/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/src/mage/game/CommanderFreeForAll.java b/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/src/mage/game/CommanderFreeForAll.java index 2c1a9e7d188..0192a2c0adf 100644 --- a/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/src/mage/game/CommanderFreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/src/mage/game/CommanderFreeForAll.java @@ -2,14 +2,14 @@ package mage.game; -import java.util.UUID; import mage.constants.MultiplayerAttackOption; import mage.constants.RangeOfInfluence; import mage.game.match.MatchType; import mage.game.mulligan.Mulligan; +import java.util.UUID; + /** - * * @author LevelX2 */ public class CommanderFreeForAll extends GameCommanderImpl { @@ -17,7 +17,7 @@ public class CommanderFreeForAll extends GameCommanderImpl { private int numPlayers; public CommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 100); } public CommanderFreeForAll(final CommanderFreeForAll game) { @@ -28,7 +28,7 @@ public class CommanderFreeForAll extends GameCommanderImpl { @Override protected void init(UUID choosingPlayerId) { startingPlayerSkipsDraw = false; - super.init(choosingPlayerId); + super.init(choosingPlayerId); } @Override diff --git a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java index 44209f3388e..2d6b1ab80b1 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.FreeForAll/src/mage/game/FreeForAll.java @@ -15,7 +15,7 @@ public class FreeForAll extends GameImpl { private int numPlayers; public FreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 60); } public FreeForAll(final FreeForAll game) { diff --git a/Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/src/mage/game/FreeformCommanderDuel.java b/Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/src/mage/game/FreeformCommanderDuel.java index d57f520f079..eccf1bfcd7f 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/src/mage/game/FreeformCommanderDuel.java +++ b/Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/src/mage/game/FreeformCommanderDuel.java @@ -11,7 +11,7 @@ import mage.game.mulligan.Mulligan; public class FreeformCommanderDuel extends GameCommanderImpl { public FreeformCommanderDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 60); } public FreeformCommanderDuel(final FreeformCommanderDuel game) { diff --git a/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/src/mage/game/FreeformCommanderFreeForAll.java b/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/src/mage/game/FreeformCommanderFreeForAll.java index 2f9aa0e29f6..7638fbe59eb 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/src/mage/game/FreeformCommanderFreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/src/mage/game/FreeformCommanderFreeForAll.java @@ -17,7 +17,7 @@ public class FreeformCommanderFreeForAll extends GameCommanderImpl { private int numPlayers; public FreeformCommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 60); } public FreeformCommanderFreeForAll(final FreeformCommanderFreeForAll game) { diff --git a/Mage.Server.Plugins/Mage.Game.MomirDuel/src/mage/game/MomirDuel.java b/Mage.Server.Plugins/Mage.Game.MomirDuel/src/mage/game/MomirDuel.java index ac51137df93..cc66fc51dfa 100644 --- a/Mage.Server.Plugins/Mage.Game.MomirDuel/src/mage/game/MomirDuel.java +++ b/Mage.Server.Plugins/Mage.Game.MomirDuel/src/mage/game/MomirDuel.java @@ -24,7 +24,7 @@ import mage.players.Player; public class MomirDuel extends GameImpl { public MomirDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 60); } public MomirDuel(final MomirDuel game) { diff --git a/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirGame.java b/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirGame.java index 0750d4d7cb1..efa5ee8b89d 100644 --- a/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirGame.java +++ b/Mage.Server.Plugins/Mage.Game.MomirGame/src/mage/game/MomirGame.java @@ -26,7 +26,7 @@ public class MomirGame extends GameImpl { private int numPlayers; public MomirGame(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 60); } public MomirGame(final MomirGame game) { diff --git a/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/src/mage/game/OathbreakerFreeForAll.java b/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/src/mage/game/OathbreakerFreeForAll.java index 7e068208e2c..90f673c200e 100644 --- a/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/src/mage/game/OathbreakerFreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/src/mage/game/OathbreakerFreeForAll.java @@ -32,7 +32,7 @@ public class OathbreakerFreeForAll extends GameCommanderImpl { private static final String COMMANDER_NAME_SIGNATURE_SPELL = "Signature Spell"; public OathbreakerFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 100); this.startingPlayerSkipsDraw = false; } diff --git a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/src/mage/game/PennyDreadfulCommanderFreeForAll.java b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/src/mage/game/PennyDreadfulCommanderFreeForAll.java index add9c578a9f..0f6ea01fae5 100644 --- a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/src/mage/game/PennyDreadfulCommanderFreeForAll.java +++ b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/src/mage/game/PennyDreadfulCommanderFreeForAll.java @@ -17,7 +17,7 @@ public class PennyDreadfulCommanderFreeForAll extends GameCommanderImpl { private int numPlayers; public PennyDreadfulCommanderFreeForAll(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 60); } public PennyDreadfulCommanderFreeForAll(final PennyDreadfulCommanderFreeForAll game) { diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java index b5e7f2b3346..21f3a61a609 100644 --- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java +++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerDuel.java @@ -1,4 +1,3 @@ - package mage.game; import mage.constants.MultiplayerAttackOption; @@ -13,7 +12,11 @@ import java.util.UUID; public class TwoPlayerDuel extends GameImpl { public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + this(attackOption, range, mulligan, startLife, 60); + } + + public TwoPlayerDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startingSize) { + super(attackOption, range, mulligan, startLife, startingSize); } public TwoPlayerDuel(final TwoPlayerDuel game) { diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java index 9705f03e5dd..720ae4fd242 100644 --- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java +++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/src/mage/game/TwoPlayerMatch.java @@ -6,7 +6,6 @@ import mage.game.match.MatchOptions; import mage.game.mulligan.Mulligan; /** - * * @author BetaSteward_at_googlemail.com */ public class TwoPlayerMatch extends MatchImpl { @@ -18,7 +17,7 @@ public class TwoPlayerMatch extends MatchImpl { @Override public void startGame() throws GameException { Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans()); - TwoPlayerDuel game = new TwoPlayerDuel(options.getAttackOption(), options.getRange(), mulligan, 20); + TwoPlayerDuel game = new TwoPlayerDuel(options.getAttackOption(), options.getRange(), mulligan, 20, options.isLimited() ? 40 : 60); // Sets a start message about the match score game.setStartMessage(this.createGameStartMessage()); initGame(game); diff --git a/Mage.Sets/src/mage/cards/a/AkoumFlameseeker.java b/Mage.Sets/src/mage/cards/a/AkoumFlameseeker.java index 4a671ca6c9c..c8cf5009c3d 100644 --- a/Mage.Sets/src/mage/cards/a/AkoumFlameseeker.java +++ b/Mage.Sets/src/mage/cards/a/AkoumFlameseeker.java @@ -80,7 +80,7 @@ class AkoumFlameseekerEffect extends OneShotEffect { if (controller != null) { Cards cards = controller.discard(1, false, source, game); if (!cards.isEmpty()) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/a/AladdinsLamp.java b/Mage.Sets/src/mage/cards/a/AladdinsLamp.java index 6db19c46d5e..e020079b682 100644 --- a/Mage.Sets/src/mage/cards/a/AladdinsLamp.java +++ b/Mage.Sets/src/mage/cards/a/AladdinsLamp.java @@ -75,7 +75,7 @@ class AladdinsLampEffect extends ReplacementEffectImpl { } controller.putCardsOnBottomOfLibrary(cards, game, source, false); game.applyEffects(); - controller.drawCards(1, game, event.getAppliedEffects()); + controller.drawCards(1, event.getSourceId(), game, event.getAppliedEffects()); discard(); return true; } diff --git a/Mage.Sets/src/mage/cards/a/AlhammarretsArchive.java b/Mage.Sets/src/mage/cards/a/AlhammarretsArchive.java index 7934c8b8585..383d20fc2c0 100644 --- a/Mage.Sets/src/mage/cards/a/AlhammarretsArchive.java +++ b/Mage.Sets/src/mage/cards/a/AlhammarretsArchive.java @@ -98,7 +98,7 @@ class AlhammarretsArchiveReplacementEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(2, game, event.getAppliedEffects()); + controller.drawCards(2, event.getSourceId(), game, event.getAppliedEffects()); } return true; } diff --git a/Mage.Sets/src/mage/cards/a/AlmsCollector.java b/Mage.Sets/src/mage/cards/a/AlmsCollector.java index 9750fc5b29e..7413e549275 100644 --- a/Mage.Sets/src/mage/cards/a/AlmsCollector.java +++ b/Mage.Sets/src/mage/cards/a/AlmsCollector.java @@ -74,8 +74,8 @@ class AlmsCollectorReplacementEffect extends ReplacementEffectImpl { Player controller = game.getPlayer(source.getControllerId()); Player opponent = game.getPlayer(event.getPlayerId()); if (controller != null && opponent != null) { - controller.drawCards(1, game, event.getAppliedEffects()); - opponent.drawCards(1, game, event.getAppliedEffects()); + controller.drawCards(1, source.getSourceId(), game, event.getAppliedEffects()); + opponent.drawCards(1, source.getSourceId(), game, event.getAppliedEffects()); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/a/AmassTheComponents.java b/Mage.Sets/src/mage/cards/a/AmassTheComponents.java index 359cd2fe902..5d7c24dbad8 100644 --- a/Mage.Sets/src/mage/cards/a/AmassTheComponents.java +++ b/Mage.Sets/src/mage/cards/a/AmassTheComponents.java @@ -63,7 +63,7 @@ class AmassTheComponentsEffect extends OneShotEffect { return false; } - player.drawCards(3, game); + player.drawCards(3, source.getSourceId(), game); if (!player.getHand().isEmpty()) { FilterCard filter = new FilterCard("card from your hand to put on the bottom of your library"); TargetCard target = new TargetCard(Zone.HAND, filter); diff --git a/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java b/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java index c2226fb5eb1..af5db56ead5 100644 --- a/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java +++ b/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java @@ -98,7 +98,7 @@ class AminatouPlusEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); putOnLibrary(player, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/a/AncientExcavation.java b/Mage.Sets/src/mage/cards/a/AncientExcavation.java index c339ac270d0..6aee0c9753c 100644 --- a/Mage.Sets/src/mage/cards/a/AncientExcavation.java +++ b/Mage.Sets/src/mage/cards/a/AncientExcavation.java @@ -63,7 +63,7 @@ class AncientExcavationEffect extends OneShotEffect { if (player != null) { DynamicValue numCards = CardsInControllerHandCount.instance; int amount = numCards.calculate(game, source, this); - player.drawCards(amount, game); + player.drawCards(amount, source.getSourceId(), game); player.discard(amount, false, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/a/AnvilOfBogardan.java b/Mage.Sets/src/mage/cards/a/AnvilOfBogardan.java index 9a15bf7de8a..7c25620ed59 100644 --- a/Mage.Sets/src/mage/cards/a/AnvilOfBogardan.java +++ b/Mage.Sets/src/mage/cards/a/AnvilOfBogardan.java @@ -57,7 +57,7 @@ class AnvilOfBogardanEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); if (targetPlayer != null) { - targetPlayer.drawCards(1, game); + targetPlayer.drawCards(1, source.getSourceId(), game); targetPlayer.discard(1, false, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/a/ArcaneArtisan.java b/Mage.Sets/src/mage/cards/a/ArcaneArtisan.java index 99cceae7889..e4028535a35 100644 --- a/Mage.Sets/src/mage/cards/a/ArcaneArtisan.java +++ b/Mage.Sets/src/mage/cards/a/ArcaneArtisan.java @@ -90,7 +90,7 @@ class ArcaneArtisanCreateTokenEffect extends OneShotEffect { if (player == null) { return false; } - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); TargetCard target = new TargetCardInHand(1, StaticFilters.FILTER_CARD); if (!player.chooseTarget(Outcome.Exile, player.getHand(), target, source, game)) { return false; diff --git a/Mage.Sets/src/mage/cards/a/ArjunTheShiftingFlame.java b/Mage.Sets/src/mage/cards/a/ArjunTheShiftingFlame.java index 458786bfd53..8a92258bf46 100644 --- a/Mage.Sets/src/mage/cards/a/ArjunTheShiftingFlame.java +++ b/Mage.Sets/src/mage/cards/a/ArjunTheShiftingFlame.java @@ -64,7 +64,7 @@ class ArjunTheShiftingFlameEffect extends OneShotEffect { if (you != null) { int count = you.getHand().size(); you.putCardsOnBottomOfLibrary(you.getHand(), game, source, true); - you.drawCards(count, game); + you.drawCards(count, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/a/AzorTheLawbringer.java b/Mage.Sets/src/mage/cards/a/AzorTheLawbringer.java index 0933ac1fa1d..5a69e07060d 100644 --- a/Mage.Sets/src/mage/cards/a/AzorTheLawbringer.java +++ b/Mage.Sets/src/mage/cards/a/AzorTheLawbringer.java @@ -168,7 +168,7 @@ class AzorTheLawbringerAttacksEffect extends OneShotEffect { if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false, null)) { controller.resetStoredBookmark(game); // otherwise you can undo the payment controller.gainLife(costX, game, source); - controller.drawCards(costX, game); + controller.drawCards(costX, source.getSourceId(), game); return true; } } diff --git a/Mage.Sets/src/mage/cards/a/AzorsGateway.java b/Mage.Sets/src/mage/cards/a/AzorsGateway.java index 499991f9ea2..06a30c883ad 100644 --- a/Mage.Sets/src/mage/cards/a/AzorsGateway.java +++ b/Mage.Sets/src/mage/cards/a/AzorsGateway.java @@ -78,7 +78,7 @@ class AzorsGatewayEffect extends OneShotEffect { UUID exileId = CardUtil.getCardExileZoneId(game, source); MageObject sourceObject = source.getSourceObject(game); if (controller != null && exileId != null && sourceObject != null) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); TargetCardInHand target = new TargetCardInHand(); controller.choose(outcome, target, source.getSourceId(), game); Card cardToExile = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/cards/a/AzraBladeseeker.java b/Mage.Sets/src/mage/cards/a/AzraBladeseeker.java index 47a9210eaa0..3dc89cd1110 100644 --- a/Mage.Sets/src/mage/cards/a/AzraBladeseeker.java +++ b/Mage.Sets/src/mage/cards/a/AzraBladeseeker.java @@ -84,7 +84,7 @@ class AzraBladeseekerEffect extends OneShotEffect { } for (PlayerCard playerCard : playerCardList) { if (playerCard.getPlayer().discard(playerCard.getCard(), source, game)) { - playerCard.getPlayer().drawCards(1, game); + playerCard.getPlayer().drawCards(1, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/b/BalanceOfPower.java b/Mage.Sets/src/mage/cards/b/BalanceOfPower.java index 7b2b9be3f4d..a53f5812ebc 100644 --- a/Mage.Sets/src/mage/cards/b/BalanceOfPower.java +++ b/Mage.Sets/src/mage/cards/b/BalanceOfPower.java @@ -59,7 +59,7 @@ class BalanceOfPowerEffect extends OneShotEffect { Player opponent = game.getPlayer(source.getFirstTarget()); if (opponent != null && player != null && opponent.getHand().size() > player.getHand().size()) { - player.drawCards(opponent.getHand().size() - player.getHand().size(), game); + player.drawCards(opponent.getHand().size() - player.getHand().size(), source.getSourceId(), game); return true; } diff --git a/Mage.Sets/src/mage/cards/b/BalefulStare.java b/Mage.Sets/src/mage/cards/b/BalefulStare.java index cccfe6ab8d5..16a49f5fa16 100644 --- a/Mage.Sets/src/mage/cards/b/BalefulStare.java +++ b/Mage.Sets/src/mage/cards/b/BalefulStare.java @@ -70,7 +70,7 @@ class BalefulStareEffect extends OneShotEffect { count++; } } - controller.drawCards(count, game); + controller.drawCards(count, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/b/BaneAlleyBroker.java b/Mage.Sets/src/mage/cards/b/BaneAlleyBroker.java index 6c7e3f8b9b6..51c9ff6ae79 100644 --- a/Mage.Sets/src/mage/cards/b/BaneAlleyBroker.java +++ b/Mage.Sets/src/mage/cards/b/BaneAlleyBroker.java @@ -106,7 +106,7 @@ class BaneAlleyBrokerDrawExileEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); Target target = new TargetCardInHand(new FilterCard("card to exile")); if (controller.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/cards/b/BarbedShocker.java b/Mage.Sets/src/mage/cards/b/BarbedShocker.java index 463e2c07f67..0ae806c0d07 100644 --- a/Mage.Sets/src/mage/cards/b/BarbedShocker.java +++ b/Mage.Sets/src/mage/cards/b/BarbedShocker.java @@ -70,7 +70,7 @@ class BarbedShockerEffect extends OneShotEffect { for (Card card : targetPlayer.getHand().getCards(game)) { targetPlayer.discard(card, source, game); } - targetPlayer.drawCards(count, game); + targetPlayer.drawCards(count, source.getSourceId(), game); return false; } return true; diff --git a/Mage.Sets/src/mage/cards/b/BiomanticMastery.java b/Mage.Sets/src/mage/cards/b/BiomanticMastery.java index 7b12e0073c1..c0c5d1f57df 100644 --- a/Mage.Sets/src/mage/cards/b/BiomanticMastery.java +++ b/Mage.Sets/src/mage/cards/b/BiomanticMastery.java @@ -63,7 +63,7 @@ class BiomanticMasteryEffect extends OneShotEffect { Player player = game.getPlayer(playerId); if (player != null) { int creatures = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, playerId, game); - controller.drawCards(creatures, game); + controller.drawCards(creatures, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/b/BlastOfGenius.java b/Mage.Sets/src/mage/cards/b/BlastOfGenius.java index b18d8819734..30e0be56375 100644 --- a/Mage.Sets/src/mage/cards/b/BlastOfGenius.java +++ b/Mage.Sets/src/mage/cards/b/BlastOfGenius.java @@ -59,7 +59,7 @@ class BlastOfGeniusEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(3, game); + player.drawCards(3, source.getSourceId(), game); TargetDiscard target = new TargetDiscard(player.getId()); if (target.canChoose(source.getSourceId(), player.getId(), game)) { player.choose(Outcome.Discard, target, source.getSourceId(), game); diff --git a/Mage.Sets/src/mage/cards/b/BloodScrivener.java b/Mage.Sets/src/mage/cards/b/BloodScrivener.java index ee24474fbd0..1b8a7a5ea51 100644 --- a/Mage.Sets/src/mage/cards/b/BloodScrivener.java +++ b/Mage.Sets/src/mage/cards/b/BloodScrivener.java @@ -70,7 +70,7 @@ class BloodScrivenerReplacementEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player player = game.getPlayer(event.getPlayerId()); if (player != null) { - player.drawCards(2, game, event.getAppliedEffects()); + player.drawCards(2, event.getSourceId(), game, event.getAppliedEffects()); player.loseLife(1, game, false); } return true; diff --git a/Mage.Sets/src/mage/cards/b/BondersOrnament.java b/Mage.Sets/src/mage/cards/b/BondersOrnament.java index 3918686f690..c63b2e08508 100644 --- a/Mage.Sets/src/mage/cards/b/BondersOrnament.java +++ b/Mage.Sets/src/mage/cards/b/BondersOrnament.java @@ -73,7 +73,7 @@ class BondersOrnamentEffect extends OneShotEffect { .noneMatch("Bonder's Ornament"::equals)) { continue; } - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/b/BountyOfTheLuxa.java b/Mage.Sets/src/mage/cards/b/BountyOfTheLuxa.java index 8a55e31f26c..37e29df7f60 100644 --- a/Mage.Sets/src/mage/cards/b/BountyOfTheLuxa.java +++ b/Mage.Sets/src/mage/cards/b/BountyOfTheLuxa.java @@ -80,7 +80,7 @@ class BountyOfTheLuxaEffect extends OneShotEffect { if (bountyOfLuxa != null) { new AddCountersSourceEffect(CounterType.FLOOD.createInstance()).apply(game, source); } - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/b/BrainPry.java b/Mage.Sets/src/mage/cards/b/BrainPry.java index 2e75ebc8321..555d1368c16 100644 --- a/Mage.Sets/src/mage/cards/b/BrainPry.java +++ b/Mage.Sets/src/mage/cards/b/BrainPry.java @@ -67,7 +67,7 @@ class BrainPryEffect extends OneShotEffect { } } if (!hasDiscarded) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } controller.lookAtCards(sourceObject.getName() + " Hand", targetPlayer.getHand(), game); } diff --git a/Mage.Sets/src/mage/cards/b/BreathstealersCrypt.java b/Mage.Sets/src/mage/cards/b/BreathstealersCrypt.java index 520cd01f91e..1141259d6bc 100644 --- a/Mage.Sets/src/mage/cards/b/BreathstealersCrypt.java +++ b/Mage.Sets/src/mage/cards/b/BreathstealersCrypt.java @@ -68,7 +68,7 @@ class BreathstealersCryptEffect extends ReplacementEffectImpl { Player player = game.getPlayer(event.getPlayerId()); if (player != null) { Cards oldHand = player.getHand().copy(); - if (player.drawCards(1, game, event.getAppliedEffects()) > 0) { + if (player.drawCards(1, event.getSourceId(), game, event.getAppliedEffects()) > 0) { Cards drawnCards = player.getHand().copy(); drawnCards.removeAll(oldHand); player.revealCards(source, "The card drawn from " + player.getName() + "'s library.", drawnCards, game); diff --git a/Mage.Sets/src/mage/cards/b/Browbeat.java b/Mage.Sets/src/mage/cards/b/Browbeat.java index e5f83778510..e96f9ae7bb4 100644 --- a/Mage.Sets/src/mage/cards/b/Browbeat.java +++ b/Mage.Sets/src/mage/cards/b/Browbeat.java @@ -80,7 +80,7 @@ class BrowbeatDrawEffect extends OneShotEffect { if (targetPlayer != null) { Player player = game.getPlayer(targetPlayer); if (player != null) { - player.drawCards(3, game); + player.drawCards(3, source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java b/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java index af6f48aedb5..50fd0a2a6e7 100644 --- a/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java +++ b/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java @@ -98,6 +98,6 @@ class BushmeatPoacherEffect extends OneShotEffect { if (amount > 0) { player.gainLife(amount, game, source); } - return player.drawCards(1, game) > 0; + return player.drawCards(1, source.getSourceId(), game) > 0; } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/CallToHeel.java b/Mage.Sets/src/mage/cards/c/CallToHeel.java index 4e9ad8d18d8..e8127595fca 100644 --- a/Mage.Sets/src/mage/cards/c/CallToHeel.java +++ b/Mage.Sets/src/mage/cards/c/CallToHeel.java @@ -67,7 +67,7 @@ class CallToHeelEffect extends OneShotEffect { if (permanent != null) { Player controller = game.getPlayer(permanent.getControllerId()); if (controller != null) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); return true; } } diff --git a/Mage.Sets/src/mage/cards/c/Camaraderie.java b/Mage.Sets/src/mage/cards/c/Camaraderie.java index 1e0880911be..8bbc87a8c50 100644 --- a/Mage.Sets/src/mage/cards/c/Camaraderie.java +++ b/Mage.Sets/src/mage/cards/c/Camaraderie.java @@ -67,7 +67,7 @@ class CamaraderieEffect extends OneShotEffect { source.getSourceId(), source.getControllerId(), game ); player.gainLife(xValue, game, source); - player.drawCards(xValue, game); + player.drawCards(xValue, source.getSourceId(), game); game.addEffect(new BoostControlledEffect(1, 1, Duration.EndOfTurn), source); return true; } diff --git a/Mage.Sets/src/mage/cards/c/CartographersHawk.java b/Mage.Sets/src/mage/cards/c/CartographersHawk.java new file mode 100644 index 00000000000..deedeb1b839 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CartographersHawk.java @@ -0,0 +1,128 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class CartographersHawk extends CardImpl { + + public CartographersHawk(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.BIRD); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Cartographer's Hawk deals combat damage to a player who controls more lands than you, return it to its owner's hand. If you do, you may search your library for a Plains card, put it onto the battlefield tapped, then shuffle your library. + this.addAbility(new CartographersHawkTriggeredAbility()); + } + + private CartographersHawk(final CartographersHawk card) { + super(card); + } + + @Override + public CartographersHawk copy() { + return new CartographersHawk(this); + } +} + +class CartographersHawkTriggeredAbility extends TriggeredAbilityImpl { + + CartographersHawkTriggeredAbility() { + super(Zone.BATTLEFIELD, new CartographersHawkEffect(), false); + } + + private CartographersHawkTriggeredAbility(final CartographersHawkTriggeredAbility ability) { + super(ability); + } + + @Override + public CartographersHawkTriggeredAbility copy() { + return new CartographersHawkTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return event.getSourceId().equals(this.getSourceId()) + && game.getBattlefield().countAll( + StaticFilters.FILTER_LAND, this.getControllerId(), game + ) < game.getBattlefield().countAll( + StaticFilters.FILTER_LAND, event.getTargetId(), game + ); + } + + @Override + public String getRule() { + return "When {this} deals combat damage to a player who controls more lands than you, " + + "return it to its owner's hand. If you do, you may search your library for a Plains card, " + + "put it onto the battlefield tapped, then shuffle your library."; + } +} + +class CartographersHawkEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard("a Plains card"); + + static { + filter.add(SubType.PLAINS.getPredicate()); + } + + CartographersHawkEffect() { + super(Outcome.Benefit); + } + + private CartographersHawkEffect(final CartographersHawkEffect effect) { + super(effect); + } + + @Override + public CartographersHawkEffect copy() { + return new CartographersHawkEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + Player player = game.getPlayer(source.getControllerId()); + if (permanent == null || player == null) { + return false; + } + if (!player.moveCards(permanent, Zone.HAND, source, game)) { + return false; + } + if (!player.chooseUse(Outcome.PutLandInPlay, "Search your library for Plains card?", source, game)) { + return true; + } + return new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter)).apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CavalierOfFlame.java b/Mage.Sets/src/mage/cards/c/CavalierOfFlame.java index 79dc2259459..01e5b3e0705 100644 --- a/Mage.Sets/src/mage/cards/c/CavalierOfFlame.java +++ b/Mage.Sets/src/mage/cards/c/CavalierOfFlame.java @@ -109,7 +109,7 @@ class CavalierOfFlameEffect extends OneShotEffect { .map(uuid -> game.getCard(uuid)) .mapToInt(card -> card != null && player.discard(card, source, game) ? 1 : 0) .sum(); - player.drawCards(counter, game); + player.drawCards(counter, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/c/CemeteryRecruitment.java b/Mage.Sets/src/mage/cards/c/CemeteryRecruitment.java index a85dd2c4abe..d40353072d9 100644 --- a/Mage.Sets/src/mage/cards/c/CemeteryRecruitment.java +++ b/Mage.Sets/src/mage/cards/c/CemeteryRecruitment.java @@ -64,7 +64,7 @@ class CemeteryRecruitmentEffect extends OneShotEffect { if (card != null) { if (controller.moveCards(card, Zone.HAND, source, game) && card.hasSubtype(SubType.ZOMBIE, game)) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java b/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java index be87c242afe..ce7de428f6a 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java +++ b/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java @@ -112,7 +112,7 @@ class ChandraDrawEffect extends OneShotEffect { for (Card card : cardsInHand) { player.discard(card, source, game); } - player.drawCards(amount + 1, game); + player.drawCards(amount + 1, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/c/ChandrasDefeat.java b/Mage.Sets/src/mage/cards/c/ChandrasDefeat.java index a8cff5456cd..2915dac0146 100644 --- a/Mage.Sets/src/mage/cards/c/ChandrasDefeat.java +++ b/Mage.Sets/src/mage/cards/c/ChandrasDefeat.java @@ -84,7 +84,7 @@ class ChandrasDefeatEffect extends OneShotEffect { if (filter.match(permanent, game) && controller != null && controller.chooseUse(outcome, "Discard a card and draw a card?", source, game)) { controller.discard(1, false, source, game); - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/c/ChanneledForce.java b/Mage.Sets/src/mage/cards/c/ChanneledForce.java index 3e3363db112..4b918233537 100644 --- a/Mage.Sets/src/mage/cards/c/ChanneledForce.java +++ b/Mage.Sets/src/mage/cards/c/ChanneledForce.java @@ -67,7 +67,7 @@ class ChanneledForceEffect extends OneShotEffect { } Player player = game.getPlayer(source.getTargets().get(0).getFirstTarget()); if (player != null) { - player.drawCards(xValue, game); + player.drawCards(xValue, source.getSourceId(), game); } game.damagePlayerOrPlaneswalker( source.getTargets().get(1).getFirstTarget(), xValue, diff --git a/Mage.Sets/src/mage/cards/c/ChroniclerOfHeroes.java b/Mage.Sets/src/mage/cards/c/ChroniclerOfHeroes.java index 0915439a16e..9d078b02715 100644 --- a/Mage.Sets/src/mage/cards/c/ChroniclerOfHeroes.java +++ b/Mage.Sets/src/mage/cards/c/ChroniclerOfHeroes.java @@ -75,7 +75,7 @@ class ChroniclerOfHeroesEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { if (new PermanentsOnTheBattlefieldCondition(filter).apply(game, source)) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/c/CivilizedScholar.java b/Mage.Sets/src/mage/cards/c/CivilizedScholar.java index 0f3f1eb7d26..480d3b6f5e3 100644 --- a/Mage.Sets/src/mage/cards/c/CivilizedScholar.java +++ b/Mage.Sets/src/mage/cards/c/CivilizedScholar.java @@ -16,13 +16,10 @@ import mage.cards.h.HomicidalBruteWatcher; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; -import mage.constants.WatcherScope; import mage.constants.Zone; import mage.game.Game; -import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.watchers.Watcher; /** * @author nantuko @@ -77,7 +74,7 @@ class CivilizedScholarEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); Card card = player.discardOne(false, source, game); if (card != null && card.isCreature()) { Permanent permanent = game.getPermanent(source.getSourceId()); diff --git a/Mage.Sets/src/mage/cards/c/ClackbridgeTroll.java b/Mage.Sets/src/mage/cards/c/ClackbridgeTroll.java index b3e3b9805ed..fb16cf21538 100644 --- a/Mage.Sets/src/mage/cards/c/ClackbridgeTroll.java +++ b/Mage.Sets/src/mage/cards/c/ClackbridgeTroll.java @@ -114,7 +114,7 @@ class ClackbridgeTrollEffect extends OneShotEffect { sourcePerm.tap(game); } controller.gainLife(3, game, source); - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/c/ClingToDust.java b/Mage.Sets/src/mage/cards/c/ClingToDust.java index 680f9ecbc3e..b3b32464472 100644 --- a/Mage.Sets/src/mage/cards/c/ClingToDust.java +++ b/Mage.Sets/src/mage/cards/c/ClingToDust.java @@ -72,7 +72,7 @@ class ClingToDustEffect extends OneShotEffect { if (isCreature) { player.gainLife(3, game, source); } else { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/c/CoercedConfession.java b/Mage.Sets/src/mage/cards/c/CoercedConfession.java index 2d727a4d8a6..128ddb264f7 100644 --- a/Mage.Sets/src/mage/cards/c/CoercedConfession.java +++ b/Mage.Sets/src/mage/cards/c/CoercedConfession.java @@ -69,7 +69,7 @@ class CoercedConfessionMillEffect extends OneShotEffect { if (foundCreatures > 0) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(foundCreatures, game); + controller.drawCards(foundCreatures, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/c/CoercivePortal.java b/Mage.Sets/src/mage/cards/c/CoercivePortal.java index 30d88f2034f..fe922573721 100644 --- a/Mage.Sets/src/mage/cards/c/CoercivePortal.java +++ b/Mage.Sets/src/mage/cards/c/CoercivePortal.java @@ -77,7 +77,7 @@ class CoercivePortalEffect extends OneShotEffect { new SacrificeSourceEffect().apply(game, source); new DestroyAllEffect(new FilterNonlandPermanent()).apply(game, source); } else { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/c/ColdEyedSelkie.java b/Mage.Sets/src/mage/cards/c/ColdEyedSelkie.java index 592581df020..118823d5c2a 100644 --- a/Mage.Sets/src/mage/cards/c/ColdEyedSelkie.java +++ b/Mage.Sets/src/mage/cards/c/ColdEyedSelkie.java @@ -68,7 +68,7 @@ class ColdEyeSelkieEffect extends OneShotEffect { if (amount > 0) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(amount, game); + controller.drawCards(amount, source.getSourceId(), game); return true; } } diff --git a/Mage.Sets/src/mage/cards/c/CollectiveDefiance.java b/Mage.Sets/src/mage/cards/c/CollectiveDefiance.java index ae5c57bb199..553a8acec7e 100644 --- a/Mage.Sets/src/mage/cards/c/CollectiveDefiance.java +++ b/Mage.Sets/src/mage/cards/c/CollectiveDefiance.java @@ -95,7 +95,7 @@ class CollectiveDefianceEffect extends OneShotEffect { for (Card card : targetPlayer.getHand().getCards(game)) { targetPlayer.discard(card, source, game); } - targetPlayer.drawCards(count, game); + targetPlayer.drawCards(count, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/c/CommenceTheEndgame.java b/Mage.Sets/src/mage/cards/c/CommenceTheEndgame.java index 45eaf89629b..b9d1fe568cb 100644 --- a/Mage.Sets/src/mage/cards/c/CommenceTheEndgame.java +++ b/Mage.Sets/src/mage/cards/c/CommenceTheEndgame.java @@ -60,7 +60,7 @@ class CommenceTheEndgameEffect extends OneShotEffect { if (player == null) { return false; } - player.drawCards(2, game); + player.drawCards(2, source.getSourceId(), game); return new AmassEffect(player.getHand().size()).apply(game, source); } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/c/ConchHorn.java b/Mage.Sets/src/mage/cards/c/ConchHorn.java index b4622ce5cac..94d727ea628 100644 --- a/Mage.Sets/src/mage/cards/c/ConchHorn.java +++ b/Mage.Sets/src/mage/cards/c/ConchHorn.java @@ -64,7 +64,7 @@ class ConchHornEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(2, game); + player.drawCards(2, source.getSourceId(), game); putOnLibrary(player, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/c/CovenantOfMinds.java b/Mage.Sets/src/mage/cards/c/CovenantOfMinds.java index 9c4ed372d42..bedea474a8d 100644 --- a/Mage.Sets/src/mage/cards/c/CovenantOfMinds.java +++ b/Mage.Sets/src/mage/cards/c/CovenantOfMinds.java @@ -74,12 +74,12 @@ class CovenantOfMindsEffect extends OneShotEffect { player.moveCards(cards, Zone.HAND, source, game); } else { player.moveCards(cards, Zone.GRAVEYARD, source, game); - player.drawCards(5, game); + player.drawCards(5, source.getSourceId(), game); } } else { if (!opponent.chooseUse(Outcome.Benefit, player.getLogName() + "'s library is empty? Do you want them to draw five cards?", source, game)) { - player.drawCards(5, game); + player.drawCards(5, source.getSourceId(), game); } } diff --git a/Mage.Sets/src/mage/cards/c/CranialArchive.java b/Mage.Sets/src/mage/cards/c/CranialArchive.java index 6c0d7d42608..4f91a820ad7 100644 --- a/Mage.Sets/src/mage/cards/c/CranialArchive.java +++ b/Mage.Sets/src/mage/cards/c/CranialArchive.java @@ -71,7 +71,7 @@ class CranialArchiveEffect extends OneShotEffect { } targetPlayer.shuffleLibrary(source, game); } - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/c/CreditVoucher.java b/Mage.Sets/src/mage/cards/c/CreditVoucher.java index 1884b3b7f37..8abaae5f4a4 100644 --- a/Mage.Sets/src/mage/cards/c/CreditVoucher.java +++ b/Mage.Sets/src/mage/cards/c/CreditVoucher.java @@ -79,7 +79,7 @@ class CreditVoucherEffect extends OneShotEffect { } controller.shuffleLibrary(source, game); if (amountShuffled > 0) { - controller.drawCards(amountShuffled, game); + controller.drawCards(amountShuffled, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/c/CullingDais.java b/Mage.Sets/src/mage/cards/c/CullingDais.java index ba08cbdb227..7a26b00aa87 100644 --- a/Mage.Sets/src/mage/cards/c/CullingDais.java +++ b/Mage.Sets/src/mage/cards/c/CullingDais.java @@ -66,7 +66,7 @@ class CullingDaisEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (p != null && player != null) { int count = p.getCounters(game).getCount(CounterType.CHARGE); - player.drawCards(count, game); + player.drawCards(count, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/c/CurseOfChaos.java b/Mage.Sets/src/mage/cards/c/CurseOfChaos.java index d4892429397..8031db361fe 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfChaos.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfChaos.java @@ -115,7 +115,7 @@ class CurseOfChaosEffect extends OneShotEffect { if (attacker != null) { if (!attacker.getHand().isEmpty() && attacker.chooseUse(outcome, "Discard a card and draw a card?", source, game)) { attacker.discard(1, false, source, game); - attacker.drawCards(1, game); + attacker.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfVengeance.java b/Mage.Sets/src/mage/cards/c/CurseOfVengeance.java index e12fb3e6da9..fe1af03565f 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfVengeance.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfVengeance.java @@ -157,7 +157,7 @@ class CurseOfVengeanceDrawLifeEffect extends OneShotEffect { Permanent sourceObject = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (sourceObject != null && controller != null) { if (sourceObject.getCounters(game).containsKey(CounterType.SPITE)) { - controller.drawCards(sourceObject.getCounters(game).getCount(CounterType.SPITE), game); + controller.drawCards(sourceObject.getCounters(game).getCount(CounterType.SPITE), source.getSourceId(), game); controller.gainLife(sourceObject.getCounters(game).getCount(CounterType.SPITE), game, source); } return true; diff --git a/Mage.Sets/src/mage/cards/d/DamnablePact.java b/Mage.Sets/src/mage/cards/d/DamnablePact.java index 71d91680b4f..33b8f0b960d 100644 --- a/Mage.Sets/src/mage/cards/d/DamnablePact.java +++ b/Mage.Sets/src/mage/cards/d/DamnablePact.java @@ -52,7 +52,7 @@ class DamnablePactEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); if (targetPlayer != null) { - targetPlayer.drawCards(source.getManaCostsToPay().getX(), game); + targetPlayer.drawCards(source.getManaCostsToPay().getX(), source.getSourceId(), game); targetPlayer.loseLife(source.getManaCostsToPay().getX(), game, false); return true; } diff --git a/Mage.Sets/src/mage/cards/d/DaredevilDragster.java b/Mage.Sets/src/mage/cards/d/DaredevilDragster.java index 112af1122ad..d0dcc2315cd 100644 --- a/Mage.Sets/src/mage/cards/d/DaredevilDragster.java +++ b/Mage.Sets/src/mage/cards/d/DaredevilDragster.java @@ -79,7 +79,7 @@ class DaredevilDragsterEffect extends OneShotEffect { permanent.addCounters(CounterType.VELOCITY.createInstance(), source, game); if (permanent.getCounters(game).getCount(CounterType.VELOCITY) >= 2) { permanent.sacrifice(source.getSourceId(), game); - controller.drawCards(2, game); + controller.drawCards(2, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/d/DarettiScrapSavant.java b/Mage.Sets/src/mage/cards/d/DarettiScrapSavant.java index 85a367404c1..03bf92605cd 100644 --- a/Mage.Sets/src/mage/cards/d/DarettiScrapSavant.java +++ b/Mage.Sets/src/mage/cards/d/DarettiScrapSavant.java @@ -101,7 +101,7 @@ class DarettiDiscardDrawEffect extends OneShotEffect { count++; } } - controller.drawCards(count, game); + controller.drawCards(count, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/d/DarkDeal.java b/Mage.Sets/src/mage/cards/d/DarkDeal.java index 1c81482bc12..e3d836b24c5 100644 --- a/Mage.Sets/src/mage/cards/d/DarkDeal.java +++ b/Mage.Sets/src/mage/cards/d/DarkDeal.java @@ -5,7 +5,6 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.UUID; -import com.j256.ormlite.stmt.query.In; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; @@ -72,7 +71,7 @@ class DarkDealEffect extends OneShotEffect { for (Map.Entry toDrawByPlayer : cardsToDraw.entrySet()) { Player player = game.getPlayer(toDrawByPlayer.getKey()); if (player != null) { - player.drawCards(toDrawByPlayer.getValue(), game); + player.drawCards(toDrawByPlayer.getValue(), source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/d/DarkIntimations.java b/Mage.Sets/src/mage/cards/d/DarkIntimations.java index d01a05305bb..7c2973c4773 100644 --- a/Mage.Sets/src/mage/cards/d/DarkIntimations.java +++ b/Mage.Sets/src/mage/cards/d/DarkIntimations.java @@ -128,7 +128,7 @@ class DarkIntimationsEffect extends OneShotEffect { } controller.moveCards(card, Zone.HAND, source, game); } - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DecreeOfPain.java b/Mage.Sets/src/mage/cards/d/DecreeOfPain.java index 0176b888466..1930d1889f4 100644 --- a/Mage.Sets/src/mage/cards/d/DecreeOfPain.java +++ b/Mage.Sets/src/mage/cards/d/DecreeOfPain.java @@ -73,7 +73,7 @@ class DecreeOfPainEffect extends OneShotEffect { } } if (destroyedCreature > 0) { - controller.drawCards(destroyedCreature, game); + controller.drawCards(destroyedCreature, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/d/DesperateRavings.java b/Mage.Sets/src/mage/cards/d/DesperateRavings.java index c439c8e2828..bcafe7eb9f5 100644 --- a/Mage.Sets/src/mage/cards/d/DesperateRavings.java +++ b/Mage.Sets/src/mage/cards/d/DesperateRavings.java @@ -62,7 +62,7 @@ class DesperateRavingsEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(2, game); + player.drawCards(2, source.getSourceId(), game); Cards hand = player.getHand(); Card card = hand.getRandom(game); player.discard(card, source, game); diff --git a/Mage.Sets/src/mage/cards/d/DiminishingReturns.java b/Mage.Sets/src/mage/cards/d/DiminishingReturns.java index e6b2d8ecdf5..cee47ba7676 100644 --- a/Mage.Sets/src/mage/cards/d/DiminishingReturns.java +++ b/Mage.Sets/src/mage/cards/d/DiminishingReturns.java @@ -72,7 +72,7 @@ class DiminishingReturnsEffect extends OneShotEffect { Player player = game.getPlayer(playerId); if (player != null) { int cardsToDrawCount = player.getAmount(0, 7, "How many cards to draw (up to 7)?", game); - player.drawCards(cardsToDrawCount, game); + player.drawCards(cardsToDrawCount, source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/d/DimirCutpurse.java b/Mage.Sets/src/mage/cards/d/DimirCutpurse.java index 5d6beefa3ba..07f119e1db9 100644 --- a/Mage.Sets/src/mage/cards/d/DimirCutpurse.java +++ b/Mage.Sets/src/mage/cards/d/DimirCutpurse.java @@ -59,7 +59,7 @@ class DimirCutpurseEffect extends OneShotEffect { damagedPlayer.discard(1, false,source, game); } if (you != null) { - you.drawCards(1, game); + you.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/d/DiscipleOfBolas.java b/Mage.Sets/src/mage/cards/d/DiscipleOfBolas.java index 001725d1679..67fd8e63d38 100644 --- a/Mage.Sets/src/mage/cards/d/DiscipleOfBolas.java +++ b/Mage.Sets/src/mage/cards/d/DiscipleOfBolas.java @@ -75,7 +75,7 @@ class DiscipleOfBolasEffect extends OneShotEffect { sacrificed.sacrifice(source.getSourceId(), game); int power = sacrificed.getPower().getValue(); controller.gainLife(power, game, source); - controller.drawCards(power, game); + controller.drawCards(power, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/d/DistantMemories.java b/Mage.Sets/src/mage/cards/d/DistantMemories.java index f93aabe1e4c..1869d6ba375 100644 --- a/Mage.Sets/src/mage/cards/d/DistantMemories.java +++ b/Mage.Sets/src/mage/cards/d/DistantMemories.java @@ -85,7 +85,7 @@ class DistantMemoriesEffect extends OneShotEffect { if (putInHand) { controller.moveCards(card, Zone.HAND, source, game); } else { - controller.drawCards(3, game); + controller.drawCards(3, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/d/DivinerSpirit.java b/Mage.Sets/src/mage/cards/d/DivinerSpirit.java index 0b844df3434..0796e310999 100644 --- a/Mage.Sets/src/mage/cards/d/DivinerSpirit.java +++ b/Mage.Sets/src/mage/cards/d/DivinerSpirit.java @@ -64,8 +64,8 @@ class DivinerSpiritEffect extends OneShotEffect { if (sourceController != null && damagedPlayer != null) { int amount = (Integer) getValue("damage"); if (amount > 0) { - sourceController.drawCards(amount, game); - damagedPlayer.drawCards(amount, game); + sourceController.drawCards(amount, source.getSourceId(), game); + damagedPlayer.drawCards(amount, source.getSourceId(), game); return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DivinersLockbox.java b/Mage.Sets/src/mage/cards/d/DivinersLockbox.java index 488626d2c4e..ce8c46dbd8e 100644 --- a/Mage.Sets/src/mage/cards/d/DivinersLockbox.java +++ b/Mage.Sets/src/mage/cards/d/DivinersLockbox.java @@ -84,7 +84,7 @@ class DivinersLockboxEffect extends OneShotEffect { player.revealCards(source, new CardsImpl(card), game); if (choice.getChoice().equals(card.getName())) { sacEffect.apply(game, source); - player.drawCards(3, game); + player.drawCards(3, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/d/DoomForetold.java b/Mage.Sets/src/mage/cards/d/DoomForetold.java index 2a997df0c61..97b9126f8e8 100644 --- a/Mage.Sets/src/mage/cards/d/DoomForetold.java +++ b/Mage.Sets/src/mage/cards/d/DoomForetold.java @@ -96,7 +96,7 @@ class DoomForetoldEffect extends OneShotEffect { } player.discard(1, false, source, game); player.loseLife(2, game, false); - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); controller.gainLife(2, game, source); effect1.apply(game, source); effect2.apply(game, source); diff --git a/Mage.Sets/src/mage/cards/d/DrasticRevelation.java b/Mage.Sets/src/mage/cards/d/DrasticRevelation.java index faec9cf5da6..d6391c7de8e 100644 --- a/Mage.Sets/src/mage/cards/d/DrasticRevelation.java +++ b/Mage.Sets/src/mage/cards/d/DrasticRevelation.java @@ -51,7 +51,7 @@ class DrasticRevelationEffect extends OneShotEffect { Player you = game.getPlayer(source.getControllerId()); if (you != null) { you.discard(you.getHand().size(), false, source, game); - you.drawCards(7, game); + you.drawCards(7, source.getSourceId(), game); Cards hand = you.getHand(); for (int i = 0; i < 3; i++) { Card card = hand.getRandom(game); diff --git a/Mage.Sets/src/mage/cards/d/DreamCache.java b/Mage.Sets/src/mage/cards/d/DreamCache.java index cebb4bd18c3..f971d3826f8 100644 --- a/Mage.Sets/src/mage/cards/d/DreamCache.java +++ b/Mage.Sets/src/mage/cards/d/DreamCache.java @@ -58,7 +58,7 @@ class DreamCacheEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(3, game); + controller.drawCards(3, source.getSourceId(), game); boolean putOnTop = controller.chooseUse(Outcome.Neutral, "Put cards on top?", source, game); TargetCardInHand target = new TargetCardInHand(2, 2, new FilterCard()); controller.chooseTarget(Outcome.Detriment, target, source, game); diff --git a/Mage.Sets/src/mage/cards/d/DreamFracture.java b/Mage.Sets/src/mage/cards/d/DreamFracture.java index d5aaa50294d..2148a395a31 100644 --- a/Mage.Sets/src/mage/cards/d/DreamFracture.java +++ b/Mage.Sets/src/mage/cards/d/DreamFracture.java @@ -70,7 +70,7 @@ class DreamFractureEffect extends OneShotEffect { countered = true; } if (controller != null) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return countered; } diff --git a/Mage.Sets/src/mage/cards/d/DreamSalvage.java b/Mage.Sets/src/mage/cards/d/DreamSalvage.java index a62f2ea0c59..397ef520cba 100644 --- a/Mage.Sets/src/mage/cards/d/DreamSalvage.java +++ b/Mage.Sets/src/mage/cards/d/DreamSalvage.java @@ -3,7 +3,6 @@ package mage.cards.d; import java.util.HashMap; import java.util.Map; -import java.util.Map.Entry; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; @@ -97,7 +96,7 @@ class DreamSalvageEffect extends OneShotEffect { && controller != null && watcher != null && watcher.getAmountCardsDiscarded(targetOpponent.getId()) > 0) { - controller.drawCards(watcher.getAmountCardsDiscarded(targetOpponent.getId()), game); + controller.drawCards(watcher.getAmountCardsDiscarded(targetOpponent.getId()), source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/e/Excavation.java b/Mage.Sets/src/mage/cards/e/Excavation.java index 5bf86b2e018..4f140eaa1f1 100644 --- a/Mage.Sets/src/mage/cards/e/Excavation.java +++ b/Mage.Sets/src/mage/cards/e/Excavation.java @@ -67,7 +67,7 @@ class ExcavationEffect extends OneShotEffect { if (source instanceof ActivatedAbilityImpl) { Player activator = game.getPlayer(((ActivatedAbilityImpl) source).getActivatorId()); if (activator != null) { - activator.drawCards(1, game); + activator.drawCards(1, source.getSourceId(), game); return true; } diff --git a/Mage.Sets/src/mage/cards/e/ExpansionExplosion.java b/Mage.Sets/src/mage/cards/e/ExpansionExplosion.java index 0b2039c0944..2ad262d7285 100644 --- a/Mage.Sets/src/mage/cards/e/ExpansionExplosion.java +++ b/Mage.Sets/src/mage/cards/e/ExpansionExplosion.java @@ -85,7 +85,7 @@ class ExplosionEffect extends OneShotEffect { effect.apply(game, source); Player player = game.getPlayer(source.getTargets().get(1).getFirstTarget()); if (player != null) { - player.drawCards(xValue, game); + player.drawCards(xValue, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/f/FaadiyahSeer.java b/Mage.Sets/src/mage/cards/f/FaadiyahSeer.java index 3b917169e55..d85c5ef6a5a 100644 --- a/Mage.Sets/src/mage/cards/f/FaadiyahSeer.java +++ b/Mage.Sets/src/mage/cards/f/FaadiyahSeer.java @@ -71,7 +71,7 @@ class FaadiyahSeerEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Card card = controller.getLibrary().getFromTop(game); - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); controller.revealCards("Fa'adiyah Seer", new CardsImpl(card), game); if (!filter.match(card, game)) { controller.discard(card, source, game); diff --git a/Mage.Sets/src/mage/cards/f/FatalLore.java b/Mage.Sets/src/mage/cards/f/FatalLore.java index 9978b96de54..24d4f8dbcb9 100644 --- a/Mage.Sets/src/mage/cards/f/FatalLore.java +++ b/Mage.Sets/src/mage/cards/f/FatalLore.java @@ -67,7 +67,7 @@ class FatalLoreEffect extends OneShotEffect { if (controller != null && chosenOpponent != null) { if (chosenOpponent.chooseUse(Outcome.Neutral, "If you choose Yes, the controller draws three cards. If no, the controller gets to destroy up to two target creatures that you control and you get to draw up to 3 cards. Those creatures can't be regenerated.", source, game)) { - controller.drawCards(3, game); + controller.drawCards(3, source.getSourceId(), game); } else { FilterCreaturePermanent filter = new FilterCreaturePermanent("chosen opponent's creature"); filter.add(new ControllerIdPredicate(chosenOpponent.getId())); diff --git a/Mage.Sets/src/mage/cards/f/Fecundity.java b/Mage.Sets/src/mage/cards/f/Fecundity.java index 2c87820a40d..d25ca1a6db1 100644 --- a/Mage.Sets/src/mage/cards/f/Fecundity.java +++ b/Mage.Sets/src/mage/cards/f/Fecundity.java @@ -60,7 +60,7 @@ class FecundityEffect extends OneShotEffect { Player controller = game.getPlayer(permanent.getControllerId()); if (controller != null) { if (controller.chooseUse(outcome, "Draw a card?", source, game)) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/f/FeveredVisions.java b/Mage.Sets/src/mage/cards/f/FeveredVisions.java index f14b2a5262d..9b100ce1fca 100644 --- a/Mage.Sets/src/mage/cards/f/FeveredVisions.java +++ b/Mage.Sets/src/mage/cards/f/FeveredVisions.java @@ -54,7 +54,7 @@ class FeveredVisionsEffect extends OneShotEffect { UUID activePlayerId = game.getActivePlayerId(); Player player = game.getPlayer(activePlayerId); if (controller != null && player != null) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); Set opponents = game.getOpponents(source.getControllerId()); if (opponents.contains(player.getId()) && player.getHand().size() > 3) { player.damage(2, source.getSourceId(), game); diff --git a/Mage.Sets/src/mage/cards/f/FieryGambit.java b/Mage.Sets/src/mage/cards/f/FieryGambit.java index 36177cf86d1..e0e22ba8fef 100644 --- a/Mage.Sets/src/mage/cards/f/FieryGambit.java +++ b/Mage.Sets/src/mage/cards/f/FieryGambit.java @@ -81,7 +81,7 @@ class FieryGambitEffect extends OneShotEffect { new DamagePlayersEffect(6, TargetController.OPPONENT).apply(game, source); } if (flipsWon > 2) { - controller.drawCards(9, game); + controller.drawCards(9, source.getSourceId(), game); new UntapAllLandsControllerEffect().apply(game, source); } } else { diff --git a/Mage.Sets/src/mage/cards/f/FiligreeFracture.java b/Mage.Sets/src/mage/cards/f/FiligreeFracture.java index 5a9e5b1f521..efcf412747f 100644 --- a/Mage.Sets/src/mage/cards/f/FiligreeFracture.java +++ b/Mage.Sets/src/mage/cards/f/FiligreeFracture.java @@ -63,7 +63,7 @@ class FiligreeFractureEffect extends OneShotEffect { permanent.destroy(source.getSourceId(), game, true); game.applyEffects(); if (permanent.getColor(game).isBlack() || permanent.getColor(game).isBlue()) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/f/FinaleOfRevelation.java b/Mage.Sets/src/mage/cards/f/FinaleOfRevelation.java index afaf5aee130..0c09ca48ada 100644 --- a/Mage.Sets/src/mage/cards/f/FinaleOfRevelation.java +++ b/Mage.Sets/src/mage/cards/f/FinaleOfRevelation.java @@ -66,11 +66,11 @@ class FinaleOfRevelationEffect extends OneShotEffect { int xValue = source.getManaCostsToPay().getX(); if (xValue < 10) { - player.drawCards(xValue, game); + player.drawCards(xValue, source.getSourceId(), game); } else { player.putCardsOnTopOfLibrary(player.getGraveyard(), game, source, false); player.shuffleLibrary(source, game); - player.drawCards(xValue, game); + player.drawCards(xValue, source.getSourceId(), game); new UntapLandsEffect(5).apply(game, source); game.addEffect(new MaximumHandSizeControllerEffect( Integer.MAX_VALUE, Duration.EndOfGame, diff --git a/Mage.Sets/src/mage/cards/f/FireProphecy.java b/Mage.Sets/src/mage/cards/f/FireProphecy.java index 61ab33e688b..04c7d2c972d 100644 --- a/Mage.Sets/src/mage/cards/f/FireProphecy.java +++ b/Mage.Sets/src/mage/cards/f/FireProphecy.java @@ -74,7 +74,7 @@ class FireProphecyEffect extends OneShotEffect { return false; } player.getLibrary().putOnBottom(card, game); - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); return true; } } diff --git a/Mage.Sets/src/mage/cards/f/Flux.java b/Mage.Sets/src/mage/cards/f/Flux.java index 8c981be444a..21be11d74db 100644 --- a/Mage.Sets/src/mage/cards/f/Flux.java +++ b/Mage.Sets/src/mage/cards/f/Flux.java @@ -61,7 +61,7 @@ class FluxEffect extends OneShotEffect { if (player != null) { int numToDiscard = player.getAmount(0, player.getHand().size(), "Discard how many cards?", game); player.discard(numToDiscard, false, source, game); - player.drawCards(numToDiscard, game); + player.drawCards(numToDiscard, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/f/Foreshadow.java b/Mage.Sets/src/mage/cards/f/Foreshadow.java index 01fabc683ef..bfa869d0659 100644 --- a/Mage.Sets/src/mage/cards/f/Foreshadow.java +++ b/Mage.Sets/src/mage/cards/f/Foreshadow.java @@ -73,7 +73,7 @@ class ForeshadowEffect extends OneShotEffect { if (card != null) { controller.moveCards(card, Zone.GRAVEYARD, source, game); if (CardUtil.haveSameNames(card.getName(), cardName)) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/f/Forget.java b/Mage.Sets/src/mage/cards/f/Forget.java index eb1030c7da0..43b8b685ea5 100644 --- a/Mage.Sets/src/mage/cards/f/Forget.java +++ b/Mage.Sets/src/mage/cards/f/Forget.java @@ -57,7 +57,7 @@ class ForgetEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(source.getFirstTarget()); if (targetPlayer != null) { - targetPlayer.drawCards(targetPlayer.discard(2, false, source, game).size(), game); + targetPlayer.drawCards(targetPlayer.discard(2, false, source, game).size(), source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/f/ForgottenCreation.java b/Mage.Sets/src/mage/cards/f/ForgottenCreation.java index 8fb1b4587df..fd93164daf9 100644 --- a/Mage.Sets/src/mage/cards/f/ForgottenCreation.java +++ b/Mage.Sets/src/mage/cards/f/ForgottenCreation.java @@ -67,7 +67,7 @@ class ForgottenCreationEffect extends OneShotEffect { if (controller != null) { int cardsInHand = controller.getHand().size(); controller.discard(cardsInHand, false, source, game); - controller.drawCards(cardsInHand, game); + controller.drawCards(cardsInHand, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/f/FruitOfTheFirstTree.java b/Mage.Sets/src/mage/cards/f/FruitOfTheFirstTree.java index b7cd53ad794..6a9c0c6af87 100644 --- a/Mage.Sets/src/mage/cards/f/FruitOfTheFirstTree.java +++ b/Mage.Sets/src/mage/cards/f/FruitOfTheFirstTree.java @@ -71,7 +71,7 @@ class FruitOfTheFirstTreeEffect extends OneShotEffect { Permanent creature = (Permanent) getValue("attachedTo"); if (controller != null && creature != null) { controller.gainLife(creature.getToughness().getValue(), game, source); - controller.drawCards(creature.getToughness().getValue(), game); + controller.drawCards(creature.getToughness().getValue(), source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/g/GarrukPrimalHunter.java b/Mage.Sets/src/mage/cards/g/GarrukPrimalHunter.java index 680b42dc5cd..872225567b6 100644 --- a/Mage.Sets/src/mage/cards/g/GarrukPrimalHunter.java +++ b/Mage.Sets/src/mage/cards/g/GarrukPrimalHunter.java @@ -80,7 +80,7 @@ class GarrukPrimalHunterEffect extends OneShotEffect { amount = p.getPower().getValue(); } } - player.drawCards(amount, game); + player.drawCards(amount, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/g/GhastlyDiscovery.java b/Mage.Sets/src/mage/cards/g/GhastlyDiscovery.java index 058c4b91680..c831e3c0e30 100644 --- a/Mage.Sets/src/mage/cards/g/GhastlyDiscovery.java +++ b/Mage.Sets/src/mage/cards/g/GhastlyDiscovery.java @@ -58,7 +58,7 @@ class GhastlyDiscoveryEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(2, game); + controller.drawCards(2, source.getSourceId(), game); controller.discard(1, false, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/g/GiveTake.java b/Mage.Sets/src/mage/cards/g/GiveTake.java index 0e3832a49ad..d27da367c50 100644 --- a/Mage.Sets/src/mage/cards/g/GiveTake.java +++ b/Mage.Sets/src/mage/cards/g/GiveTake.java @@ -72,7 +72,7 @@ class TakeEffect extends OneShotEffect { creature.removeCounters(CounterType.P1P1.getName(), numberCounters, game); Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(numberCounters, game); + controller.drawCards(numberCounters, source.getSourceId(), game); } else { throw new UnsupportedOperationException("Controller missing"); } diff --git a/Mage.Sets/src/mage/cards/g/GlintEyeNephilim.java b/Mage.Sets/src/mage/cards/g/GlintEyeNephilim.java index d9eb7c728aa..f20c884b5d1 100644 --- a/Mage.Sets/src/mage/cards/g/GlintEyeNephilim.java +++ b/Mage.Sets/src/mage/cards/g/GlintEyeNephilim.java @@ -74,7 +74,7 @@ class GlintEyeNephilimEffect extends OneShotEffect { if (amount > 0) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(amount, game); + controller.drawCards(amount, source.getSourceId(), game); return true; } } diff --git a/Mage.Sets/src/mage/cards/g/GoblinArtisans.java b/Mage.Sets/src/mage/cards/g/GoblinArtisans.java index 876e1ee6dc8..1e95ff9b777 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinArtisans.java +++ b/Mage.Sets/src/mage/cards/g/GoblinArtisans.java @@ -79,7 +79,7 @@ class GoblinArtisansEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { if (controller.flipCoin(source, game, true)) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } else { List artifacts = game.getBattlefield().getActivePermanents(new FilterControlledArtifactPermanent(), source.getControllerId(), game); if (artifacts.isEmpty()) {//Don't even bother if there is no artifact to 'counter'/sacrifice diff --git a/Mage.Sets/src/mage/cards/g/GodEternalBontu.java b/Mage.Sets/src/mage/cards/g/GodEternalBontu.java index ab116887243..b52d00e9b78 100644 --- a/Mage.Sets/src/mage/cards/g/GodEternalBontu.java +++ b/Mage.Sets/src/mage/cards/g/GodEternalBontu.java @@ -96,6 +96,6 @@ class GodEternalBontuEffect extends OneShotEffect { counter++; } } - return player.drawCards(counter, game) > 0; + return player.drawCards(counter, source.getSourceId(), game) > 0; } } diff --git a/Mage.Sets/src/mage/cards/g/GrandMoffTarkin.java b/Mage.Sets/src/mage/cards/g/GrandMoffTarkin.java index 3299f166c3b..a14a1d58dd4 100644 --- a/Mage.Sets/src/mage/cards/g/GrandMoffTarkin.java +++ b/Mage.Sets/src/mage/cards/g/GrandMoffTarkin.java @@ -137,7 +137,7 @@ class GrandMoffTarkinEffect extends OneShotEffect { game.informPlayers(player.getLogName() + " pays 2 life to prevent " + targetCreature.getName() + " being destroyed"); Player sourceController = game.getPlayer(source.getControllerId()); if (sourceController != null) { - sourceController.drawCards(1, game); + sourceController.drawCards(1, source.getSourceId(), game); } return true; diff --git a/Mage.Sets/src/mage/cards/g/Gravestorm.java b/Mage.Sets/src/mage/cards/g/Gravestorm.java index 7e9074117f9..3dead51265b 100644 --- a/Mage.Sets/src/mage/cards/g/Gravestorm.java +++ b/Mage.Sets/src/mage/cards/g/Gravestorm.java @@ -79,7 +79,7 @@ class GravestormEffect extends OneShotEffect { if (!opponentExilesACard) { if (you.chooseUse(Outcome.DrawCard, "Draw a card?", source, game)) { - you.drawCards(1, game); + you.drawCards(1, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/g/GrevenPredatorCaptain.java b/Mage.Sets/src/mage/cards/g/GrevenPredatorCaptain.java index cdf3130f8d9..78b90478741 100644 --- a/Mage.Sets/src/mage/cards/g/GrevenPredatorCaptain.java +++ b/Mage.Sets/src/mage/cards/g/GrevenPredatorCaptain.java @@ -124,7 +124,7 @@ class GrevenPredatorCaptainEffect extends OneShotEffect { if (!permanent.sacrifice(source.getSourceId(), game)) { return false; } - player.drawCards(power, game); + player.drawCards(power, source.getSourceId(), game); player.loseLife(toughness, game, false); return true; } diff --git a/Mage.Sets/src/mage/cards/g/GrothamaAllDevouring.java b/Mage.Sets/src/mage/cards/g/GrothamaAllDevouring.java index c576139f725..0d56901a0ab 100644 --- a/Mage.Sets/src/mage/cards/g/GrothamaAllDevouring.java +++ b/Mage.Sets/src/mage/cards/g/GrothamaAllDevouring.java @@ -158,7 +158,7 @@ class GrothamaAllDevouringDrawCardsEffect extends OneShotEffect { if (player != null) { int toDraw = damageMap.getOrDefault(player.getId(), 0); if (toDraw > 0) { - player.drawCards(toDraw, game); + player.drawCards(toDraw, source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/g/GuardianProject.java b/Mage.Sets/src/mage/cards/g/GuardianProject.java index dd4dcd85a1e..d4b791f4fd1 100644 --- a/Mage.Sets/src/mage/cards/g/GuardianProject.java +++ b/Mage.Sets/src/mage/cards/g/GuardianProject.java @@ -21,7 +21,6 @@ import mage.filter.predicate.permanent.TokenPredicate; import mage.game.Game; import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -145,7 +144,7 @@ class GuardianProjectEffect extends OneShotEffect { if (GuardianProjectTriggeredAbility.checkCondition( mor.getPermanentOrLKIBattlefield(game), source.getControllerId(), game) ) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/g/GuildSummit.java b/Mage.Sets/src/mage/cards/g/GuildSummit.java index 748fa134a14..1558862ef07 100644 --- a/Mage.Sets/src/mage/cards/g/GuildSummit.java +++ b/Mage.Sets/src/mage/cards/g/GuildSummit.java @@ -90,7 +90,7 @@ class GuildSummitEffect extends OneShotEffect { } } if (tappedAmount > 0) { - you.drawCards(tappedAmount, game); + you.drawCards(tappedAmount, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/g/GwafaHazidProfiteer.java b/Mage.Sets/src/mage/cards/g/GwafaHazidProfiteer.java index 65c37123760..55f4fe61df0 100644 --- a/Mage.Sets/src/mage/cards/g/GwafaHazidProfiteer.java +++ b/Mage.Sets/src/mage/cards/g/GwafaHazidProfiteer.java @@ -79,7 +79,7 @@ class GwafaHazidProfiteerEffect1 extends OneShotEffect { Player controller = game.getPlayer(targetCreature.getControllerId()); targetCreature.addCounters(CounterType.BRIBERY.createInstance(), source, game); if (controller != null) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/g/GyrudaDoomOfDepths.java b/Mage.Sets/src/mage/cards/g/GyrudaDoomOfDepths.java index 670f1419c2b..8f93745ee1b 100644 --- a/Mage.Sets/src/mage/cards/g/GyrudaDoomOfDepths.java +++ b/Mage.Sets/src/mage/cards/g/GyrudaDoomOfDepths.java @@ -61,7 +61,7 @@ enum OboshThePreypiercerCompanionCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { return deck .stream() .filter(card -> !card.isLand()) diff --git a/Mage.Sets/src/mage/cards/h/HappilyEverAfter.java b/Mage.Sets/src/mage/cards/h/HappilyEverAfter.java index c1f1b476a15..d478d436bc4 100644 --- a/Mage.Sets/src/mage/cards/h/HappilyEverAfter.java +++ b/Mage.Sets/src/mage/cards/h/HappilyEverAfter.java @@ -80,7 +80,7 @@ class HappilyEverAfterEffect extends OneShotEffect { .filter(Objects::nonNull) .forEachOrdered(player -> { player.gainLife(5, game, source); - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); }); return true; } diff --git a/Mage.Sets/src/mage/cards/h/HarborGuardian.java b/Mage.Sets/src/mage/cards/h/HarborGuardian.java index 9f6834dffc0..6e0553058a7 100644 --- a/Mage.Sets/src/mage/cards/h/HarborGuardian.java +++ b/Mage.Sets/src/mage/cards/h/HarborGuardian.java @@ -67,7 +67,7 @@ class HarborGuardianEffect extends OneShotEffect { Player defender = game.getPlayer(defenderId); if (defender != null) { if (defender.chooseUse(outcome, "Draw a card?", source, game)) { - defender.drawCards(1, game); + defender.drawCards(1, source.getSourceId(), game); } } return false; diff --git a/Mage.Sets/src/mage/cards/h/HeartwarmingRedemption.java b/Mage.Sets/src/mage/cards/h/HeartwarmingRedemption.java index 80dd636e959..11447206c64 100644 --- a/Mage.Sets/src/mage/cards/h/HeartwarmingRedemption.java +++ b/Mage.Sets/src/mage/cards/h/HeartwarmingRedemption.java @@ -57,7 +57,7 @@ class HeartwarmingRedemptionEffect extends OneShotEffect { return false; } int discarded = player.discard(player.getHand().size(), false, source, game).size(); - player.drawCards(discarded + 1, game); + player.drawCards(discarded + 1, source.getSourceId(), game); player.gainLife(player.getHand().size(), game, source); return true; } diff --git a/Mage.Sets/src/mage/cards/h/HeartwoodStoryteller.java b/Mage.Sets/src/mage/cards/h/HeartwoodStoryteller.java index a4238dec7c8..090d335f580 100644 --- a/Mage.Sets/src/mage/cards/h/HeartwoodStoryteller.java +++ b/Mage.Sets/src/mage/cards/h/HeartwoodStoryteller.java @@ -106,7 +106,7 @@ class HeartwoodStorytellerEffect extends OneShotEffect { Player player = game.getPlayer(playerId); if (player != null) { if (player.chooseUse(outcome, "Draw a card?", source, game)) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/h/HeedTheMists.java b/Mage.Sets/src/mage/cards/h/HeedTheMists.java index a2be2063be6..105251cecb2 100644 --- a/Mage.Sets/src/mage/cards/h/HeedTheMists.java +++ b/Mage.Sets/src/mage/cards/h/HeedTheMists.java @@ -57,7 +57,7 @@ public final class HeedTheMists extends CardImpl { if (card != null) { int cmc = card.getConvertedManaCost(); controller.moveCards(card, Zone.GRAVEYARD, source, game); - controller.drawCards(cmc, game); + controller.drawCards(cmc, source.getSourceId(), game); } } return result; diff --git a/Mage.Sets/src/mage/cards/h/HoardersGreed.java b/Mage.Sets/src/mage/cards/h/HoardersGreed.java index 580f83182a3..0c14b533c2e 100644 --- a/Mage.Sets/src/mage/cards/h/HoardersGreed.java +++ b/Mage.Sets/src/mage/cards/h/HoardersGreed.java @@ -58,7 +58,7 @@ class HoardersGreedEffect extends OneShotEffect { if (controller != null) { do { controller.loseLife(2, game, false); - controller.drawCards(2, game); + controller.drawCards(2, source.getSourceId(), game); } while (controller.canRespond() && ClashEffect.getInstance().apply(game, source)); return true; } diff --git a/Mage.Sets/src/mage/cards/h/HumbleDefector.java b/Mage.Sets/src/mage/cards/h/HumbleDefector.java index 7ea21d06414..89488a79660 100644 --- a/Mage.Sets/src/mage/cards/h/HumbleDefector.java +++ b/Mage.Sets/src/mage/cards/h/HumbleDefector.java @@ -69,7 +69,7 @@ class HumbleDefectorEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(2, game); + controller.drawCards(2, source.getSourceId(), game); } Permanent humbleDefector = (Permanent) source.getSourceObjectIfItStillExists(game); Player targetOpponent = game.getPlayer(getTargetPointer().getFirst(game, source)); diff --git a/Mage.Sets/src/mage/cards/h/HuntersProwess.java b/Mage.Sets/src/mage/cards/h/HuntersProwess.java index 68f7e96a0e7..8fcbe40d413 100644 --- a/Mage.Sets/src/mage/cards/h/HuntersProwess.java +++ b/Mage.Sets/src/mage/cards/h/HuntersProwess.java @@ -73,7 +73,7 @@ class HuntersProwessDrawEffect extends OneShotEffect { if (controller != null) { int damage = (Integer) this.getValue("damage"); if (damage > 0) { - controller.drawCards(damage, game); + controller.drawCards(damage, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/h/HydroidKrasis.java b/Mage.Sets/src/mage/cards/h/HydroidKrasis.java index 85012dac512..41e5cc9507d 100644 --- a/Mage.Sets/src/mage/cards/h/HydroidKrasis.java +++ b/Mage.Sets/src/mage/cards/h/HydroidKrasis.java @@ -86,7 +86,7 @@ class HydroidKrasisEffect extends OneShotEffect { return false; } int halfCost = Math.floorDiv(((SpellAbility) obj).getManaCostsToPay().getX(), 2); - player.drawCards(halfCost, game); + player.drawCards(halfCost, source.getSourceId(), game); player.gainLife(halfCost, game, source); return true; } diff --git a/Mage.Sets/src/mage/cards/i/IllusoryAmbusher.java b/Mage.Sets/src/mage/cards/i/IllusoryAmbusher.java index f53dc194725..1b6e2b315af 100644 --- a/Mage.Sets/src/mage/cards/i/IllusoryAmbusher.java +++ b/Mage.Sets/src/mage/cards/i/IllusoryAmbusher.java @@ -67,7 +67,7 @@ class IllusoryAmbusherDealtDamageEffect extends OneShotEffect { if (player != null) { int amount = (Integer) getValue("damage"); if (amount > 0) { - player.drawCards(amount, game); + player.drawCards(amount, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/i/ImpulsiveWager.java b/Mage.Sets/src/mage/cards/i/ImpulsiveWager.java index fbb277555a8..7c2cf13d446 100644 --- a/Mage.Sets/src/mage/cards/i/ImpulsiveWager.java +++ b/Mage.Sets/src/mage/cards/i/ImpulsiveWager.java @@ -68,7 +68,7 @@ class ImpulsiveWagerEffect extends OneShotEffect { effect.setTargetPointer(getTargetPointer()); effect.apply(game, source); } else { - player.drawCards(2, game); + player.drawCards(2, source.getSourceId(), game); } } diff --git a/Mage.Sets/src/mage/cards/i/IncendiaryCommand.java b/Mage.Sets/src/mage/cards/i/IncendiaryCommand.java index 6fc1a4aaa82..d5f4a165a05 100644 --- a/Mage.Sets/src/mage/cards/i/IncendiaryCommand.java +++ b/Mage.Sets/src/mage/cards/i/IncendiaryCommand.java @@ -95,7 +95,7 @@ class IncendiaryCommandDrawEffect extends OneShotEffect { for (Map.Entry toDrawByPlayer : cardsToDraw.entrySet()) { Player player = game.getPlayer(toDrawByPlayer.getKey()); if (player != null) { - player.drawCards(toDrawByPlayer.getValue(), game); + player.drawCards(toDrawByPlayer.getValue(), source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/i/IndathaTriome.java b/Mage.Sets/src/mage/cards/i/IndathaTriome.java index 68813477ced..22d2d1572fe 100644 --- a/Mage.Sets/src/mage/cards/i/IndathaTriome.java +++ b/Mage.Sets/src/mage/cards/i/IndathaTriome.java @@ -22,8 +22,8 @@ public final class IndathaTriome extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); this.subtype.add(SubType.PLAINS); - this.subtype.add(SubType.FOREST); this.subtype.add(SubType.SWAMP); + this.subtype.add(SubType.FOREST); // ({T}: Add {W}, {B}, or {G}.) this.addAbility(new WhiteManaAbility()); diff --git a/Mage.Sets/src/mage/cards/i/InducedAmnesia.java b/Mage.Sets/src/mage/cards/i/InducedAmnesia.java index 9c4588818d6..dbdac63fb78 100644 --- a/Mage.Sets/src/mage/cards/i/InducedAmnesia.java +++ b/Mage.Sets/src/mage/cards/i/InducedAmnesia.java @@ -77,7 +77,7 @@ class InducedAmnesiaExileEffect extends OneShotEffect { } game.informPlayers(sourcePermanent.getLogName() + ": " + targetPlayer.getLogName() + " exiles their hand face down (" + numberOfCards + "card" + (numberOfCards > 1 ? "s" : "") + ')'); game.applyEffects(); - targetPlayer.drawCards(numberOfCards, game); + targetPlayer.drawCards(numberOfCards, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/i/IndulgentTormentor.java b/Mage.Sets/src/mage/cards/i/IndulgentTormentor.java index c2dbee86167..824bb44abe9 100644 --- a/Mage.Sets/src/mage/cards/i/IndulgentTormentor.java +++ b/Mage.Sets/src/mage/cards/i/IndulgentTormentor.java @@ -88,7 +88,7 @@ class IndulgentTormentorEffect extends OneShotEffect { return true; } } - game.getPlayer(source.getControllerId()).drawCards(1, game); + game.getPlayer(source.getControllerId()).drawCards(1, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/i/InfernalOffering.java b/Mage.Sets/src/mage/cards/i/InfernalOffering.java index 11be4c2397e..3a829371a8d 100644 --- a/Mage.Sets/src/mage/cards/i/InfernalOffering.java +++ b/Mage.Sets/src/mage/cards/i/InfernalOffering.java @@ -99,7 +99,7 @@ class InfernalOfferingSacrificeEffect extends OneShotEffect { for (UUID playerId : toDraw) { Player playerToDraw = game.getPlayer(playerId); if (playerToDraw != null) { - playerToDraw.drawCards(2, game); + playerToDraw.drawCards(2, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/i/InspiredUltimatum.java b/Mage.Sets/src/mage/cards/i/InspiredUltimatum.java index 53374c1c9bd..25fd5eef7cc 100644 --- a/Mage.Sets/src/mage/cards/i/InspiredUltimatum.java +++ b/Mage.Sets/src/mage/cards/i/InspiredUltimatum.java @@ -65,7 +65,7 @@ class InspiredUltimatumEffect extends OneShotEffect { ); player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(5, game); + player.drawCards(5, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/i/IntellectualOffering.java b/Mage.Sets/src/mage/cards/i/IntellectualOffering.java index 1218fe286b4..a97e9376458 100644 --- a/Mage.Sets/src/mage/cards/i/IntellectualOffering.java +++ b/Mage.Sets/src/mage/cards/i/IntellectualOffering.java @@ -64,10 +64,10 @@ class IntellectualOfferingDrawEffect extends OneShotEffect { if (player != null) { Target target = new TargetOpponent(true); target.choose(Outcome.DrawCard, source.getControllerId(), source.getSourceId(), game); - player.drawCards(3, game); + player.drawCards(3, source.getSourceId(), game); Player opponent = game.getPlayer(target.getFirstTarget()); if (opponent != null) { - opponent.drawCards(3, game); + opponent.drawCards(3, source.getSourceId(), game); return true; } } diff --git a/Mage.Sets/src/mage/cards/i/InterpretTheSigns.java b/Mage.Sets/src/mage/cards/i/InterpretTheSigns.java index d1d486f31dd..877c0bd31fc 100644 --- a/Mage.Sets/src/mage/cards/i/InterpretTheSigns.java +++ b/Mage.Sets/src/mage/cards/i/InterpretTheSigns.java @@ -64,7 +64,7 @@ class InterpretTheSignsEffect extends OneShotEffect { Card card = controller.getLibrary().getFromTop(game); if (card != null) { controller.revealCards(sourceCard.getName(), new CardsImpl(card), game); - controller.drawCards(card.getConvertedManaCost(), game); + controller.drawCards(card.getConvertedManaCost(), source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/i/IzzetKeyrune.java b/Mage.Sets/src/mage/cards/i/IzzetKeyrune.java index 992bca57bcb..028df9bfd5c 100644 --- a/Mage.Sets/src/mage/cards/i/IzzetKeyrune.java +++ b/Mage.Sets/src/mage/cards/i/IzzetKeyrune.java @@ -20,7 +20,6 @@ import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.token.TokenImpl; -import mage.game.permanent.token.Token; import mage.players.Player; /** @@ -71,7 +70,7 @@ public final class IzzetKeyrune extends CardImpl { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null && player.chooseUse(Outcome.DrawCard, "Do you wish to draw a card? If you do, discard a card.", source, game)) { - if (player.drawCards(1, game) > 0) { + if (player.drawCards(1, source.getSourceId(), game) > 0) { player.discard(1, false, source, game); } return true; diff --git a/Mage.Sets/src/mage/cards/j/JaceMemoryAdept.java b/Mage.Sets/src/mage/cards/j/JaceMemoryAdept.java index 4694847ea22..ffc521f1a4d 100644 --- a/Mage.Sets/src/mage/cards/j/JaceMemoryAdept.java +++ b/Mage.Sets/src/mage/cards/j/JaceMemoryAdept.java @@ -73,7 +73,7 @@ class JaceMemoryAdeptEffect extends DrawCardTargetEffect { for (UUID target : targetPointer.getTargets(game, source)) { Player player = game.getPlayer(target); if (player != null) { - player.drawCards(amount.calculate(game, source, this), game); + player.drawCards(amount.calculate(game, source, this), source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/j/JaceWielderOfMysteries.java b/Mage.Sets/src/mage/cards/j/JaceWielderOfMysteries.java index e6feb931d17..2332417ac97 100644 --- a/Mage.Sets/src/mage/cards/j/JaceWielderOfMysteries.java +++ b/Mage.Sets/src/mage/cards/j/JaceWielderOfMysteries.java @@ -127,7 +127,7 @@ class JaceWielderOfMysteriesEffect extends OneShotEffect { if (player == null) { return false; } - player.drawCards(7, game); + player.drawCards(7, source.getSourceId(), game); if (!player.getLibrary().hasCards()) { player.won(game); } diff --git a/Mage.Sets/src/mage/cards/j/JacesArchivist.java b/Mage.Sets/src/mage/cards/j/JacesArchivist.java index a6934dd8624..3cb16b5b21e 100644 --- a/Mage.Sets/src/mage/cards/j/JacesArchivist.java +++ b/Mage.Sets/src/mage/cards/j/JacesArchivist.java @@ -77,7 +77,7 @@ class JacesArchivistEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(maxDiscarded, game); + player.drawCards(maxDiscarded, source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/j/JandorsRing.java b/Mage.Sets/src/mage/cards/j/JandorsRing.java index c9022834ae4..c74ce25a504 100644 --- a/Mage.Sets/src/mage/cards/j/JandorsRing.java +++ b/Mage.Sets/src/mage/cards/j/JandorsRing.java @@ -82,7 +82,7 @@ class JandorsRingEffect extends OneShotEffect { if (effect.apply(game, source)) {//Conditional was already checked, card should be in hand, but if for some weird reason it fails, the card won't be drawn, although the cost will already be paid Player controller = game.getPlayer(source.getControllerId()); if(controller != null) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/j/JayaBallard.java b/Mage.Sets/src/mage/cards/j/JayaBallard.java index 7d7e86c13e5..8af23864bfc 100644 --- a/Mage.Sets/src/mage/cards/j/JayaBallard.java +++ b/Mage.Sets/src/mage/cards/j/JayaBallard.java @@ -87,7 +87,7 @@ class JayaBallardDiscardDrawEffect extends OneShotEffect { count++; } } - controller.drawCards(count, game); + controller.drawCards(count, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/j/JeganthaTheWellspring.java b/Mage.Sets/src/mage/cards/j/JeganthaTheWellspring.java index 62fba79d082..4f309bbe837 100644 --- a/Mage.Sets/src/mage/cards/j/JeganthaTheWellspring.java +++ b/Mage.Sets/src/mage/cards/j/JeganthaTheWellspring.java @@ -64,8 +64,8 @@ enum JeganthaTheWellspringCompanionCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { - return deck.stream().allMatch(JeganthaTheWellspringCompanionCondition::checkCard); + public boolean isLegal(Set deck, int startingSize) { + return deck.stream().noneMatch(JeganthaTheWellspringCompanionCondition::checkCard); } private static final boolean checkCard(Card card) { diff --git a/Mage.Sets/src/mage/cards/k/KaheeraTheOrphanguard.java b/Mage.Sets/src/mage/cards/k/KaheeraTheOrphanguard.java index 0fa1715734c..d8762ae5f03 100644 --- a/Mage.Sets/src/mage/cards/k/KaheeraTheOrphanguard.java +++ b/Mage.Sets/src/mage/cards/k/KaheeraTheOrphanguard.java @@ -96,7 +96,7 @@ enum KaheeraTheOrphanguardCompanionCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { return deck.stream() .filter(MageObject::isCreature) .allMatch(KaheeraTheOrphanguardCompanionCondition::checkTypes); diff --git a/Mage.Sets/src/mage/cards/k/KefnetTheMindful.java b/Mage.Sets/src/mage/cards/k/KefnetTheMindful.java index 447a86bc258..bcc6c9a437c 100644 --- a/Mage.Sets/src/mage/cards/k/KefnetTheMindful.java +++ b/Mage.Sets/src/mage/cards/k/KefnetTheMindful.java @@ -115,7 +115,7 @@ class KefnetTheMindfulEffect extends OneShotEffect { filterControlledLand.add(CardType.LAND.getPredicate()); Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); if (controller.chooseUse(Outcome.AIDontUseIt, "Do you want to return a land you control to its owner's hand?", null, "Yes", "No", source, game)) { Effect effect = new ReturnToHandChosenControlledPermanentEffect(filterControlledLand); effect.apply(game, source); diff --git a/Mage.Sets/src/mage/cards/k/KelsienThePlague.java b/Mage.Sets/src/mage/cards/k/KelsienThePlague.java new file mode 100644 index 00000000000..bcb1f8b16cc --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KelsienThePlague.java @@ -0,0 +1,179 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.counter.AddCountersControllerEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +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.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class KelsienThePlague extends CardImpl { + + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creature you don't control"); + + static { + filter.add(TargetController.NOT_YOU.getControllerPredicate()); + } + + public KelsienThePlague(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{W}{B}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ASSASSIN); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // Kelsien, the Plague gets +1/+1 for each experience counter you have. + this.addAbility(new SimpleStaticAbility(new BoostSourceEffect( + KelsienThePlagueCount.instance, KelsienThePlagueCount.instance, + Duration.WhileOnBattlefield, false + ))); + + // {T}: Kelsien deals 1 damage to target creature you don't control. When that creature dies this turn, you get an experience counter. + Ability ability = new SimpleActivatedAbility(new KelsienThePlagueEffect(), new TapSourceCost()); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + private KelsienThePlague(final KelsienThePlague card) { + super(card); + } + + @Override + public KelsienThePlague copy() { + return new KelsienThePlague(this); + } +} + +enum KelsienThePlagueCount implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + int amount = 0; + Player player = game.getPlayer(sourceAbility.getControllerId()); + if (player != null) { + amount = player.getCounters().getCount(CounterType.EXPERIENCE); + } + return amount; + } + + @Override + public KelsienThePlagueCount copy() { + return instance; + } + + @Override + public String toString() { + return "1"; + } + + @Override + public String getMessage() { + return "experience counter you have"; + } +} + +class KelsienThePlagueEffect extends OneShotEffect { + + KelsienThePlagueEffect() { + super(Outcome.Benefit); + staticText = "{this} deals 1 damage to target creature you don't control. " + + "When that creature dies this turn, you get an experience counter."; + } + + private KelsienThePlagueEffect(final KelsienThePlagueEffect effect) { + super(effect); + } + + @Override + public KelsienThePlagueEffect copy() { + return new KelsienThePlagueEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent == null) { + return false; + } + permanent.damage(1, source.getSourceId(), game); + game.addDelayedTriggeredAbility(new KelsienThePlagueDelayedTriggeredAbility(permanent.getId()), source); + return true; + } +} + +class KelsienThePlagueDelayedTriggeredAbility extends DelayedTriggeredAbility { + + private final UUID target; + + KelsienThePlagueDelayedTriggeredAbility(UUID target) { + super(new AddCountersControllerEffect( + CounterType.EXPERIENCE.createInstance(), false + ), Duration.EndOfTurn, true); + this.target = target; + } + + private KelsienThePlagueDelayedTriggeredAbility(KelsienThePlagueDelayedTriggeredAbility 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)) { + return false; + } + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.isDiesEvent()) { + return true; + } + return false; + } + + @Override + public KelsienThePlagueDelayedTriggeredAbility copy() { + return new KelsienThePlagueDelayedTriggeredAbility(this); + } + + @Override + public String getRule() { + return "When that creature dies this turn, you get an experience counter."; + } +} diff --git a/Mage.Sets/src/mage/cards/k/KerugaTheMacrosage.java b/Mage.Sets/src/mage/cards/k/KerugaTheMacrosage.java index 6594ce24a99..a9373bc5b70 100644 --- a/Mage.Sets/src/mage/cards/k/KerugaTheMacrosage.java +++ b/Mage.Sets/src/mage/cards/k/KerugaTheMacrosage.java @@ -66,7 +66,7 @@ enum KerugaCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { return deck.stream().allMatch(card -> card.isLand() || card.getConvertedManaCost() >= 3); } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/k/KhorvathsFury.java b/Mage.Sets/src/mage/cards/k/KhorvathsFury.java index 208080a28d0..6c9471afde9 100644 --- a/Mage.Sets/src/mage/cards/k/KhorvathsFury.java +++ b/Mage.Sets/src/mage/cards/k/KhorvathsFury.java @@ -75,7 +75,7 @@ class KhorvathsFuryEffect extends OneShotEffect { } for (Player player : choice.getFriends()) { if (player != null) { - player.drawCards(cardsToDraw.get(player.getId()) + 1, game); + player.drawCards(cardsToDraw.get(player.getId()) + 1, source.getSourceId(), game); } } for (Player player : choice.getFoes()) { diff --git a/Mage.Sets/src/mage/cards/k/KnollspineDragon.java b/Mage.Sets/src/mage/cards/k/KnollspineDragon.java index 10124eefd8d..6b85accd453 100644 --- a/Mage.Sets/src/mage/cards/k/KnollspineDragon.java +++ b/Mage.Sets/src/mage/cards/k/KnollspineDragon.java @@ -71,7 +71,7 @@ class KnollspineDragonEffect extends OneShotEffect { AmountOfDamageAPlayerReceivedThisTurnWatcher watcher = game.getState().getWatcher(AmountOfDamageAPlayerReceivedThisTurnWatcher.class); if (watcher != null) { int drawAmount = watcher.getAmountOfDamageReceivedThisTurn(targetOpponent.getId()); - controller.drawCards(drawAmount, game); + controller.drawCards(drawAmount, source.getSourceId(), game); game.informPlayers(controller.getLogName() + "draws " + drawAmount + " cards"); return true; } diff --git a/Mage.Sets/src/mage/cards/k/KozilekTheGreatDistortion.java b/Mage.Sets/src/mage/cards/k/KozilekTheGreatDistortion.java index 9f97442b73a..fa1649cf911 100644 --- a/Mage.Sets/src/mage/cards/k/KozilekTheGreatDistortion.java +++ b/Mage.Sets/src/mage/cards/k/KozilekTheGreatDistortion.java @@ -91,7 +91,7 @@ class KozilekDrawEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(7 - controller.getHand().size(), game); + controller.drawCards(7 - controller.getHand().size(), source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/k/KynaiosAndTiroOfMeletis.java b/Mage.Sets/src/mage/cards/k/KynaiosAndTiroOfMeletis.java index 7fe353b16e2..df0d477d0f6 100644 --- a/Mage.Sets/src/mage/cards/k/KynaiosAndTiroOfMeletis.java +++ b/Mage.Sets/src/mage/cards/k/KynaiosAndTiroOfMeletis.java @@ -70,7 +70,7 @@ class KynaiosAndTirosEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); PlayerList playerList = game.getState().getPlayerList().copy(); while (!playerList.get().equals(source.getControllerId()) && controller.canRespond()) { @@ -113,7 +113,7 @@ class KynaiosAndTirosEffect extends OneShotEffect { for (UUID playerId : noLandPlayers) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/l/LaquatussCreativity.java b/Mage.Sets/src/mage/cards/l/LaquatussCreativity.java index b2f75203a9e..ec94e5aef96 100644 --- a/Mage.Sets/src/mage/cards/l/LaquatussCreativity.java +++ b/Mage.Sets/src/mage/cards/l/LaquatussCreativity.java @@ -59,7 +59,7 @@ class LaquatussCreativityEffect extends OneShotEffect { Player player = game.getPlayer(source.getFirstTarget()); if(player != null) { int handCount = player.getHand().count(new FilterCard(), game); - player.drawCards(handCount, game); + player.drawCards(handCount, source.getSourceId(), game); player.discard(handCount, false, source, game); } return false; diff --git a/Mage.Sets/src/mage/cards/l/LastStand.java b/Mage.Sets/src/mage/cards/l/LastStand.java index aca592d6596..1c4ca320256 100644 --- a/Mage.Sets/src/mage/cards/l/LastStand.java +++ b/Mage.Sets/src/mage/cards/l/LastStand.java @@ -101,7 +101,7 @@ class LastStandEffect extends OneShotEffect { // Draw a card for each Island you control, then discard that many cards int islands = game.getBattlefield().count(filterIsland, source.getSourceId(), source.getControllerId(), game); if (islands > 0) { - controller.drawCards(islands, game); + controller.drawCards(islands, source.getSourceId(), game); controller.discard(islands, false, source, game); } diff --git a/Mage.Sets/src/mage/cards/l/LeaveChance.java b/Mage.Sets/src/mage/cards/l/LeaveChance.java index 262a76dc986..4298a545403 100644 --- a/Mage.Sets/src/mage/cards/l/LeaveChance.java +++ b/Mage.Sets/src/mage/cards/l/LeaveChance.java @@ -87,7 +87,7 @@ class ChanceEffect extends OneShotEffect { } } game.applyEffects(); - controller.drawCards(target.getTargets().size(), game); + controller.drawCards(target.getTargets().size(), source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/l/LiarsPendulum.java b/Mage.Sets/src/mage/cards/l/LiarsPendulum.java index bf86998ce4d..195878591b6 100644 --- a/Mage.Sets/src/mage/cards/l/LiarsPendulum.java +++ b/Mage.Sets/src/mage/cards/l/LiarsPendulum.java @@ -102,7 +102,7 @@ class LiarsPendulumEffect extends OneShotEffect { if (controller.chooseUse(outcome, "Reveal your hand?", source, game)) { controller.revealCards("hand of " + controller.getName(), controller.getHand(), game); if (!rightGuess) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/l/Lich.java b/Mage.Sets/src/mage/cards/l/Lich.java index e77d1031f57..6eee63d51aa 100644 --- a/Mage.Sets/src/mage/cards/l/Lich.java +++ b/Mage.Sets/src/mage/cards/l/Lich.java @@ -86,7 +86,7 @@ class LichLifeGainReplacementEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player controller = game.getPlayer(event.getPlayerId()); if (controller != null) { - controller.drawCards(event.getAmount(), game); + controller.drawCards(event.getAmount(), source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/l/LichsMirror.java b/Mage.Sets/src/mage/cards/l/LichsMirror.java index 0ca9064c0f8..3bff7b7d4e7 100644 --- a/Mage.Sets/src/mage/cards/l/LichsMirror.java +++ b/Mage.Sets/src/mage/cards/l/LichsMirror.java @@ -85,7 +85,7 @@ class LichsMirrorEffect extends ReplacementEffectImpl { } player.shuffleLibrary(source, game); - player.drawCards(7, game); + player.drawCards(7, source.getSourceId(), game); player.setLife(20, game, source); } diff --git a/Mage.Sets/src/mage/cards/l/LifebloodHydra.java b/Mage.Sets/src/mage/cards/l/LifebloodHydra.java index 57fb1d7a075..64488b6dadb 100644 --- a/Mage.Sets/src/mage/cards/l/LifebloodHydra.java +++ b/Mage.Sets/src/mage/cards/l/LifebloodHydra.java @@ -76,7 +76,7 @@ class LifebloodHydraEffect extends OneShotEffect { Permanent diedPermanent = (Permanent) getValue("permanentLeftBattlefield"); if (diedPermanent != null) { controller.gainLife(diedPermanent.getPower().getValue(), game, source); - controller.drawCards(diedPermanent.getPower().getValue(), game); + controller.drawCards(diedPermanent.getPower().getValue(), source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/l/LifesLegacy.java b/Mage.Sets/src/mage/cards/l/LifesLegacy.java index cf2f6faaa3e..bb093b9b0e8 100644 --- a/Mage.Sets/src/mage/cards/l/LifesLegacy.java +++ b/Mage.Sets/src/mage/cards/l/LifesLegacy.java @@ -66,7 +66,7 @@ class LifesLegacyEffect extends OneShotEffect { } } if (power > 0) { - controller.drawCards(power, game); + controller.drawCards(power, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/l/LordWindgrace.java b/Mage.Sets/src/mage/cards/l/LordWindgrace.java index b751835dbf1..9e4fcc1a9bb 100644 --- a/Mage.Sets/src/mage/cards/l/LordWindgrace.java +++ b/Mage.Sets/src/mage/cards/l/LordWindgrace.java @@ -103,9 +103,9 @@ class LordWindgraceEffect extends OneShotEffect { } Card card = player.discardOne(false, source, game); if (card == null || !card.isLand()) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } else { - player.drawCards(2, game); + player.drawCards(2, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/l/LostLegacy.java b/Mage.Sets/src/mage/cards/l/LostLegacy.java index a2eec689c1d..a8bd230b498 100644 --- a/Mage.Sets/src/mage/cards/l/LostLegacy.java +++ b/Mage.Sets/src/mage/cards/l/LostLegacy.java @@ -61,7 +61,7 @@ class LostLegacyEffect extends SearchTargetGraveyardHandLibraryForCardNameAndExi boolean result = super.applySearchAndExile(game, source, cardName, targetPointer.getFirst(game, source)); int cardsExiled = cardsInHandBefore - targetPlayer.getHand().count(filter, game); if (cardsExiled > 0) { - targetPlayer.drawCards(cardsExiled, game); + targetPlayer.drawCards(cardsExiled, source.getSourceId(), game); } return result; } diff --git a/Mage.Sets/src/mage/cards/l/LudevicNecroAlchemist.java b/Mage.Sets/src/mage/cards/l/LudevicNecroAlchemist.java index 45991117b8a..4fc4cd12e24 100644 --- a/Mage.Sets/src/mage/cards/l/LudevicNecroAlchemist.java +++ b/Mage.Sets/src/mage/cards/l/LudevicNecroAlchemist.java @@ -103,7 +103,7 @@ class LudevicNecroAlchemistEffect extends OneShotEffect { Player player = game.getPlayer(game.getActivePlayerId()); if (player != null && player.chooseUse(Outcome.DrawCard, "Draw a card?", source, game)) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/l/LumengridAugur.java b/Mage.Sets/src/mage/cards/l/LumengridAugur.java index 8f747c7a32e..3139e17f5d0 100644 --- a/Mage.Sets/src/mage/cards/l/LumengridAugur.java +++ b/Mage.Sets/src/mage/cards/l/LumengridAugur.java @@ -71,7 +71,7 @@ class LumengridAugurEffect extends OneShotEffect { Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (player != null) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); Card discardedCard = player.discardOne(false, source, game); if (discardedCard != null && discardedCard.isArtifact()) { if (sourcePermanent != null) { diff --git a/Mage.Sets/src/mage/cards/l/LurrusOfTheDreamDen.java b/Mage.Sets/src/mage/cards/l/LurrusOfTheDreamDen.java index f3dd806aa3c..8eca5e0f868 100644 --- a/Mage.Sets/src/mage/cards/l/LurrusOfTheDreamDen.java +++ b/Mage.Sets/src/mage/cards/l/LurrusOfTheDreamDen.java @@ -72,7 +72,7 @@ enum LurrusOfTheDreamDenCompanionCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { return deck.stream() .filter(MageObject::isPermanent) .mapToInt(MageObject::getConvertedManaCost) diff --git a/Mage.Sets/src/mage/cards/l/LutriTheSpellchaser.java b/Mage.Sets/src/mage/cards/l/LutriTheSpellchaser.java index d0a33d48bf0..b1d9545da64 100644 --- a/Mage.Sets/src/mage/cards/l/LutriTheSpellchaser.java +++ b/Mage.Sets/src/mage/cards/l/LutriTheSpellchaser.java @@ -83,7 +83,7 @@ enum LutriTheSpellchaserCompanionCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { Map cardMap = new HashMap(); deck.stream() .filter(card -> !card.isLand()) diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheJar.java b/Mage.Sets/src/mage/cards/m/MagusOfTheJar.java index f1c9c8778a1..df052031749 100644 --- a/Mage.Sets/src/mage/cards/m/MagusOfTheJar.java +++ b/Mage.Sets/src/mage/cards/m/MagusOfTheJar.java @@ -83,7 +83,7 @@ class MagusoftheJarEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(7, game); + player.drawCards(7, source.getSourceId(), game); } } //Delayed ability diff --git a/Mage.Sets/src/mage/cards/m/MalignantGrowth.java b/Mage.Sets/src/mage/cards/m/MalignantGrowth.java index 3256638b3b9..3172d1c94e0 100644 --- a/Mage.Sets/src/mage/cards/m/MalignantGrowth.java +++ b/Mage.Sets/src/mage/cards/m/MalignantGrowth.java @@ -80,6 +80,6 @@ class MalignantGrowthEffect extends OneShotEffect { if (counters == 0) { return true; } - return player.damage(player.drawCards(counters, game), source.getSourceId(), game) > 0; + return player.damage(player.drawCards(counters, source.getSourceId(), game), source.getSourceId(), game) > 0; } } diff --git a/Mage.Sets/src/mage/cards/m/ManipulateFate.java b/Mage.Sets/src/mage/cards/m/ManipulateFate.java index 5c342c1cc8a..2883532f69e 100644 --- a/Mage.Sets/src/mage/cards/m/ManipulateFate.java +++ b/Mage.Sets/src/mage/cards/m/ManipulateFate.java @@ -69,7 +69,7 @@ class ManipulateFateEffect extends SearchEffect { } } player.shuffleLibrary(source, game); - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/m/MartialImpetus.java b/Mage.Sets/src/mage/cards/m/MartialImpetus.java new file mode 100644 index 00000000000..fb3359b5be3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MartialImpetus.java @@ -0,0 +1,77 @@ +package mage.cards.m; + +import mage.abilities.Ability; +import mage.abilities.common.AttacksAttachedTriggeredAbility; +import mage.abilities.common.GoadAttachedAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MartialImpetus extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(MartialImpetusPredicate.instance); + } + + public MartialImpetus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets +1/+1 and is goaded. + this.addAbility(new GoadAttachedAbility(new BoostEnchantedEffect(1, 1))); + + // Whenever enchanted creature attacks, each other creature that's attacking one of your opponents gets +1/+1 until end of turn. + this.addAbility(new AttacksAttachedTriggeredAbility( + new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, true).setText( + "each other creature that's attacking one of your opponents gets +1/+1 until end of turn" + ), AttachmentType.AURA, false) + ); + } + + private MartialImpetus(final MartialImpetus card) { + super(card); + } + + @Override + public MartialImpetus copy() { + return new MartialImpetus(this); + } +} + +enum MartialImpetusPredicate implements ObjectSourcePlayerPredicate> { + instance; + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + return input.getObject() != null && input.getObject().isAttacking() && + game.getCombat() + .getDefendingPlayerId(input.getObject().getId(), game) + .equals(game.getControllerId(input.getSourceId())); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/MartyrsCry.java b/Mage.Sets/src/mage/cards/m/MartyrsCry.java index d7f765b3570..01b553475c0 100644 --- a/Mage.Sets/src/mage/cards/m/MartyrsCry.java +++ b/Mage.Sets/src/mage/cards/m/MartyrsCry.java @@ -67,7 +67,7 @@ class MartyrsCryEffect extends OneShotEffect { for (UUID playerId : game.getPlayerList().toList()) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(playerCrtCount.getOrDefault(playerId, 0), game); + player.drawCards(playerCrtCount.getOrDefault(playerId, 0), source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/m/MemoryJar.java b/Mage.Sets/src/mage/cards/m/MemoryJar.java index 8b1c6c052ad..d1709a4b197 100644 --- a/Mage.Sets/src/mage/cards/m/MemoryJar.java +++ b/Mage.Sets/src/mage/cards/m/MemoryJar.java @@ -79,7 +79,7 @@ class MemoryJarEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(7, game); + player.drawCards(7, source.getSourceId(), game); } } //Delayed ability diff --git a/Mage.Sets/src/mage/cards/m/MidnightClock.java b/Mage.Sets/src/mage/cards/m/MidnightClock.java index 5b798709302..97ac36038f1 100644 --- a/Mage.Sets/src/mage/cards/m/MidnightClock.java +++ b/Mage.Sets/src/mage/cards/m/MidnightClock.java @@ -135,7 +135,7 @@ class MidnightClockEffect extends OneShotEffect { cards.addAll(player.getGraveyard()); player.putCardsOnTopOfLibrary(cards, game, source, false); player.shuffleLibrary(source, game); - player.drawCards(7, game); + player.drawCards(7, source.getSourceId(), game); return effect.apply(game, source); } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/Mindmoil.java b/Mage.Sets/src/mage/cards/m/Mindmoil.java index bb0dda60d37..b4ba0dadc1b 100644 --- a/Mage.Sets/src/mage/cards/m/Mindmoil.java +++ b/Mage.Sets/src/mage/cards/m/Mindmoil.java @@ -53,7 +53,7 @@ class MindmoilEffect extends OneShotEffect { if (you != null) { int count = you.getHand().size(); you.putCardsOnBottomOfLibrary(you.getHand(), game, source, true); - you.drawCards(count, game); + you.drawCards(count, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/m/MindsAglow.java b/Mage.Sets/src/mage/cards/m/MindsAglow.java index b5eaadc85b3..7614b133e21 100644 --- a/Mage.Sets/src/mage/cards/m/MindsAglow.java +++ b/Mage.Sets/src/mage/cards/m/MindsAglow.java @@ -70,7 +70,7 @@ class MindsAglowEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(xSum, game); + player.drawCards(xSum, source.getSourceId(), game); } } diff --git a/Mage.Sets/src/mage/cards/m/MindstormCrown.java b/Mage.Sets/src/mage/cards/m/MindstormCrown.java index d07e17dd1ce..533486457d1 100644 --- a/Mage.Sets/src/mage/cards/m/MindstormCrown.java +++ b/Mage.Sets/src/mage/cards/m/MindstormCrown.java @@ -65,7 +65,7 @@ class MindstormCrownEffect extends OneShotEffect { MindstormCrownWatcher watcher = game.getState().getWatcher(MindstormCrownWatcher.class); if (watcher != null && watcher.getCardsInHandCount() == 0) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } else { if (permanent != null) { controller.damage(1, permanent.getId(), game); diff --git a/Mage.Sets/src/mage/cards/m/MinionsMurmurs.java b/Mage.Sets/src/mage/cards/m/MinionsMurmurs.java index 94fb18394a6..ae171e9a0e5 100644 --- a/Mage.Sets/src/mage/cards/m/MinionsMurmurs.java +++ b/Mage.Sets/src/mage/cards/m/MinionsMurmurs.java @@ -56,7 +56,7 @@ public final class MinionsMurmurs extends CardImpl { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { int creaturesControlled = game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, controller.getId(), game); - controller.drawCards(creaturesControlled, game); + controller.drawCards(creaturesControlled, source.getSourceId(), game); controller.loseLife(creaturesControlled, game, false); return true; } diff --git a/Mage.Sets/src/mage/cards/m/Mise.java b/Mage.Sets/src/mage/cards/m/Mise.java index 06074b560f1..221affc8fd5 100644 --- a/Mage.Sets/src/mage/cards/m/Mise.java +++ b/Mage.Sets/src/mage/cards/m/Mise.java @@ -60,7 +60,7 @@ class MiseEffect extends OneShotEffect { if (card != null) { player.revealCards("Mise", cards, game, true); if (card.getName().equals(namedCard)) { - player.drawCards(3, game); + player.drawCards(3, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/m/MoltenPsyche.java b/Mage.Sets/src/mage/cards/m/MoltenPsyche.java index cd0acb81ab6..7d80268bf97 100644 --- a/Mage.Sets/src/mage/cards/m/MoltenPsyche.java +++ b/Mage.Sets/src/mage/cards/m/MoltenPsyche.java @@ -78,7 +78,7 @@ class MoltenPsycheEffect extends OneShotEffect { for (UUID playerId : cardsToDraw.keySet()) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(cardsToDraw.get(playerId), game); + player.drawCards(cardsToDraw.get(playerId), source.getSourceId(), game); } } if (MetalcraftCondition.instance.apply(game, source)) { diff --git a/Mage.Sets/src/mage/cards/m/MomentousFall.java b/Mage.Sets/src/mage/cards/m/MomentousFall.java index 0685bdda5f8..05a94426788 100644 --- a/Mage.Sets/src/mage/cards/m/MomentousFall.java +++ b/Mage.Sets/src/mage/cards/m/MomentousFall.java @@ -68,7 +68,7 @@ class MomentousFallEffect extends OneShotEffect { } } if (power > 0) { - controller.drawCards(power, game); + controller.drawCards(power, source.getSourceId(), game); } if (toughness > 0) { controller.gainLife(toughness, game, source); diff --git a/Mage.Sets/src/mage/cards/m/MurderOfCrows.java b/Mage.Sets/src/mage/cards/m/MurderOfCrows.java index 8b02356dc6b..462a0e926b5 100644 --- a/Mage.Sets/src/mage/cards/m/MurderOfCrows.java +++ b/Mage.Sets/src/mage/cards/m/MurderOfCrows.java @@ -63,7 +63,7 @@ class MurderOfCrowsEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null && player.chooseUse(Outcome.DrawCard, "Do you wish to draw a card? If you do, discard a card.", source, game)) { - if (player.drawCards(1, game) > 0) { + if (player.drawCards(1, source.getSourceId(), game) > 0) { player.discard(1, false, source, game); } return true; diff --git a/Mage.Sets/src/mage/cards/m/MysticRemora.java b/Mage.Sets/src/mage/cards/m/MysticRemora.java index 409ae14e810..ff57096a5d0 100644 --- a/Mage.Sets/src/mage/cards/m/MysticRemora.java +++ b/Mage.Sets/src/mage/cards/m/MysticRemora.java @@ -123,7 +123,7 @@ class MysticRemoraEffect extends OneShotEffect { && cost.pay(source, game, source.getSourceId(), opponent.getId(), false, null)) { return true; } - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/n/NantukoCultivator.java b/Mage.Sets/src/mage/cards/n/NantukoCultivator.java index 4395d9e3a3f..f284e81d74a 100644 --- a/Mage.Sets/src/mage/cards/n/NantukoCultivator.java +++ b/Mage.Sets/src/mage/cards/n/NantukoCultivator.java @@ -68,7 +68,7 @@ class NantukoCultivatorEffect extends OneShotEffect { if(permanent != null) { permanent.addCounters(CounterType.P1P1.createInstance(count), source, game); } - player.drawCards(count, game); + player.drawCards(count, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/n/NarsetOfTheAncientWay.java b/Mage.Sets/src/mage/cards/n/NarsetOfTheAncientWay.java index 71ac46c9814..f0423b043d3 100644 --- a/Mage.Sets/src/mage/cards/n/NarsetOfTheAncientWay.java +++ b/Mage.Sets/src/mage/cards/n/NarsetOfTheAncientWay.java @@ -133,7 +133,7 @@ class NarsetOfTheAncientWayDrawEffect extends OneShotEffect { if (player == null) { return false; } - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); if (player.getHand().isEmpty() || !player.chooseUse(Outcome.Discard, "Discard a card?", source, game)) { return false; } diff --git a/Mage.Sets/src/mage/cards/n/NaturesResurgence.java b/Mage.Sets/src/mage/cards/n/NaturesResurgence.java index c1c416b2f30..2c6eb292f79 100644 --- a/Mage.Sets/src/mage/cards/n/NaturesResurgence.java +++ b/Mage.Sets/src/mage/cards/n/NaturesResurgence.java @@ -63,7 +63,7 @@ class NaturesResurgenceEffect extends OneShotEffect { Player player = game.getPlayer(playerId); if (player != null) { int amount = player.getGraveyard().count(filter, game); - player.drawCards(amount, game); + player.drawCards(amount, source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/n/NefariousLich.java b/Mage.Sets/src/mage/cards/n/NefariousLich.java index 3a41d772f6e..7b433356486 100644 --- a/Mage.Sets/src/mage/cards/n/NefariousLich.java +++ b/Mage.Sets/src/mage/cards/n/NefariousLich.java @@ -130,7 +130,7 @@ class NefariousLichLifeGainReplacementEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player controller = game.getPlayer(event.getPlayerId()); if (controller != null) { - controller.drawCards(event.getAmount(), game); + controller.drawCards(event.getAmount(), source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/n/NehebDreadhordeChampion.java b/Mage.Sets/src/mage/cards/n/NehebDreadhordeChampion.java index bb93391c240..338608ef223 100644 --- a/Mage.Sets/src/mage/cards/n/NehebDreadhordeChampion.java +++ b/Mage.Sets/src/mage/cards/n/NehebDreadhordeChampion.java @@ -92,7 +92,7 @@ class NehebDreadhordeChampionEffect extends OneShotEffect { if (counter == 0) { return true; } - player.drawCards(counter, game); + player.drawCards(counter, source.getSourceId(), game); player.getManaPool().addMana(mana, game, source, true); return true; } diff --git a/Mage.Sets/src/mage/cards/n/NessianBoar.java b/Mage.Sets/src/mage/cards/n/NessianBoar.java index a81dac34106..56d6c7b15ac 100644 --- a/Mage.Sets/src/mage/cards/n/NessianBoar.java +++ b/Mage.Sets/src/mage/cards/n/NessianBoar.java @@ -69,6 +69,6 @@ class NessianBoarEffect extends OneShotEffect { return false; } Player player = game.getPlayer(permanent.getControllerId()); - return player != null && player.drawCards(1, game) > 0; + return player != null && player.drawCards(1, source.getSourceId(), game) > 0; } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/n/NicolBolasDragonGod.java b/Mage.Sets/src/mage/cards/n/NicolBolasDragonGod.java index f8b65004fe9..64dbc70f1ef 100644 --- a/Mage.Sets/src/mage/cards/n/NicolBolasDragonGod.java +++ b/Mage.Sets/src/mage/cards/n/NicolBolasDragonGod.java @@ -129,7 +129,7 @@ class NicolBolasDragonGodPlusOneEffect extends OneShotEffect { if (player == null) { return false; } - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); Set cardsOnBattlefield = new LinkedHashSet<>(); Set cards = new LinkedHashSet<>(); for (UUID opponentId : game.getState().getPlayersInRange(player.getId(), game)) { diff --git a/Mage.Sets/src/mage/cards/n/NinThePainArtist.java b/Mage.Sets/src/mage/cards/n/NinThePainArtist.java index 945c3047f57..c21c6fd23e7 100644 --- a/Mage.Sets/src/mage/cards/n/NinThePainArtist.java +++ b/Mage.Sets/src/mage/cards/n/NinThePainArtist.java @@ -75,7 +75,7 @@ class NinThePainArtistEffect extends OneShotEffect { permanent.damage(source.getManaCostsToPay().getX(), source.getSourceId(), game, false, true); Player player = game.getPlayer(permanent.getControllerId()); if (player != null) { - player.drawCards(source.getManaCostsToPay().getX(), game); + player.drawCards(source.getManaCostsToPay().getX(), source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/n/NissasDefeat.java b/Mage.Sets/src/mage/cards/n/NissasDefeat.java index ca228c724bf..09c1c4513b0 100644 --- a/Mage.Sets/src/mage/cards/n/NissasDefeat.java +++ b/Mage.Sets/src/mage/cards/n/NissasDefeat.java @@ -83,7 +83,7 @@ class NissasDefeatEffect extends OneShotEffect { // If it was a Nissa planeswalker, draw a card if (filter.match(permanent, game) && controller != null) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/n/NissasRevelation.java b/Mage.Sets/src/mage/cards/n/NissasRevelation.java index 220dd0fe864..77f0c5cacd8 100644 --- a/Mage.Sets/src/mage/cards/n/NissasRevelation.java +++ b/Mage.Sets/src/mage/cards/n/NissasRevelation.java @@ -69,7 +69,7 @@ class NissasRevelationEffect extends OneShotEffect { cards.add(card); controller.revealCards(sourceObject.getIdName(), cards, game); if (card.isCreature()) { - controller.drawCards(card.getPower().getValue(), game); + controller.drawCards(card.getPower().getValue(), source.getSourceId(), game); controller.gainLife(card.getToughness().getValue(), game, source); } } diff --git a/Mage.Sets/src/mage/cards/n/NotionThief.java b/Mage.Sets/src/mage/cards/n/NotionThief.java index 79b0045f7fd..697baa67bac 100644 --- a/Mage.Sets/src/mage/cards/n/NotionThief.java +++ b/Mage.Sets/src/mage/cards/n/NotionThief.java @@ -76,7 +76,7 @@ class NotionThiefReplacementEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(1, game, event.getAppliedEffects()); + player.drawCards(1, event.getSourceId(), game, event.getAppliedEffects()); } return true; } diff --git a/Mage.Sets/src/mage/cards/o/OathOfScholars.java b/Mage.Sets/src/mage/cards/o/OathOfScholars.java index f25287cc509..fb454039a7e 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfScholars.java +++ b/Mage.Sets/src/mage/cards/o/OathOfScholars.java @@ -107,7 +107,7 @@ class OathOfScholarsEffect extends OneShotEffect { } if (firstPlayer.chooseUse(Outcome.AIDontUseIt, "Discard your hand and draw 3 cards?", source, game)) { firstPlayer.discard(firstPlayer.getHand().size(), true, source, game); - firstPlayer.drawCards(3, game); + firstPlayer.drawCards(3, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/o/ObNixilisTheHateTwisted.java b/Mage.Sets/src/mage/cards/o/ObNixilisTheHateTwisted.java index 43c3addb15f..f635e8ea1f0 100644 --- a/Mage.Sets/src/mage/cards/o/ObNixilisTheHateTwisted.java +++ b/Mage.Sets/src/mage/cards/o/ObNixilisTheHateTwisted.java @@ -79,7 +79,7 @@ class ObNixilisTheHateTwistedEffect extends OneShotEffect { if (player == null) { return false; } - player.drawCards(2, game); + player.drawCards(2, source.getSourceId(), game); return true; } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/o/Oblation.java b/Mage.Sets/src/mage/cards/o/Oblation.java index 9abe58ad697..5e84b814d1b 100644 --- a/Mage.Sets/src/mage/cards/o/Oblation.java +++ b/Mage.Sets/src/mage/cards/o/Oblation.java @@ -65,7 +65,7 @@ class OblationEffect extends OneShotEffect { game.applyEffects(); // so effects from creatures that were on the battlefield won't trigger from draw - player.drawCards(2, game); + player.drawCards(2, source.getSourceId(), game); return true; } } diff --git a/Mage.Sets/src/mage/cards/o/OboshThePreypiercer.java b/Mage.Sets/src/mage/cards/o/OboshThePreypiercer.java index da92f2651a6..012eb183e09 100644 --- a/Mage.Sets/src/mage/cards/o/OboshThePreypiercer.java +++ b/Mage.Sets/src/mage/cards/o/OboshThePreypiercer.java @@ -58,7 +58,7 @@ enum OboshThePreypiercerCompanionCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { return deck .stream() .filter(card -> !card.isLand()) diff --git a/Mage.Sets/src/mage/cards/o/OratorOfOjutai.java b/Mage.Sets/src/mage/cards/o/OratorOfOjutai.java index b11340a5275..9362e0f9094 100644 --- a/Mage.Sets/src/mage/cards/o/OratorOfOjutai.java +++ b/Mage.Sets/src/mage/cards/o/OratorOfOjutai.java @@ -136,7 +136,7 @@ class OratorOfOjutaiEffect extends OneShotEffect { if (sourcePermanent != null) { DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = game.getState().getWatcher(DragonOnTheBattlefieldWhileSpellWasCastWatcher.class); if (watcher != null && watcher.castWithConditionTrue(sourcePermanent.getSpellAbility().getId())) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); return true; } } diff --git a/Mage.Sets/src/mage/cards/o/OtherworldAtlas.java b/Mage.Sets/src/mage/cards/o/OtherworldAtlas.java index 660200e5888..dfe9041edf2 100644 --- a/Mage.Sets/src/mage/cards/o/OtherworldAtlas.java +++ b/Mage.Sets/src/mage/cards/o/OtherworldAtlas.java @@ -68,7 +68,7 @@ class OtherworldAtlasDrawEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(sourcePlayer.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(amount, game); + player.drawCards(amount, source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/o/OverwhelmingIntellect.java b/Mage.Sets/src/mage/cards/o/OverwhelmingIntellect.java index 1feb1afa928..dbc14c81665 100644 --- a/Mage.Sets/src/mage/cards/o/OverwhelmingIntellect.java +++ b/Mage.Sets/src/mage/cards/o/OverwhelmingIntellect.java @@ -61,7 +61,7 @@ class OverwhelmingIntellectEffect extends OneShotEffect { Spell spell = game.getStack().getSpell(getTargetPointer().getFirst(game, source)); if (controller != null && spell != null) { game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game); - controller.drawCards(spell.getConvertedManaCost(), game); + controller.drawCards(spell.getConvertedManaCost(), source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/p/PainsReward.java b/Mage.Sets/src/mage/cards/p/PainsReward.java index 7d121bd3cf3..67d1e27a881 100644 --- a/Mage.Sets/src/mage/cards/p/PainsReward.java +++ b/Mage.Sets/src/mage/cards/p/PainsReward.java @@ -81,7 +81,7 @@ class PainsRewardEffect extends OneShotEffect { game.informPlayers(winner.getLogName() + " won the auction with a bid of " + highBid + " life" + (highBid > 1 ? "s" : "")); winner.loseLife(highBid, game, false); - winner.drawCards(4, game); + winner.drawCards(4, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/p/ParasiticImpetus.java b/Mage.Sets/src/mage/cards/p/ParasiticImpetus.java new file mode 100644 index 00000000000..9a0dad6d1e8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/ParasiticImpetus.java @@ -0,0 +1,58 @@ +package mage.cards.p; + +import mage.abilities.Ability; +import mage.abilities.common.AttacksAttachedTriggeredAbility; +import mage.abilities.common.GoadAttachedAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeControllerAttachedEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ParasiticImpetus extends CardImpl { + + public ParasiticImpetus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets +2/+2 and is goaded. + this.addAbility(new GoadAttachedAbility(new BoostEnchantedEffect(2, 2))); + + // Whenever enchanted creature attacks, its controller loses 2 life and you gain 2 life. + ability = new AttacksAttachedTriggeredAbility( + new LoseLifeControllerAttachedEffect(2), AttachmentType.AURA, false + ); + ability.addEffect(new GainLifeEffect(2).concatBy("and")); + this.addAbility(ability); + } + + private ParasiticImpetus(final ParasiticImpetus card) { + super(card); + } + + @Override + public ParasiticImpetus copy() { + return new ParasiticImpetus(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PartingThoughts.java b/Mage.Sets/src/mage/cards/p/PartingThoughts.java index b6e908c2ee2..ddca0883aa1 100644 --- a/Mage.Sets/src/mage/cards/p/PartingThoughts.java +++ b/Mage.Sets/src/mage/cards/p/PartingThoughts.java @@ -66,7 +66,7 @@ class PartingThoughtsEffect extends OneShotEffect { numberOfCounters += counter.getCount(); } if (numberOfCounters > 0) { - controller.drawCards(numberOfCounters, game); + controller.drawCards(numberOfCounters, source.getSourceId(), game); controller.loseLife(numberOfCounters, game, false); } } diff --git a/Mage.Sets/src/mage/cards/p/PatientRebuilding.java b/Mage.Sets/src/mage/cards/p/PatientRebuilding.java index a884bf96150..130c1182c36 100644 --- a/Mage.Sets/src/mage/cards/p/PatientRebuilding.java +++ b/Mage.Sets/src/mage/cards/p/PatientRebuilding.java @@ -77,7 +77,7 @@ class PatientRebuildingEffect extends OneShotEffect { } } if (numberOfLandCards > 0) { - return controller.drawCards(numberOfLandCards, game) > 0; + return controller.drawCards(numberOfLandCards, source.getSourceId(), game) > 0; } return true; } diff --git a/Mage.Sets/src/mage/cards/p/PendantOfProsperity.java b/Mage.Sets/src/mage/cards/p/PendantOfProsperity.java index bdd8d5f4a16..b6cffe30fa0 100644 --- a/Mage.Sets/src/mage/cards/p/PendantOfProsperity.java +++ b/Mage.Sets/src/mage/cards/p/PendantOfProsperity.java @@ -5,25 +5,19 @@ import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; -import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.Duration; import mage.constants.Zone; import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; -import mage.target.Target; import mage.target.common.TargetCardInHand; -import mage.target.common.TargetOpponent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; import mage.abilities.effects.common.EntersBattlefieldUnderControlOfOpponentOfChoiceEffect; @@ -85,7 +79,7 @@ class PendantOfProsperityEffect extends OneShotEffect { if (player == null) { return false; } - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); if (!player.chooseUse(outcome, "Put a land into play from your hand?", source, game)) { return true; } diff --git a/Mage.Sets/src/mage/cards/p/PetalsOfInsight.java b/Mage.Sets/src/mage/cards/p/PetalsOfInsight.java index e331b795996..ab83a8e016f 100644 --- a/Mage.Sets/src/mage/cards/p/PetalsOfInsight.java +++ b/Mage.Sets/src/mage/cards/p/PetalsOfInsight.java @@ -71,7 +71,7 @@ class PetalsOfInsightEffect extends OneShotEffect { controller.moveCards(spellCard, Zone.HAND, source, game); } } else { - controller.drawCards(3, game); + controller.drawCards(3, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/p/Plagiarize.java b/Mage.Sets/src/mage/cards/p/Plagiarize.java index 8e4d4cc4a9b..405be022a26 100644 --- a/Mage.Sets/src/mage/cards/p/Plagiarize.java +++ b/Mage.Sets/src/mage/cards/p/Plagiarize.java @@ -64,7 +64,7 @@ class PlagiarizeEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(1, game, event.getAppliedEffects()); + player.drawCards(1, event.getSourceId(), game, event.getAppliedEffects()); } return true; } diff --git a/Mage.Sets/src/mage/cards/p/PleaForPower.java b/Mage.Sets/src/mage/cards/p/PleaForPower.java index f59ea464314..95fa283b168 100644 --- a/Mage.Sets/src/mage/cards/p/PleaForPower.java +++ b/Mage.Sets/src/mage/cards/p/PleaForPower.java @@ -72,7 +72,7 @@ class PleaForPowerEffect extends OneShotEffect { if (timeCount > knowledgeCount) { new AddExtraTurnControllerEffect().apply(game, source); } else { - controller.drawCards(3, game); + controller.drawCards(3, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/p/PrecognitivePerception.java b/Mage.Sets/src/mage/cards/p/PrecognitivePerception.java index 32f2d035519..d6c07ab8a8d 100644 --- a/Mage.Sets/src/mage/cards/p/PrecognitivePerception.java +++ b/Mage.Sets/src/mage/cards/p/PrecognitivePerception.java @@ -62,7 +62,7 @@ class PrecognitivePerceptionEffect extends OneShotEffect { if (AddendumCondition.instance.apply(game, source)) { controller.scry(3, source, game); } - controller.drawCards(3, game); + controller.drawCards(3, source.getSourceId(), game); return true; } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/p/PredatoryImpetus.java b/Mage.Sets/src/mage/cards/p/PredatoryImpetus.java new file mode 100644 index 00000000000..4422d7bacb9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PredatoryImpetus.java @@ -0,0 +1,108 @@ +package mage.cards.p; + +import mage.abilities.Ability; +import mage.abilities.common.GoadAttachedAbility; +import mage.abilities.effects.RequirementEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PredatoryImpetus extends CardImpl { + + public PredatoryImpetus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets +3/+3, must be blocked if able, and is goaded. + this.addAbility(new GoadAttachedAbility( + new BoostEnchantedEffect(3, 3) + .setText("Enchanted creature gets +3/+3,"), + new PredatoryImpetusEffect() + )); + } + + private PredatoryImpetus(final PredatoryImpetus card) { + super(card); + } + + @Override + public PredatoryImpetus copy() { + return new PredatoryImpetus(this); + } +} + +class PredatoryImpetusEffect extends RequirementEffect { + + PredatoryImpetusEffect() { + super(Duration.WhileOnBattlefield); + staticText = "must be blocked if able,"; + } + + private PredatoryImpetusEffect(final PredatoryImpetusEffect effect) { + super(effect); + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + Permanent attachment = game.getPermanent(source.getSourceId()); + if (attachment != null && attachment.getAttachedTo() != null) { + Permanent attachedCreature = game.getPermanent(attachment.getAttachedTo()); + if (attachedCreature != null && attachedCreature.isAttacking()) { + return permanent.canBlock(attachment.getAttachedTo(), game); + } + } + return false; + } + + @Override + public boolean mustAttack(Game game) { + return false; + } + + @Override + public boolean mustBlock(Game game) { + return false; + } + + @Override + public UUID mustBlockAttacker(Ability source, Game game) { + Permanent attachment = game.getPermanent(source.getSourceId()); + if (attachment != null && attachment.getAttachedTo() != null) { + return attachment.getAttachedTo(); + } + return null; + } + + @Override + public int getMinNumberOfBlockers() { + return 1; + } + + @Override + public PredatoryImpetusEffect copy() { + return new PredatoryImpetusEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/Predict.java b/Mage.Sets/src/mage/cards/p/Predict.java index c2ae143a7af..1f9ec4f9302 100644 --- a/Mage.Sets/src/mage/cards/p/Predict.java +++ b/Mage.Sets/src/mage/cards/p/Predict.java @@ -71,7 +71,7 @@ class PredictEffect extends OneShotEffect { amount = 2; } } - controller.drawCards(amount, game); + controller.drawCards(amount, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/p/PrimalEmpathy.java b/Mage.Sets/src/mage/cards/p/PrimalEmpathy.java index 025e70d1a7f..a295e4793b4 100644 --- a/Mage.Sets/src/mage/cards/p/PrimalEmpathy.java +++ b/Mage.Sets/src/mage/cards/p/PrimalEmpathy.java @@ -83,7 +83,7 @@ class PrimalEmpathyEffect extends OneShotEffect { .mapToInt(MageInt::getValue) .anyMatch(i -> i >= highestPower); if (flag) { - return player.drawCards(1, game) > 0; + return player.drawCards(1, source.getSourceId(), game) > 0; } Target target = new TargetControlledCreaturePermanent(); target.setNotTarget(true); diff --git a/Mage.Sets/src/mage/cards/p/PsychicVortex.java b/Mage.Sets/src/mage/cards/p/PsychicVortex.java index 31cd032e07d..91789ec2cc3 100644 --- a/Mage.Sets/src/mage/cards/p/PsychicVortex.java +++ b/Mage.Sets/src/mage/cards/p/PsychicVortex.java @@ -62,7 +62,7 @@ class PsychicVortexCost extends CostImpl { public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { Player controller = game.getPlayer(controllerId); if (controller != null) { - controller.drawCards(1, game); + controller.drawCards(1, sourceId, game); this.paid = true; return true; } diff --git a/Mage.Sets/src/mage/cards/q/QuartzwoodCrasher.java b/Mage.Sets/src/mage/cards/q/QuartzwoodCrasher.java index 0e6d9aac34b..427efbbf60d 100644 --- a/Mage.Sets/src/mage/cards/q/QuartzwoodCrasher.java +++ b/Mage.Sets/src/mage/cards/q/QuartzwoodCrasher.java @@ -132,11 +132,6 @@ class QuartzwoodCrasherWatcher extends Watcher { super(WatcherScope.GAME); } - private QuartzwoodCrasherWatcher(final QuartzwoodCrasherWatcher watcher) { - super(watcher); - this.damageMap.putAll(watcher.damageMap); - } - @Override public void watch(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.COMBAT_DAMAGE_STEP_POST) { @@ -161,9 +156,4 @@ class QuartzwoodCrasherWatcher extends Watcher { } return damageMap.get(damagedPlayerId).getOrDefault(controllerId, 0); } - - @Override - public QuartzwoodCrasherWatcher copy() { - return new QuartzwoodCrasherWatcher(this); - } } diff --git a/Mage.Sets/src/mage/cards/r/RavenousGigantotherium.java b/Mage.Sets/src/mage/cards/r/RavenousGigantotherium.java new file mode 100644 index 00000000000..268f4085c4e --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RavenousGigantotherium.java @@ -0,0 +1,134 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageMultiEffect; +import mage.abilities.effects.common.DevourEffect; +import mage.abilities.keyword.DevourAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.Target; +import mage.target.common.TargetCreaturePermanentAmount; + +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class RavenousGigantotherium extends CardImpl { + + public RavenousGigantotherium(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}"); + + this.subtype.add(SubType.BEAST); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Devour 3 + this.addAbility(new DevourAbility(DevourEffect.DevourFactor.Devour3)); + + // When Ravenous Gigantotherium enters the battlefield, it deals X damage divided as you choose among up to X target creatures, where X is its power. Each of those creatures deals damage equal to its power to Ravenous Gigantotherium. + this.addAbility(new RavenousGigantotheriumAbility()); + } + + private RavenousGigantotherium(final RavenousGigantotherium card) { + super(card); + } + + @Override + public RavenousGigantotherium copy() { + return new RavenousGigantotherium(this); + } +} + +class RavenousGigantotheriumAbility extends EntersBattlefieldTriggeredAbility { + + RavenousGigantotheriumAbility() { + super(null, false); + } + + private RavenousGigantotheriumAbility(final RavenousGigantotheriumAbility ability) { + super(ability); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (!super.checkTrigger(event, game)) { + return false; + } + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); + if (permanent == null) { + return false; + } + int power = Math.min(permanent.getPower().getValue(), 0); + this.getEffects().clear(); + this.addEffect(new DamageMultiEffect(power)); + this.addEffect(new RavenousGigantotheriumEffect()); + this.getTargets().clear(); + if (power < 1) { + return true; + } + this.addTarget(new TargetCreaturePermanentAmount(power)); + return true; + } + + @Override + public String getRule() { + return "When {this} enters the battlefield, it deals X damage " + + "divided as you choose among up to X target creatures, where X is its power. " + + "Each of those creatures deals damage equal to its power to {this}."; + } + + @Override + public RavenousGigantotheriumAbility copy() { + return new RavenousGigantotheriumAbility(this); + } +} + +class RavenousGigantotheriumEffect extends OneShotEffect { + + RavenousGigantotheriumEffect() { + super(Outcome.Benefit); + } + + private RavenousGigantotheriumEffect(final RavenousGigantotheriumEffect effect) { + super(effect); + } + + @Override + public RavenousGigantotheriumEffect copy() { + return new RavenousGigantotheriumEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourcePerm = game.getPermanent(source.getSourceId()); + if (sourcePerm == null) { + return false; + } + List permanentList = source + .getTargets() + .stream() + .map(Target::getTargets) + .flatMap(Collection::stream) + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + for (Permanent permanent : permanentList) { + sourcePerm.damage(permanent.getPower().getValue(), permanent.getId(), game); + } + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/ReadTheRunes.java b/Mage.Sets/src/mage/cards/r/ReadTheRunes.java index 407b3f7bc68..ed406a3715a 100644 --- a/Mage.Sets/src/mage/cards/r/ReadTheRunes.java +++ b/Mage.Sets/src/mage/cards/r/ReadTheRunes.java @@ -59,7 +59,7 @@ class ReadTheRunesEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - int drawnCards = controller.drawCards(source.getManaCostsToPay().getX(), game); + int drawnCards = controller.drawCards(source.getManaCostsToPay().getX(), source.getSourceId(), game); Target target = new TargetControlledPermanent(0, drawnCards, new FilterControlledPermanent(), true); controller.chooseTarget(Outcome.Sacrifice, target, source, game); int sacrificedPermanents = 0; diff --git a/Mage.Sets/src/mage/cards/r/RecurringInsight.java b/Mage.Sets/src/mage/cards/r/RecurringInsight.java index 9fa6dd3ff93..adb29672126 100644 --- a/Mage.Sets/src/mage/cards/r/RecurringInsight.java +++ b/Mage.Sets/src/mage/cards/r/RecurringInsight.java @@ -57,7 +57,7 @@ class RecurringInsightEffect extends OneShotEffect { if (controller != null) { Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source)); if (opponent != null) { - controller.drawCards(opponent.getHand().size(), game); + controller.drawCards(opponent.getHand().size(), source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/r/Reprocess.java b/Mage.Sets/src/mage/cards/r/Reprocess.java index e25958e0f19..bb16d7dcb17 100644 --- a/Mage.Sets/src/mage/cards/r/Reprocess.java +++ b/Mage.Sets/src/mage/cards/r/Reprocess.java @@ -78,7 +78,7 @@ class ReprocessEffect extends OneShotEffect { amount++; } } - player.drawCards(amount, game); + player.drawCards(amount, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/r/ResearchDevelopment.java b/Mage.Sets/src/mage/cards/r/ResearchDevelopment.java index d21da059267..cc9497ea6f3 100644 --- a/Mage.Sets/src/mage/cards/r/ResearchDevelopment.java +++ b/Mage.Sets/src/mage/cards/r/ResearchDevelopment.java @@ -146,7 +146,7 @@ class DevelopmentEffect extends OneShotEffect { if (opponent != null && opponent.chooseUse(Outcome.Detriment, "Allow " + player.getLogName() + " to draw a card instead? (" + Integer.toString(i + 1) + ')', source, game)) { game.informPlayers(opponent.getLogName() + " had chosen to let " + player.getLogName() + " draw a card."); - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); putToken = false; break; } diff --git a/Mage.Sets/src/mage/cards/r/RhysticStudy.java b/Mage.Sets/src/mage/cards/r/RhysticStudy.java index 21b51a968bb..8c34fd706d2 100644 --- a/Mage.Sets/src/mage/cards/r/RhysticStudy.java +++ b/Mage.Sets/src/mage/cards/r/RhysticStudy.java @@ -69,7 +69,7 @@ class RhysticStudyDrawEffect extends OneShotEffect { && cost.pay(source, game, source.getSourceId(), opponent.getId(), false, null)) { return true; } - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/r/RiskFactor.java b/Mage.Sets/src/mage/cards/r/RiskFactor.java index c9dd1373c04..9133a2df219 100644 --- a/Mage.Sets/src/mage/cards/r/RiskFactor.java +++ b/Mage.Sets/src/mage/cards/r/RiskFactor.java @@ -67,7 +67,7 @@ class RiskFactorEffect extends OneShotEffect { if (opponent.chooseUse(outcome, "Do you choose to take the damage?", source, game)) { opponent.damage(4, source.getSourceId(), game); } else { - controller.drawCards(3, game); + controller.drawCards(3, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/r/RixMaadiReveler.java b/Mage.Sets/src/mage/cards/r/RixMaadiReveler.java index 82136a1ee75..a8196431f41 100644 --- a/Mage.Sets/src/mage/cards/r/RixMaadiReveler.java +++ b/Mage.Sets/src/mage/cards/r/RixMaadiReveler.java @@ -73,10 +73,10 @@ class RixMaadiRevelerEffect extends OneShotEffect { } if (SpectacleCondition.instance.apply(game, source)) { player.discard(player.getHand().size(), false, source, game); - player.drawCards(3, game); + player.drawCards(3, source.getSourceId(), game); } else { player.discard(1, false, source, game); - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/r/RowdyCrew.java b/Mage.Sets/src/mage/cards/r/RowdyCrew.java index f4171399c08..7d34ad922fe 100644 --- a/Mage.Sets/src/mage/cards/r/RowdyCrew.java +++ b/Mage.Sets/src/mage/cards/r/RowdyCrew.java @@ -71,7 +71,7 @@ class RowdyCrewEffect extends OneShotEffect { Permanent creature = game.getPermanent(source.getSourceId()); Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(3, game); + player.drawCards(3, source.getSourceId(), game); Cards cards = new CardsImpl(); int cardsInHand = player.getHand().size(); switch (cardsInHand) { diff --git a/Mage.Sets/src/mage/cards/r/Rumination.java b/Mage.Sets/src/mage/cards/r/Rumination.java index ea20a2779a1..1951201ed1e 100644 --- a/Mage.Sets/src/mage/cards/r/Rumination.java +++ b/Mage.Sets/src/mage/cards/r/Rumination.java @@ -56,7 +56,7 @@ public final class Rumination extends CardImpl { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(3, game); + player.drawCards(3, source.getSourceId(), game); putOnLibrary(player, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/s/SandstoneOracle.java b/Mage.Sets/src/mage/cards/s/SandstoneOracle.java index 3762ff4d0a0..775c31c40c4 100644 --- a/Mage.Sets/src/mage/cards/s/SandstoneOracle.java +++ b/Mage.Sets/src/mage/cards/s/SandstoneOracle.java @@ -74,7 +74,7 @@ class SandstoneOracleEffect extends OneShotEffect { game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " has chosen " + opponent.getLogName()); int cardsDiff = opponent.getHand().size() - controller.getHand().size(); if (cardsDiff > 0) { - controller.drawCards(cardsDiff, game); + controller.drawCards(cardsDiff, source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java b/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java index 7cb65b50ac6..8690b7fb60d 100644 --- a/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java +++ b/Mage.Sets/src/mage/cards/s/SarkhanUnbroken.java @@ -82,7 +82,7 @@ class SarkhanUnbrokenAbility1 extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); game.fireUpdatePlayersEvent(); diff --git a/Mage.Sets/src/mage/cards/s/SawtoothLoon.java b/Mage.Sets/src/mage/cards/s/SawtoothLoon.java index 36288ecc170..d6cccfa11ff 100644 --- a/Mage.Sets/src/mage/cards/s/SawtoothLoon.java +++ b/Mage.Sets/src/mage/cards/s/SawtoothLoon.java @@ -84,7 +84,7 @@ class SawtoothLoonEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(2, game); + controller.drawCards(2, source.getSourceId(), game); TargetCardInHand target = new TargetCardInHand(2, 2, new FilterCard()); controller.chooseTarget(Outcome.Detriment, target, source, game); Cards cardsToLibrary = new CardsImpl(target.getTargets()); diff --git a/Mage.Sets/src/mage/cards/s/SawtuskDemolisher.java b/Mage.Sets/src/mage/cards/s/SawtuskDemolisher.java new file mode 100644 index 00000000000..8e90904631c --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SawtuskDemolisher.java @@ -0,0 +1,98 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.MutatesSourceTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.keyword.MutateAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.BeastToken; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SawtuskDemolisher extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("noncreature permanent"); + + static { + filter.add(Predicates.not(CardType.CREATURE.getPredicate())); + } + + public SawtuskDemolisher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + + this.subtype.add(SubType.BEAST); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Mutate {3}{G} + this.addAbility(new MutateAbility(this, "{3}{G}")); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Whenever this creature mutates, destroy target noncreature permanent. Its controller creates a 3/3 green Beast creature token. + Ability ability = new MutatesSourceTriggeredAbility(new SawtuskDemolisherEffect()); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + private SawtuskDemolisher(final SawtuskDemolisher card) { + super(card); + } + + @Override + public SawtuskDemolisher copy() { + return new SawtuskDemolisher(this); + } +} + +class SawtuskDemolisherEffect extends OneShotEffect { + + SawtuskDemolisherEffect() { + super(Outcome.Benefit); + staticText = "destroy target noncreature permanent. Its controller creates a 3/3 green Beast creature token."; + } + + private SawtuskDemolisherEffect(final SawtuskDemolisherEffect effect) { + super(effect); + } + + @Override + public SawtuskDemolisherEffect copy() { + return new SawtuskDemolisherEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent == null) { + return false; + } + Player player = game.getPlayer(permanent.getControllerId()); + permanent.destroy(source.getSourceId(), game, false); + if (player == null) { + return false; + } + Effect effect = new CreateTokenTargetEffect(new BeastToken()); + effect.setTargetPointer(new FixedTarget(player.getId(), game)); + return effect.apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/cards/s/ScryingGlass.java b/Mage.Sets/src/mage/cards/s/ScryingGlass.java index bb535f3a52a..f0fd0cc4e92 100644 --- a/Mage.Sets/src/mage/cards/s/ScryingGlass.java +++ b/Mage.Sets/src/mage/cards/s/ScryingGlass.java @@ -71,7 +71,7 @@ class ScryingGlassEffect extends OneShotEffect { targetOpponent.revealCards(source, targetOpponent.getHand(), game); if (targetOpponent.getHand().count(filter, game) == amount) { game.informPlayers(controller.getName() + " has chosen the exact number and color of the revealed cards from " + targetOpponent.getName() + "'s hand. They draw a card."); - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); return true; } else { game.informPlayers(controller.getName() + " has chosen incorrectly and will not draw a card."); diff --git a/Mage.Sets/src/mage/cards/s/SeasonedPyromancer.java b/Mage.Sets/src/mage/cards/s/SeasonedPyromancer.java index c40f20bda26..5aed1a1767e 100644 --- a/Mage.Sets/src/mage/cards/s/SeasonedPyromancer.java +++ b/Mage.Sets/src/mage/cards/s/SeasonedPyromancer.java @@ -84,7 +84,7 @@ class SeasonedPyromancerEffect extends OneShotEffect { int nonlands = player .discard(2, false, source, game) .count(StaticFilters.FILTER_CARD_NON_LAND, game); - player.drawCards(2, game); + player.drawCards(2, source.getSourceId(), game); if (nonlands == 0) { return true; } diff --git a/Mage.Sets/src/mage/cards/s/SeeBeyond.java b/Mage.Sets/src/mage/cards/s/SeeBeyond.java index 74728b840cc..aedd6c6073a 100644 --- a/Mage.Sets/src/mage/cards/s/SeeBeyond.java +++ b/Mage.Sets/src/mage/cards/s/SeeBeyond.java @@ -53,7 +53,7 @@ class SeeBeyondEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if(controller != null) { - controller.drawCards(2, game); + controller.drawCards(2, source.getSourceId(), game); if (!controller.getHand().isEmpty()) { TargetCard target = new TargetCard(Zone.HAND, new FilterCard("card to shuffle into your library")); controller.choose(Outcome.Detriment, controller.getHand(), target, game); diff --git a/Mage.Sets/src/mage/cards/s/SelvalaHeartOfTheWilds.java b/Mage.Sets/src/mage/cards/s/SelvalaHeartOfTheWilds.java index 3516ba3642e..fdbd148e2df 100644 --- a/Mage.Sets/src/mage/cards/s/SelvalaHeartOfTheWilds.java +++ b/Mage.Sets/src/mage/cards/s/SelvalaHeartOfTheWilds.java @@ -7,9 +7,7 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.GreatestPowerAmongControlledCreaturesValue; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ManaEffect; import mage.abilities.effects.mana.AddManaInAnyCombinationEffect; @@ -18,7 +16,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.StaticFilters; -import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicate; import mage.filter.predicate.permanent.AnotherPredicate; @@ -102,7 +99,7 @@ class SelvalaHeartOfTheWildsEffect extends OneShotEffect { Player permanentController = game.getPlayer(permanent.getControllerId()); if (permanentController != null && permanentController.chooseUse(Outcome.DrawCard, "Would you like to draw a card?", source, game)) { - permanentController.drawCards(1, game); + permanentController.drawCards(1, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/s/SerumPowder.java b/Mage.Sets/src/mage/cards/s/SerumPowder.java index b30d9caf37d..0f9ac2704e6 100644 --- a/Mage.Sets/src/mage/cards/s/SerumPowder.java +++ b/Mage.Sets/src/mage/cards/s/SerumPowder.java @@ -69,7 +69,7 @@ class SerumPowderReplaceEffect extends ReplacementEffectImpl { for (Card card: cards.getCards(game)) { card.moveToExile(null, null, source.getSourceId(), game); } - controller.drawCards(cardsHand, game); + controller.drawCards(cardsHand, source.getSourceId(), game); } game.informPlayers(sourceCard.getLogName() +": " + controller.getLogName() + " exiles hand and draws " + cardsHand + " card(s)"); return true; diff --git a/Mage.Sets/src/mage/cards/s/ShahOfNaarIsle.java b/Mage.Sets/src/mage/cards/s/ShahOfNaarIsle.java index be4bed717a8..9e9d404ff64 100644 --- a/Mage.Sets/src/mage/cards/s/ShahOfNaarIsle.java +++ b/Mage.Sets/src/mage/cards/s/ShahOfNaarIsle.java @@ -106,7 +106,7 @@ class ShahOfNaarIsleEffect extends OneShotEffect { Player opponent = game.getPlayer(playerId); if (opponent != null) { int number = opponent.getAmount(0, 3, "Draw how many cards?", game); - opponent.drawCards(number, game); + opponent.drawCards(number, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/s/ShatterTheSky.java b/Mage.Sets/src/mage/cards/s/ShatterTheSky.java index b150c4c041f..df61edd0014 100644 --- a/Mage.Sets/src/mage/cards/s/ShatterTheSky.java +++ b/Mage.Sets/src/mage/cards/s/ShatterTheSky.java @@ -75,7 +75,7 @@ class ShatterTheSkyEffect extends OneShotEffect { .distinct() .map(game::getPlayer) .filter(Objects::nonNull) - .forEach(player -> player.drawCards(1, game)); + .forEach(player -> player.drawCards(1, source.getSourceId(), game)); effect.apply(game, source); return true; } diff --git a/Mage.Sets/src/mage/cards/s/Shocker.java b/Mage.Sets/src/mage/cards/s/Shocker.java index 87ae2908072..e988fd2caff 100644 --- a/Mage.Sets/src/mage/cards/s/Shocker.java +++ b/Mage.Sets/src/mage/cards/s/Shocker.java @@ -64,7 +64,7 @@ class ShockerEffect extends OneShotEffect { for (Card card : targetPlayer.getHand().getCards(game)) { targetPlayer.discard(card, source, game); } - targetPlayer.drawCards(count, game); + targetPlayer.drawCards(count, source.getSourceId(), game); return false; } return true; diff --git a/Mage.Sets/src/mage/cards/s/SibilantSpirit.java b/Mage.Sets/src/mage/cards/s/SibilantSpirit.java index 80c491f681e..6b68ad9b4b2 100644 --- a/Mage.Sets/src/mage/cards/s/SibilantSpirit.java +++ b/Mage.Sets/src/mage/cards/s/SibilantSpirit.java @@ -66,7 +66,7 @@ class SibilantSpiritEffect extends OneShotEffect { Player defender = game.getPlayer(defenderId); if (defender != null) { if (defender.chooseUse(outcome, "Draw a card?", source, game)) { - defender.drawCards(1, game); + defender.drawCards(1, source.getSourceId(), game); } } return false; diff --git a/Mage.Sets/src/mage/cards/s/Sindbad.java b/Mage.Sets/src/mage/cards/s/Sindbad.java index 771411d55c2..acdee2cf532 100644 --- a/Mage.Sets/src/mage/cards/s/Sindbad.java +++ b/Mage.Sets/src/mage/cards/s/Sindbad.java @@ -69,7 +69,7 @@ class SindbadEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Card card = controller.getLibrary().getFromTop(game); - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); controller.revealCards("Sindbad", new CardsImpl(card), game); if (!filter.match(card, game)) { controller.discard(card, source, game); diff --git a/Mage.Sets/src/mage/cards/s/SirensRuse.java b/Mage.Sets/src/mage/cards/s/SirensRuse.java index 62baaece6b5..1b815fabecb 100644 --- a/Mage.Sets/src/mage/cards/s/SirensRuse.java +++ b/Mage.Sets/src/mage/cards/s/SirensRuse.java @@ -66,7 +66,7 @@ class SirensRuseEffect extends ExileTargetForSourceEffect { if (super.apply(game, source)) { new ReturnToBattlefieldUnderYourControlTargetEffect(true).apply(game, source); if (isPirate && player != null) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/s/SkeletalScrying.java b/Mage.Sets/src/mage/cards/s/SkeletalScrying.java index 7e65477a115..76a790f5f58 100644 --- a/Mage.Sets/src/mage/cards/s/SkeletalScrying.java +++ b/Mage.Sets/src/mage/cards/s/SkeletalScrying.java @@ -105,7 +105,7 @@ class SkeletalScryingEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if ( controller != null ) { - controller.drawCards(amount.calculate(game, source, this), game); + controller.drawCards(amount.calculate(game, source, this), source.getSourceId(), game); controller.loseLife(amount.calculate(game, source, this), game, false); return true; } diff --git a/Mage.Sets/src/mage/cards/s/SkullknockerOgre.java b/Mage.Sets/src/mage/cards/s/SkullknockerOgre.java index c4d453f514e..f75f81793cc 100644 --- a/Mage.Sets/src/mage/cards/s/SkullknockerOgre.java +++ b/Mage.Sets/src/mage/cards/s/SkullknockerOgre.java @@ -65,7 +65,7 @@ class SkullknockerOgreEffect extends OneShotEffect { return false; } if (player.discard(1, true, source, game).size() > 0) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/s/Slithermuse.java b/Mage.Sets/src/mage/cards/s/Slithermuse.java index b067606a0e7..0f80ab9aaa3 100644 --- a/Mage.Sets/src/mage/cards/s/Slithermuse.java +++ b/Mage.Sets/src/mage/cards/s/Slithermuse.java @@ -83,7 +83,7 @@ class SlithermuseEffect extends OneShotEffect { game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + chosenPlayer.getLogName()); int diff = chosenPlayer.getHand().size() - player.getHand().size(); if (diff > 0) { - player.drawCards(diff, game); + player.drawCards(diff, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/s/SoldeviSentry.java b/Mage.Sets/src/mage/cards/s/SoldeviSentry.java index 14d2fdb476e..0b451c79346 100644 --- a/Mage.Sets/src/mage/cards/s/SoldeviSentry.java +++ b/Mage.Sets/src/mage/cards/s/SoldeviSentry.java @@ -56,7 +56,7 @@ class SoldeviSentryEffect extends RegenerateSourceEffect { if (permanent != null && permanent.regenerate(this.getId(), game)) { if (opponent != null) { if (opponent.chooseUse(Outcome.DrawCard, "Draw a card?", source, game)) { - opponent.drawCards(1, game); + opponent.drawCards(1, source.getSourceId(), game); } } this.used = true; diff --git a/Mage.Sets/src/mage/cards/s/SoulOfRavnica.java b/Mage.Sets/src/mage/cards/s/SoulOfRavnica.java index 431b8a329cf..070cac316f3 100644 --- a/Mage.Sets/src/mage/cards/s/SoulOfRavnica.java +++ b/Mage.Sets/src/mage/cards/s/SoulOfRavnica.java @@ -95,7 +95,7 @@ class SoulOfRavnicaEffect extends OneShotEffect { colors.add(ObjectColor.WHITE); } } - controller.drawCards(colors.size(), game); + controller.drawCards(colors.size(), source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/s/SoulRansom.java b/Mage.Sets/src/mage/cards/s/SoulRansom.java index bab5f1d07b5..d227a097d67 100644 --- a/Mage.Sets/src/mage/cards/s/SoulRansom.java +++ b/Mage.Sets/src/mage/cards/s/SoulRansom.java @@ -94,7 +94,7 @@ class SoulRansomEffect extends OneShotEffect { if (controller == null) { return false; } - controller.drawCards(2, game); + controller.drawCards(2, source.getSourceId(), game); return true; } } diff --git a/Mage.Sets/src/mage/cards/s/SoulsMajesty.java b/Mage.Sets/src/mage/cards/s/SoulsMajesty.java index fef36bc2c12..19d4172741d 100644 --- a/Mage.Sets/src/mage/cards/s/SoulsMajesty.java +++ b/Mage.Sets/src/mage/cards/s/SoulsMajesty.java @@ -52,7 +52,7 @@ public final class SoulsMajesty extends CardImpl { Permanent target = game.getPermanent(source.getFirstTarget()); Player player = game.getPlayer(source.getControllerId()); if (player != null && target != null) { - player.drawCards(target.getPower().getValue(), game); + player.drawCards(target.getPower().getValue(), source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/s/SpellboundDragon.java b/Mage.Sets/src/mage/cards/s/SpellboundDragon.java index e7f03140a9a..5083039fee7 100644 --- a/Mage.Sets/src/mage/cards/s/SpellboundDragon.java +++ b/Mage.Sets/src/mage/cards/s/SpellboundDragon.java @@ -71,7 +71,7 @@ class SpellboundDragonEffect extends OneShotEffect { Player you = game.getPlayer(source.getControllerId()); Permanent dragon = game.getPermanent(source.getSourceId()); if(you != null) { - you.drawCards(1, game); + you.drawCards(1, source.getSourceId(), game); TargetDiscard target = new TargetDiscard(you.getId()); you.choose(Outcome.Discard, target, source.getSourceId(), game); Card card = you.getHand().get(target.getFirstTarget(), game); diff --git a/Mage.Sets/src/mage/cards/s/SpiritualFocus.java b/Mage.Sets/src/mage/cards/s/SpiritualFocus.java index 4b1de900be9..4eb184fec1c 100644 --- a/Mage.Sets/src/mage/cards/s/SpiritualFocus.java +++ b/Mage.Sets/src/mage/cards/s/SpiritualFocus.java @@ -106,7 +106,7 @@ class SpiritualFocusDrawCardEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (player != null && permanent != null) { if (player.chooseUse(outcome, "Draw a card (" + permanent.getLogName() + ')', source, game)) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/s/SqueesRevenge.java b/Mage.Sets/src/mage/cards/s/SqueesRevenge.java index f30ec04673e..036d5f293f6 100644 --- a/Mage.Sets/src/mage/cards/s/SqueesRevenge.java +++ b/Mage.Sets/src/mage/cards/s/SqueesRevenge.java @@ -60,7 +60,7 @@ class SqueesRevengeEffect extends OneShotEffect { return true; } } - player.drawCards(2 * number, game); + player.drawCards(2 * number, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/s/Standstill.java b/Mage.Sets/src/mage/cards/s/Standstill.java index 2460a184d4d..13109fa7afc 100644 --- a/Mage.Sets/src/mage/cards/s/Standstill.java +++ b/Mage.Sets/src/mage/cards/s/Standstill.java @@ -97,7 +97,7 @@ class StandstillEffect extends OneShotEffect { for (UUID uuid : game.getOpponents(this.getTargetPointer().getFirst(game, source))) { Player player = game.getPlayer(uuid); if (player != null) { - player.drawCards(3, game); + player.drawCards(3, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/s/StunningReversal.java b/Mage.Sets/src/mage/cards/s/StunningReversal.java index ed6eb68610b..9f4cd5e2f68 100644 --- a/Mage.Sets/src/mage/cards/s/StunningReversal.java +++ b/Mage.Sets/src/mage/cards/s/StunningReversal.java @@ -65,7 +65,7 @@ class StunningReversalEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player player = game.getPlayer(event.getPlayerId()); if (player != null) { - player.drawCards(7, game); + player.drawCards(7, source.getSourceId(), game); player.setLife(1, game, source); this.discard(); } diff --git a/Mage.Sets/src/mage/cards/s/SurvivalCache.java b/Mage.Sets/src/mage/cards/s/SurvivalCache.java index d780249ce8a..1a80b98e864 100644 --- a/Mage.Sets/src/mage/cards/s/SurvivalCache.java +++ b/Mage.Sets/src/mage/cards/s/SurvivalCache.java @@ -62,7 +62,7 @@ class SurvivalCacheEffect extends OneShotEffect { } } if (haveMoreLife) - sourcePlayer.drawCards(1, game); + sourcePlayer.drawCards(1, source.getSourceId(), game); } return false; } diff --git a/Mage.Sets/src/mage/cards/s/SurvivorOfTheUnseen.java b/Mage.Sets/src/mage/cards/s/SurvivorOfTheUnseen.java index 70ec11cf45a..277de3506cc 100644 --- a/Mage.Sets/src/mage/cards/s/SurvivorOfTheUnseen.java +++ b/Mage.Sets/src/mage/cards/s/SurvivorOfTheUnseen.java @@ -71,7 +71,7 @@ class SurvivorOfTheUnseenEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(2, game); + player.drawCards(2, source.getSourceId(), game); putOnLibrary(player, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/s/SwansOfBrynArgoll.java b/Mage.Sets/src/mage/cards/s/SwansOfBrynArgoll.java index c97e5c43383..093cee48e02 100644 --- a/Mage.Sets/src/mage/cards/s/SwansOfBrynArgoll.java +++ b/Mage.Sets/src/mage/cards/s/SwansOfBrynArgoll.java @@ -80,21 +80,21 @@ class SwansOfBrynArgollEffect extends PreventionEffectImpl { if (spell != null) { Player controllerOfSpell = game.getPlayer(spell.getControllerId()); if(controllerOfSpell != null) { - controllerOfSpell.drawCards(preventionEffectData.getPreventedDamage(), game); + controllerOfSpell.drawCards(preventionEffectData.getPreventedDamage(), source.getSourceId(), game); passed = true; } } if (permanent != null) { Player controllerOfPermanent = game.getPlayer(permanent.getControllerId()); if(controllerOfPermanent != null) { - controllerOfPermanent.drawCards(preventionEffectData.getPreventedDamage(), game); + controllerOfPermanent.drawCards(preventionEffectData.getPreventedDamage(), source.getSourceId(), game); passed = true; } } if (emblem != null) { Player controllerOfEmblem = game.getPlayer(emblem.getControllerId()); if(controllerOfEmblem != null) { - controllerOfEmblem.drawCards(preventionEffectData.getPreventedDamage(), game); + controllerOfEmblem.drawCards(preventionEffectData.getPreventedDamage(), source.getSourceId(), game); } passed = true; } @@ -104,7 +104,7 @@ class SwansOfBrynArgollEffect extends PreventionEffectImpl { if (cardSource != null) { Player owner = game.getPlayer(cardSource.getOwnerId()); if (owner != null) { - owner.drawCards(preventionEffectData.getPreventedDamage(), game); + owner.drawCards(preventionEffectData.getPreventedDamage(), source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/s/SwiftSilence.java b/Mage.Sets/src/mage/cards/s/SwiftSilence.java index d0619b05d60..3ca62a310bd 100644 --- a/Mage.Sets/src/mage/cards/s/SwiftSilence.java +++ b/Mage.Sets/src/mage/cards/s/SwiftSilence.java @@ -66,7 +66,7 @@ class SwiftSilenceEffect extends OneShotEffect { } Player controller = game.getPlayer(source.getControllerId()); if (toDraw > 0 && controller != null){ - controller.drawCards(toDraw, game); + controller.drawCards(toDraw, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/s/SylvanLibrary.java b/Mage.Sets/src/mage/cards/s/SylvanLibrary.java index f18b270789c..18b1f1cfd3c 100644 --- a/Mage.Sets/src/mage/cards/s/SylvanLibrary.java +++ b/Mage.Sets/src/mage/cards/s/SylvanLibrary.java @@ -71,7 +71,7 @@ class SylvanLibraryEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - controller.drawCards(2, game); + controller.drawCards(2, source.getSourceId(), game); SylvanLibraryCardsDrawnThisTurnWatcher watcher = game.getState().getWatcher(SylvanLibraryCardsDrawnThisTurnWatcher.class); if (watcher != null) { Cards cards = new CardsImpl(); diff --git a/Mage.Sets/src/mage/cards/s/SyphonMind.java b/Mage.Sets/src/mage/cards/s/SyphonMind.java index 820017992ae..ba5bc4e75a6 100644 --- a/Mage.Sets/src/mage/cards/s/SyphonMind.java +++ b/Mage.Sets/src/mage/cards/s/SyphonMind.java @@ -76,7 +76,7 @@ class SyphonMindEffect extends OneShotEffect { } } } - you.drawCards(amount, game); + you.drawCards(amount, source.getSourceId(), game); } return result; } diff --git a/Mage.Sets/src/mage/cards/t/TeferisPuzzleBox.java b/Mage.Sets/src/mage/cards/t/TeferisPuzzleBox.java index 67190e2740c..4ead6cbd57e 100644 --- a/Mage.Sets/src/mage/cards/t/TeferisPuzzleBox.java +++ b/Mage.Sets/src/mage/cards/t/TeferisPuzzleBox.java @@ -55,7 +55,7 @@ class TeferisPuzzleBoxEffect extends OneShotEffect { if (player != null) { int count = player.getHand().size(); player.putCardsOnBottomOfLibrary(player.getHand(), game, source, true); - player.drawCards(count, game); + player.drawCards(count, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/t/TemporalCascade.java b/Mage.Sets/src/mage/cards/t/TemporalCascade.java index dc8e42bed9f..d4d1fb3971e 100644 --- a/Mage.Sets/src/mage/cards/t/TemporalCascade.java +++ b/Mage.Sets/src/mage/cards/t/TemporalCascade.java @@ -63,7 +63,7 @@ class TemporalCascadeDrawEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(sourcePlayer.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(7, game); + player.drawCards(7, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/t/TemporaryTruce.java b/Mage.Sets/src/mage/cards/t/TemporaryTruce.java index c3c6ba017b6..b842241d4bc 100644 --- a/Mage.Sets/src/mage/cards/t/TemporaryTruce.java +++ b/Mage.Sets/src/mage/cards/t/TemporaryTruce.java @@ -58,7 +58,7 @@ class TemporaryTruceEffect extends OneShotEffect { Player player = game.getPlayer(playerId); if (player != null) { int cardsToDraw = player.getAmount(0, 2, "Draw how many cards?", game); - player.drawCards(cardsToDraw, game); + player.drawCards(cardsToDraw, source.getSourceId(), game); player.gainLife((2 - cardsToDraw) * 2, game, source); } } diff --git a/Mage.Sets/src/mage/cards/t/TheBattleOfNaboo.java b/Mage.Sets/src/mage/cards/t/TheBattleOfNaboo.java index 75e60e1bf53..569b56fe786 100644 --- a/Mage.Sets/src/mage/cards/t/TheBattleOfNaboo.java +++ b/Mage.Sets/src/mage/cards/t/TheBattleOfNaboo.java @@ -74,7 +74,7 @@ class TheBattleOfNabooEffect extends OneShotEffect { if (player != null) { int x = source.getManaCostsToPay().getX(); if (x > 0) { - player.drawCards(2 * x, game); + player.drawCards(2 * x, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/t/TheGreatAurora.java b/Mage.Sets/src/mage/cards/t/TheGreatAurora.java index 5756d961aaa..ee5e5e07f91 100644 --- a/Mage.Sets/src/mage/cards/t/TheGreatAurora.java +++ b/Mage.Sets/src/mage/cards/t/TheGreatAurora.java @@ -98,7 +98,7 @@ class TheGreatAuroraEffect extends OneShotEffect { if (player != null) { int count = permanentsCount.get(playerId); if (count > 0) { - player.drawCards(count, game); + player.drawCards(count, source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/t/ThoughtGorger.java b/Mage.Sets/src/mage/cards/t/ThoughtGorger.java index 944775d342b..117beb14e2d 100644 --- a/Mage.Sets/src/mage/cards/t/ThoughtGorger.java +++ b/Mage.Sets/src/mage/cards/t/ThoughtGorger.java @@ -106,7 +106,7 @@ class ThoughtGorgerEffectLeaves extends OneShotEffect { Permanent thoughtGorgerLastState = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); int numberCounters = thoughtGorgerLastState.getCounters(game).getCount(CounterType.P1P1); if (player != null) { - player.drawCards(numberCounters, game); + player.drawCards(numberCounters, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/t/ThoughtReflection.java b/Mage.Sets/src/mage/cards/t/ThoughtReflection.java index 9a0c041548b..591cab79cac 100644 --- a/Mage.Sets/src/mage/cards/t/ThoughtReflection.java +++ b/Mage.Sets/src/mage/cards/t/ThoughtReflection.java @@ -75,7 +75,7 @@ class ThoughtReflectionReplacementEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player you = game.getPlayer(event.getPlayerId()); if (you != null) { - you.drawCards(2, game, event.getAppliedEffects()); + you.drawCards(2, event.getSourceId(), game, event.getAppliedEffects()); } return true; } diff --git a/Mage.Sets/src/mage/cards/t/ThrasiosTritonHero.java b/Mage.Sets/src/mage/cards/t/ThrasiosTritonHero.java index 510ae0081ba..4f70c21434c 100644 --- a/Mage.Sets/src/mage/cards/t/ThrasiosTritonHero.java +++ b/Mage.Sets/src/mage/cards/t/ThrasiosTritonHero.java @@ -89,7 +89,7 @@ class ThrasiosTritonHeroEffect extends OneShotEffect { if (card.isLand()) { controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); } else { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/t/TibaltTheFiendBlooded.java b/Mage.Sets/src/mage/cards/t/TibaltTheFiendBlooded.java index 43fc0c641a3..d3a95cc41ca 100644 --- a/Mage.Sets/src/mage/cards/t/TibaltTheFiendBlooded.java +++ b/Mage.Sets/src/mage/cards/t/TibaltTheFiendBlooded.java @@ -86,7 +86,7 @@ class TibaltTheFiendBloodedFirstEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); Card card = player.getHand().getRandom(game); player.discard(card, source, game); return true; diff --git a/Mage.Sets/src/mage/cards/t/TidalBarracuda.java b/Mage.Sets/src/mage/cards/t/TidalBarracuda.java new file mode 100644 index 00000000000..f14f6fd12d6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TidalBarracuda.java @@ -0,0 +1,84 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.game.events.GameEvent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TidalBarracuda extends CardImpl { + + private static final FilterCard filter = new FilterCard("spells"); + + public TidalBarracuda(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.FISH); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Any player may cast spells as though they had flash. + this.addAbility(new SimpleStaticAbility(new CastAsThoughItHadFlashAllEffect( + Duration.WhileOnBattlefield, filter, true + ))); + + // Your opponents can't cast spells during your turn. + this.addAbility(new SimpleStaticAbility(new TidalBarracudaEffect())); + } + + private TidalBarracuda(final TidalBarracuda card) { + super(card); + } + + @Override + public TidalBarracuda copy() { + return new TidalBarracuda(this); + } +} + +class TidalBarracudaEffect extends ContinuousRuleModifyingEffectImpl { + + TidalBarracudaEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "Your opponents can't cast spells during your turn"; + } + + private TidalBarracudaEffect(final TidalBarracudaEffect effect) { + super(effect); + } + + @Override + public TidalBarracudaEffect copy() { + return new TidalBarracudaEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @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) { + return game.isActivePlayer(source.getControllerId()) && + game.getPlayer(source.getControllerId()).hasOpponent(event.getPlayerId(), game); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TitanHunter.java b/Mage.Sets/src/mage/cards/t/TitanHunter.java new file mode 100644 index 00000000000..6202dd76585 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TitanHunter.java @@ -0,0 +1,88 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.InvertCondition; +import mage.abilities.condition.common.MorbidCondition; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.target.common.TargetControlledPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TitanHunter extends CardImpl { + + private static final Condition condition = new InvertCondition(MorbidCondition.instance); + + public TitanHunter(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(4); + this.toughness = new MageInt(5); + + // At the beginning of each player's end step, if no creatures died this turn, Titan Hunter deals 4 damage to that player. + this.addAbility(new ConditionalInterveningIfTriggeredAbility( + new BeginningOfEndStepTriggeredAbility( + new TitanHunterEffect(), TargetController.EACH_PLAYER, false + ), condition, "At the beginning of each player's end step, " + + "if no creatures died this turn, {this} deals 4 damage to that player." + )); + + // {1}{B}, Sacrifice a creature: You gain 4 life. + Ability ability = new SimpleActivatedAbility(new GainLifeEffect(4), new ManaCostsImpl("{1}{B}")); + ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + this.addAbility(ability); + } + + private TitanHunter(final TitanHunter card) { + super(card); + } + + @Override + public TitanHunter copy() { + return new TitanHunter(this); + } +} + +class TitanHunterEffect extends OneShotEffect { + + TitanHunterEffect() { + super(Outcome.Benefit); + } + + private TitanHunterEffect(final TitanHunterEffect effect) { + super(effect); + } + + @Override + public TitanHunterEffect copy() { + return new TitanHunterEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return game.damagePlayerOrPlaneswalker( + game.getActivePlayerId(), 4, source.getSourceId(), + game, false, true + ) > 0; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/t/TriadOfFates.java b/Mage.Sets/src/mage/cards/t/TriadOfFates.java index 472b1da334e..28b9c340f80 100644 --- a/Mage.Sets/src/mage/cards/t/TriadOfFates.java +++ b/Mage.Sets/src/mage/cards/t/TriadOfFates.java @@ -108,7 +108,7 @@ class DrawCardControllerTargetEffect extends OneShotEffect { if (creature != null) { Player controllerOfTarget = game.getPlayer(creature.getControllerId()); if (controllerOfTarget != null) { - controllerOfTarget.drawCards(2, game); + controllerOfTarget.drawCards(2, source.getSourceId(), game); } } return false; diff --git a/Mage.Sets/src/mage/cards/t/Truce.java b/Mage.Sets/src/mage/cards/t/Truce.java index 7cd117dd167..49762b869b4 100644 --- a/Mage.Sets/src/mage/cards/t/Truce.java +++ b/Mage.Sets/src/mage/cards/t/Truce.java @@ -58,7 +58,7 @@ class TruceEffect extends OneShotEffect { Player player = game.getPlayer(playerId); if (player != null) { int cardsToDraw = player.getAmount(0, 2, "Draw how many cards?", game); - player.drawCards(cardsToDraw, game); + player.drawCards(cardsToDraw, source.getSourceId(), game); player.gainLife((2 - cardsToDraw) * 2, game, source); } } diff --git a/Mage.Sets/src/mage/cards/t/TwistedJustice.java b/Mage.Sets/src/mage/cards/t/TwistedJustice.java index 3fa21371eea..dff11f79f66 100644 --- a/Mage.Sets/src/mage/cards/t/TwistedJustice.java +++ b/Mage.Sets/src/mage/cards/t/TwistedJustice.java @@ -69,7 +69,7 @@ class TwistedJusticeEffect extends OneShotEffect { Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { permanent.sacrifice(source.getSourceId(), game); - controller.drawCards(permanent.getPower().getValue(), game); + controller.drawCards(permanent.getPower().getValue(), source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/t/TymnaTheWeaver.java b/Mage.Sets/src/mage/cards/t/TymnaTheWeaver.java index 9dd2b4b8d4b..85fe4193928 100644 --- a/Mage.Sets/src/mage/cards/t/TymnaTheWeaver.java +++ b/Mage.Sets/src/mage/cards/t/TymnaTheWeaver.java @@ -82,7 +82,7 @@ class TymnaTheWeaverEffect extends OneShotEffect { Cost cost = new PayLifeCost(cardsToDraw); if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game) && cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { - controller.drawCards(cardsToDraw, game); + controller.drawCards(cardsToDraw, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/u/UginTheSpiritDragon.java b/Mage.Sets/src/mage/cards/u/UginTheSpiritDragon.java index 880666f4e9e..fa5a3d07f63 100644 --- a/Mage.Sets/src/mage/cards/u/UginTheSpiritDragon.java +++ b/Mage.Sets/src/mage/cards/u/UginTheSpiritDragon.java @@ -129,7 +129,7 @@ class UginTheSpiritDragonEffect3 extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { controller.gainLife(7, game, source); - controller.drawCards(7, game); + controller.drawCards(7, source.getSourceId(), game); TargetCardInHand target = new TargetCardInHand(0, 7, new FilterPermanentCard("permanent cards")); if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { controller.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); diff --git a/Mage.Sets/src/mage/cards/u/UginsInsight.java b/Mage.Sets/src/mage/cards/u/UginsInsight.java index d9ac5d10b69..cf9309d5503 100644 --- a/Mage.Sets/src/mage/cards/u/UginsInsight.java +++ b/Mage.Sets/src/mage/cards/u/UginsInsight.java @@ -59,7 +59,7 @@ class UginsInsightEffect extends OneShotEffect { if (highCMC > 0) { controller.scry(highCMC, source, game); } - controller.drawCards(3, game); + controller.drawCards(3, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/u/UmoriTheCollector.java b/Mage.Sets/src/mage/cards/u/UmoriTheCollector.java index 7943a5c430e..a56cab1d0a0 100644 --- a/Mage.Sets/src/mage/cards/u/UmoriTheCollector.java +++ b/Mage.Sets/src/mage/cards/u/UmoriTheCollector.java @@ -64,7 +64,7 @@ enum UmoriCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { Set cardTypes = new HashSet<>(); for (Card card : deck) { // Lands are fine. diff --git a/Mage.Sets/src/mage/cards/u/UnifyingTheory.java b/Mage.Sets/src/mage/cards/u/UnifyingTheory.java index 365f47ad428..653142390ec 100644 --- a/Mage.Sets/src/mage/cards/u/UnifyingTheory.java +++ b/Mage.Sets/src/mage/cards/u/UnifyingTheory.java @@ -64,7 +64,7 @@ class UnifyingTheoryEffect extends OneShotEffect { if (caster.chooseUse(Outcome.DrawCard, "Pay {2} to draw a card?", source, game)) { Cost cost = new ManaCostsImpl("{2}"); if (cost.pay(source, game, source.getSourceId(), caster.getId(), false, null)) { - caster.drawCards(1, game); + caster.drawCards(1, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/u/UnmooredEgo.java b/Mage.Sets/src/mage/cards/u/UnmooredEgo.java index 8b09521818b..10c481c367e 100644 --- a/Mage.Sets/src/mage/cards/u/UnmooredEgo.java +++ b/Mage.Sets/src/mage/cards/u/UnmooredEgo.java @@ -111,7 +111,7 @@ class UnmooredEgoEffect extends OneShotEffect { if (numberOfCardsExiledFromHand > 0) { game.getState().applyEffects(game); - targetPlayer.drawCards(numberOfCardsExiledFromHand, game); + targetPlayer.drawCards(numberOfCardsExiledFromHand, source.getSourceId(), game); } } diff --git a/Mage.Sets/src/mage/cards/u/UnpredictableCyclone.java b/Mage.Sets/src/mage/cards/u/UnpredictableCyclone.java index fa93ed088c0..c6cb82b273e 100644 --- a/Mage.Sets/src/mage/cards/u/UnpredictableCyclone.java +++ b/Mage.Sets/src/mage/cards/u/UnpredictableCyclone.java @@ -13,6 +13,7 @@ import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.stack.StackObject; import mage.players.Player; import java.util.UUID; @@ -26,7 +27,7 @@ public final class UnpredictableCyclone extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}{R}"); // If a cycling ability of another nonland card would cause you to draw a card, instead exile cards from the top of your library until you exile a card that shares a card type with the cycled card. You may cast that card without paying its mana cost. Then put the exiled cards that weren't cast this way on the bottom of your library in a random order. - this.addAbility(new SimpleStaticAbility(new ArchmageAscensionReplacementEffect())); + this.addAbility(new SimpleStaticAbility(new UnpredictableCycloneReplacementEffect())); // Cycling {2} this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); @@ -42,9 +43,9 @@ public final class UnpredictableCyclone extends CardImpl { } } -class ArchmageAscensionReplacementEffect extends ReplacementEffectImpl { +class UnpredictableCycloneReplacementEffect extends ReplacementEffectImpl { - ArchmageAscensionReplacementEffect() { + UnpredictableCycloneReplacementEffect() { super(Duration.WhileOnBattlefield, Outcome.Benefit); staticText = "If a cycling ability of another nonland card would cause you to draw a card, " + "instead exile cards from the top of your library until you exile a card " + @@ -52,13 +53,13 @@ class ArchmageAscensionReplacementEffect extends ReplacementEffectImpl { "Then put the exiled cards that weren't cast this way on the bottom of your library in a random order."; } - private ArchmageAscensionReplacementEffect(final ArchmageAscensionReplacementEffect effect) { + private UnpredictableCycloneReplacementEffect(final UnpredictableCycloneReplacementEffect effect) { super(effect); } @Override - public ArchmageAscensionReplacementEffect copy() { - return new ArchmageAscensionReplacementEffect(this); + public UnpredictableCycloneReplacementEffect copy() { + return new UnpredictableCycloneReplacementEffect(this); } @Override @@ -69,8 +70,12 @@ class ArchmageAscensionReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player player = game.getPlayer(event.getPlayerId()); - Card sourceCard = game.getCard(event.getSourceId()); - if (player == null || sourceCard == null || sourceCard.isLand()) { + StackObject stackObject = game.getStack().getStackObject(event.getSourceId()); + if (player == null || stackObject == null) { + return false; + } + Card sourceCard = game.getCard(stackObject.getSourceId()); + if (sourceCard == null) { return false; } Cards cards = new CardsImpl(); @@ -98,11 +103,22 @@ class ArchmageAscensionReplacementEffect extends ReplacementEffectImpl { @Override public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.CYCLE_DRAW; + return event.getType() == GameEvent.EventType.DRAW_CARD; } @Override public boolean applies(GameEvent event, Ability source, Game game) { - return event.getPlayerId().equals(source.getControllerId()); + if (!event.getPlayerId().equals(source.getControllerId())) { + return false; + } + Player player = game.getPlayer(event.getPlayerId()); + StackObject stackObject = game.getStack().getStackObject(event.getSourceId()); + if (player == null || stackObject == null + || stackObject.getStackAbility() == null + || !(stackObject.getStackAbility() instanceof CyclingAbility)) { + return false; + } + Card sourceCard = game.getCard(stackObject.getSourceId()); + return sourceCard != null && !sourceCard.isLand(); } } diff --git a/Mage.Sets/src/mage/cards/u/UrgorosTheEmptyOne.java b/Mage.Sets/src/mage/cards/u/UrgorosTheEmptyOne.java index daf81034bbb..bd4571d3594 100644 --- a/Mage.Sets/src/mage/cards/u/UrgorosTheEmptyOne.java +++ b/Mage.Sets/src/mage/cards/u/UrgorosTheEmptyOne.java @@ -69,7 +69,7 @@ class UrgorosTheEmptyOneEffect extends OneShotEffect { Player attackedPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); if (controller != null && attackedPlayer != null) { if (attackedPlayer.getHand().isEmpty()) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } else { attackedPlayer.discardOne(true, source, game); } diff --git a/Mage.Sets/src/mage/cards/u/UrzaAcademyHeadmaster.java b/Mage.Sets/src/mage/cards/u/UrzaAcademyHeadmaster.java index 7119d1df9f5..48d020b4d2c 100644 --- a/Mage.Sets/src/mage/cards/u/UrzaAcademyHeadmaster.java +++ b/Mage.Sets/src/mage/cards/u/UrzaAcademyHeadmaster.java @@ -550,7 +550,7 @@ class UrzaAcademyHeadmasterBrainstormEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(3, game); + player.drawCards(3, source.getSourceId(), game); putOnLibrary(player, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/v/VanishIntoMemory.java b/Mage.Sets/src/mage/cards/v/VanishIntoMemory.java index e2274dea49d..6ff09bc0792 100644 --- a/Mage.Sets/src/mage/cards/v/VanishIntoMemory.java +++ b/Mage.Sets/src/mage/cards/v/VanishIntoMemory.java @@ -72,7 +72,7 @@ class VanishIntoMemoryEffect extends OneShotEffect { MageObject sourceObject = game.getObject(source.getSourceId()); if (controller != null && permanent != null && sourceObject != null) { if (controller.moveCardsToExile(permanent, source, game, true, source.getSourceId(), sourceObject.getIdName())) { - controller.drawCards(permanent.getPower().getValue(), game); + controller.drawCards(permanent.getPower().getValue(), source.getSourceId(), game); ExileZone exile = game.getExile().getExileZone(source.getSourceId()); // only if permanent is in exile (tokens would be stop to exist) if (exile != null && !exile.isEmpty()) { diff --git a/Mage.Sets/src/mage/cards/v/VendilionClique.java b/Mage.Sets/src/mage/cards/v/VendilionClique.java index a2dd78280e4..dd054298ab5 100644 --- a/Mage.Sets/src/mage/cards/v/VendilionClique.java +++ b/Mage.Sets/src/mage/cards/v/VendilionClique.java @@ -85,7 +85,7 @@ class VendilionCliqueEffect extends OneShotEffect { cards.add(card); player.revealCards(sourceObject.getIdName(), cards, game); player.putCardsOnBottomOfLibrary(cards, game, source, true); - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/v/Vex.java b/Mage.Sets/src/mage/cards/v/Vex.java index 48dfa184eca..6290902bd33 100644 --- a/Mage.Sets/src/mage/cards/v/Vex.java +++ b/Mage.Sets/src/mage/cards/v/Vex.java @@ -65,7 +65,7 @@ class VexEffect extends OneShotEffect { countered = true; } if (controller != null) { - controller.drawCards(1, game); + controller.drawCards(1, source.getSourceId(), game); } return countered; } diff --git a/Mage.Sets/src/mage/cards/v/VisionsOfBeyond.java b/Mage.Sets/src/mage/cards/v/VisionsOfBeyond.java index bd4e1e68ea6..59f51ea1b90 100644 --- a/Mage.Sets/src/mage/cards/v/VisionsOfBeyond.java +++ b/Mage.Sets/src/mage/cards/v/VisionsOfBeyond.java @@ -59,7 +59,7 @@ class VisionsOfBeyondEffect extends OneShotEffect { } } } - sourcePlayer.drawCards(count, game); + sourcePlayer.drawCards(count, source.getSourceId(), game); return true; } diff --git a/Mage.Sets/src/mage/cards/v/VitalityHunter.java b/Mage.Sets/src/mage/cards/v/VitalityHunter.java new file mode 100644 index 00000000000..f0d1a180e6a --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VitalityHunter.java @@ -0,0 +1,66 @@ +package mage.cards.v; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.MonstrosityAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.game.Game; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.TargetAdjuster; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class VitalityHunter extends CardImpl { + + public VitalityHunter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.NIGHTMARE); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // {X}{W}{W}: Monstrosity X. + this.addAbility(new MonstrosityAbility("{X}{W}{W}", Integer.MAX_VALUE)); + + // When Vitality Hunter becomes monstrous, put a lifelink counter on each of up to X target creatures. + Ability ability = new BecomesMonstrousSourceTriggeredAbility( + new AddCountersTargetEffect(CounterType.LIFELINK.createInstance()) + .setText("put a lifelink counter on each of up to X target creatures") + ); + ability.setTargetAdjuster(VitalityHunterAdjuster.instance); + this.addAbility(ability); + } + + private VitalityHunter(final VitalityHunter card) { + super(card); + } + + @Override + public VitalityHunter copy() { + return new VitalityHunter(this); + } +} + +enum VitalityHunterAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + int xValue = ((BecomesMonstrousSourceTriggeredAbility) ability).getMonstrosityValue(); + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanent(0, xValue)); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java b/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java index 96cd3c87fbe..2986d5b86d9 100644 --- a/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java +++ b/Mage.Sets/src/mage/cards/w/WellOfKnowledge.java @@ -105,7 +105,7 @@ class WellOfKnowledgeEffect extends OneShotEffect { if (source instanceof ActivatedAbilityImpl) { Player activator = game.getPlayer(((ActivatedAbilityImpl) source).getActivatorId()); if (activator != null) { - activator.drawCards(1, game); + activator.drawCards(1, source.getSourceId(), game); return true; } diff --git a/Mage.Sets/src/mage/cards/w/WellOfLostDreams.java b/Mage.Sets/src/mage/cards/w/WellOfLostDreams.java index 523c6df0cda..6b05181425a 100644 --- a/Mage.Sets/src/mage/cards/w/WellOfLostDreams.java +++ b/Mage.Sets/src/mage/cards/w/WellOfLostDreams.java @@ -62,7 +62,7 @@ class WellOfLostDreamsEffect extends OneShotEffect { if (xValue > 0) { if (new GenericManaCost(xValue).pay(source, game, source.getSourceId(), controller.getId(), false)) { game.informPlayers(controller.getLogName() + " payed {" + xValue + '}'); - controller.drawCards(xValue, game); + controller.drawCards(xValue, source.getSourceId(), game); } else { return false; } diff --git a/Mage.Sets/src/mage/cards/w/WhirlpoolWarrior.java b/Mage.Sets/src/mage/cards/w/WhirlpoolWarrior.java index 158017976cd..aeef381aef6 100644 --- a/Mage.Sets/src/mage/cards/w/WhirlpoolWarrior.java +++ b/Mage.Sets/src/mage/cards/w/WhirlpoolWarrior.java @@ -90,7 +90,7 @@ class WhirlpoolWarriorActivatedEffect extends OneShotEffect { for (Entry entry : playerCards.entrySet()) { Player player = game.getPlayer(entry.getKey()); if (player != null) { - player.drawCards(entry.getValue(), game); + player.drawCards(entry.getValue(), source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/w/WhisperingMadness.java b/Mage.Sets/src/mage/cards/w/WhisperingMadness.java index 36ec9924224..be9b8b6bc93 100644 --- a/Mage.Sets/src/mage/cards/w/WhisperingMadness.java +++ b/Mage.Sets/src/mage/cards/w/WhisperingMadness.java @@ -73,7 +73,7 @@ class WhisperingMadnessEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(sourcePlayer.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(maxDiscarded, game); + player.drawCards(maxDiscarded, source.getSourceId(), game); } } diff --git a/Mage.Sets/src/mage/cards/w/WickedGuardian.java b/Mage.Sets/src/mage/cards/w/WickedGuardian.java index 23136034fbc..946cbb96ff4 100644 --- a/Mage.Sets/src/mage/cards/w/WickedGuardian.java +++ b/Mage.Sets/src/mage/cards/w/WickedGuardian.java @@ -87,6 +87,6 @@ class WickedGuardianEffect extends OneShotEffect { return false; } permanent.damage(2, source.getSourceId(), game); - return player.drawCards(1, game) > 0; + return player.drawCards(1, source.getSourceId(), game) > 0; } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/w/Windfall.java b/Mage.Sets/src/mage/cards/w/Windfall.java index ed5d20aed72..955883d9d86 100644 --- a/Mage.Sets/src/mage/cards/w/Windfall.java +++ b/Mage.Sets/src/mage/cards/w/Windfall.java @@ -70,7 +70,7 @@ class WindfallEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(maxDiscarded, game); + player.drawCards(maxDiscarded, source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/w/WindsOfChange.java b/Mage.Sets/src/mage/cards/w/WindsOfChange.java index 035f882abc9..a2584e505f5 100644 --- a/Mage.Sets/src/mage/cards/w/WindsOfChange.java +++ b/Mage.Sets/src/mage/cards/w/WindsOfChange.java @@ -69,7 +69,7 @@ class WindsOfChangeEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null && permanentsCount.containsKey(playerId)) { - player.drawCards(permanentsCount.get(playerId), game); + player.drawCards(permanentsCount.get(playerId), source.getSourceId(), game); } } return true; diff --git a/Mage.Sets/src/mage/cards/w/WitheringGaze.java b/Mage.Sets/src/mage/cards/w/WitheringGaze.java index 2a0c3b8ff40..6ce7cc4b71b 100644 --- a/Mage.Sets/src/mage/cards/w/WitheringGaze.java +++ b/Mage.Sets/src/mage/cards/w/WitheringGaze.java @@ -70,7 +70,7 @@ class WitheringGazeEffect extends OneShotEffect { count++; } } - controller.drawCards(count, game); + controller.drawCards(count, source.getSourceId(), game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/w/WordsOfWisdom.java b/Mage.Sets/src/mage/cards/w/WordsOfWisdom.java index 6351d1eb27f..57edc3de523 100644 --- a/Mage.Sets/src/mage/cards/w/WordsOfWisdom.java +++ b/Mage.Sets/src/mage/cards/w/WordsOfWisdom.java @@ -62,7 +62,7 @@ class WordsOfWisdomEffect extends OneShotEffect { if (!playerId.equals(controller.getId())) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } } } diff --git a/Mage.Sets/src/mage/cards/y/YennettCrypticSovereign.java b/Mage.Sets/src/mage/cards/y/YennettCrypticSovereign.java index 6794aa5a3bd..7aa8e4e55fa 100644 --- a/Mage.Sets/src/mage/cards/y/YennettCrypticSovereign.java +++ b/Mage.Sets/src/mage/cards/y/YennettCrypticSovereign.java @@ -99,10 +99,10 @@ class YennettCrypticSovereignEffect extends OneShotEffect { choose not to cast it, you draw a card. Keep in mind that revealing a card doesn’t cause it to change zones. This means that the card you draw will be the card you revealed. */ - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } } else { - player.drawCards(1, game); + player.drawCards(1, source.getSourceId(), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/y/YorionSkyNomad.java b/Mage.Sets/src/mage/cards/y/YorionSkyNomad.java new file mode 100644 index 00000000000..c7cb415a8b3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/y/YorionSkyNomad.java @@ -0,0 +1,141 @@ +package mage.cards.y; + +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.keyword.CompanionAbility; +import mage.abilities.keyword.CompanionCondition; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.*; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.game.Game; +import mage.game.permanent.PermanentCard; +import mage.game.permanent.PermanentMeld; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.targetpointer.FixedTargets; +import mage.util.CardUtil; + +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class YorionSkyNomad extends CardImpl { + + public YorionSkyNomad(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W/U}{W/U}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.BIRD); + this.subtype.add(SubType.SERPENT); + this.power = new MageInt(4); + this.toughness = new MageInt(5); + + // Companion — Your starting deck contains at least twenty cards more than the minimum deck size. + this.addAbility(new CompanionAbility(YorionSkyNomadCompanionCondition.instance)); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Yorion enters the battlefield, exile any number of other nonland permanents you own and control. Return those cards to the battlefield at the beginning of the next end step. + this.addAbility(new EntersBattlefieldTriggeredAbility(new YorionSkyNomadEffect())); + } + + private YorionSkyNomad(final YorionSkyNomad card) { + super(card); + } + + @Override + public YorionSkyNomad copy() { + return new YorionSkyNomad(this); + } +} + +enum YorionSkyNomadCompanionCondition implements CompanionCondition { + instance; + + @Override + public String getRule() { + return "Your starting deck contains at least twenty cards more than the minimum deck size."; + } + + @Override + public boolean isLegal(Set deck, int startingSize) { + return deck.size() >= startingSize + 20; + } +} + +class YorionSkyNomadEffect extends OneShotEffect { + + private static final FilterPermanent filter + = new FilterControlledPermanent("other nonland permanents you own and control"); + + static { + filter.add(Predicates.not(CardType.LAND.getPredicate())); + filter.add(TargetController.YOU.getOwnerPredicate()); + filter.add(AnotherPredicate.instance); + } + + YorionSkyNomadEffect() { + super(Outcome.Benefit); + staticText = "exile any number of other nonland permanents you own and control. " + + "Return those cards to the battlefield at the beginning of the next end step."; + } + + private YorionSkyNomadEffect(final YorionSkyNomadEffect effect) { + super(effect); + } + + @Override + public YorionSkyNomadEffect copy() { + return new YorionSkyNomadEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (sourceObject == null || controller == null) { + return false; + } + TargetPermanent target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true); + controller.choose(outcome, target, source.getSourceId(), game); + Set toExile = target.getTargets().stream().map(game::getPermanent).collect(Collectors.toSet()); + UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); + controller.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName()); + + Cards cardsToReturn = new CardsImpl(); + for (Card exiled : toExile) { + if (exiled instanceof PermanentMeld) { + MeldCard meldCard = (MeldCard) ((PermanentCard) exiled).getCard(); + Card topCard = meldCard.getTopHalfCard(); + Card bottomCard = meldCard.getBottomHalfCard(); + if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter()) { + cardsToReturn.add(topCard); + } + if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter()) { + cardsToReturn.add(bottomCard); + } + } else if (exiled.getZoneChangeCounter(game) == game.getState().getZoneChangeCounter(exiled.getId()) - 1) { + cardsToReturn.add(exiled); + } + } + Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(); + effect.setTargetPointer(new FixedTargets(cardsToReturn, game)); + AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); + game.addDelayedTriggeredAbility(delayedAbility, source); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/z/ZirdaTheDawnwaker.java b/Mage.Sets/src/mage/cards/z/ZirdaTheDawnwaker.java index cfa381ba605..ce3781fbb46 100644 --- a/Mage.Sets/src/mage/cards/z/ZirdaTheDawnwaker.java +++ b/Mage.Sets/src/mage/cards/z/ZirdaTheDawnwaker.java @@ -72,7 +72,7 @@ enum ZirdaTheDawnwakerCompanionCondition implements CompanionCondition { } @Override - public boolean isLegal(Set deck) { + public boolean isLegal(Set deck, int startingSize) { return deck .stream() .filter(MageObject::isPermanent) diff --git a/Mage.Sets/src/mage/sets/Commander2020Edition.java b/Mage.Sets/src/mage/sets/Commander2020Edition.java index 882bf6fff4f..ac981efe655 100644 --- a/Mage.Sets/src/mage/sets/Commander2020Edition.java +++ b/Mage.Sets/src/mage/sets/Commander2020Edition.java @@ -67,6 +67,7 @@ public final class Commander2020Edition extends ExpansionSet { cards.add(new SetCardInfo("Call the Coppercoats", 23, Rarity.RARE, mage.cards.c.CallTheCoppercoats.class)); cards.add(new SetCardInfo("Canopy Vista", 261, Rarity.RARE, mage.cards.c.CanopyVista.class)); cards.add(new SetCardInfo("Captivating Crew", 144, Rarity.RARE, mage.cards.c.CaptivatingCrew.class)); + cards.add(new SetCardInfo("Cartographer's Hawk", 24, Rarity.RARE, mage.cards.c.CartographersHawk.class)); cards.add(new SetCardInfo("Cast Out", 79, Rarity.UNCOMMON, mage.cards.c.CastOut.class)); cards.add(new SetCardInfo("Cataclysmic Gearhulk", 80, Rarity.MYTHIC, mage.cards.c.CataclysmicGearhulk.class)); cards.add(new SetCardInfo("Cavalry Pegasus", 81, Rarity.COMMON, mage.cards.c.CavalryPegasus.class)); @@ -168,6 +169,7 @@ public final class Commander2020Edition extends ExpansionSet { cards.add(new SetCardInfo("Kalemne's Captain", 92, Rarity.RARE, mage.cards.k.KalemnesCaptain.class)); cards.add(new SetCardInfo("Karametra, God of Harvests", 218, Rarity.MYTHIC, mage.cards.k.KarametraGodOfHarvests.class)); cards.add(new SetCardInfo("Kathril, Aspect Warper", 10, Rarity.MYTHIC, mage.cards.k.KathrilAspectWarper.class)); + cards.add(new SetCardInfo("Kelsien, the Plague", 11, Rarity.MYTHIC, mage.cards.k.KelsienThePlague.class)); cards.add(new SetCardInfo("Kessig Wolf Run", 284, Rarity.RARE, mage.cards.k.KessigWolfRun.class)); cards.add(new SetCardInfo("Knight of the White Orchid", 93, Rarity.RARE, mage.cards.k.KnightOfTheWhiteOrchid.class)); cards.add(new SetCardInfo("Kodama's Reach", 180, Rarity.COMMON, mage.cards.k.KodamasReach.class)); @@ -182,6 +184,7 @@ public final class Commander2020Edition extends ExpansionSet { cards.add(new SetCardInfo("Magus of the Disk", 94, Rarity.RARE, mage.cards.m.MagusOfTheDisk.class)); cards.add(new SetCardInfo("Magus of the Wheel", 156, Rarity.RARE, mage.cards.m.MagusOfTheWheel.class)); cards.add(new SetCardInfo("Majestic Myriarch", 182, Rarity.MYTHIC, mage.cards.m.MajesticMyriarch.class)); + cards.add(new SetCardInfo("Martial Impetus", 28, Rarity.UNCOMMON, mage.cards.m.MartialImpetus.class)); cards.add(new SetCardInfo("Masked Admirers", 183, Rarity.RARE, mage.cards.m.MaskedAdmirers.class)); cards.add(new SetCardInfo("Melek, Izzet Paragon", 220, Rarity.RARE, mage.cards.m.MelekIzzetParagon.class)); cards.add(new SetCardInfo("Memorial to Folly", 288, Rarity.UNCOMMON, mage.cards.m.MemorialToFolly.class)); @@ -217,10 +220,12 @@ public final class Commander2020Edition extends ExpansionSet { cards.add(new SetCardInfo("Otrimi, the Ever-Playful", 12, Rarity.MYTHIC, mage.cards.o.OtrimiTheEverPlayful.class)); cards.add(new SetCardInfo("Outpost Siege", 157, Rarity.RARE, mage.cards.o.OutpostSiege.class)); cards.add(new SetCardInfo("Painful Truths", 134, Rarity.RARE, mage.cards.p.PainfulTruths.class)); + cards.add(new SetCardInfo("Parasitic Impetus", 46, Rarity.UNCOMMON, mage.cards.p.ParasiticImpetus.class)); cards.add(new SetCardInfo("Path of Ancestry", 298, Rarity.COMMON, mage.cards.p.PathOfAncestry.class)); cards.add(new SetCardInfo("Portal Mage", 122, Rarity.RARE, mage.cards.p.PortalMage.class)); cards.add(new SetCardInfo("Prairie Stream", 299, Rarity.RARE, mage.cards.p.PrairieStream.class)); cards.add(new SetCardInfo("Predator Ooze", 185, Rarity.RARE, mage.cards.p.PredatorOoze.class)); + cards.add(new SetCardInfo("Predatory Impetus", 62, Rarity.UNCOMMON, mage.cards.p.PredatoryImpetus.class)); cards.add(new SetCardInfo("Profane Command", 135, Rarity.RARE, mage.cards.p.ProfaneCommand.class)); cards.add(new SetCardInfo("Propaganda", 123, Rarity.UNCOMMON, mage.cards.p.Propaganda.class)); cards.add(new SetCardInfo("Prophetic Bolt", 227, Rarity.RARE, mage.cards.p.PropheticBolt.class)); @@ -229,7 +234,8 @@ public final class Commander2020Edition extends ExpansionSet { cards.add(new SetCardInfo("Putrefy", 228, Rarity.UNCOMMON, mage.cards.p.Putrefy.class)); cards.add(new SetCardInfo("Rakdos Carnarium", 300, Rarity.COMMON, mage.cards.r.RakdosCarnarium.class)); cards.add(new SetCardInfo("Rakdos Signet", 249, Rarity.UNCOMMON, mage.cards.r.RakdosSignet.class)); - cards.add(new SetCardInfo("Rashmi, Eternities Crafter", 229, Rarity.RARE, mage.cards.r.RashmiEternitiesCrafter.class)); + cards.add(new SetCardInfo("Rashmi, Eternities Crafter", 229, Rarity.MYTHIC, mage.cards.r.RashmiEternitiesCrafter.class)); + cards.add(new SetCardInfo("Ravenous Gigantotherium", 63, Rarity.RARE, mage.cards.r.RavenousGigantotherium.class)); cards.add(new SetCardInfo("Reclamation Sage", 186, Rarity.UNCOMMON, mage.cards.r.ReclamationSage.class)); cards.add(new SetCardInfo("Reliquary Tower", 301, Rarity.UNCOMMON, mage.cards.r.ReliquaryTower.class)); cards.add(new SetCardInfo("Remote Isle", 302, Rarity.COMMON, mage.cards.r.RemoteIsle.class)); @@ -240,6 +246,7 @@ public final class Commander2020Edition extends ExpansionSet { cards.add(new SetCardInfo("Sakura-Tribe Elder", 187, Rarity.COMMON, mage.cards.s.SakuraTribeElder.class)); cards.add(new SetCardInfo("Sandsteppe Citadel", 305, Rarity.UNCOMMON, mage.cards.s.SandsteppeCitadel.class)); cards.add(new SetCardInfo("Satyr Wayfinder", 188, Rarity.COMMON, mage.cards.s.SatyrWayfinder.class)); + cards.add(new SetCardInfo("Sawtusk Demolisher", 64, Rarity.RARE, mage.cards.s.SawtuskDemolisher.class)); cards.add(new SetCardInfo("Scavenger Grounds", 306, Rarity.RARE, mage.cards.s.ScavengerGrounds.class)); cards.add(new SetCardInfo("Secluded Steppe", 307, Rarity.UNCOMMON, mage.cards.s.SecludedSteppe.class)); cards.add(new SetCardInfo("Selesnya Sanctuary", 308, Rarity.COMMON, mage.cards.s.SelesnyaSanctuary.class)); @@ -286,6 +293,8 @@ public final class Commander2020Edition extends ExpansionSet { cards.add(new SetCardInfo("Thalia's Lieutenant", 103, Rarity.RARE, mage.cards.t.ThaliasLieutenant.class)); cards.add(new SetCardInfo("The Locust God", 219, Rarity.MYTHIC, mage.cards.t.TheLocustGod.class)); cards.add(new SetCardInfo("Thraben Doomsayer", 104, Rarity.RARE, mage.cards.t.ThrabenDoomsayer.class)); + cards.add(new SetCardInfo("Tidal Barracuda", 39, Rarity.RARE, mage.cards.t.TidalBarracuda.class)); + cards.add(new SetCardInfo("Titan Hunter", 48, Rarity.RARE, mage.cards.t.TitanHunter.class)); cards.add(new SetCardInfo("Titan of Eternal Fire", 163, Rarity.RARE, mage.cards.t.TitanOfEternalFire.class)); cards.add(new SetCardInfo("Together Forever", 105, Rarity.RARE, mage.cards.t.TogetherForever.class)); cards.add(new SetCardInfo("Tribute to the Wild", 193, Rarity.UNCOMMON, mage.cards.t.TributeToTheWild.class)); @@ -298,6 +307,7 @@ public final class Commander2020Edition extends ExpansionSet { cards.add(new SetCardInfo("Vastwood Hydra", 194, Rarity.RARE, mage.cards.v.VastwoodHydra.class)); cards.add(new SetCardInfo("Vigilante Justice", 164, Rarity.UNCOMMON, mage.cards.v.VigilanteJustice.class)); cards.add(new SetCardInfo("Villainous Wealth", 233, Rarity.RARE, mage.cards.v.VillainousWealth.class)); + cards.add(new SetCardInfo("Vitality Hunter", 30, Rarity.RARE, mage.cards.v.VitalityHunter.class)); cards.add(new SetCardInfo("Vizier of Tumbling Sands", 126, Rarity.UNCOMMON, mage.cards.v.VizierOfTumblingSands.class)); cards.add(new SetCardInfo("Vorapede", 195, Rarity.MYTHIC, mage.cards.v.Vorapede.class)); cards.add(new SetCardInfo("Whiplash Trap", 127, Rarity.COMMON, mage.cards.w.WhiplashTrap.class)); diff --git a/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java b/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java index 00fc24c96e9..771653f1d49 100644 --- a/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java +++ b/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java @@ -326,6 +326,7 @@ public final class IkoriaLairOfBehemoths extends ExpansionSet { cards.add(new SetCardInfo("Wingspan Mentor", 72, Rarity.UNCOMMON, mage.cards.w.WingspanMentor.class)); cards.add(new SetCardInfo("Winota, Joiner of Forces", 216, Rarity.MYTHIC, mage.cards.w.WinotaJoinerOfForces.class)); cards.add(new SetCardInfo("Yidaro, Wandering Monster", 141, Rarity.RARE, mage.cards.y.YidaroWanderingMonster.class)); + cards.add(new SetCardInfo("Yorion, Sky Nomad", 232, Rarity.RARE, mage.cards.y.YorionSkyNomad.class)); cards.add(new SetCardInfo("Zagoth Crystal", 242, Rarity.UNCOMMON, mage.cards.z.ZagothCrystal.class)); cards.add(new SetCardInfo("Zagoth Mamba", 106, Rarity.UNCOMMON, mage.cards.z.ZagothMamba.class)); cards.add(new SetCardInfo("Zagoth Triome", 259, Rarity.RARE, mage.cards.z.ZagothTriome.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/UnpredictableCycloneTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/UnpredictableCycloneTest.java new file mode 100644 index 00000000000..aa49299fb20 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/UnpredictableCycloneTest.java @@ -0,0 +1,114 @@ +package org.mage.test.cards.single; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author TheElk801 + */ +public class UnpredictableCycloneTest extends CardTestPlayerBase { + + @Test + public void testCyclone() { + // Make sure the card works normally + + addCard(Zone.LIBRARY, playerA, "Goblin Piker"); + addCard(Zone.LIBRARY, playerA, "Swamp", 10); + skipInitShuffling(); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Unpredictable Cyclone"); + addCard(Zone.HAND, playerA, "Desert Cerodon"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cycling"); + setChoice(playerA, "Yes"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + assertPermanentCount(playerA, "Goblin Piker", 1); + } + + @Test + public void testLandCycle() { + // Make sure it doesn't apply to cycling lands + + addCard(Zone.LIBRARY, playerA, "Swamp", 10); + skipInitShuffling(); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Unpredictable Cyclone"); + addCard(Zone.HAND, playerA, "Forgotten Cave"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cycling"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + assertHandCount(playerA, "Swamp", 1); + } + + @Test + public void testModifiedDraw() { + // If a draw is increased, the ability will apply additional times + + addCard(Zone.LIBRARY, playerA, "Goblin Piker", 2); + addCard(Zone.LIBRARY, playerA, "Swamp", 10); + skipInitShuffling(); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Unpredictable Cyclone"); + addCard(Zone.BATTLEFIELD, playerA, "Thought Reflection"); + addCard(Zone.HAND, playerA, "Desert Cerodon"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cycling"); + setChoice(playerA, "Thought Reflection"); // apply doubling first + + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + assertPermanentCount(playerA, "Goblin Piker", 2); + } + + @Test + public void testModifiedDraw2() { + // Make sure the effect works with multiple stacked replacement effects + + addCard(Zone.LIBRARY, playerA, "Goblin Piker", 4); + addCard(Zone.LIBRARY, playerA, "Swamp", 10); + skipInitShuffling(); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Unpredictable Cyclone"); + addCard(Zone.BATTLEFIELD, playerA, "Thought Reflection", 2); + addCard(Zone.HAND, playerA, "Desert Cerodon"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cycling"); + setChoice(playerA, "Thought Reflection", 3); // apply doubling first + + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + assertPermanentCount(playerA, "Goblin Piker", 4); + } + + @Test + public void testStolenDraw() { + // if your opponent cycles a card and you steal that draw with Notion Thief, the draw will still be replaced + + addCard(Zone.LIBRARY, playerA, "Goblin Piker", 1); + addCard(Zone.LIBRARY, playerA, "Swamp", 10); + skipInitShuffling(); + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + addCard(Zone.BATTLEFIELD, playerB, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Unpredictable Cyclone"); + addCard(Zone.HAND, playerB, "Desert Cerodon"); + addCard(Zone.HAND, playerA, "Plagiarize"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Plagiarize", playerB); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Cycling"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + assertPermanentCount(playerA, "Goblin Piker", 1); + } +} 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 08fcf3c4658..b7ac18de7b6 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 @@ -2511,13 +2511,13 @@ public class TestPlayer implements Player { } @Override - public int drawCards(int num, Game game) { - return computerPlayer.drawCards(num, game); + public int drawCards(int num, UUID sourceId, Game game) { + return computerPlayer.drawCards(num, sourceId, game); } @Override - public int drawCards(int num, Game game, List appliedEffects) { - return computerPlayer.drawCards(num, game, appliedEffects); + public int drawCards(int num, UUID sourceId, Game game, List appliedEffects) { + return computerPlayer.drawCards(num, sourceId, game, appliedEffects); } @Override diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/performance/SerializationTest.java b/Mage.Tests/src/test/java/org/mage/test/serverside/performance/SerializationTest.java index b3739a93834..1720bdcf10b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/performance/SerializationTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/performance/SerializationTest.java @@ -3,7 +3,11 @@ package org.mage.test.serverside.performance; import mage.abilities.keyword.InfectAbility; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; +import mage.constants.PhaseStep; +import mage.constants.Zone; import mage.counters.CounterType; +import mage.game.Game; +import mage.game.mulligan.LondonMulligan; import mage.game.permanent.PermanentCard; import mage.game.permanent.PermanentImpl; import mage.remote.traffic.ZippedObjectImpl; @@ -50,4 +54,25 @@ public class SerializationTest extends CardTestPlayerBase { Assert.assertEquals("Must get infected counter", 1, permanent.getCounters(currentGame).getCount(CounterType.M1M1)); } + @Test + public void test_LondonMulligan() { + LondonMulligan mulligan = new LondonMulligan(15); + Object compressed = CompressUtil.compress(mulligan); + Assert.assertTrue("Must be zip", compressed instanceof ZippedObjectImpl); + LondonMulligan uncompressed = (LondonMulligan) CompressUtil.decompress(compressed); + Assert.assertEquals("Must be same", mulligan.getFreeMulligans(), uncompressed.getFreeMulligans()); + } + + @Test + public void test_Game() { + addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + Object compressed = CompressUtil.compress(currentGame); + Assert.assertTrue("Must be zip", compressed instanceof ZippedObjectImpl); + Game uncompressed = (Game) CompressUtil.decompress(compressed); + Assert.assertEquals("Must be same", 1, uncompressed.getBattlefield().getAllActivePermanents().size()); + } } 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 f5b42ee552b..c5bcdeb7ded 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 @@ -528,12 +528,12 @@ public class PlayerStub implements Player { } @Override - public int drawCards(int num, Game game) { + public int drawCards(int num, UUID sourceId, Game game) { return 0; } @Override - public int drawCards(int num, Game game, List appliedEffects) { + public int drawCards(int num, UUID sourceId, Game game, List appliedEffects) { return 0; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/BrainstormEffect.java b/Mage/src/main/java/mage/abilities/effects/common/BrainstormEffect.java index cf8e4b6558f..5dd98633e86 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/BrainstormEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/BrainstormEffect.java @@ -29,7 +29,7 @@ public class BrainstormEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - player.drawCards(3, game); + player.drawCards(3, source.getSourceId(), game); putOnLibrary(player, source, game); putOnLibrary(player, source, game); return true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/DrawCardAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DrawCardAllEffect.java index 0e87c451e8c..772d25845ac 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DrawCardAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DrawCardAllEffect.java @@ -59,7 +59,7 @@ public class DrawCardAllEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(amount.calculate(game, source, this), game); + player.drawCards(amount.calculate(game, source, this), source.getSourceId(), game); } } break; @@ -67,7 +67,7 @@ public class DrawCardAllEffect extends OneShotEffect { for (UUID playerId : game.getOpponents(controller.getId())) { Player player = game.getPlayer(playerId); if (player != null) { - player.drawCards(amount.calculate(game, source, this), game); + player.drawCards(amount.calculate(game, source, this), source.getSourceId(), game); } } break; diff --git a/Mage/src/main/java/mage/abilities/effects/common/DrawCardSourceControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DrawCardSourceControllerEffect.java index 8e260bd88c3..978826b327d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DrawCardSourceControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DrawCardSourceControllerEffect.java @@ -54,7 +54,7 @@ public class DrawCardSourceControllerEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (player != null && player.canRespond()) { - player.drawCards(amount.calculate(game, source, this), game); + player.drawCards(amount.calculate(game, source, this), source.getSourceId(), game); return true; } return false; 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 c56ae3840ba..15adc05b828 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DrawCardTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DrawCardTargetEffect.java @@ -70,7 +70,7 @@ public class DrawCardTargetEffect extends OneShotEffect { } if (!optional || player.chooseUse(outcome, "Use draw effect?", source, game)) { - player.drawCards(cardsToDraw, game); + player.drawCards(cardsToDraw, source.getSourceId(), game); } } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DrawDiscardControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DrawDiscardControllerEffect.java index f682be6e67f..7823789af5a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DrawDiscardControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DrawDiscardControllerEffect.java @@ -58,7 +58,7 @@ public class DrawDiscardControllerEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (player != null) { if (!optional || player.chooseUse(outcome, "Use draw, then discard effect?", source, game)) { - player.drawCards(cardsToDraw, game); + player.drawCards(cardsToDraw, source.getSourceId(), game); player.discard(cardsToDiscard, false, source, game); } return true; diff --git a/Mage/src/main/java/mage/abilities/effects/common/DrawDiscardOneOfThemEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DrawDiscardOneOfThemEffect.java index 2731eebd398..2738e12505a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DrawDiscardOneOfThemEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DrawDiscardOneOfThemEffect.java @@ -46,7 +46,7 @@ public class DrawDiscardOneOfThemEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Cards initialHand = controller.getHand().copy(); - controller.drawCards(cardsToDraw, game); + controller.drawCards(cardsToDraw, source.getSourceId(), game); Cards drawnCards = new CardsImpl(controller.getHand().copy()); drawnCards.removeAll(initialHand); if (!drawnCards.isEmpty()) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/DrawDiscardTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DrawDiscardTargetEffect.java index 5c134042e18..9a8f21ae21d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DrawDiscardTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DrawDiscardTargetEffect.java @@ -49,7 +49,7 @@ public class DrawDiscardTargetEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); if (player != null) { - player.drawCards(cardsToDraw, game); + player.drawCards(cardsToDraw, source.getSourceId(), game); player.discard(cardsToDiscard, false, source, game); return true; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ShuffleHandIntoLibraryDrawThatManySourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ShuffleHandIntoLibraryDrawThatManySourceEffect.java index 05c1908d489..8f896f18cc0 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ShuffleHandIntoLibraryDrawThatManySourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ShuffleHandIntoLibraryDrawThatManySourceEffect.java @@ -37,7 +37,7 @@ public class ShuffleHandIntoLibraryDrawThatManySourceEffect extends OneShotEffec controller.moveCards(controller.getHand(), Zone.LIBRARY, source, game); controller.shuffleLibrary(source, game); game.applyEffects(); // then - controller.drawCards(cardsHand, game); + controller.drawCards(cardsHand, source.getSourceId(), game); } return true; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardHandDrawSameNumberSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardHandDrawSameNumberSourceEffect.java index 8cda8768560..8fb68238efd 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardHandDrawSameNumberSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardHandDrawSameNumberSourceEffect.java @@ -28,7 +28,7 @@ public class DiscardHandDrawSameNumberSourceEffect extends OneShotEffect { if (player != null) { int amount = player.getHand().getCards(game).size(); player.discard(amount, false, source, game); - player.drawCards(amount, game); + player.drawCards(amount, source.getSourceId(), game); return true; } return false; diff --git a/Mage/src/main/java/mage/abilities/keyword/CompanionAbility.java b/Mage/src/main/java/mage/abilities/keyword/CompanionAbility.java index b4f6ff5ebac..cbf32664aa3 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CompanionAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/CompanionAbility.java @@ -34,8 +34,8 @@ public class CompanionAbility extends StaticAbility { return "Companion — " + condition.getRule(); } - public boolean isLegal(Set cards) { - return condition.isLegal(cards); + public boolean isLegal(Set cards, int startingSize) { + return condition.isLegal(cards, startingSize); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/CompanionCondition.java b/Mage/src/main/java/mage/abilities/keyword/CompanionCondition.java index ce43630cc22..161bd2aad95 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CompanionCondition.java +++ b/Mage/src/main/java/mage/abilities/keyword/CompanionCondition.java @@ -17,7 +17,8 @@ public interface CompanionCondition extends Serializable { /** * @param deck The set of cards to check. + * @param startingSize * @return Whether the companion is valid for that deck. */ - boolean isLegal(Set deck); + boolean isLegal(Set deck, int startingSize); } diff --git a/Mage/src/main/java/mage/abilities/keyword/CyclingAbility.java b/Mage/src/main/java/mage/abilities/keyword/CyclingAbility.java index b3c028278d2..e236cd7fb94 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CyclingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/CyclingAbility.java @@ -1,18 +1,13 @@ package mage.abilities.keyword; -import mage.abilities.Ability; import mage.abilities.ActivatedAbilityImpl; import mage.abilities.costs.Cost; import mage.abilities.costs.common.CyclingDiscardCost; import mage.abilities.costs.mana.ManaCost; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.players.Player; import mage.target.common.TargetCardInLibrary; /** @@ -24,7 +19,7 @@ public class CyclingAbility extends ActivatedAbilityImpl { private final String text; public CyclingAbility(Cost cost) { - super(Zone.HAND, new CyclingDrawEffect(), cost); + super(Zone.HAND, new DrawCardSourceControllerEffect(1), cost); this.addCost(new CyclingDiscardCost()); this.cost = cost; this.text = "Cycling"; @@ -60,37 +55,3 @@ public class CyclingAbility extends ActivatedAbilityImpl { return rule.toString(); } } - -class CyclingDrawEffect extends OneShotEffect { - - CyclingDrawEffect() { - super(Outcome.Benefit); - staticText = "draw a card"; - } - - private CyclingDrawEffect(final CyclingDrawEffect effect) { - super(effect); - } - - @Override - public CyclingDrawEffect copy() { - return new CyclingDrawEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getSourceId()); - if (player == null) { - return false; - } - GameEvent event = GameEvent.getEvent( - GameEvent.EventType.CYCLE_DRAW, source.getSourceId(), - source.getSourceId(), source.getControllerId() - ); - if (game.replaceEvent(event)) { - return true; - } - player.drawCards(1, game); - return true; - } -} \ No newline at end of file diff --git a/Mage/src/main/java/mage/actions/MageDrawAction.java b/Mage/src/main/java/mage/actions/MageDrawAction.java index dba094ec986..bf1fe4e922a 100644 --- a/Mage/src/main/java/mage/actions/MageDrawAction.java +++ b/Mage/src/main/java/mage/actions/MageDrawAction.java @@ -1,8 +1,5 @@ package mage.actions; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import mage.actions.impl.MageAction; import mage.actions.score.ArtificialScoringSystem; import mage.cards.Card; @@ -12,6 +9,10 @@ import mage.game.events.GameEvent; import mage.players.Player; import mage.util.CardUtil; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + /** * Action for drawing cards. * @@ -37,11 +38,12 @@ public class MageDrawAction extends MageAction { /** * Draw and set action score. * - * @param game Game context. + * @param sourceId + * @param game Game context. * @return */ @Override - public int doAction(Game game) { + public int doAction(UUID sourceId, Game game) { int numDrawn = 0; int score = 0; GameEvent event = GameEvent.getEvent(GameEvent.EventType.DRAW_CARDS, player.getId(), null, player.getId(), null, amount); @@ -49,7 +51,7 @@ public class MageDrawAction extends MageAction { if (amount < 2 || !game.replaceEvent(event)) { amount = event.getAmount(); for (int i = 0; i < amount; i++) { - int value = drawCard(game); + int value = drawCard(sourceId, game); if (value == NEGATIVE_VALUE) { continue; } @@ -62,7 +64,7 @@ public class MageDrawAction extends MageAction { if (player.isEmptyDraw()) { event = GameEvent.getEvent(GameEvent.EventType.EMPTY_DRAW, player.getId(), player.getId()); if (!game.replaceEvent(event)) { - game.doAction(new MageLoseGameAction(player, MageLoseGameAction.DRAW_REASON)); + game.doAction(new MageLoseGameAction(player, MageLoseGameAction.DRAW_REASON), sourceId); } } @@ -76,11 +78,12 @@ public class MageDrawAction extends MageAction { * Draw a card if possible (there is no replacement effect that prevent us * from drawing). Fire event about card drawn. * + * @param sourceId * @param game * @return */ - protected int drawCard(Game game) { - GameEvent event = GameEvent.getEvent(GameEvent.EventType.DRAW_CARD, player.getId(), player.getId()); + protected int drawCard(UUID sourceId, Game game) { + GameEvent event = GameEvent.getEvent(GameEvent.EventType.DRAW_CARD, player.getId(), sourceId, player.getId()); event.addAppliedEffects(appliedEffects); if (!game.replaceEvent(event)) { Card card = player.getLibrary().removeFromTop(game); diff --git a/Mage/src/main/java/mage/actions/MageLoseGameAction.java b/Mage/src/main/java/mage/actions/MageLoseGameAction.java index f824f1f126c..55468ae9a37 100644 --- a/Mage/src/main/java/mage/actions/MageLoseGameAction.java +++ b/Mage/src/main/java/mage/actions/MageLoseGameAction.java @@ -5,6 +5,8 @@ import mage.actions.score.ArtificialScoringSystem; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** * Lose game action. * @@ -26,7 +28,7 @@ public class MageLoseGameAction extends MageAction { } @Override - public int doAction(final Game game) { + public int doAction(UUID sourceId, final Game game) { oldLosingPlayer = game.getLosingPlayer(); if (oldLosingPlayer == null && player.canLose(game)) { setScore(player, ArtificialScoringSystem.inst.getLoseGameScore(game)); diff --git a/Mage/src/main/java/mage/actions/impl/MageAction.java b/Mage/src/main/java/mage/actions/impl/MageAction.java index 7ad9aa79720..9a384769eb0 100644 --- a/Mage/src/main/java/mage/actions/impl/MageAction.java +++ b/Mage/src/main/java/mage/actions/impl/MageAction.java @@ -3,6 +3,8 @@ package mage.actions.impl; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** * Base class for mage actions. * @@ -52,10 +54,12 @@ public abstract class MageAction { /** * Execute action. * + * + * @param sourceId * @param game Game context. * @return */ - public abstract int doAction(final Game game); + public abstract int doAction(UUID sourceId, final Game game); /** * Undo action. diff --git a/Mage/src/main/java/mage/game/Game.java b/Mage/src/main/java/mage/game/Game.java index d2d20ed707a..c13da0ceb26 100644 --- a/Mage/src/main/java/mage/game/Game.java +++ b/Mage/src/main/java/mage/game/Game.java @@ -411,7 +411,7 @@ public interface Game extends MageItem, Serializable { boolean endTurn(Ability source); - int doAction(MageAction action); + int doAction(MageAction action, UUID sourceId); //game transaction methods void saveState(boolean bookmark); diff --git a/Mage/src/main/java/mage/game/GameCanadianHighlanderImpl.java b/Mage/src/main/java/mage/game/GameCanadianHighlanderImpl.java index ab7408114aa..f306f4cf203 100644 --- a/Mage/src/main/java/mage/game/GameCanadianHighlanderImpl.java +++ b/Mage/src/main/java/mage/game/GameCanadianHighlanderImpl.java @@ -12,7 +12,7 @@ import java.util.UUID; public abstract class GameCanadianHighlanderImpl extends GameImpl { public GameCanadianHighlanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 100); } public GameCanadianHighlanderImpl(final GameCanadianHighlanderImpl game) { diff --git a/Mage/src/main/java/mage/game/GameCommanderImpl.java b/Mage/src/main/java/mage/game/GameCommanderImpl.java index 36af5d30f8f..31709e29650 100644 --- a/Mage/src/main/java/mage/game/GameCommanderImpl.java +++ b/Mage/src/main/java/mage/game/GameCommanderImpl.java @@ -31,8 +31,8 @@ public abstract class GameCommanderImpl extends GameImpl { protected boolean startingPlayerSkipsDraw = true; - public GameCommanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + public GameCommanderImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startingSize) { + super(attackOption, range, mulligan, startLife, startingSize); } public GameCommanderImpl(final GameCommanderImpl game) { diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index 454aefb61b0..212d9f1d6f2 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -135,6 +135,7 @@ public abstract class GameImpl implements Game, Serializable { private int priorityTime; private final int startLife; + private final int startingSize; protected PlayerList playerList; // auto-generated from state, don't copy // infinite loop check (no copy of this attributes neccessary) @@ -151,7 +152,7 @@ public abstract class GameImpl implements Game, Serializable { private Map usePowerInsteadOfToughnessForDamageLethalityFilters = new HashMap<>(); - public GameImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { + public GameImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife, int startingSize) { this.id = UUID.randomUUID(); this.range = range; this.mulligan = mulligan; @@ -159,6 +160,7 @@ public abstract class GameImpl implements Game, Serializable { this.state = new GameState(); this.startLife = startLife; this.executingRollback = false; + this.startingSize = startingSize; initGameDefaultWatchers(); } @@ -188,6 +190,7 @@ public abstract class GameImpl implements Game, Serializable { this.saveGame = game.saveGame; this.startLife = game.startLife; this.enterWithCounters.putAll(game.enterWithCounters); + this.startingSize = game.startingSize; } @Override @@ -946,7 +949,7 @@ public abstract class GameImpl implements Game, Serializable { for (Ability ability : card.getAbilities(this)) { if (ability instanceof CompanionAbility) { CompanionAbility companionAbility = (CompanionAbility) ability; - if (companionAbility.isLegal(new HashSet<>(player.getLibrary().getCards(this)))) { + if (companionAbility.isLegal(new HashSet<>(player.getLibrary().getCards(this)), startingSize)) { potentialCompanions.add(card); break; } @@ -1033,7 +1036,7 @@ public abstract class GameImpl implements Game, Serializable { player.initLife(this.getLife()); } if (!gameOptions.testMode) { - player.drawCards(startingHandSize, this); + player.drawCards(startingHandSize, null, this); } } @@ -3038,9 +3041,9 @@ public abstract class GameImpl implements Game, Serializable { } @Override - public int doAction(MageAction action) { + public int doAction(MageAction action, UUID sourceId) { //actions.add(action); - int value = action.doAction(this); + int value = action.doAction(sourceId, this); // score += action.getScore(scorePlayer); return value; } diff --git a/Mage/src/main/java/mage/game/GameTinyLeadersImpl.java b/Mage/src/main/java/mage/game/GameTinyLeadersImpl.java index 0a64d1b381f..97bccb6b1ab 100644 --- a/Mage/src/main/java/mage/game/GameTinyLeadersImpl.java +++ b/Mage/src/main/java/mage/game/GameTinyLeadersImpl.java @@ -32,7 +32,7 @@ public abstract class GameTinyLeadersImpl extends GameImpl { protected boolean startingPlayerSkipsDraw = true; public GameTinyLeadersImpl(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan, int startLife) { - super(attackOption, range, mulligan, startLife); + super(attackOption, range, mulligan, startLife, 50); } public GameTinyLeadersImpl(final GameTinyLeadersImpl game) { diff --git a/Mage/src/main/java/mage/game/command/planes/AcademyAtTolariaWestPlane.java b/Mage/src/main/java/mage/game/command/planes/AcademyAtTolariaWestPlane.java index 80c0e9677d9..0f254591506 100644 --- a/Mage/src/main/java/mage/game/command/planes/AcademyAtTolariaWestPlane.java +++ b/Mage/src/main/java/mage/game/command/planes/AcademyAtTolariaWestPlane.java @@ -93,7 +93,7 @@ class DrawCardsActivePlayerEffect extends OneShotEffect { } Player player = game.getPlayer(game.getActivePlayerId()); if (player != null) { - player.drawCards(amount.calculate(game, source, this), game); + player.drawCards(amount.calculate(game, source, this), source.getSourceId(), game); return true; } return false; diff --git a/Mage/src/main/java/mage/game/mulligan/CanadianHighlanderMulligan.java b/Mage/src/main/java/mage/game/mulligan/CanadianHighlanderMulligan.java index 320f39897c9..7ded68c3436 100644 --- a/Mage/src/main/java/mage/game/mulligan/CanadianHighlanderMulligan.java +++ b/Mage/src/main/java/mage/game/mulligan/CanadianHighlanderMulligan.java @@ -118,7 +118,7 @@ public class CanadianHighlanderMulligan extends VancouverMulligan { .append(" mulligans to ") .append(Integer.toString(numToMulliganTo)) .append(numToMulliganTo == 1 ? " card" : " cards").toString()); - player.drawCards(numToMulliganTo, game); + player.drawCards(numToMulliganTo, null, game); } } diff --git a/Mage/src/main/java/mage/game/mulligan/LondonMulligan.java b/Mage/src/main/java/mage/game/mulligan/LondonMulligan.java index aec6f4bc28b..33a213ca230 100644 --- a/Mage/src/main/java/mage/game/mulligan/LondonMulligan.java +++ b/Mage/src/main/java/mage/game/mulligan/LondonMulligan.java @@ -103,7 +103,7 @@ public class LondonMulligan extends Mulligan { .append(newHandSize) .append(newHandSize == 1 ? " card" : " cards").toString()); } - player.drawCards(numCards, game); + player.drawCards(numCards, null, game); if (player.getHand().size() > newHandSize) { int cardsToDiscard = player.getHand().size() - newHandSize; diff --git a/Mage/src/main/java/mage/game/mulligan/Mulligan.java b/Mage/src/main/java/mage/game/mulligan/Mulligan.java index 43abf6c2840..52bab013f7b 100644 --- a/Mage/src/main/java/mage/game/mulligan/Mulligan.java +++ b/Mage/src/main/java/mage/game/mulligan/Mulligan.java @@ -4,9 +4,10 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; +import java.io.Serializable; import java.util.*; -public abstract class Mulligan { +public abstract class Mulligan implements Serializable { protected final int freeMulligans; protected final Map usedFreeMulligans = new HashMap<>(); diff --git a/Mage/src/main/java/mage/game/mulligan/ParisMulligan.java b/Mage/src/main/java/mage/game/mulligan/ParisMulligan.java index 89ed63c087d..33b2ae0b765 100644 --- a/Mage/src/main/java/mage/game/mulligan/ParisMulligan.java +++ b/Mage/src/main/java/mage/game/mulligan/ParisMulligan.java @@ -53,7 +53,7 @@ public class ParisMulligan extends Mulligan { .append(deduction == 0 ? " for free and draws " : " down to ") .append((numCards - deduction)) .append(numCards - deduction == 1 ? " card" : " cards").toString()); - player.drawCards(numCards - deduction, game); + player.drawCards(numCards - deduction, null, game); } @Override diff --git a/Mage/src/main/java/mage/game/turn/DrawStep.java b/Mage/src/main/java/mage/game/turn/DrawStep.java index 1e721d416b8..b1320c740a2 100644 --- a/Mage/src/main/java/mage/game/turn/DrawStep.java +++ b/Mage/src/main/java/mage/game/turn/DrawStep.java @@ -1,15 +1,13 @@ - - package mage.game.turn; -import java.util.UUID; import mage.constants.PhaseStep; import mage.game.Game; import mage.game.events.GameEvent.EventType; import mage.players.Player; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public class DrawStep extends Step { @@ -29,7 +27,7 @@ public class DrawStep extends Step { public void beginStep(Game game, UUID activePlayerId) { Player activePlayer = game.getPlayer(activePlayerId); //20091005 - 504.1/703.4c - activePlayer.drawCards(1, game); + activePlayer.drawCards(1, null, game); // game.saveState(); game.applyEffects(); super.beginStep(game, activePlayerId); diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java index c4a7a065ca3..2128323f2cf 100644 --- a/Mage/src/main/java/mage/players/Player.java +++ b/Mage/src/main/java/mage/players/Player.java @@ -311,9 +311,9 @@ public interface Player extends MageItem, Copyable { void shuffleLibrary(Ability source, Game game); - int drawCards(int num, Game game); + int drawCards(int num, UUID sourceId, Game game); - int drawCards(int num, Game game, List appliedEffects); + int drawCards(int num, UUID sourceId, Game game, List appliedEffects); boolean cast(SpellAbility ability, Game game, boolean noMana, MageObjectReference reference); diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 74125259fb6..98f3ea5878f 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -673,16 +673,16 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public int drawCards(int num, Game game) { + public int drawCards(int num, UUID sourceId, Game game) { if (num > 0) { - return game.doAction(new MageDrawAction(this, num, null)); + return game.doAction(new MageDrawAction(this, num, null), sourceId); } return 0; } @Override - public int drawCards(int num, Game game, List appliedEffects) { - return game.doAction(new MageDrawAction(this, num, appliedEffects)); + public int drawCards(int num, UUID sourceId, Game game, List appliedEffects) { + return game.doAction(new MageDrawAction(this, num, appliedEffects), sourceId); } @Override diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 458267e80e6..9d74e814e98 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -36743,7 +36743,7 @@ Otrimi, the Ever-Playful|Commander 2020|12|M|{3}{B}{G}{U}|Legendary Creature - N Pako, Arcane Retriever|Commander 2020|13|M|{3}{R}{G}|Legendary Creature - Elemental Hound|3|3|Partner with Haldan, Avid Arcanist$Haste$Whenever Pako, Arcane Retriever attacks, exile the top card of each player's library and put a fetch counter on each of them. Put a +1/+1 counter on Pako for each noncreature card exiled this way.| Shabraz, the Skyshark|Commander 2020|14|M|{3}{W}{U}|Legendary Creature - Shark Bird|3|3|Partner with Brallin, Skyshark Rider$Flying$Whenever you draw a card, put a +1/+1 counter on Shabraz, the Skyshark and you gain 1 life.${W/U}: Target Human gains flying until end of turn.| Silvar, Devourer of the Free|Commander 2020|15|M|{3}{B}{R}|Legendary Creature - Cat Nightmare|4|2|Partner with Trynn, Champion of Freedom$Menace$Sacrifice a Human: Put a +1/+1 counter on Silvar, Devourer of the Free. It gains indestructible until end of turn.| -Tayam, Luminous Enigma|Commander 2020|16|M|{1}{W}{B}{G}|Legendary Creature - Nightmare beast|3|3|Each other creature you control enters the battlefield with an additional vigilance counter on it.${3}, Remove three counters from among creatures you control: Put the top three cards of your library into your graveyard, then return a permanent with converted mana cost 3 or less from your graveyard to the battlefield.| +Tayam, Luminous Enigma|Commander 2020|16|M|{1}{W}{B}{G}|Legendary Creature - Nightmare Beast|3|3|Each other creature you control enters the battlefield with an additional vigilance counter on it.${3}, Remove three counters from among creatures you control: Put the top three cards of your library into your graveyard, then return a permanent card with converted mana cost 3 or less from your graveyard to the battlefield.| Ukkima, Stalking Shadow|Commander 2020|17|M|{1}{U}{B}|Legendary Creature - Whale Wolf|2|2|Partner with Cazur, Ruthless Stalker$Ukkima, Stalking Shadow can't be blocked.$When Ukkima leaves the battlefield, it deals X damage to target player and you gain X life, where X is its power.| Xyris, the Writhing Storm|Commander 2020|18|M|{2}{G}{U}{R}|Legendary Creature - Snake Leviathan|3|5|Flying$Whenever an opponent draws a card except the first one they draw in each of their draw steps, create a 1/1 green Snake creature token.$Whenever Xyris, the Writhing Storm deals combat damage to a player, you and that player each draw that many cards.| Yannik, Scavenging Sentinel|Commander 2020|19|M|{2}{G}{W}|Legendary Creature - Hyena Beast|3|3|Partner with Nikara, Lair Scavenger$Vigilance$When Yannik, Scavenging Sentinel enters the battlefield, exile another creature you control until Yannik leaves the battlefield. When you do, distribute X +1/+1 counters among any number of target creatures, where X is the exiled creature's power.| @@ -36757,7 +36757,7 @@ Flawless Maneuver|Commander 2020|26|R|{2}{W}|Instant|||If you control a commande Herald of the Forgotten|Commander 2020|27|R|{6}{W}{W}|Creature - Cat Beast|6|6|Flying$When Herald of the Forgotten enters the battlefield, if you cast it, return any number of target permanent cards with cycling abilities from your graveyard to the battlefield.| Martial Impetus|Commander 2020|28|U|{2}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +1/+1 and is goaded.$Whenever enchanted creature attacks, each other creature that's attacking one of your opponents gets +1/+1 until end of turn.| Verge Rangers|Commander 2020|29|R|{2}{W}|Creature - Human Scout|3|3|First strike$You may look at the top card of your library any time.$As long as an opponent controls more lands than you, you may play lands from the top of your library.| -Vitality Hunter|Commander 2020|30|R|{3}{W}|Creature - Nightmare|3|4|Lifelink${X}{W}{W}: Monstrosity X.$When Vitality Hunter becomes monsterous, put a lifelink counter on each of up to X target creatures.| +Vitality Hunter|Commander 2020|30|R|{3}{W}|Creature - Nightmare|3|4|Lifelink${X}{W}{W}: Monstrosity X.$When Vitality Hunter becomes monstrous, put a lifelink counter on each of up to X target creatures.| Crystalline Resonance|Commander 2020|31|R|{2}{U}|Enchantment|||Whenever you cycle a card, you may have Crystalline Resonance become a copy of another target permanent until your next turn, except it has this ability.| Decoy Gambit|Commander 2020|32|R|{2}{U}|Instant|||For each opponent, choose up to one target creature that player controls, then return that creature to its owner's hand unless its controller has you draw a card.| Eon Frolicker|Commander 2020|33|R|{2}{U}{U}|Creature - Elemental Otter|5|5|Flying$When Eon Frolicker enters the battlefield, if you cast it, target opponent takes an extra turn after this one. Until your next turn, you and planeswalkers you control gain protection from that player.| @@ -36769,7 +36769,7 @@ Souvenir Snatcher|Commander 2020|38|R|{4}{U}|Creature - Bird|4|4|Mutate {5}{U}$F Tidal Barracuda|Commander 2020|39|R|{3}{U}|Creature - Fish|3|4|Any player may cast spells as though they had flash.$Your opponents can't cast spells during your turn.| Boneyard Mycodrax|Commander 2020|40|R|{2}{B}|Creature - Fungus|*|*|Boneyard Mycodrax's power and toughness are each equal to the number of other creature cards in your graveyard.$Scavenge {4}{B}| Daring Fiendbonder|Commander 2020|41|R|{3}{B}|Creature - Human Warlock|5|1|Haste$Daring Fiendbonder attacks each combat if able.${1}{B}, Exile Daring Fiendbonder from your graveyard: Put an indestructible counter on target creature. Activate this ability only any time you could cast a sorcery.| -Deadly Rollick|Commander 2020|42|R|{3}{B}|Instant|||If you control a commander, you may cast this card without paying its mana cost$Exile target creature.| +Deadly Rollick|Commander 2020|42|R|{3}{B}|Instant|||If you control a commander, you may cast this spell without paying its mana cost.$Exile target creature.| Dredge the Mire|Commander 2020|43|R|{3}{B}|Sorcery|||Each opponent chooses a creature card in their graveyard. Put those cards onto the battlefield under your control.| Mindleecher|Commander 2020|44|R|{4}{B}{B}|Creature - Nightmare|5|5|Mutate {4}{B}$Flying$Whenever this creature mutates, exile the top card of each opponent's library face down. You may look at and play those cards for as long as they remain exiled.| Netherborn Altar|Commander 2020|45|R|{1}{B}|Artifact|||{T}, Put a soul counter on Netherborn Altar: Put your commander into your hand from the command zone. Then you lose 3 life for each soul counter on Netherborn Altar.| @@ -36777,8 +36777,8 @@ Parasitic Impetus|Commander 2020|46|U|{2}{B}|Enchantment - Aura|||Enchant creatu Species Specialist|Commander 2020|47|R|{2}{B}{B}|Creature - Human Warrior|2|3|As Species Specialist enters the battlefield, choose a creature type.$Whenever a creature of the chosen type dies, you may draw a card.| Titan Hunter|Commander 2020|48|R|{4}{B}|Creature - Human Warrior|4|5|At the beginning of each player's end step, if no creatures died this turn, Titan Hunter deals 4 damage to that player.${1}{B}, Sacrifice a creature: You gain 4 life.| Agitator Ant|Commander 2020|49|R|{2}{R}|Creature - Insect|2|2|At the beginning of your end step, each player may put two +1/+1 counters on a creature they control. Goad each creature that had counters put on it this way.| -Deflecting Swat|Commander 2020|50|R|{2}{R}|Instant|||If you control a commander, you may cast this spell without paying its mana cost.$You may chose new targets for target spell or ability.| -Fireflux Squad|Commander 2020|51|R|{3}{R}|Creature - Human Soldier|4|3|Haste$Whenever Fireflux Squad attacks, you may exile another target attacking creature you control. If you do, reveal cards from the top of your library until you reveal a creature card. Put that card onto the battlefield tapped and atacking and the rest on the bottom of your library in a random order.| +Deflecting Swat|Commander 2020|50|R|{2}{R}|Instant|||If you control a commander, you may cast this spell without paying its mana cost.$You may choose new targets for target spell or ability.| +Fireflux Squad|Commander 2020|51|R|{3}{R}|Creature - Human Soldier|4|3|Haste$Whenever Fireflux Squad attacks, you may exile another target attacking creature you control. If you do, reveal cards from the top of your library until you reveal a creature card. Put that card onto the battlefield tapped and attacking and the rest on the bottom of your library in a random order.| Frontier Warmonger|Commander 2020|52|R|{3}{R}|Creature - Human Warrior|4|4|Whenever one or more creatures attack an opponent or a planeswalker an opponent controls, those creatures gain menace until end of turn.| Lavabrink Floodgates|Commander 2020|53|R|{3}{R}|Artifact|||{T}: Add {R}{R}.$At the beginning of each player's upkeep, that player may put a doom counter on Lavabrink Floodgates or remove a doom counter from it. Then if it has three or more doom counters on it, sacrifice it. When you do, it deals 6 damage to each creature.| Molten Echoes|Commander 2020|54|R|{2}{R}{R}|Enchantment|||As Molten Echoes enters the battlefield, choose a creature type.$Whenever a nontoken creature of the chosen type enters the battlefield under your control, create a token that's a copy of that creature. That token gains haste. Exile it at the beginning of the next end step.| @@ -36793,9 +36793,9 @@ Predatory Impetus|Commander 2020|62|U|{4}{G}|Enchantment - Aura|||Enchant creatu Ravenous Gigantotherium|Commander 2020|63|R|{5}{G}{G}|Creature - Beast|3|3|Devour 3$When Ravenous Gigantotherium enters the battlefield, it deals X damage divided as you choose among up to X target creatures, where X is its power. Each of those creatures deals damage equal to its power to Ravenous Gigantotherium.| Sawtusk Demolisher|Commander 2020|64|R|{4}{G}{G}|Creature - Beast|6|6|Mutate {3}{G}$Trample$Whenever this creature mutates, destroy target noncreature permanent. Its controller creates a 3/3 green Beast creature token.| Selective Adaptation|Commander 2020|65|R|{4}{G}{G}|Sorcery|||Reveal the top seven cards of your library. Choose from among them a card with flying, a card with first strike, and so on for double strike, deathtouch, haste, hexproof, indestructible, lifelink, menace, reach, trample, and vigilance. Put one of the chosen cards onto the battlefield, the other chosen cards into your hand, and the rest into your graveyard.| -Slippery Bogbonder|Commander 2020|66|R|{3}{G}|Creature - Human Druid|3|3|Flash$Hexproof$When Slippery Bogbonder enters the battlefield, put a hexproof counter on target creature. Then mover any number of counters from among creatures you control onto that creature.| +Slippery Bogbonder|Commander 2020|66|R|{3}{G}|Creature - Human Druid|3|3|Flash$Hexproof$When Slippery Bogbonder enters the battlefield, put a hexproof counter on target creature. Then move any number of counters from among creatures you control onto that creature.| Bonder's Ornament|Commander 2020|67|C|{3}|Artifact|||{T}: Add one mana of any color.${4}, {T}: Each player who controls a permanent named Bonder's Ornament draws a card.| -Manascape Refractor|Commander 2020|68|R|{3}|Artifact|||Manascape Refractor enters the battlefield tapped.$Manascape Refractor has all activated abilities of all lands on the battlefield.$You may spend mana of though it were mana of any color to pay the activation costs of Manascape Refractor's abilities.| +Manascape Refractor|Commander 2020|68|R|{3}|Artifact|||Manascape Refractor enters the battlefield tapped.$Manascape Refractor has all activated abilities of all lands on the battlefield.$You may spend mana as though it were mana of any color to pay the activation costs of Manascape Refractor's abilities.| Sanctuary Blade|Commander 2020|69|R|{2}|Artifact - Equipment|||As Sanctuary Blade becomes attached to a creature, choose a color.$Equipped creature gets +2/+0 and has protection from the last chosen color.$Equip {3}| Twinning Staff|Commander 2020|70|R|{3}|Artifact|||If you would copy a spell one or more times, instead copy it that many times plus an additional time. You may choose new targets for the additional copy.${7}, {T}: Copy target instant or sorcery spell you control. You may choose new targets for the copy.| Nesting Grounds|Commander 2020|71|R||Land|||{T}: Add {C}.${1}, {T}: Move a counter from target permanent you control onto another target permanent. Activate this ability only any time you could cast a sorcery.| @@ -36957,7 +36957,7 @@ Niv-Mizzet, the Firemind|Commander 2020|225|R|{2}{U}{U}{R}{R}|Legendary Creature Nyx Weaver|Commander 2020|226|U|{1}{B}{G}|Enchantment Creature - Spider|2|3|Reach$At the beginning of your upkeep, put the top two cards of your library into your graveyard.${1}{B}{G}, Exile Nyx Weaver: Return target card from your graveyard to your hand.| Prophetic Bolt|Commander 2020|227|R|{3}{U}{R}|Instant|||Prophetic Bolt deals 4 damage to any target. Look at the top four cards of your library. Put one of those cards into your hand and the rest on the bottom of your library in any order.| Putrefy|Commander 2020|228|U|{1}{B}{G}|Instant|||Destroy target artifact or creature. It can't be regenerated.| -Rashmi, Eternities Crafter|Commander 2020|229|R|{2}{G}{U}|Legendary Creature - Elf Druid|2|3|Whenever you cast your first spell each turn, reveal the top card of your library. If it's a nonland card with converted mana cost less than that spell's, you may cast it without paying its mana cost. If you don't cast the revealed card, put it into your hand.| +Rashmi, Eternities Crafter|Commander 2020|229|M|{2}{G}{U}|Legendary Creature - Elf Druid|2|3|Whenever you cast your first spell each turn, reveal the top card of your library. If it's a nonland card with converted mana cost less than that spell's, you may cast it without paying its mana cost. If you don't cast the revealed card, put it into your hand.| Temur Charm|Commander 2020|230|U|{G}{U}{R}|Instant|||Choose one —$• Target creature you control gets +1/+1 until end of turn. It fights target creature you don't control.$• Counter target spell unless its controller pays {3}.$• Creatures with power 3 or less can't block this turn.| Terminate|Commander 2020|231|U|{B}{R}|Instant|||Destroy target creature. It can't be regenerated.| Trygon Predator|Commander 2020|232|U|{1}{G}{U}|Creature - Beast|2|3|Flying$Whenever Trygon Predator deals combat damage to a player, you may destroy target artifact or enchantment that player controls.| @@ -37097,7 +37097,7 @@ Capture Sphere|Ikoria: Lair of Behemoths|44|C|{3}{U}|Enchantment - Aura|||Flash$ Convolute|Ikoria: Lair of Behemoths|45|C|{2}{U}|Instant|||Counter target spell unless its controller pays {4}.| Crystacean|Ikoria: Lair of Behemoths|46|C|{3}{U}|Creature - Crab|1|6|Flash| Dreamtail Heron|Ikoria: Lair of Behemoths|47|C|{4}{U}|Creature - Elemental Bird|3|4|Mutate {3}{U}$Flying$Whenever this creature mutates, draw a card.| -Escape Protocol|Ikoria: Lair of Behemoths|48|U|{1}{U}|Enchantment|||Whenever you cycle a card, you may pay {1}. When you do, exile target creature or artifact you control, then return it to the battlefield under its owner's control.| +Escape Protocol|Ikoria: Lair of Behemoths|48|U|{1}{U}|Enchantment|||Whenever you cycle a card, you may pay {1}. When you do, exile target artifact or creature you control, then return it to the battlefield under its owner's control.| Essence Scatter|Ikoria: Lair of Behemoths|49|C|{1}{U}|Instant|||Counter target creature spell.| Facet Reader|Ikoria: Lair of Behemoths|50|C|{1}{U}|Creature - Human Wizard|1|2|{1}, {T}: Draw a card, then discard a card.| Frost Lynx|Ikoria: Lair of Behemoths|51|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.| @@ -37296,7 +37296,7 @@ Blossoming Sands|Ikoria: Lair of Behemoths|244|C||Land|||Blossoming Sands enters Bonders' Enclave|Ikoria: Lair of Behemoths|245|R||Land|||{T}: Add {C}.${3}, {T}: Draw a card. Activate this ability only if you control a creature with power 4 or greater.| Dismal Backwater|Ikoria: Lair of Behemoths|246|C||Land|||Dismal Backwater enters the battlefield tapped.$When Dismal Backwater enters the battlefield, you gain 1 life.${T}: Add {U} or {B}.| Evolving Wilds|Ikoria: Lair of Behemoths|247|C||Land|||{T}, Sacrifice Evolving Wilds: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle your library.| -Indatha Triome|Ikoria: Lair of Behemoths|248|R||Land - Plains Forest Swamp|||({T}: Add {W}, {B}, or {G}.)$Indatha Triome enters the battlefield tapped.$Cycling {3}| +Indatha Triome|Ikoria: Lair of Behemoths|248|R||Land - Plains Swamp Forest|||({T}: Add {W}, {B}, or {G}.)$Indatha Triome enters the battlefield tapped.$Cycling {3}| Jungle Hollow|Ikoria: Lair of Behemoths|249|C||Land|||Jungle Hollow enters the battlefield tapped.$When Jungle Hollow enters the battlefield, you gain 1 life.${T}: Add {B} or {G}.| Ketria Triome|Ikoria: Lair of Behemoths|250|R||Land - Forest Island Mountain|||({T}: Add {G}, {U}, or {R}.)$Ketria Triome enters the battlefield tapped.$Cycling {3}| Raugrin Triome|Ikoria: Lair of Behemoths|251|R||Land - Island Mountain Plains|||({T}: Add {U}, {R}, or {W}.)$Raugrin Triome enters the battlefield tapped.$Cycling {3}|