diff --git a/Mage.Client/src/main/java/mage/client/components/HoverButton.java b/Mage.Client/src/main/java/mage/client/components/HoverButton.java index f7eca203f0..d7998fe504 100644 --- a/Mage.Client/src/main/java/mage/client/components/HoverButton.java +++ b/Mage.Client/src/main/java/mage/client/components/HoverButton.java @@ -1,12 +1,17 @@ package mage.client.components; -import mage.client.util.Command; - -import javax.swing.*; -import java.awt.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.font.FontRenderContext; +import javax.swing.JPanel; +import mage.client.util.Command; /** * Image button with hover. @@ -48,6 +53,8 @@ public class HoverButton extends JPanel implements MouseListener { static final Font textSetFontBold = new Font("Arial", Font.BOLD, 14); private boolean useMiniFont = false; + private boolean alignTextLeft = false; + public HoverButton(String text, Image image, Rectangle size) { this(text, image, image, null, image, size); if (image == null) { @@ -113,7 +120,7 @@ public class HoverButton extends JPanel implements MouseListener { } topTextOffsetX = calculateOffsetForTop(g2d, topText); g2d.setColor(textBGColor); - g2d.drawString(topText, topTextOffsetX+1, 13); + g2d.drawString(topText, topTextOffsetX + 1, 13); g2d.setColor(textColor); g2d.drawString(topText, topTextOffsetX, 12); } @@ -148,7 +155,11 @@ public class HoverButton extends JPanel implements MouseListener { frc = g2d.getFontRenderContext(); textWidth = (int) textFontMini.getStringBounds(text, frc).getWidth(); } - textOffsetX = (imageSize.width - textWidth) / 2; + if (alignTextLeft) { + textOffsetX = 0; + } else { + textOffsetX = (imageSize.width - textWidth) / 2; + } } return textOffsetX; } @@ -277,4 +288,8 @@ public class HoverButton extends JPanel implements MouseListener { this.textAlwaysVisible = textAlwaysVisible; } + public void setAlignTextLeft(boolean alignTextLeft) { + this.alignTextLeft = alignTextLeft; + } + } diff --git a/Mage.Client/src/main/java/mage/client/components/MageTextArea.java b/Mage.Client/src/main/java/mage/client/components/MageTextArea.java index 47c68ce141..159e437a0f 100644 --- a/Mage.Client/src/main/java/mage/client/components/MageTextArea.java +++ b/Mage.Client/src/main/java/mage/client/components/MageTextArea.java @@ -1,19 +1,16 @@ package mage.client.components; +import java.awt.Color; +import javax.swing.JEditorPane; +import javax.swing.SwingUtilities; import org.mage.card.arcane.ManaSymbols; import org.mage.card.arcane.UI; -import javax.swing.*; -import java.awt.*; -import javax.swing.text.JTextComponent; - /** - * Component for displaying text in mage. - * Supports drawing mana symbols. + * Component for displaying text in mage. Supports drawing mana symbols. * * @author nantuko */ - public class MageTextArea extends JEditorPane { public MageTextArea() { @@ -27,10 +24,10 @@ public class MageTextArea extends JEditorPane { @Override public void setText(String text) { - setText(text, 16); + setText(text, 0); } - public void setText(String text, int fontSize) { + public void setText(String text, final int panelWidth) { if (text == null) { return; } @@ -38,23 +35,36 @@ public class MageTextArea extends JEditorPane { final StringBuilder buffer = new StringBuilder(512); // Dialog is a java logical font family, so it should work on all systems buffer.append("
"); - text = text.replaceAll("#([^#]+)#", "$1"); + // Don't know what it does (easy italc?) but it bugs with multiple #HTML color codes (LevelX2) + //text = text.replaceAll("#([^#]+)#", "$1"); //text = text.replaceAll("\\s*//\\s*", "
"); text = text.replace("\r\n", "
"); + final String basicText = ManaSymbols.replaceSymbolsWithHTML(text, ManaSymbols.Type.PAY); if (text.length() > 0) { - buffer.append(ManaSymbols.replaceSymbolsWithHTML(text, ManaSymbols.Type.PAY)); + buffer.append(basicText); } buffer.append("
"); SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { - MageTextArea.super.setText(buffer.toString()); - //System.out.println(buffer.toString()); + String promptText = buffer.toString(); + MageTextArea.super.setText(promptText); + // in case the text don't fit in the panel a tooltip with the text is added + if (panelWidth > 0 && MageTextArea.this.getPreferredSize().getWidth() > panelWidth) { +// String tooltip = promptText +// .replace("color: #FFFFFF'>", "color: #111111'>

") +// .replace("", "

"); + String tooltip = "

" + basicText + "

"; + MageTextArea.super.setToolTipText(tooltip); + } else { + MageTextArea.super.setToolTipText(null); + } setCaretPosition(0); } }); diff --git a/Mage.Client/src/main/java/mage/client/dialog/CardInfoWindowDialog.java b/Mage.Client/src/main/java/mage/client/dialog/CardInfoWindowDialog.java index a0abd01fbf..284852f6c0 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/CardInfoWindowDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/CardInfoWindowDialog.java @@ -112,6 +112,25 @@ public class CardInfoWindowDialog extends MageDialog { cards.cleanUp(); } + public void loadCards(ExileView exile, BigCard bigCard, UUID gameId) { + boolean changed = cards.loadCards(exile, bigCard, gameId, null); + String titel = name + " (" + exile.size() + ")"; + setTitle(titel); + this.setTitelBarToolTip(titel); + if (exile.size() > 0) { + show(); + if (changed) { + try { + this.setIcon(false); + } catch (PropertyVetoException ex) { + Logger.getLogger(CardInfoWindowDialog.class.getName()).log(Level.SEVERE, null, ex); + } + } + } else { + this.hideDialog(); + } + } + public void loadCards(SimpleCardsView showCards, BigCard bigCard, UUID gameId) { cards.loadCards(showCards, bigCard, gameId); showAndPositionWindow(); @@ -120,8 +139,9 @@ public class CardInfoWindowDialog extends MageDialog { public void loadCards(CardsView showCards, BigCard bigCard, UUID gameId) { cards.loadCards(showCards, bigCard, gameId, null); if (showType.equals(ShowType.GRAVEYARD)) { - setTitle(name + "'s Graveyard (" + showCards.size() + ")"); - this.setTitelBarToolTip(name); + String titel = name + "'s Graveyard (" + showCards.size() + ")"; + setTitle(titel); + this.setTitelBarToolTip(titel); } showAndPositionWindow(); } @@ -160,22 +180,6 @@ public class CardInfoWindowDialog extends MageDialog { }); } - public void loadCards(ExileView exile, BigCard bigCard, UUID gameId) { - boolean changed = cards.loadCards(exile, bigCard, gameId, null); - if (exile.size() > 0) { - show(); - if (changed) { - try { - this.setIcon(false); - } catch (PropertyVetoException ex) { - Logger.getLogger(CardInfoWindowDialog.class.getName()).log(Level.SEVERE, null, ex); - } - } - } else { - this.hideDialog(); - } - } - /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form index cfc3e9c036..74699d8653 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form @@ -1150,21 +1150,21 @@ - + - + - + - + @@ -1256,6 +1256,14 @@ + + + + + + + + @@ -1328,14 +1336,6 @@ - - - - - - - - diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java index 39f59bf388..8ae68984ae 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java @@ -420,12 +420,12 @@ public class PreferencesDialog extends javax.swing.JDialog { txtBattlefieldIBGMPath = new javax.swing.JTextField(); btnBattlefieldBGMBrowse = new javax.swing.JButton(); tabAvatars = new javax.swing.JPanel(); - jScrollPane1 = new javax.swing.JScrollPane(); - jPanel9 = new javax.swing.JPanel(); + avatarPane = new javax.swing.JScrollPane(); + avatarPanel = new javax.swing.JPanel(); + jLabel12 = new javax.swing.JLabel(); jPanel10 = new javax.swing.JPanel(); jPanel13 = new javax.swing.JPanel(); jPanel11 = new javax.swing.JPanel(); - jLabel12 = new javax.swing.JLabel(); jPanel12 = new javax.swing.JPanel(); jPanel14 = new javax.swing.JPanel(); jPanel15 = new javax.swing.JPanel(); @@ -1190,6 +1190,9 @@ public class PreferencesDialog extends javax.swing.JDialog { tabsPanel.addTab("Sounds", tabSounds); + jLabel12.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N + jLabel12.setText("Choose your avatar:"); + jPanel10.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true)); javax.swing.GroupLayout jPanel10Layout = new javax.swing.GroupLayout(jPanel10); @@ -1229,9 +1232,6 @@ public class PreferencesDialog extends javax.swing.JDialog { .addGap(0, 100, Short.MAX_VALUE) ); - jLabel12.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N - jLabel12.setText("Choose your avatar:"); - jPanel12.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true)); javax.swing.GroupLayout jPanel12Layout = new javax.swing.GroupLayout(jPanel12); @@ -1352,68 +1352,68 @@ public class PreferencesDialog extends javax.swing.JDialog { .addGap(0, 100, Short.MAX_VALUE) ); - javax.swing.GroupLayout jPanel9Layout = new javax.swing.GroupLayout(jPanel9); - jPanel9.setLayout(jPanel9Layout); - jPanel9Layout.setHorizontalGroup( - jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel9Layout.createSequentialGroup() - .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel9Layout.createSequentialGroup() + javax.swing.GroupLayout avatarPanelLayout = new javax.swing.GroupLayout(avatarPanel); + avatarPanel.setLayout(avatarPanelLayout); + avatarPanelLayout.setHorizontalGroup( + avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(avatarPanelLayout.createSequentialGroup() + .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(avatarPanelLayout.createSequentialGroup() .addContainerGap() .addComponent(jLabel12)) - .addGroup(jPanel9Layout.createSequentialGroup() - .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel9Layout.createSequentialGroup() + .addGroup(avatarPanelLayout.createSequentialGroup() + .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(avatarPanelLayout.createSequentialGroup() .addGap(30, 30, 30) - .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jPanel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel19, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(33, 33, 33) - .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addGroup(jPanel9Layout.createSequentialGroup() + .addGroup(avatarPanelLayout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel9Layout.createSequentialGroup() + .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(avatarPanelLayout.createSequentialGroup() .addGap(20, 20, 20) .addComponent(jPanel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(33, 33, 33) .addComponent(jPanel17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jLabel13)))) .addGap(32, 32, 32) - .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - jPanel9Layout.setVerticalGroup( - jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel9Layout.createSequentialGroup() + avatarPanelLayout.setVerticalGroup( + avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(avatarPanelLayout.createSequentialGroup() .addContainerGap() .addComponent(jLabel12) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(26, 26, 26) - .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(23, 23, 23) - .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jPanel19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) - .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(jPanel9Layout.createSequentialGroup() + .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(avatarPanelLayout.createSequentialGroup() .addComponent(jLabel13) .addGap(18, 18, 18) .addComponent(jPanel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) @@ -1422,17 +1422,17 @@ public class PreferencesDialog extends javax.swing.JDialog { .addGap(25, 25, 25)) ); - jScrollPane1.setViewportView(jPanel9); + avatarPane.setViewportView(avatarPanel); javax.swing.GroupLayout tabAvatarsLayout = new javax.swing.GroupLayout(tabAvatars); tabAvatars.setLayout(tabAvatarsLayout); tabAvatarsLayout.setHorizontalGroup( tabAvatarsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 590, Short.MAX_VALUE) + .addComponent(avatarPane, javax.swing.GroupLayout.DEFAULT_SIZE, 590, Short.MAX_VALUE) ); tabAvatarsLayout.setVerticalGroup( tabAvatarsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 359, Short.MAX_VALUE) + .addComponent(avatarPane, javax.swing.GroupLayout.DEFAULT_SIZE, 359, Short.MAX_VALUE) ); tabsPanel.addTab("Avatars", tabAvatars); @@ -2423,7 +2423,7 @@ public class PreferencesDialog extends javax.swing.JDialog { public static UserData getUserData() { return new UserData(UserGroup.PLAYER, - getSelectedAvatar(), + PreferencesDialog.selectedAvatarId, PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_ANY_ZONE, "true").equals("true"), PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_ALLOW_REQUEST_SHOW_HAND_CARDS, "true").equals("true"), PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_CONFIRM_EMPTY_MANA_POOL, "true").equals("true"), @@ -2434,6 +2434,8 @@ public class PreferencesDialog extends javax.swing.JDialog { } // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JScrollPane avatarPane; + private javax.swing.JPanel avatarPanel; private javax.swing.JButton btnBattlefieldBGMBrowse; private javax.swing.JButton btnBrowseBackgroundImage; private javax.swing.JButton btnBrowseBattlefieldImage; @@ -2506,8 +2508,6 @@ public class PreferencesDialog extends javax.swing.JDialog { private javax.swing.JPanel jPanel19; private javax.swing.JPanel jPanel20; private javax.swing.JPanel jPanel21; - private javax.swing.JPanel jPanel9; - private javax.swing.JScrollPane jScrollPane1; private javax.swing.JLabel labelPreferedImageLanguage; private javax.swing.JLabel lblProxyPassword; private javax.swing.JLabel lblProxyPort; diff --git a/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java b/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java index fdd97d9b35..f246336bd6 100644 --- a/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java +++ b/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java @@ -1,37 +1,36 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ /* * FeedbackPanel.java * * Created on 23-Dec-2009, 9:54:01 PM */ - package mage.client.game; import java.awt.Component; @@ -61,6 +60,7 @@ public class FeedbackPanel extends javax.swing.JPanel { private static final Logger logger = Logger.getLogger(FeedbackPanel.class); public enum FeedbackMode { + INFORM, QUESTION, CONFIRM, CANCEL, SELECT, END } @@ -73,7 +73,9 @@ public class FeedbackPanel extends javax.swing.JPanel { private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor(); - /** Creates new form FeedbackPanel */ + /** + * Creates new form FeedbackPanel + */ public FeedbackPanel() { //initComponents(); customInitComponents(); @@ -170,7 +172,7 @@ public class FeedbackPanel extends javax.swing.JPanel { while (c != null && !(c instanceof GamePane)) { c = c.getParent(); } - if (c != null && ((GamePane)c).isVisible()) { // check if GamePanel still visible + if (c != null && ((GamePane) c).isVisible()) { // check if GamePanel still visible FeedbackPanel.this.btnRight.doClick(); } } @@ -181,8 +183,8 @@ public class FeedbackPanel extends javax.swing.JPanel { private void handleOptions(Map options) { if (options != null) { if (options.containsKey("UI.right.btn.text")) { - this.btnRight.setText((String)options.get("UI.right.btn.text")); - this.helper.setRight((String)options.get("UI.right.btn.text"), true); + this.btnRight.setText((String) options.get("UI.right.btn.text")); + this.helper.setRight((String) options.get("UI.right.btn.text"), true); } if (options.containsKey("dialog")) { connectedDialog = (MageDialog) options.get("dialog"); @@ -224,7 +226,7 @@ public class FeedbackPanel extends javax.swing.JPanel { btnUndo = new javax.swing.JButton(); btnUndo.setVisible(true); - setBackground(new java.awt.Color(0,0,0,80)); + setBackground(new java.awt.Color(0, 0, 0, 80)); btnRight.setText("Cancel"); btnRight.addActionListener(new java.awt.event.ActionListener() { @@ -294,7 +296,7 @@ public class FeedbackPanel extends javax.swing.JPanel { session.sendPlayerString(gameId, "special"); }//GEN-LAST:event_btnSpecialActionPerformed - private void btnUndoActionPerformed(java.awt.event.ActionEvent evt) { + private void btnUndoActionPerformed(java.awt.event.ActionEvent evt) { session.sendPlayerAction(PlayerAction.UNDO, gameId, null); } @@ -309,7 +311,7 @@ public class FeedbackPanel extends javax.swing.JPanel { public void setConnectedChatPanel(ChatPanel chatPanel) { this.connectedChatPanel = chatPanel; } - + public void pressOKYesOrDone() { if (btnLeft.getText().equals("OK") || btnLeft.getText().equals("Yes")) { btnLeft.doClick(); diff --git a/Mage.Client/src/main/java/mage/client/game/HelperPanel.java b/Mage.Client/src/main/java/mage/client/game/HelperPanel.java index 602e94b6b1..f4f716f92b 100644 --- a/Mage.Client/src/main/java/mage/client/game/HelperPanel.java +++ b/Mage.Client/src/main/java/mage/client/game/HelperPanel.java @@ -1,40 +1,43 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.client.game; import java.awt.Color; import java.awt.Dimension; import java.awt.GridBagLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.SwingUtilities; +import javax.swing.ToolTipManager; +import javax.swing.UIManager; import mage.client.components.MageTextArea; /** @@ -58,11 +61,15 @@ public class HelperPanel extends JPanel { private javax.swing.JButton linkSpecial; private javax.swing.JButton linkUndo; + private final int defaultDismissTimeout = ToolTipManager.sharedInstance().getDismissDelay(); + private final Object tooltipBackground = UIManager.get("info"); + public HelperPanel() { initComponents(); } private void initComponents() { + setBackground(new Color(0, 0, 0, 100)); //setLayout(new GridBagLayout()); setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); @@ -84,7 +91,7 @@ public class HelperPanel extends JPanel { add(jPanel); add(container); - + btnSpecial = new JButton("Special"); btnSpecial.setVisible(false); container.add(btnSpecial); @@ -101,22 +108,24 @@ public class HelperPanel extends JPanel { btnLeft.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent evt) { - if (linkLeft != null) {{ - Thread worker = new Thread(){ - @Override - public void run(){ - SwingUtilities.invokeLater(new Runnable(){ - @Override - public void run(){ - setState("",false,"",false); - setSpecial("", false); - linkLeft.doClick(); - } - }); - } - }; - worker.start(); - }} + if (linkLeft != null) { + { + Thread worker = new Thread() { + @Override + public void run() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + setState("", false, "", false); + setSpecial("", false); + linkLeft.doClick(); + } + }); + } + }; + worker.start(); + } + } } }); @@ -124,13 +133,13 @@ public class HelperPanel extends JPanel { @Override public void actionPerformed(java.awt.event.ActionEvent evt) { if (linkRight != null) { - Thread worker = new Thread(){ + Thread worker = new Thread() { @Override - public void run(){ - SwingUtilities.invokeLater(new Runnable(){ + public void run() { + SwingUtilities.invokeLater(new Runnable() { @Override - public void run(){ - setState("",false,"",false); + public void run() { + setState("", false, "", false); setSpecial("", false); linkRight.doClick(); } @@ -145,42 +154,61 @@ public class HelperPanel extends JPanel { btnSpecial.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent evt) { - if (linkSpecial != null) {{ - Thread worker = new Thread(){ - @Override - public void run(){ - SwingUtilities.invokeLater(new Runnable(){ - @Override - public void run(){ - setState("",false,"",false); - setSpecial("", false); - linkSpecial.doClick(); - } - }); - } - }; - worker.start(); - }} + if (linkSpecial != null) { + { + Thread worker = new Thread() { + @Override + public void run() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + setState("", false, "", false); + setSpecial("", false); + linkSpecial.doClick(); + } + }); + } + }; + worker.start(); + } + } } }); btnUndo.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent evt) { - if (linkUndo != null) {{ - Thread worker = new Thread(){ - @Override - public void run(){ - SwingUtilities.invokeLater(new Runnable(){ - @Override - public void run(){ - linkUndo.doClick(); - } - }); - } - }; - worker.start(); - }} + if (linkUndo != null) { + { + Thread worker = new Thread() { + @Override + public void run() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + linkUndo.doClick(); + } + }); + } + }; + worker.start(); + } + } + } + }); + + textArea.addMouseListener(new MouseAdapter() { + + @Override + public void mouseEntered(MouseEvent me) { + ToolTipManager.sharedInstance().setDismissDelay(100000); + UIManager.put("info", Color.DARK_GRAY); + } + + @Override + public void mouseExited(MouseEvent me) { + ToolTipManager.sharedInstance().setDismissDelay(defaultDismissTimeout); + UIManager.put("info", tooltipBackground); } }); } @@ -218,19 +246,20 @@ public class HelperPanel extends JPanel { this.linkSpecial = special; this.linkUndo = undo; } - + public void setMessage(String message) { - if (message.startsWith("Use alternative cost")) { - message = "Use alternative cost?"; - } else if (message.contains("Use ")) { - if (message.length() < this.getWidth() / 10) { - message = getSmallText(message); - } else { - message = "Use ability?" + getSmallText(message.substring(0, this.getWidth() / 10)); - } - } - textArea.setText(message); +// if (message.startsWith("Use alternative cost")) { +// message = "Use alternative cost?"; +// } else if (message.contains("Use ")) { +// if (message.length() < this.getWidth() / 10) { +// message = getSmallText(message); +// } else { +// message = "Use ability?" + getSmallText(message.substring(0, this.getWidth() / 10)); +// } +// } + textArea.setText(message, this.getWidth()); } + protected String getSmallText(String text) { return "
" + text + "
"; } diff --git a/Mage.Client/src/main/java/mage/client/game/PlayerPanelExt.java b/Mage.Client/src/main/java/mage/client/game/PlayerPanelExt.java index 895d0f7c69..5b8de71db4 100644 --- a/Mage.Client/src/main/java/mage/client/game/PlayerPanelExt.java +++ b/Mage.Client/src/main/java/mage/client/game/PlayerPanelExt.java @@ -328,8 +328,8 @@ public class PlayerPanelExt extends javax.swing.JPanel { avatar.add(new JLabel()); avatar.add(new JLabel()); avatar.add(avatarFlag); - avatar.setAlignmentY(CENTER_ALIGNMENT); - avatarFlag.setHorizontalAlignment(JLabel.CENTER); + avatar.setAlignTextLeft(true); + avatarFlag.setHorizontalAlignment(JLabel.LEFT); avatarFlag.setVerticalAlignment(JLabel.BOTTOM); avatar.add(new JLabel()); String showPlayerNamePermanently = MageFrame.getPreferences().get(PreferencesDialog.KEY_SHOW_PLAYER_NAMES_PERMANENTLY, "true"); diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java index 4fc02a780e..c6ba9cec91 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java @@ -1286,7 +1286,7 @@ public class ComputerPlayer extends PlayerImpl implements Player { } @Override - public boolean chooseUse(Outcome outcome, String message, Game game) { + public boolean chooseUse(Outcome outcome, String message, Ability source, Game game) { log.debug("chooseUse: " + outcome.isGood()); // Be proactive! Always use abilities, the evaluation function will decide if it's good or not // Otherwise some abilities won't be used by AI like LoseTargetEffect that has "bad" outcome diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java index c64f365fd4..f43fc6dc02 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java +++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java @@ -1,16 +1,16 @@ /* * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,20 +20,31 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ package mage.player.ai; -import mage.constants.Outcome; -import mage.abilities.*; +import java.io.Serializable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.ActivatedAbility; +import mage.abilities.Mode; +import mage.abilities.Modes; +import mage.abilities.TriggeredAbility; import mage.abilities.common.PassAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.cards.Card; import mage.cards.Cards; import mage.choices.Choice; +import mage.constants.Outcome; import mage.game.Game; import mage.game.combat.CombatGroup; import mage.game.permanent.Permanent; @@ -44,13 +55,10 @@ import mage.target.TargetAmount; import mage.target.TargetCard; import org.apache.log4j.Logger; -import java.io.Serializable; -import java.util.*; - /** * * plays randomly - * + * * @author BetaSteward_at_googlemail.com */ public class SimulatedPlayerMCTS extends MCTSPlayer { @@ -58,7 +66,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { private boolean isSimulatedPlayer; private static Random rnd = new Random(); private int actionCount = 0; - private static final transient Logger logger = Logger.getLogger(SimulatedPlayerMCTS.class); + private static final transient Logger logger = Logger.getLogger(SimulatedPlayerMCTS.class); public SimulatedPlayerMCTS(UUID id, boolean isSimulatedPlayer) { super(id); @@ -83,14 +91,15 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { return actionCount; } - @Override + @Override public boolean priority(Game game) { // logger.info("priority"); boolean didSomething = false; Ability ability = getAction(game); // logger.info("simulate " + ability.toString()); - if (!(ability instanceof PassAbility)) + if (!(ability instanceof PassAbility)) { didSomething = true; + } activateAbility((ActivatedAbility) ability, game); @@ -102,16 +111,18 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { List playables = getPlayableAbilities(game); Ability ability; while (true) { - if (playables.size() == 1) + if (playables.size() == 1) { ability = playables.get(0); - else + } else { ability = playables.get(rnd.nextInt(playables.size())); + } List options = getPlayableOptions(ability, game); if (!options.isEmpty()) { - if (options.size() == 1) + if (options.size() == 1) { ability = options.get(0); - else + } else { ability = options.get(rnd.nextInt(options.size())); + } } if (ability.getManaCosts().getVariableCosts().size() > 0) { int amount = getAvailableManaProducers(game).size() - ability.getManaCosts().convertedManaCost(); @@ -133,7 +144,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { // } // } // else { - break; + break; // } } return ability; @@ -147,12 +158,12 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { List options = getPlayableOptions(source, game); if (options.isEmpty()) { ability = source; - } - else { - if (options.size() == 1) + } else { + if (options.size() == 1) { ability = options.get(0); - else + } else { ability = options.get(rnd.nextInt(options.size())); + } } if (ability.isUsesStack()) { game.getStack().push(new StackAbility(ability, playerId)); @@ -205,7 +216,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { } List blockers = getAvailableBlockers(game); - for (Permanent blocker: blockers) { + for (Permanent blocker : blockers) { int check = rnd.nextInt(numGroups + 1); if (check < numGroups) { CombatGroup group = game.getCombat().getGroups().get(check); @@ -242,9 +253,10 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { } protected boolean chooseRandomTarget(Target target, Ability source, Game game) { - Set possibleTargets = target.possibleTargets(source==null?null:source.getSourceId(), playerId, game); - if (possibleTargets.isEmpty()) + Set possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game); + if (possibleTargets.isEmpty()) { return false; + } if (!target.isRequired(source)) { if (rnd.nextInt(possibleTargets.size() + 1) == 0) { return false; @@ -266,8 +278,9 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { @Override public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) { - if (this.isHuman()) + if (this.isHuman()) { return chooseRandom(target, game); + } return super.choose(outcome, target, sourceId, game); } @@ -318,7 +331,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { @Override public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) { - Set possibleTargets = target.possibleTargets(source==null?null:source.getSourceId(), playerId, game); + Set possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game); if (possibleTargets.isEmpty()) { return !target.isRequired(source); } @@ -347,11 +360,11 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { } @Override - public boolean chooseUse(Outcome outcome, String message, Game game) { + public boolean chooseUse(Outcome outcome, String message, Ability source, Game game) { if (this.isHuman()) { return rnd.nextBoolean(); } - return super.chooseUse(outcome, message, game); + return super.chooseUse(outcome, message, source, game); } @Override @@ -436,8 +449,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { if (targets.size() == 1) { targetId = targets.get(0); amount = remainingDamage; - } - else { + } else { targetId = targets.get(rnd.nextInt(targets.size())); amount = rnd.nextInt(damage + 1); } @@ -445,8 +457,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { if (permanent != null) { permanent.damage(amount, sourceId, game, false, true); remainingDamage -= amount; - } - else { + } else { Player player = game.getPlayer(targetId); if (player != null) { player.damage(amount, sourceId, game, false, true); @@ -455,8 +466,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer { } targets.remove(targetId); } - } - else { + } else { super.assignDamage(damage, targets, singleTargetName, sourceId, game); } } diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index 77bb838f1d..3d0370d9e7 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -1,35 +1,50 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.player.human; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; import mage.MageObject; -import mage.abilities.*; +import mage.abilities.Ability; +import mage.abilities.ActivatedAbility; +import mage.abilities.Mode; +import mage.abilities.Modes; +import mage.abilities.PlayLandAbility; +import mage.abilities.SpecialAction; +import mage.abilities.SpellAbility; +import mage.abilities.TriggeredAbility; import mage.abilities.costs.VariableCost; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.mana.ManaCost; @@ -42,7 +57,13 @@ import mage.cards.Cards; import mage.cards.decks.Deck; import mage.choices.Choice; import mage.choices.ChoiceImpl; -import mage.constants.*; +import mage.constants.Constants; +import mage.constants.ManaType; +import mage.constants.Outcome; +import mage.constants.PhaseStep; +import mage.constants.PlayerAction; +import mage.constants.RangeOfInfluence; +import mage.constants.Zone; import mage.filter.common.FilterAttackingCreature; import mage.filter.common.FilterBlockingCreature; import mage.filter.common.FilterCreatureForCombat; @@ -63,13 +84,10 @@ import mage.target.TargetPermanent; import mage.target.common.TargetAttackingCreature; import mage.target.common.TargetCreatureOrPlayer; import mage.target.common.TargetDefender; +import mage.util.GameLog; import mage.util.ManaUtil; import org.apache.log4j.Logger; -import java.io.Serializable; -import java.util.*; -import mage.util.GameLog; - /** * * @author BetaSteward_at_googlemail.com @@ -85,6 +103,7 @@ public class HumanPlayer extends PlayerImpl { protected static final Choice replacementEffectChoice = new ChoiceImpl(true); private static final Logger log = Logger.getLogger(HumanPlayer.class); + static { replacementEffectChoice.setMessage("Choose replacement effect to resolve first"); } @@ -104,7 +123,7 @@ public class HumanPlayer extends PlayerImpl { response.clear(); log.debug("Waiting response from player: " + getId()); game.resumeTimer(getTurnControlledBy()); - synchronized(response) { + synchronized (response) { try { response.wait(); log.debug("Got response from player: " + getId()); @@ -145,9 +164,9 @@ public class HumanPlayer extends PlayerImpl { updateGameStatePriority("chooseMulligan", game); int nextHandSize = game.mulliganDownTo(playerId); game.fireAskPlayerEvent(playerId, new StringBuilder("Mulligan ") - .append(getHand().size() > nextHandSize?"down to ":"for free, draw ") + .append(getHand().size() > nextHandSize ? "down to " : "for free, draw ") .append(nextHandSize) - .append(nextHandSize == 1?" card?":" cards?").toString()); + .append(nextHandSize == 1 ? " card?" : " cards?").toString()); waitForBooleanResponse(game); if (!abort) { return response.getBoolean(); @@ -156,9 +175,9 @@ public class HumanPlayer extends PlayerImpl { } @Override - public boolean chooseUse(Outcome outcome, String message, Game game) { + public boolean chooseUse(Outcome outcome, String message, Ability source, Game game) { updateGameStatePriority("chooseUse", game); - game.fireAskPlayerEvent(playerId, message); + game.fireAskPlayerEvent(playerId, addSecondLineWithObjectName(message, source == null ? null : source.getSourceId(), game)); waitForBooleanResponse(game); if (!abort) { return response.getBoolean(); @@ -166,6 +185,19 @@ public class HumanPlayer extends PlayerImpl { return false; } + private String addSecondLineWithObjectName(String message, UUID sourceId, Game game) { + if (sourceId != null) { + MageObject mageObject = game.getPermanent(sourceId); + if (mageObject == null) { + mageObject = game.getCard(sourceId); + } + if (mageObject != null) { + message += "
" + mageObject.getLogName() + "
"; + } + } + return message; + } + @Override public int chooseReplacementEffect(Map rEffects, Game game) { updateGameStatePriority("chooseEffect", game); @@ -173,7 +205,7 @@ public class HumanPlayer extends PlayerImpl { return 0; } if (!autoSelectReplacementEffects.isEmpty()) { - for (String autoKey :autoSelectReplacementEffects) { + for (String autoKey : autoSelectReplacementEffects) { int count = 0; for (String effectKey : rEffects.keySet()) { if (effectKey.equals(autoKey)) { @@ -230,22 +262,22 @@ public class HumanPlayer extends PlayerImpl { @Override public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) { - return choose(outcome, target, sourceId, game, null); + return choose(outcome, target, sourceId, game, null); } @Override public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game, Map options) { - updateGameStatePriority("choose(5)", game); + updateGameStatePriority("choose(5)", game); UUID abilityControllerId = playerId; if (target.getTargetController() != null && target.getAbilityController() != null) { abilityControllerId = target.getAbilityController(); - } + } if (options == null) { options = new HashMap<>(); } while (!abort) { Set targetIds = target.possibleTargets(sourceId, abilityControllerId, game); - if (targetIds == null || targetIds.isEmpty()) { + if (targetIds == null || targetIds.isEmpty()) { return target.getTargets().size() >= target.getNumberOfTargets(); } boolean required = target.isRequired(sourceId, game); @@ -254,18 +286,18 @@ public class HumanPlayer extends PlayerImpl { } List chosen = target.getTargets(); - options.put("chosen", (Serializable)chosen); + options.put("chosen", (Serializable) chosen); - game.fireSelectTargetEvent(getId(), target.getMessage(), targetIds, required, getOptions(target, options)); + game.fireSelectTargetEvent(getId(), addSecondLineWithObjectName(target.getMessage(), sourceId, game), targetIds, required, getOptions(target, options)); waitForResponse(game); if (response.getUUID() != null) { if (!targetIds.contains(response.getUUID())) { continue; } if (target instanceof TargetPermanent) { - if (((TargetPermanent)target).canTarget(abilityControllerId, response.getUUID(), sourceId, game, false)) { + if (((TargetPermanent) target).canTarget(abilityControllerId, response.getUUID(), sourceId, game, false)) { target.add(response.getUUID(), game); - if(target.doneChosing()){ + if (target.doneChosing()) { return true; } } @@ -276,8 +308,8 @@ public class HumanPlayer extends PlayerImpl { if (target.getTargets().contains(response.getUUID())) { // if already included remove it with target.remove(response.getUUID()); } else { - target.addTarget(response.getUUID(), (Ability)object, game); - if(target.doneChosing()){ + target.addTarget(response.getUUID(), (Ability) object, game); + if (target.doneChosing()) { return true; } } @@ -288,7 +320,7 @@ public class HumanPlayer extends PlayerImpl { target.remove(response.getUUID()); } else { target.addTarget(response.getUUID(), null, game); - if(target.doneChosing()){ + if (target.doneChosing()) { return true; } } @@ -316,12 +348,13 @@ public class HumanPlayer extends PlayerImpl { abilityControllerId = target.getAbilityController(); } while (!abort) { - Set possibleTargets = target.possibleTargets(source==null?null:source.getSourceId(), abilityControllerId, game); + Set possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), abilityControllerId, game); boolean required = target.isRequired(source); if (possibleTargets.isEmpty() || target.getTargets().size() >= target.getNumberOfTargets()) { required = false; } - game.fireSelectTargetEvent(getId(), target.getMessage(), possibleTargets, required, getOptions(target, null)); + + game.fireSelectTargetEvent(getId(), addSecondLineWithObjectName(target.getMessage(), source == null ? null : source.getSourceId(), game), possibleTargets, required, getOptions(target, null)); waitForResponse(game); if (response.getUUID() != null) { if (target.getTargets().contains(response.getUUID())) { @@ -331,11 +364,11 @@ public class HumanPlayer extends PlayerImpl { if (possibleTargets.contains(response.getUUID())) { if (target.canTarget(abilityControllerId, response.getUUID(), source, game)) { target.addTarget(response.getUUID(), source, game); - if(target.doneChosing()){ + if (target.doneChosing()) { return true; } } - } + } } else { if (target.getTargets().size() >= target.getNumberOfTargets()) { return true; @@ -348,7 +381,7 @@ public class HumanPlayer extends PlayerImpl { return false; } - private Map getOptions(Target target, Map options ) { + private Map getOptions(Target target, Map options) { if (options == null) { options = new HashMap<>(); } @@ -356,7 +389,7 @@ public class HumanPlayer extends PlayerImpl { options.put("UI.right.btn.text", "Done"); } options.put("targetZone", target.getZone()); - return options; + return options; } @Override @@ -378,7 +411,7 @@ public class HumanPlayer extends PlayerImpl { } Map options = getOptions(target, null); List chosen = target.getTargets(); - options.put("chosen", (Serializable)chosen); + options.put("chosen", (Serializable) chosen); List choosable = new ArrayList<>(); for (UUID cardId : cards) { if (target.canTarget(cardId, cards, game)) { @@ -392,7 +425,7 @@ public class HumanPlayer extends PlayerImpl { waitForResponse(game); if (response.getUUID() != null) { if (target.canTarget(response.getUUID(), cards, game)) { - if (target.getTargets().contains(response.getUUID())) { // if already included remove it with + if (target.getTargets().contains(response.getUUID())) { // if already included remove it with target.remove(response.getUUID()); } else { target.add(response.getUUID(), game); @@ -432,7 +465,7 @@ public class HumanPlayer extends PlayerImpl { } Map options = getOptions(target, null); List chosen = target.getTargets(); - options.put("chosen", (Serializable)chosen); + options.put("chosen", (Serializable) chosen); List choosable = new ArrayList<>(); for (UUID cardId : cards) { if (target.canTarget(cardId, cards, game)) { @@ -442,10 +475,10 @@ public class HumanPlayer extends PlayerImpl { if (!choosable.isEmpty()) { options.put("choosable", (Serializable) choosable); } - game.fireSelectTargetEvent(playerId, target.getMessage(), cards, required, options); + game.fireSelectTargetEvent(playerId, addSecondLineWithObjectName(target.getMessage(), source == null ? null : source.getSourceId(), game), cards, required, options); waitForResponse(game); if (response.getUUID() != null) { - if (target.getTargets().contains(response.getUUID())) { // if already included remove it + if (target.getTargets().contains(response.getUUID())) { // if already included remove it target.remove(response.getUUID()); } else { if (target.canTarget(response.getUUID(), cards, game)) { @@ -471,8 +504,8 @@ public class HumanPlayer extends PlayerImpl { public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) { updateGameStatePriority("chooseTargetAmount", game); while (!abort) { - game.fireSelectTargetEvent(playerId, target.getMessage() + "\n Amount remaining:" + target.getAmountRemaining(), - target.possibleTargets(source==null?null:source.getSourceId(), playerId, game), + game.fireSelectTargetEvent(playerId, addSecondLineWithObjectName(target.getMessage() + "\n Amount remaining:" + target.getAmountRemaining(), source.getSourceId(), game), + target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game), target.isRequired(source), getOptions(target, null)); waitForResponse(game); @@ -495,7 +528,7 @@ public class HumanPlayer extends PlayerImpl { passed = false; if (!abort) { if (passedAllTurns) { - if(passWithManaPoolCheck(game)) { + if (passWithManaPoolCheck(game)) { return false; } } @@ -503,7 +536,7 @@ public class HumanPlayer extends PlayerImpl { passedUntilStackResolved = false; boolean dontCheckPassStep = false; if (passedTurn) { - if(passWithManaPoolCheck(game)) { + if (passWithManaPoolCheck(game)) { return false; } } @@ -512,7 +545,7 @@ public class HumanPlayer extends PlayerImpl { // it's a main phase if (!skippedAtLeastOnce || (!playerId.equals(game.getActivePlayerId()) && !this.getUserData().getUserSkipPrioritySteps().isStopOnAllMainPhases())) { skippedAtLeastOnce = true; - if(passWithManaPoolCheck(game)) { + if (passWithManaPoolCheck(game)) { return false; } } else { @@ -521,7 +554,7 @@ public class HumanPlayer extends PlayerImpl { } } else { skippedAtLeastOnce = true; - if(passWithManaPoolCheck(game)) { + if (passWithManaPoolCheck(game)) { return false; } } @@ -531,7 +564,7 @@ public class HumanPlayer extends PlayerImpl { // It's end of turn phase if (!skippedAtLeastOnce || (playerId.equals(game.getActivePlayerId()) && !this.getUserData().getUserSkipPrioritySteps().isStopOnAllEndPhases())) { skippedAtLeastOnce = true; - if(passWithManaPoolCheck(game)) { + if (passWithManaPoolCheck(game)) { return false; } } else { @@ -540,20 +573,20 @@ public class HumanPlayer extends PlayerImpl { } } else { skippedAtLeastOnce = true; - if(passWithManaPoolCheck(game)) { + if (passWithManaPoolCheck(game)) { return false; } } } if (!dontCheckPassStep && checkPassStep(game)) { - if(passWithManaPoolCheck(game)) { + if (passWithManaPoolCheck(game)) { return false; } - } + } } else if (passedUntilStackResolved) { if (dateLastAddedToStack == game.getStack().getDateLastAdded()) { dateLastAddedToStack = game.getStack().getDateLastAdded(); - if(passWithManaPoolCheck(game)) { + if (passWithManaPoolCheck(game)) { return false; } } else { @@ -564,7 +597,7 @@ public class HumanPlayer extends PlayerImpl { updateGameStatePriority("priority", game); game.firePriorityEvent(playerId); waitForResponse(game); - if(game.executingRollback()) { + if (game.executingRollback()) { return true; } if (response.getBoolean() != null || response.getInteger() != null) { @@ -573,10 +606,10 @@ public class HumanPlayer extends PlayerImpl { } else { continue; } - } + } break; } - + if (response.getString() != null && response.getString().equals("special")) { specialAction(game); } else if (response.getUUID() != null) { @@ -593,7 +626,7 @@ public class HumanPlayer extends PlayerImpl { if (game.getPriorityPlayerId().equals(playerId)) { actingPlayer = this; } else if (getPlayersUnderYourControl().contains(game.getPriorityPlayerId())) { - actingPlayer = game.getPlayer(game.getPriorityPlayerId()); + actingPlayer = game.getPlayer(game.getPriorityPlayerId()); } if (actingPlayer != null) { LinkedHashMap useableAbilities = actingPlayer.getUseableActivatedAbilities(object, zone, game); @@ -628,7 +661,7 @@ public class HumanPlayer extends PlayerImpl { game.fireSelectTargetEvent(playerId, "Pick triggered ability (goes to the stack first)", abilities); waitForResponse(game); if (response.getUUID() != null) { - for (TriggeredAbility ability: abilities) { + for (TriggeredAbility ability : abilities) { if (ability.getId().equals(response.getUUID())) { return ability; } @@ -638,7 +671,6 @@ public class HumanPlayer extends PlayerImpl { return null; } - @Override public boolean playMana(ManaCost unpaid, String promptText, Game game) { payManaMode = true; @@ -647,7 +679,6 @@ public class HumanPlayer extends PlayerImpl { return result; } - protected boolean playManaHandling(ManaCost unpaid, String promptText, Game game) { updateGameStatePriority("playMana", game); game.firePlayManaEvent(playerId, "Pay " + promptText); @@ -666,9 +697,9 @@ public class HumanPlayer extends PlayerImpl { ManaCostsImpl costs = (ManaCostsImpl) unpaid; for (ManaCost cost : costs.getUnpaid()) { if (cost instanceof PhyrexianManaCost) { - PhyrexianManaCost ph = (PhyrexianManaCost)cost; + PhyrexianManaCost ph = (PhyrexianManaCost) cost; if (ph.canPay(null, null, playerId, game)) { - ((PhyrexianManaCost)cost).pay(null, game, null, playerId, false); + ((PhyrexianManaCost) cost).pay(null, game, null, playerId, false); } break; } @@ -679,13 +710,14 @@ public class HumanPlayer extends PlayerImpl { if (response.getResponseManaTypePlayerId().equals(this.getId())) { this.getManaPool().unlockManaType(response.getManaType()); } - // TODO: Handle if mana pool + // TODO: Handle if mana pool } return true; } /** * Gets the amount of mana the player want to spent for a x spell + * * @param min * @param max * @param message @@ -700,7 +732,7 @@ public class HumanPlayer extends PlayerImpl { game.fireGetAmountEvent(playerId, message, min, max); waitForIntegerResponse(game); if (response != null && response.getInteger() != null) { - xValue = response.getInteger(); + xValue = response.getInteger(); } return xValue; } @@ -712,7 +744,7 @@ public class HumanPlayer extends PlayerImpl { game.fireGetAmountEvent(playerId, message, min, max); waitForIntegerResponse(game); if (response != null && response.getInteger() != null) { - xValue = response.getInteger(); + xValue = response.getInteger(); } return xValue; } @@ -722,7 +754,7 @@ public class HumanPlayer extends PlayerImpl { MageObject object = game.getObject(response.getUUID()); if (object == null) { return; - } + } Zone zone = game.getState().getZone(object.getId()); if (zone != null) { LinkedHashMap useableAbilities = getUseableManaAbilities(object, zone, game); @@ -739,8 +771,8 @@ public class HumanPlayer extends PlayerImpl { FilterCreatureForCombat filter = filterCreatureForCombat.copy(); filter.add(new ControllerIdPredicate(attackingPlayerId)); while (!abort) { - if (passedAllTurns || - (!getUserData().getUserSkipPrioritySteps().isStopOnDeclareAttackersDuringSkipAction() && (passedTurn || passedUntilEndOfTurn || passedUntilNextMain) )) { + if (passedAllTurns + || (!getUserData().getUserSkipPrioritySteps().isStopOnDeclareAttackersDuringSkipAction() && (passedTurn || passedUntilEndOfTurn || passedUntilNextMain))) { return; } Map options = new HashMap<>(); @@ -751,7 +783,7 @@ public class HumanPlayer extends PlayerImpl { possibleAttackers.add(possibleAttacker.getId()); } } - options.put(Constants.Option.POSSIBLE_ATTACKERS, (Serializable)possibleAttackers); + options.put(Constants.Option.POSSIBLE_ATTACKERS, (Serializable) possibleAttackers); game.fireSelectEvent(playerId, "Select attackers", options); waitForResponse(game); @@ -761,7 +793,7 @@ public class HumanPlayer extends PlayerImpl { if (!game.getCombat().getAttackers().containsAll(game.getCombat().getCreaturesForcedToAttack().keySet())) { int forcedAttackers = 0; StringBuilder sb = new StringBuilder(); - for (UUID creatureId :game.getCombat().getCreaturesForcedToAttack().keySet()) { + for (UUID creatureId : game.getCombat().getCreaturesForcedToAttack().keySet()) { boolean validForcedAttacker = false; if (game.getCombat().getAttackers().contains(creatureId)) { Set possibleDefender = game.getCombat().getCreaturesForcedToAttack().get(creatureId); @@ -777,10 +809,10 @@ public class HumanPlayer extends PlayerImpl { sb.append(creature.getName()).append(" "); } } - + } if (game.getCombat().getMaxAttackers() > forcedAttackers) { - game.informPlayer(this, sb.insert(0," more attacker(s) that are forced to attack.\nCreatures forced to attack: ") + game.informPlayer(this, sb.insert(0, " more attacker(s) that are forced to attack.\nCreatures forced to attack: ") .insert(0, Math.min(game.getCombat().getMaxAttackers() - forcedAttackers, game.getCombat().getCreaturesForcedToAttack().size() - forcedAttackers)) .insert(0, "You have to attack with ").toString()); continue; @@ -799,18 +831,17 @@ public class HumanPlayer extends PlayerImpl { if (attacker != null) { if (filterCreatureForCombat.match(attacker, null, playerId, game)) { selectDefender(game.getCombat().getDefenders(), attacker.getId(), game); - } - else if (filterAttack.match(attacker, null, playerId, game) && game.getStack().isEmpty()) { + } else if (filterAttack.match(attacker, null, playerId, game) && game.getStack().isEmpty()) { removeAttackerIfPossible(game, attacker); } } - } + } } } private void removeAttackerIfPossible(Game game, Permanent attacker) { for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(attacker, game).entrySet()) { - RequirementEffect effect = (RequirementEffect)entry.getKey(); + RequirementEffect effect = (RequirementEffect) entry.getKey(); if (effect.mustAttack(game)) { if (game.getCombat().getMaxAttackers() >= game.getCombat().getCreaturesForcedToAttack().size() && game.getCombat().getDefenders().size() == 1) { return; // we can't change creatures forced to attack if only one possible defender exists and all forced creatures can attack @@ -840,8 +871,7 @@ public class HumanPlayer extends PlayerImpl { if (possibleDefender.size() == 1) { declareAttacker(attackerId, defenders.iterator().next(), game, true); return true; - } - else { + } else { TargetDefender target = new TargetDefender(possibleDefender, attackerId); target.setNotTarget(true); // player or planswalker hexproof does not prevent attacking a player if (forcedToAttack) { @@ -880,14 +910,14 @@ public class HumanPlayer extends PlayerImpl { if (blocker != null) { boolean removeBlocker = false; // does not block yet and can block or can block more attackers - if (filter.match(blocker, null, playerId, game)) { + if (filter.match(blocker, null, playerId, game)) { selectCombatGroup(defendingPlayerId, blocker.getId(), game); } else { if (filterBlock.match(blocker, null, playerId, game) && game.getStack().isEmpty()) { removeBlocker = true; - } + } } - + if (removeBlocker) { game.getCombat().removeBlocker(blocker.getId(), game); } @@ -903,7 +933,7 @@ public class HumanPlayer extends PlayerImpl { game.fireSelectTargetEvent(playerId, "Pick attacker", attackers, true); waitForResponse(game); if (response.getUUID() != null) { - for (Permanent perm: attackers) { + for (Permanent perm : attackers) { if (perm.getId().equals(response.getUUID())) { return perm.getId(); } @@ -913,7 +943,6 @@ public class HumanPlayer extends PlayerImpl { return null; } - @Override public UUID chooseBlockerOrder(List blockers, CombatGroup combatGroup, List blockerOrder, Game game) { updateGameStatePriority("chooseBlockerOrder", game); @@ -921,7 +950,7 @@ public class HumanPlayer extends PlayerImpl { game.fireSelectTargetEvent(playerId, "Pick blocker", blockers, true); waitForResponse(game); if (response.getUUID() != null) { - for (Permanent perm: blockers) { + for (Permanent perm : blockers) { if (perm.getId().equals(response.getUUID())) { return perm.getId(); } @@ -942,7 +971,7 @@ public class HumanPlayer extends PlayerImpl { CombatGroup group = game.getCombat().findGroup(response.getUUID()); if (group != null) { // check if already blocked, if not add - if (!group.getBlockers().contains(blockerId)) { + if (!group.getBlockers().contains(blockerId)) { declareBlocker(defenderId, blockerId, response.getUUID(), game); } else { // else remove from block game.getCombat().removeBlockerGromGroup(blockerId, group, game); @@ -967,8 +996,7 @@ public class HumanPlayer extends PlayerImpl { if (permanent != null) { permanent.damage(damageAmount, sourceId, game, false, true); remainingDamage -= damageAmount; - } - else { + } else { Player player = game.getPlayer(target.getFirstTarget()); if (player != null) { player.damage(damageAmount, sourceId, game, false, true); @@ -1006,7 +1034,7 @@ public class HumanPlayer extends PlayerImpl { draft.firePickCardEvent(playerId); } - protected void specialAction(Game game) { + protected void specialAction(Game game) { LinkedHashMap specialActions = game.getState().getSpecialActions().getControlledBy(playerId, false); if (!specialActions.isEmpty()) { updateGameStatePriority("specialAction", game); @@ -1041,7 +1069,7 @@ public class HumanPlayer extends PlayerImpl { @Override public boolean activateAbility(ActivatedAbility ability, Game game) { getManaPool().setStock(); // needed for the "mana already in the pool has to be used manually" option - return super.activateAbility(ability, game); + return super.activateAbility(ability, game); } protected void activateAbility(LinkedHashMap abilities, MageObject object, Game game) { @@ -1066,7 +1094,7 @@ public class HumanPlayer extends PlayerImpl { if (this.getUserData().isShowAbilityPickerForced()) { if (ability instanceof PlayLandAbility) { return true; - } + } if (!ability.getSourceId().equals(getCastSourceIdWithAlternateMana()) && ability.getManaCostsToPay().convertedManaCost() > 0) { return true; } @@ -1078,10 +1106,10 @@ public class HumanPlayer extends PlayerImpl { } return true; } - + @Override public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana) { - switch(ability.getSpellAbilityType()) { + switch (ability.getSpellAbilityType()) { case SPLIT: case SPLIT_FUSED: MageObject object = game.getObject(ability.getSourceId()); @@ -1111,7 +1139,7 @@ public class HumanPlayer extends PlayerImpl { if (modes.size() > 1) { MageObject obj = game.getObject(source.getSourceId()); Map modeMap = new LinkedHashMap<>(); - for (Mode mode: modes.values()) { + for (Mode mode : modes.values()) { if (!modes.getSelectedModes().contains(mode.getId()) // show only modes not already selected && mode.getTargets().canChoose(source.getSourceId(), source.getControllerId(), game)) { // and where targets are available String modeText = mode.getEffects().getText(mode); @@ -1125,7 +1153,7 @@ public class HumanPlayer extends PlayerImpl { game.fireGetModeEvent(playerId, "Choose Mode", modeMap); waitForResponse(game); if (response.getUUID() != null) { - for (Mode mode: modes.values()) { + for (Mode mode : modes.values()) { if (mode.getId().equals(response.getUUID())) { return mode; } @@ -1150,7 +1178,7 @@ public class HumanPlayer extends PlayerImpl { @Override public void setResponseString(String responseString) { - synchronized(response) { + synchronized (response) { response.setString(responseString); response.notify(); log.debug("Got response string from player: " + getId()); @@ -1159,7 +1187,7 @@ public class HumanPlayer extends PlayerImpl { @Override public void setResponseManaType(UUID manaTypePlayerId, ManaType manaType) { - synchronized(response) { + synchronized (response) { response.setManaType(manaType); response.setResponseManaTypePlayerId(manaTypePlayerId); response.notify(); @@ -1169,7 +1197,7 @@ public class HumanPlayer extends PlayerImpl { @Override public void setResponseUUID(UUID responseUUID) { - synchronized(response) { + synchronized (response) { response.setUUID(responseUUID); response.notify(); log.debug("Got response UUID from player: " + getId()); @@ -1178,7 +1206,7 @@ public class HumanPlayer extends PlayerImpl { @Override public void setResponseBoolean(Boolean responseBoolean) { - synchronized(response) { + synchronized (response) { response.setBoolean(responseBoolean); response.notify(); log.debug("Got response boolean from player: " + getId()); @@ -1187,7 +1215,7 @@ public class HumanPlayer extends PlayerImpl { @Override public void setResponseInteger(Integer responseInteger) { - synchronized(response) { + synchronized (response) { response.setInteger(responseInteger); response.notify(); log.debug("Got response integer from player: " + getId()); @@ -1197,7 +1225,7 @@ public class HumanPlayer extends PlayerImpl { @Override public void abort() { abort = true; - synchronized(response) { + synchronized (response) { response.notify(); log.debug("Got cancel action from player: " + getId()); } @@ -1205,7 +1233,7 @@ public class HumanPlayer extends PlayerImpl { @Override public void skip() { - synchronized(response) { + synchronized (response) { response.setInteger(0); response.notify(); log.debug("Got skip action from player: " + getId()); @@ -1232,10 +1260,10 @@ public class HumanPlayer extends PlayerImpl { super.sendPlayerAction(playerAction, game); } } - + protected boolean passWithManaPoolCheck(Game game) { - if (userData.confirmEmptyManaPool() && - game.getStack().isEmpty() && getManaPool().count() > 0) { + if (userData.confirmEmptyManaPool() + && game.getStack().isEmpty() && getManaPool().count() > 0) { String activePlayerText; if (game.getActivePlayerId().equals(playerId)) { activePlayerText = "Your turn"; @@ -1245,14 +1273,14 @@ public class HumanPlayer extends PlayerImpl { String priorityPlayerText = ""; if (!isGameUnderControl()) { priorityPlayerText = " / priority " + game.getPlayer(game.getPriorityPlayerId()).getName(); - } + } if (!chooseUse(Outcome.Detriment, GameLog.getPlayerConfirmColoredText("You have still mana in your mana pool. Pass regardless?") - + GameLog.getSmallSecondLineText(activePlayerText + " / " + game.getStep().getType().toString() + priorityPlayerText), game)) { + + GameLog.getSmallSecondLineText(activePlayerText + " / " + game.getStep().getType().toString() + priorityPlayerText), null, game)) { sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, game); return false; } } pass(game); return true; - } + } } diff --git a/Mage.Sets/src/mage/sets/alarareborn/ArsenalThresher.java b/Mage.Sets/src/mage/sets/alarareborn/ArsenalThresher.java index 0f9a30c2e8..16bc181405 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/ArsenalThresher.java +++ b/Mage.Sets/src/mage/sets/alarareborn/ArsenalThresher.java @@ -99,7 +99,7 @@ class ArsenalThresherEffect extends OneShotEffect { Permanent arsenalThresher = game.getPermanent(source.getSourceId()); FilterArtifactCard filter = new FilterArtifactCard(); filter.add(new AnotherCardPredicate()); - if (you.chooseUse(Outcome.Benefit, "Do you want to reveal other artifacts in your hand?", game)) { + if (you.chooseUse(Outcome.Benefit, "Do you want to reveal other artifacts in your hand?", source, game)) { Cards cards = new CardsImpl(); if (you.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) { TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter); diff --git a/Mage.Sets/src/mage/sets/alarareborn/EtherwroughtPage.java b/Mage.Sets/src/mage/sets/alarareborn/EtherwroughtPage.java index 7e3d9fb67f..d5179abf89 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/EtherwroughtPage.java +++ b/Mage.Sets/src/mage/sets/alarareborn/EtherwroughtPage.java @@ -111,7 +111,7 @@ class EtherwroughtPageEffect extends OneShotEffect { CardsImpl cards = new CardsImpl(); cards.add(card); controller.lookAtCards("Etherwrought Page", cards, game); - if (controller.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", game)) { + if (controller.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", source, game)) { return controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game); } return true; diff --git a/Mage.Sets/src/mage/sets/alarareborn/SovereignsOfLostAlara.java b/Mage.Sets/src/mage/sets/alarareborn/SovereignsOfLostAlara.java index f6f70200a1..a04ea9aaf2 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/SovereignsOfLostAlara.java +++ b/Mage.Sets/src/mage/sets/alarareborn/SovereignsOfLostAlara.java @@ -139,7 +139,7 @@ class SovereignsOfLostAlaraEffect extends OneShotEffect { FilterCard filter = new FilterCard("aura that could enchant the lone attacking creature"); filter.add(new SubtypePredicate("Aura")); filter.add(new AuraCardCanAttachToPermanentId(attackingCreature.getId())); - if (you.chooseUse(Outcome.Benefit, "Do you want to search your library?", game)) { + if (you.chooseUse(Outcome.Benefit, "Do you want to search your library?", source, game)) { TargetCardInLibrary target = new TargetCardInLibrary(filter); target.setNotTarget(true); if (you.searchLibrary(target, game)) { diff --git a/Mage.Sets/src/mage/sets/alarareborn/VectisDominator.java b/Mage.Sets/src/mage/sets/alarareborn/VectisDominator.java index e315a53fe2..6c3e4d6f24 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/VectisDominator.java +++ b/Mage.Sets/src/mage/sets/alarareborn/VectisDominator.java @@ -104,7 +104,7 @@ class VectisDominatorEffect extends OneShotEffect { if (player != null) { cost.clearPaid(); final StringBuilder sb = new StringBuilder("Pay 2 life? (Otherwise ").append(targetCreature.getName()).append(" will be tapped)"); - if (player.chooseUse(Outcome.Benefit, sb.toString(), game)) { + if (player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), true); } if (!cost.isPaid()) { diff --git a/Mage.Sets/src/mage/sets/anthologyjacevschandra/TerrainGenerator.java b/Mage.Sets/src/mage/sets/anthologyjacevschandra/TerrainGenerator.java index 3a67a29363..70d9d0ece9 100644 --- a/Mage.Sets/src/mage/sets/anthologyjacevschandra/TerrainGenerator.java +++ b/Mage.Sets/src/mage/sets/anthologyjacevschandra/TerrainGenerator.java @@ -106,7 +106,7 @@ class PutLandOnBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutLandInPlay, choiceText, game)) { + if (player == null || !player.chooseUse(Outcome.PutLandInPlay, choiceText, source, game)) { return false; } diff --git a/Mage.Sets/src/mage/sets/avacynrestored/BrunaLightOfAlabaster.java b/Mage.Sets/src/mage/sets/avacynrestored/BrunaLightOfAlabaster.java index a43cb08b87..50c4d35934 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/BrunaLightOfAlabaster.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/BrunaLightOfAlabaster.java @@ -122,7 +122,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect { return false; } - while (player.isInGame() && player.chooseUse(Outcome.Benefit, "Attach an Aura from the battlefield?", game)) { + while (player.isInGame() && player.chooseUse(Outcome.Benefit, "Attach an Aura from the battlefield?", source, game)) { Target targetAura = new TargetPermanent(filterAura); if (player.choose(Outcome.Benefit, targetAura, source.getSourceId(), game)) { Permanent aura = game.getPermanent(targetAura.getFirstTarget()); @@ -137,7 +137,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect { } int count = player.getHand().count(filterAuraCard, game); - while (player.isInGame() && count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your hand?", game)) { + while (player.isInGame() && count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your hand?", source, game)) { TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard); if (player.choose(Outcome.Benefit, player.getHand(), targetAura, game)) { Card aura = game.getCard(targetAura.getFirstTarget()); @@ -151,7 +151,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect { } count = player.getGraveyard().count(filterAuraCard, game); - while (player.isInGame() && count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your graveyard?", game)) { + while (player.isInGame() && count > 0 && player.chooseUse(Outcome.Benefit, "Attach an Aura from your graveyard?", source, game)) { TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard); if (player.choose(Outcome.Benefit, player.getGraveyard(), targetAura, game)) { Card aura = game.getCard(targetAura.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/avacynrestored/DescendantsPath.java b/Mage.Sets/src/mage/sets/avacynrestored/DescendantsPath.java index a6f0e7964a..0bb9524661 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/DescendantsPath.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/DescendantsPath.java @@ -110,7 +110,7 @@ class DescendantsPathEffect extends OneShotEffect { } if (found) { game.informPlayers(sourceObject.getLogName() + ": Found a creature that shares a creature type with the revealed card."); - if (controller.chooseUse(Outcome.Benefit, "Cast the card?", game)) { + if (controller.chooseUse(Outcome.Benefit, "Cast the card?", source, game)) { controller.cast(card.getSpellAbility(), game, true); } else { game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " canceled casting the card."); diff --git a/Mage.Sets/src/mage/sets/avacynrestored/Fettergeist.java b/Mage.Sets/src/mage/sets/avacynrestored/Fettergeist.java index 74ad7a641a..6b8cec80c8 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/Fettergeist.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/Fettergeist.java @@ -105,7 +105,7 @@ class FettergeistUnlessPaysEffect extends OneShotEffect { if (count == 0) { return true; } - if (player.chooseUse(Outcome.Benefit, "Pay " + count + "?", game)) { + if (player.chooseUse(Outcome.Benefit, "Pay " + count + "?", source, game)) { GenericManaCost cost = new GenericManaCost(count); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { return true; diff --git a/Mage.Sets/src/mage/sets/avacynrestored/KillingWave.java b/Mage.Sets/src/mage/sets/avacynrestored/KillingWave.java index 2fbd65300a..8b81ec6c96 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/KillingWave.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/KillingWave.java @@ -106,7 +106,7 @@ class KillingWaveEffect extends OneShotEffect { int playerLife = player.getLife(); for (Permanent creature : creatures) { String message = "Pay " + amount + " life? If you don't, " + creature.getName() + " will be sacrificed."; - if (playerLife - amount - lifePaid >= 0 && player != null && player.chooseUse(Outcome.Neutral, message, game)) { + if (playerLife - amount - lifePaid >= 0 && player != null && player.chooseUse(Outcome.Neutral, message, source, game)) { game.informPlayers(player.getLogName() + " pays " + amount + " life. He will not sacrifice " + creature.getName()); lifePaid += amount; } else { diff --git a/Mage.Sets/src/mage/sets/avacynrestored/PrimalSurge.java b/Mage.Sets/src/mage/sets/avacynrestored/PrimalSurge.java index ebd4d5178b..7dd2e0918d 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/PrimalSurge.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/PrimalSurge.java @@ -100,7 +100,7 @@ class PrimalSurgeEffect extends OneShotEffect { if ((cardType.contains(CardType.ARTIFACT) || cardType.contains(CardType.CREATURE) || cardType.contains(CardType.ENCHANTMENT) || cardType.contains(CardType.LAND) || cardType.contains(CardType.PLANESWALKER)) - && player.chooseUse(Outcome.PutCardInPlay, "Put " + card.getName() + " onto the battlefield?", game)) { + && player.chooseUse(Outcome.PutCardInPlay, "Put " + card.getName() + " onto the battlefield?", source, game)) { card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false); Permanent permanent = game.getPermanent(card.getId()); diff --git a/Mage.Sets/src/mage/sets/avacynrestored/VexingDevil.java b/Mage.Sets/src/mage/sets/avacynrestored/VexingDevil.java index d06ce403fe..bbf11eb017 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/VexingDevil.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/VexingDevil.java @@ -89,7 +89,7 @@ class VexingDevilEffect extends OneShotEffect { if (controller != null && permanent != null) { for (UUID opponentUuid : game.getOpponents(source.getControllerId())) { Player opponent = game.getPlayer(opponentUuid); - if (opponent != null && opponent.chooseUse(Outcome.LoseLife, "Make " + permanent.getLogName() + " deal 4 damage to you?", game)) { + if (opponent != null && opponent.chooseUse(Outcome.LoseLife, "Make " + permanent.getLogName() + " deal 4 damage to you?", source, game)) { game.informPlayers(opponent.getLogName() + " has chosen to receive 4 damage from " + permanent.getLogName()); opponent.damage(4, permanent.getId(), game, false, true); permanent.sacrifice(source.getSourceId(), game); diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/IwamoriOfTheOpenFist.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/IwamoriOfTheOpenFist.java index 6d0beacd94..98bc1dbe5f 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/IwamoriOfTheOpenFist.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/IwamoriOfTheOpenFist.java @@ -113,7 +113,7 @@ class IwamoriOfTheOpenFistEffect extends OneShotEffect { Player opponent = game.getPlayer(playerId); Target target = new TargetCardInHand(filter); if (opponent != null && target.canChoose(source.getSourceId(), opponent.getId(), game)) { - if (opponent.chooseUse(Outcome.PutCreatureInPlay, "Put a legendary creature card from your hand onto the battlefield?", game)) { + if (opponent.chooseUse(Outcome.PutCreatureInPlay, "Put a legendary creature card from your hand onto the battlefield?", source, game)) { if (target.chooseTarget(Outcome.PutCreatureInPlay, opponent.getId(), source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/OgreMarauder.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/OgreMarauder.java index 530f6624ee..cc0ed1bcf5 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/OgreMarauder.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/OgreMarauder.java @@ -99,7 +99,7 @@ class OgreMarauderEffect extends OneShotEffect { if (defender != null && sourceObject != null) { Cost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent()); if (cost.canPay(source, source.getSourceId(), defendingPlayerId, game) && - defender.chooseUse(Outcome.LoseAbility, "Sacrifice a creature to prevent that " + sourceObject.getLogName() + " can't be blocked?", game)) { + defender.chooseUse(Outcome.LoseAbility, "Sacrifice a creature to prevent that " + sourceObject.getLogName() + " can't be blocked?", source, game)) { if (!cost.pay(source, game, source.getSourceId(), defendingPlayerId, false)) { // cost was not payed - so source can't be blocked ContinuousEffect effect = new CantBeBlockedSourceEffect(Duration.EndOfTurn); diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/ToilsOfNightAndDay.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/ToilsOfNightAndDay.java index 57e893e3b3..56722fff90 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/ToilsOfNightAndDay.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/ToilsOfNightAndDay.java @@ -90,9 +90,9 @@ public class ToilsOfNightAndDay extends CardImpl { for (UUID targetId : source.getTargets().get(0).getTargets()) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - if (player.chooseUse(Outcome.Tap, new StringBuilder("Tap ").append(permanent.getName()).append("?").toString(), game)) { + if (player.chooseUse(Outcome.Tap, new StringBuilder("Tap ").append(permanent.getName()).append("?").toString(), source, game)) { permanent.tap(game); - } else if (player.chooseUse(Outcome.Untap, new StringBuilder("Untap ").append(permanent.getName()).append("?").toString(), game)) { + } else if (player.chooseUse(Outcome.Untap, new StringBuilder("Untap ").append(permanent.getName()).append("?").toString(), source, game)) { permanent.untap(game); } } diff --git a/Mage.Sets/src/mage/sets/bornofthegods/ArbiterOfTheIdeal.java b/Mage.Sets/src/mage/sets/bornofthegods/ArbiterOfTheIdeal.java index 99f5dc3002..0ace003045 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/ArbiterOfTheIdeal.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/ArbiterOfTheIdeal.java @@ -122,7 +122,7 @@ class ArbiterOfTheIdealEffect extends OneShotEffect { player.revealCards("Arbiter of the Ideal", cards, game); if (card != null) { - if (filter.match(card, game) && player.chooseUse(outcome, new StringBuilder("Put ").append(card.getName()).append("onto battlefield?").toString(), game)) { + if (filter.match(card, game) && player.chooseUse(outcome, new StringBuilder("Put ").append(card.getName()).append("onto battlefield?").toString(), source, game)) { card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId()); Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { diff --git a/Mage.Sets/src/mage/sets/bornofthegods/FloodtideSerpent.java b/Mage.Sets/src/mage/sets/bornofthegods/FloodtideSerpent.java index 1b0262eedf..962b63f528 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/FloodtideSerpent.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/FloodtideSerpent.java @@ -100,7 +100,7 @@ class FloodtideSerpentReplacementEffect extends ReplacementEffectImpl { if ( player != null ) { ReturnToHandTargetPermanentCost attackCost = new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)); if ( attackCost.canPay(source, source.getSourceId(), event.getPlayerId(), game) && - player.chooseUse(Outcome.Neutral, "Return an enchantment you control to hand to attack?", game) ) + player.chooseUse(Outcome.Neutral, "Return an enchantment you control to hand to attack?", source, game) ) { if (attackCost.pay(source, game, source.getSourceId(), event.getPlayerId(), true) ) { return false; diff --git a/Mage.Sets/src/mage/sets/bornofthegods/HeroOfLeinaTower.java b/Mage.Sets/src/mage/sets/bornofthegods/HeroOfLeinaTower.java index 713c52c575..7611a10855 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/HeroOfLeinaTower.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/HeroOfLeinaTower.java @@ -95,7 +95,7 @@ class HeroOfLeinaTowerEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player you = game.getPlayer(source.getControllerId()); ManaCosts cost = new ManaCostsImpl("{X}"); - if (you != null && you.chooseUse(Outcome.BoostCreature, "Do you want to to pay {X}?", game)) { + if (you != null && you.chooseUse(Outcome.BoostCreature, "Do you want to to pay {X}?", source, game)) { int costX = you.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source); cost.add(new GenericManaCost(costX)); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { diff --git a/Mage.Sets/src/mage/sets/bornofthegods/HeroesPodium.java b/Mage.Sets/src/mage/sets/bornofthegods/HeroesPodium.java index 79e27e57ee..d8610794d7 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/HeroesPodium.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/HeroesPodium.java @@ -171,7 +171,7 @@ class HeroesPodiumEffect extends OneShotEffect { player.lookAtCards("Heroes' Podium", cards, game); // You may reveal a legendary creature card from among them and put it into your hand. - if (!cards.isEmpty() && legendaryIncluded && player.chooseUse(outcome, "Put a legendary creature card into your hand?", game)) { + if (!cards.isEmpty() && legendaryIncluded && player.chooseUse(outcome, "Put a legendary creature card into your hand?", source, game)) { if (cards.size() == 1) { Card card = cards.getRandom(game); cards.remove(card); diff --git a/Mage.Sets/src/mage/sets/bornofthegods/MogisGodOfSlaughter.java b/Mage.Sets/src/mage/sets/bornofthegods/MogisGodOfSlaughter.java index d20bef3036..85fb229bf7 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/MogisGodOfSlaughter.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/MogisGodOfSlaughter.java @@ -127,7 +127,7 @@ class DoUnlessTargetPaysCost extends OneShotEffect { } message = CardUtil.replaceSourceName(message, mageObject.getLogName()); cost.clearPaid(); - if (cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(executingEffect.getOutcome(), message, game)) { + if (cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(executingEffect.getOutcome(), message, source, game)) { cost.pay(source, game, source.getSourceId(), player.getId(), false); } if (!cost.isPaid()) { diff --git a/Mage.Sets/src/mage/sets/bornofthegods/OracleOfBones.java b/Mage.Sets/src/mage/sets/bornofthegods/OracleOfBones.java index 1e171ceaa6..15fa1489e8 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/OracleOfBones.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/OracleOfBones.java @@ -108,7 +108,7 @@ class OracleOfBonesCastEffect extends OneShotEffect { if (controller != null) { Target target = new TargetCardInHand(filter); if (target.canChoose(source.getSourceId(), controller.getId(), game) && - controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", game)) { + controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", source, game)) { Card cardToCast = null; boolean cancel = false; while (controller.isInGame() && !cancel) { diff --git a/Mage.Sets/src/mage/sets/bornofthegods/SatyrWayfinder.java b/Mage.Sets/src/mage/sets/bornofthegods/SatyrWayfinder.java index 64eb989e36..11c738d397 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/SatyrWayfinder.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/SatyrWayfinder.java @@ -104,7 +104,7 @@ class SatyrWayfinderEffect extends OneShotEffect { controller.revealCards(sourceObject.getName(), cards, game); TargetCard target = new TargetCard(Zone.LIBRARY, filterPutInHand); if (properCardFound && - controller.chooseUse(outcome, "Put a land card into your hand?", game) && + controller.chooseUse(outcome, "Put a land card into your hand?", source, game) && controller.choose(Outcome.DrawCard, cards, target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/CutTheTethers.java b/Mage.Sets/src/mage/sets/championsofkamigawa/CutTheTethers.java index 2582b063a7..8b8bfd29f6 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/CutTheTethers.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/CutTheTethers.java @@ -96,7 +96,7 @@ class CutTheTethersEffect extends OneShotEffect { Player player = game.getPlayer(creature.getControllerId()); if (player != null) { boolean paid = false; - if (player.chooseUse(outcome, new StringBuilder("Pay {3} to keep ").append(creature.getName()).append(" on the battlefield?").toString(), game)) { + if (player.chooseUse(outcome, new StringBuilder("Pay {3} to keep ").append(creature.getName()).append(" on the battlefield?").toString(), source, game)) { Cost cost = new GenericManaCost(3); if (!cost.pay(source, game, source.getSourceId(), creature.getControllerId(), false)) { paid = true; diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/GhostlyPrison.java b/Mage.Sets/src/mage/sets/championsofkamigawa/GhostlyPrison.java index 72b4101982..a59826a420 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/GhostlyPrison.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/GhostlyPrison.java @@ -103,7 +103,7 @@ class GhostlyPrisonReplacementEffect extends ReplacementEffectImpl { if ( player != null && event.getTargetId().equals(source.getControllerId())) { ManaCostsImpl attackTax = new ManaCostsImpl("{2}"); if (attackTax.canPay(source, source.getSourceId(), event.getPlayerId(), game) && - player.chooseUse(Outcome.Benefit, "Pay {2} to attack player?", game) ) { + player.chooseUse(Outcome.Benefit, "Pay {2} to attack player?", source, game) ) { if (attackTax.payOrRollback(source, game, this.getId(), event.getPlayerId())) { return false; } diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/Hinder.java b/Mage.Sets/src/mage/sets/championsofkamigawa/Hinder.java index afdac715e2..dac84fa0c2 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/Hinder.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/Hinder.java @@ -163,7 +163,7 @@ class HinderReplacementEffect extends ReplacementEffectImpl { Card card = (Card) targetObject; Player player = game.getPlayer(source.getControllerId()); if (player != null) { - boolean top = player.chooseUse(Outcome.Neutral, "Put " + card.getName() + " on top of the library? Otherwise it will be put on the bottom.", game); + boolean top = player.chooseUse(Outcome.Neutral, "Put " + card.getName() + " on top of the library? Otherwise it will be put on the bottom.", source, game); if (card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, top, event.getAppliedEffects())) { game.informPlayers(player.getLogName() + " has put " + card.getName() + " on " + (top ? "top" : "the bottom") + " of the library."); } diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/InameLifeAspect.java b/Mage.Sets/src/mage/sets/championsofkamigawa/InameLifeAspect.java index 1d26ed807d..f9352d28dc 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/InameLifeAspect.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/InameLifeAspect.java @@ -106,7 +106,7 @@ class InameLifeAspectEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (controller != null && sourceObject != null) { - if (controller.chooseUse(outcome, "Exile " + sourceObject.getLogName() + " to return Spirit cards?", game)) { + if (controller.chooseUse(outcome, "Exile " + sourceObject.getLogName() + " to return Spirit cards?", source, game)) { new ExileSourceEffect().apply(game, source); return new ReturnToHandTargetEffect().apply(game, source); } diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/ThroughTheBreach.java b/Mage.Sets/src/mage/sets/championsofkamigawa/ThroughTheBreach.java index a7401b052d..86980d0f77 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/ThroughTheBreach.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/ThroughTheBreach.java @@ -102,7 +102,7 @@ class ThroughTheBreachEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - if (controller.chooseUse(Outcome.PutCreatureInPlay, choiceText, game)) { + if (controller.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard()); if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/coldsnap/ArcumDagsson.java b/Mage.Sets/src/mage/sets/coldsnap/ArcumDagsson.java index 599c9f69ce..653bb2a81d 100644 --- a/Mage.Sets/src/mage/sets/coldsnap/ArcumDagsson.java +++ b/Mage.Sets/src/mage/sets/coldsnap/ArcumDagsson.java @@ -115,7 +115,7 @@ class ArcumDagssonEffect extends OneShotEffect { Player player = game.getPlayer(artifactCreature.getControllerId()); if (player != null) { artifactCreature.sacrifice(source.getSourceId(), game); - if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for a noncreature artifact card?", game)) { + if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for a noncreature artifact card?", source, game)) { TargetCardInLibrary target = new TargetCardInLibrary(filter); if (player.searchLibrary(target, game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/coldsnap/ScryingSheets.java b/Mage.Sets/src/mage/sets/coldsnap/ScryingSheets.java index f0a1d5e8b5..5196fbb029 100644 --- a/Mage.Sets/src/mage/sets/coldsnap/ScryingSheets.java +++ b/Mage.Sets/src/mage/sets/coldsnap/ScryingSheets.java @@ -100,7 +100,7 @@ class ScryingSheetsEffect extends OneShotEffect { cards.add(card); player.lookAtCards("Scrying Sheets", cards, game); if (card.getSupertype().contains("Snow")) { - if (player.chooseUse(outcome, new StringBuilder("Reveal ").append(card.getName()).append(" and put it into your hand?").toString(), game)) { + if (player.chooseUse(outcome, new StringBuilder("Reveal ").append(card.getName()).append(" and put it into your hand?").toString(), source, game)) { card = player.getLibrary().removeFromTop(game); player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); player.revealCards("Scrying Sheets", cards, game); diff --git a/Mage.Sets/src/mage/sets/commander/ChorusOfTheConclave.java b/Mage.Sets/src/mage/sets/commander/ChorusOfTheConclave.java index fc8e0235a8..7454b49566 100644 --- a/Mage.Sets/src/mage/sets/commander/ChorusOfTheConclave.java +++ b/Mage.Sets/src/mage/sets/commander/ChorusOfTheConclave.java @@ -112,7 +112,7 @@ class ChorusOfTheConclaveReplacementEffect extends ReplacementEffectImpl { int xCost = 0; Player you = game.getPlayer(source.getControllerId()); if (you != null) { - if (you.chooseUse(Outcome.Benefit, "Do you wish to pay the additonal cost to add +1/+1 counters to the creature you cast?", game)) { + if (you.chooseUse(Outcome.Benefit, "Do you wish to pay the additonal cost to add +1/+1 counters to the creature you cast?", source, game)) { xCost += playerPaysXGenericMana(you, source, game); // save the x value to be available for ETB replacement effect Object object = game.getState().getValue("spellX" + source.getSourceId()); diff --git a/Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java b/Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java index 562935d4c6..ae71daeb4d 100644 --- a/Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java +++ b/Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java @@ -149,7 +149,7 @@ class KaaliaOfTheVastEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, "Put an Angel, Demon, or Dragon creature card from your hand onto the battlefield tapped and attacking?", game)) { + if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, "Put an Angel, Demon, or Dragon creature card from your hand onto the battlefield tapped and attacking?", source, game)) { return false; } TargetCardInHand target = new TargetCardInHand(filter); diff --git a/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java b/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java index 0397ca4cff..5be1bed0a2 100644 --- a/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java +++ b/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java @@ -100,7 +100,7 @@ class TheMimeoplasmEffect extends OneShotEffect { Permanent permanent = game.getPermanent(source.getSourceId()); if (controller != null && permanent != null) { if (new CardsInAllGraveyardsCount(new FilterCreatureCard()).calculate(game, source, this) >= 2) { - if (controller.chooseUse(Outcome.Benefit, "Do you want to exile two creature cards from graveyards?", game)) { + if (controller.chooseUse(Outcome.Benefit, "Do you want to exile two creature cards from graveyards?", source, game)) { TargetCardInGraveyard targetCopy = new TargetCardInGraveyard(new FilterCreatureCard("creature card to become a copy of")); TargetCardInGraveyard targetCounters = new TargetCardInGraveyard(new FilterCreatureCard("creature card to determine amount of additional +1/+1 counters")); if (controller.choose(Outcome.Copy, targetCopy, source.getSourceId(), game)) { diff --git a/Mage.Sets/src/mage/sets/commander/VeteranExplorer.java b/Mage.Sets/src/mage/sets/commander/VeteranExplorer.java index 6e4a6390a3..7644250ea4 100644 --- a/Mage.Sets/src/mage/sets/commander/VeteranExplorer.java +++ b/Mage.Sets/src/mage/sets/commander/VeteranExplorer.java @@ -114,7 +114,7 @@ class VeteranExplorerEffect extends OneShotEffect { } private void chooseAndSearchLibrary(List usingPlayers, Player player, Ability source, Game game) { - if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for up to two basic land cards and put them onto the battlefield?", game)) { + if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for up to two basic land cards and put them onto the battlefield?", source, game)) { usingPlayers.add(player); TargetCardInLibrary target = new TargetCardInLibrary(0, 2, new FilterBasicLandCard()); if (player.searchLibrary(target, game)) { diff --git a/Mage.Sets/src/mage/sets/commander/WhirlpoolWhelm.java b/Mage.Sets/src/mage/sets/commander/WhirlpoolWhelm.java index b330973075..88036f444a 100644 --- a/Mage.Sets/src/mage/sets/commander/WhirlpoolWhelm.java +++ b/Mage.Sets/src/mage/sets/commander/WhirlpoolWhelm.java @@ -90,7 +90,7 @@ class WhirlpoolWhelmEffect extends OneShotEffect { if (controller != null) { boolean topOfLibrary = false; if (ClashEffect.getInstance().apply(game, source)) { - topOfLibrary = controller.chooseUse(outcome, "Put " + creature.getLogName() + " to top of libraray instead?" , game); + topOfLibrary = controller.chooseUse(outcome, "Put " + creature.getLogName() + " to top of libraray instead?" , source, game); } if (topOfLibrary) { controller.moveCardToHandWithInfo(creature, source.getSourceId(), game, Zone.BATTLEFIELD); diff --git a/Mage.Sets/src/mage/sets/commander/WildRicochet.java b/Mage.Sets/src/mage/sets/commander/WildRicochet.java index 6b411aa35d..7c6f93ea12 100644 --- a/Mage.Sets/src/mage/sets/commander/WildRicochet.java +++ b/Mage.Sets/src/mage/sets/commander/WildRicochet.java @@ -92,7 +92,7 @@ class WildRicochetEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Spell spell = game.getStack().getSpell(source.getFirstTarget()); Player you = game.getPlayer(source.getControllerId()); - if (spell != null && you != null && you.chooseUse(Outcome.Benefit, "Do you wish to choose new targets for " + spell.getName() + "?", game)) { + if (spell != null && you != null && you.chooseUse(Outcome.Benefit, "Do you wish to choose new targets for " + spell.getName() + "?", source, game)) { spell.chooseNewTargets(game, you.getId()); } if (spell != null) { @@ -100,7 +100,7 @@ class WildRicochetEffect extends OneShotEffect { copy.setControllerId(source.getControllerId()); copy.setCopiedSpell(true); game.getStack().push(copy); - if (you != null && you.chooseUse(Outcome.Benefit, "Do you wish to choose new targets for the copied " + spell.getName() + "?", game)) { + if (you != null && you.chooseUse(Outcome.Benefit, "Do you wish to choose new targets for the copied " + spell.getName() + "?", source, game)) { return copy.chooseNewTargets(game, you.getId()); } } diff --git a/Mage.Sets/src/mage/sets/commander2013/CurseOfChaos.java b/Mage.Sets/src/mage/sets/commander2013/CurseOfChaos.java index cb4931a6e3..a0d5c026d2 100644 --- a/Mage.Sets/src/mage/sets/commander2013/CurseOfChaos.java +++ b/Mage.Sets/src/mage/sets/commander2013/CurseOfChaos.java @@ -141,7 +141,7 @@ class CurseOfChaosEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player attacker = game.getPlayer(this.getTargetPointer().getFirst(game, source)); if (attacker != null) { - if (attacker.getHand().size() > 0 && attacker.chooseUse(outcome, "Discard a card and draw a card?", game)){ + if (attacker.getHand().size() > 0 && attacker.chooseUse(outcome, "Discard a card and draw a card?", source, game)){ attacker.discard(1, false, source, game); attacker.drawCards(1, game); } diff --git a/Mage.Sets/src/mage/sets/commander2013/CurseOfInertia.java b/Mage.Sets/src/mage/sets/commander2013/CurseOfInertia.java index 45f60abb0c..5f674df5b6 100644 --- a/Mage.Sets/src/mage/sets/commander2013/CurseOfInertia.java +++ b/Mage.Sets/src/mage/sets/commander2013/CurseOfInertia.java @@ -141,11 +141,11 @@ class CurseOfInertiaTapOrUntapTargetEffect extends OneShotEffect { Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (targetPermanent != null) { if (targetPermanent.isTapped()) { - if (player.chooseUse(Outcome.Untap, "Untap that permanent?", game)) { + if (player.chooseUse(Outcome.Untap, "Untap that permanent?", source, game)) { targetPermanent.untap(game); } } else { - if (player.chooseUse(Outcome.Tap, "Tap that permanent?", game)) { + if (player.chooseUse(Outcome.Tap, "Tap that permanent?", source, game)) { targetPermanent.tap(game); } } diff --git a/Mage.Sets/src/mage/sets/commander2013/JelevaNephaliasScourge.java b/Mage.Sets/src/mage/sets/commander2013/JelevaNephaliasScourge.java index 2c9f4f77f2..4fbc4aba7c 100644 --- a/Mage.Sets/src/mage/sets/commander2013/JelevaNephaliasScourge.java +++ b/Mage.Sets/src/mage/sets/commander2013/JelevaNephaliasScourge.java @@ -152,7 +152,7 @@ class JelevaNephaliasCastEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - if (controller.chooseUse(outcome, "Cast an instant or sorcery from exile?", game)) { + if (controller.chooseUse(outcome, "Cast an instant or sorcery from exile?", source, game)) { TargetCardInExile target = new TargetCardInExile(new FilterInstantOrSorceryCard(), CardUtil.getCardExileZoneId(game, source)); if (controller.choose(Outcome.PlayForFree, game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)), target, game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/commander2013/LimDulsVault.java b/Mage.Sets/src/mage/sets/commander2013/LimDulsVault.java index 7a3b813c94..70324bd4e9 100644 --- a/Mage.Sets/src/mage/sets/commander2013/LimDulsVault.java +++ b/Mage.Sets/src/mage/sets/commander2013/LimDulsVault.java @@ -105,7 +105,7 @@ class LimDulsVaultEffect extends OneShotEffect { } } player.lookAtCards("Lim-Dul's Vault", cards, game); - doAgain = player.chooseUse(outcome, "Pay 1 lfe and look at the next 5 cards?", game); + doAgain = player.chooseUse(outcome, "Pay 1 lfe and look at the next 5 cards?", source, game); if (doAgain) { player.loseLife(1, game); } else { diff --git a/Mage.Sets/src/mage/sets/commander2013/PlagueBoiler.java b/Mage.Sets/src/mage/sets/commander2013/PlagueBoiler.java index 4ea19f2722..e02eaaca2d 100644 --- a/Mage.Sets/src/mage/sets/commander2013/PlagueBoiler.java +++ b/Mage.Sets/src/mage/sets/commander2013/PlagueBoiler.java @@ -101,7 +101,7 @@ class PlagueBoilerEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (controller != null && sourcePermanent != null) { - if (!sourcePermanent.getCounters().containsKey(CounterType.PLAGUE) || controller.chooseUse(outcome, "Put a plague counter on? (No removes one)", game)) { + if (!sourcePermanent.getCounters().containsKey(CounterType.PLAGUE) || controller.chooseUse(outcome, "Put a plague counter on? (No removes one)", source, game)) { return new AddCountersSourceEffect(CounterType.PLAGUE.createInstance(), true).apply(game, source); } else { return new RemoveCounterSourceEffect(CounterType.PLAGUE.createInstance()).apply(game, source); diff --git a/Mage.Sets/src/mage/sets/commander2013/SwordOfTheParuns.java b/Mage.Sets/src/mage/sets/commander2013/SwordOfTheParuns.java index 5af02c7199..1257d41af7 100644 --- a/Mage.Sets/src/mage/sets/commander2013/SwordOfTheParuns.java +++ b/Mage.Sets/src/mage/sets/commander2013/SwordOfTheParuns.java @@ -123,11 +123,11 @@ class MayTapOrUntapAttachedEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (equipedCreature != null && player != null) { if (equipedCreature.isTapped()) { - if (player.chooseUse(Outcome.Untap, "Untap equipped creature?", game)) { + if (player.chooseUse(Outcome.Untap, "Untap equipped creature?", source, game)) { equipedCreature.untap(game); } } else { - if (player.chooseUse(Outcome.Tap, "Tap equipped creature?", game)) { + if (player.chooseUse(Outcome.Tap, "Tap equipped creature?", source, game)) { equipedCreature.tap(game); } } diff --git a/Mage.Sets/src/mage/sets/commander2013/TemptWithDiscovery.java b/Mage.Sets/src/mage/sets/commander2013/TemptWithDiscovery.java index d14c411cc4..e684acd302 100644 --- a/Mage.Sets/src/mage/sets/commander2013/TemptWithDiscovery.java +++ b/Mage.Sets/src/mage/sets/commander2013/TemptWithDiscovery.java @@ -102,7 +102,7 @@ class TemptWithDiscoveryEffect extends OneShotEffect { for (UUID playerId : game.getOpponents(controller.getId())) { Player opponent = game.getPlayer(playerId); if (opponent != null) { - if (opponent.chooseUse(outcome, "Search your library for a land card and put it onto the battlefield?", game)) { + if (opponent.chooseUse(outcome, "Search your library for a land card and put it onto the battlefield?", source, game)) { target.clearChosen(); opponentsUsedSearch++; if (opponent.searchLibrary(target, game)) { diff --git a/Mage.Sets/src/mage/sets/commander2013/TemptWithGlory.java b/Mage.Sets/src/mage/sets/commander2013/TemptWithGlory.java index 8927b6bde9..dc0da22a51 100644 --- a/Mage.Sets/src/mage/sets/commander2013/TemptWithGlory.java +++ b/Mage.Sets/src/mage/sets/commander2013/TemptWithGlory.java @@ -94,7 +94,7 @@ class TemptWithGloryEffect extends OneShotEffect { for (UUID playerId : game.getOpponents(controller.getId())) { Player opponent = game.getPlayer(playerId); if (opponent != null) { - if (opponent.chooseUse(outcome, "Put a +1/+1 counter on each creature you control?", game)) { + if (opponent.chooseUse(outcome, "Put a +1/+1 counter on each creature you control?", source, game)) { opponentsAddedCounters++; addCounterToEachCreature(playerId, counter, game); game.informPlayers(opponent.getLogName() + " added a +1/+1 counter on each of its creatures"); diff --git a/Mage.Sets/src/mage/sets/commander2013/TemptWithImmortality.java b/Mage.Sets/src/mage/sets/commander2013/TemptWithImmortality.java index 1ad0e58046..633914244a 100644 --- a/Mage.Sets/src/mage/sets/commander2013/TemptWithImmortality.java +++ b/Mage.Sets/src/mage/sets/commander2013/TemptWithImmortality.java @@ -102,7 +102,7 @@ class TemptWithImmortalityEffect extends OneShotEffect { Target targetOpponent = new TargetCardInGraveyard(filter); if (targetOpponent.canChoose(source.getSourceId(), opponent.getId(), game)) { - if (opponent.chooseUse(outcome, new StringBuilder("Return a creature card from your graveyard to the battlefield?").toString(), game)) { + if (opponent.chooseUse(outcome, new StringBuilder("Return a creature card from your graveyard to the battlefield?").toString(), source, game)) { if (opponent.chooseTarget(outcome, targetOpponent, source, game)) { Card card = game.getCard(targetOpponent.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/commander2013/TemptWithReflections.java b/Mage.Sets/src/mage/sets/commander2013/TemptWithReflections.java index 6451a9eab7..53cecb0c1c 100644 --- a/Mage.Sets/src/mage/sets/commander2013/TemptWithReflections.java +++ b/Mage.Sets/src/mage/sets/commander2013/TemptWithReflections.java @@ -104,7 +104,7 @@ class TemptWithReflectionsEffect extends OneShotEffect { do { if (game.getOpponents(source.getControllerId()).contains(player.getId())) { String decision; - if (player.chooseUse(outcome, "Put a copy of target creature onto the battlefield for you?", game)) { + if (player.chooseUse(outcome, "Put a copy of target creature onto the battlefield for you?", source, game)) { playersSaidYes.add(player.getId()); decision = " chooses to copy "; } else { diff --git a/Mage.Sets/src/mage/sets/commander2013/TemptWithVengeance.java b/Mage.Sets/src/mage/sets/commander2013/TemptWithVengeance.java index 13511b636d..06a6df8d5f 100644 --- a/Mage.Sets/src/mage/sets/commander2013/TemptWithVengeance.java +++ b/Mage.Sets/src/mage/sets/commander2013/TemptWithVengeance.java @@ -94,7 +94,7 @@ class TemptWithVengeanceEffect extends OneShotEffect { for (UUID playerId : game.getOpponents(controller.getId())) { Player opponent = game.getPlayer(playerId); if (opponent != null) { - if (opponent.chooseUse(outcome, "Put " + xValue + " Elemental Tokens onto the battlefield?", game)) { + if (opponent.chooseUse(outcome, "Put " + xValue + " Elemental Tokens onto the battlefield?", source, game)) { opponentsAddedTokens += xValue; tokenCopy.putOntoBattlefield(xValue, game, source.getSourceId(), playerId, false, false); } diff --git a/Mage.Sets/src/mage/sets/commander2013/WarCadence.java b/Mage.Sets/src/mage/sets/commander2013/WarCadence.java index d34d2bd6ab..c2032efb95 100644 --- a/Mage.Sets/src/mage/sets/commander2013/WarCadence.java +++ b/Mage.Sets/src/mage/sets/commander2013/WarCadence.java @@ -92,7 +92,7 @@ class WarCadenceReplacementEffect extends ReplacementEffectImpl { String mana = new StringBuilder("{").append(amount).append("}").toString(); ManaCostsImpl cost = new ManaCostsImpl(mana); if ( cost.canPay(source, source.getSourceId(), event.getPlayerId(), game) && - player.chooseUse(Outcome.Benefit, new StringBuilder("Pay ").append(mana).append(" to declare blocker?").toString(), game) ) { + player.chooseUse(Outcome.Benefit, new StringBuilder("Pay ").append(mana).append(" to declare blocker?").toString(), source, game) ) { if (cost.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) { return false; } diff --git a/Mage.Sets/src/mage/sets/commander2014/AssaultSuit.java b/Mage.Sets/src/mage/sets/commander2014/AssaultSuit.java index 42d7ff1ed9..8840a4cba2 100644 --- a/Mage.Sets/src/mage/sets/commander2014/AssaultSuit.java +++ b/Mage.Sets/src/mage/sets/commander2014/AssaultSuit.java @@ -160,7 +160,7 @@ class AssaultSuitGainControlEffect extends OneShotEffect { if (equipment.getAttachedTo() != null) { Permanent equippedCreature = game.getPermanent(equipment.getAttachedTo()); if (equippedCreature != null && controller.chooseUse(outcome, - "Let have " + activePlayer.getLogName() + " gain control of " + equippedCreature.getLogName() + "?", game)) { + "Let have " + activePlayer.getLogName() + " gain control of " + equippedCreature.getLogName() + "?", source, game)) { equippedCreature.untap(game); ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfTurn, activePlayer.getId()); effect.setTargetPointer(new FixedTarget(equipment.getAttachedTo())); diff --git a/Mage.Sets/src/mage/sets/commander2014/NahiriTheLithomancer.java b/Mage.Sets/src/mage/sets/commander2014/NahiriTheLithomancer.java index 3fad57eaff..826add7420 100644 --- a/Mage.Sets/src/mage/sets/commander2014/NahiriTheLithomancer.java +++ b/Mage.Sets/src/mage/sets/commander2014/NahiriTheLithomancer.java @@ -139,7 +139,7 @@ class NahiriTheLithomancerFirstAbilityEffect extends OneShotEffect { //TODO: Make sure the Equipment can legally enchant the token, preferably on targetting. Target target = new TargetControlledPermanent(0, 1, filter, true); if (target.canChoose(source.getSourceId(), controller.getId(), game) && - controller.chooseUse(outcome, "Attach an Equipment you control to the created Token?", game)) { + controller.chooseUse(outcome, "Attach an Equipment you control to the created Token?", source, game)) { if (target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), game)) { Permanent equipmentPermanent = game.getPermanent(target.getFirstTarget()); if (equipmentPermanent != null) { @@ -199,7 +199,7 @@ class NahiriTheLithomancerSecondAbilityEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - if (controller.chooseUse(Outcome.PutCardInPlay, "Put an Equipment from hand? (No = from graveyard)", game)) { + if (controller.chooseUse(Outcome.PutCardInPlay, "Put an Equipment from hand? (No = from graveyard)", source, game)) { Target target = new TargetCardInHand(0, 1, filter); controller.choose(outcome, target, source.getSourceId(), game); Card card = controller.getHand().get(target.getFirstTarget(), game); diff --git a/Mage.Sets/src/mage/sets/commander2014/ShaperParasite.java b/Mage.Sets/src/mage/sets/commander2014/ShaperParasite.java index 99317c8f73..93b2ee92d0 100644 --- a/Mage.Sets/src/mage/sets/commander2014/ShaperParasite.java +++ b/Mage.Sets/src/mage/sets/commander2014/ShaperParasite.java @@ -106,7 +106,7 @@ class ShaperParasiteEffect extends ContinuousEffectImpl { super.init(source, game); Player player = game.getPlayer(source.getControllerId()); String message = "Should the target creature get -2/+2 instead of +2/-2?"; - if (player != null && player.chooseUse(Outcome.Neutral, message, game)) { + if (player != null && player.chooseUse(Outcome.Neutral, message, source, game)) { this.power *= -1; this.toughness *= -1; } diff --git a/Mage.Sets/src/mage/sets/commander2014/WaveOfVitriol.java b/Mage.Sets/src/mage/sets/commander2014/WaveOfVitriol.java index bf1405c76a..19994d3145 100644 --- a/Mage.Sets/src/mage/sets/commander2014/WaveOfVitriol.java +++ b/Mage.Sets/src/mage/sets/commander2014/WaveOfVitriol.java @@ -124,7 +124,7 @@ class WaveOfVitriolEffect extends OneShotEffect { } game.getState().handleSimultaneousEvent(game); for(Map.Entry entry: sacrificedLands.entrySet()) { - if (entry.getKey().chooseUse(Outcome.PutLandInPlay, "Search your library for up to " + entry.getValue() + " basic lands?", game)) { + if (entry.getKey().chooseUse(Outcome.PutLandInPlay, "Search your library for up to " + entry.getValue() + " basic lands?", source, game)) { Target target = new TargetCardInLibrary(0, entry.getValue(), new FilterBasicLandCard()); entry.getKey().chooseTarget(outcome, target, source, game); for(UUID targetId: target.getTargets()) { diff --git a/Mage.Sets/src/mage/sets/conflux/MaelstromArchangel.java b/Mage.Sets/src/mage/sets/conflux/MaelstromArchangel.java index dacb2b6bc6..073e0230c0 100644 --- a/Mage.Sets/src/mage/sets/conflux/MaelstromArchangel.java +++ b/Mage.Sets/src/mage/sets/conflux/MaelstromArchangel.java @@ -101,7 +101,7 @@ class MaelstromArchangelCastEffect extends OneShotEffect { if (controller != null) { Target target = new TargetCardInHand(filter); if (target.canChoose(source.getSourceId(), controller.getId(), game) && - controller.chooseUse(outcome, "Cast a nonland card from your hand without paying its mana cost?", game)) { + controller.chooseUse(outcome, "Cast a nonland card from your hand without paying its mana cost?", source, game)) { Card cardToCast = null; boolean cancel = false; while (controller.isInGame() && !cancel) { diff --git a/Mage.Sets/src/mage/sets/conflux/MasterTransmuter.java b/Mage.Sets/src/mage/sets/conflux/MasterTransmuter.java index 5c150f9121..98fb20c1ff 100644 --- a/Mage.Sets/src/mage/sets/conflux/MasterTransmuter.java +++ b/Mage.Sets/src/mage/sets/conflux/MasterTransmuter.java @@ -104,7 +104,7 @@ class MasterTransmuterEffect extends OneShotEffect { if (controller != null) { Target target = new TargetCardInHand(new FilterArtifactCard("an artifact card from your hand")); if (target.canChoose(source.getSourceId(), source.getControllerId(), game) - && controller.chooseUse(outcome, "Put an artifact from your hand to battlefield?", game) + && controller.chooseUse(outcome, "Put an artifact from your hand to battlefield?", source, game) && controller.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/conflux/PathToExile.java b/Mage.Sets/src/mage/sets/conflux/PathToExile.java index 66e23cbdc7..bc78ddb72e 100644 --- a/Mage.Sets/src/mage/sets/conflux/PathToExile.java +++ b/Mage.Sets/src/mage/sets/conflux/PathToExile.java @@ -94,7 +94,7 @@ class PathToExileEffect extends OneShotEffect { Player player = game.getPlayer(permanent.getControllerId()); // if the zone change to exile gets replaced does not prevent the target controller to be able to search controller.moveCardToExileWithInfo(permanent, null, "", source.getSourceId(), game, Zone.BATTLEFIELD, true); - if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for a basic land card?", game)) { + if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for a basic land card?", source, game)) { TargetCardInLibrary target = new TargetCardInLibrary(new FilterBasicLandCard()); if (player.searchLibrary(target, game)) { Card card = player.getLibrary().getCard(target.getFirstTarget(), game); diff --git a/Mage.Sets/src/mage/sets/conspiracy/CoercivePortal.java b/Mage.Sets/src/mage/sets/conspiracy/CoercivePortal.java index 7dcd761408..b08a39c58d 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/CoercivePortal.java +++ b/Mage.Sets/src/mage/sets/conspiracy/CoercivePortal.java @@ -92,7 +92,7 @@ class CoercivePortalEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - if (player.chooseUse(Outcome.DestroyPermanent, "Choose carnage?", game)) { + if (player.chooseUse(Outcome.DestroyPermanent, "Choose carnage?", source, game)) { carnageCount++; game.informPlayers(player.getLogName() + " has chosen: carnage"); } diff --git a/Mage.Sets/src/mage/sets/conspiracy/TyrantsChoice.java b/Mage.Sets/src/mage/sets/conspiracy/TyrantsChoice.java index 845b4b01c3..8b2613ffe2 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/TyrantsChoice.java +++ b/Mage.Sets/src/mage/sets/conspiracy/TyrantsChoice.java @@ -88,7 +88,7 @@ class TyrantsChoiceEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - if (player.chooseUse(Outcome.Sacrifice, "Choose death?", game)) { + if (player.chooseUse(Outcome.Sacrifice, "Choose death?", source, game)) { deathCount++; game.informPlayers(player.getLogName() + " has chosen: death"); } diff --git a/Mage.Sets/src/mage/sets/darkascension/CallToTheKindred.java b/Mage.Sets/src/mage/sets/darkascension/CallToTheKindred.java index 664e4a8e00..7d0fcaf0d4 100644 --- a/Mage.Sets/src/mage/sets/darkascension/CallToTheKindred.java +++ b/Mage.Sets/src/mage/sets/darkascension/CallToTheKindred.java @@ -141,7 +141,7 @@ class CallToTheKindredEffect extends OneShotEffect { sb.delete(sb.length() - 2, sb.length()); filter.setMessage(sb.toString()); - if (cards.count(filter, game) > 0 && player.chooseUse(Outcome.DrawCard, "Do you wish to put a creature card onto the battlefield?", game)) { + if (cards.count(filter, game) > 0 && player.chooseUse(Outcome.DrawCard, "Do you wish to put a creature card onto the battlefield?", source, game)) { TargetCard target = new TargetCard(Zone.PICK, filter); if (player.choose(Outcome.PutCreatureInPlay, cards, target, game)) { diff --git a/Mage.Sets/src/mage/sets/darkascension/Counterlash.java b/Mage.Sets/src/mage/sets/darkascension/Counterlash.java index 6b1e86113c..cafcf17997 100644 --- a/Mage.Sets/src/mage/sets/darkascension/Counterlash.java +++ b/Mage.Sets/src/mage/sets/darkascension/Counterlash.java @@ -96,7 +96,7 @@ class CounterlashEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (stackObject != null && player != null) { game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game); - if (player.chooseUse(Outcome.PutCardInPlay, "Cast a nonland card in your hand that shares a card type with that spell without paying its mana cost?", game)) { + if (player.chooseUse(Outcome.PutCardInPlay, "Cast a nonland card in your hand that shares a card type with that spell without paying its mana cost?", source, game)) { FilterCard filter = new FilterCard(); ArrayList> types = new ArrayList>(); for (CardType type: stackObject.getCardType()) { diff --git a/Mage.Sets/src/mage/sets/darkascension/CurseOfEchoes.java b/Mage.Sets/src/mage/sets/darkascension/CurseOfEchoes.java index bc023ef881..297f33647d 100644 --- a/Mage.Sets/src/mage/sets/darkascension/CurseOfEchoes.java +++ b/Mage.Sets/src/mage/sets/darkascension/CurseOfEchoes.java @@ -152,7 +152,7 @@ class CurseOfEchoesEffect extends OneShotEffect { for (UUID playerId: game.getPlayerList()) { if (!playerId.equals(spell.getControllerId())) { Player player = game.getPlayer(playerId); - if (player.chooseUse(Outcome.Copy, chooseMessage, game)) { + if (player.chooseUse(Outcome.Copy, chooseMessage, source, game)) { Spell copy = spell.copySpell(); copy.setControllerId(playerId); copy.setCopiedSpell(true); diff --git a/Mage.Sets/src/mage/sets/darksteel/AEtherVial.java b/Mage.Sets/src/mage/sets/darksteel/AEtherVial.java index b675857cc8..baa5d24d1c 100644 --- a/Mage.Sets/src/mage/sets/darksteel/AEtherVial.java +++ b/Mage.Sets/src/mage/sets/darksteel/AEtherVial.java @@ -109,7 +109,7 @@ class AEtherVialEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (player == null || player.getHand().count(filter, game) == 0 - || !player.chooseUse(this.outcome, choiceText, game)) { + || !player.chooseUse(this.outcome, choiceText, source, game)) { return false; } diff --git a/Mage.Sets/src/mage/sets/darksteel/PanopticMirror.java b/Mage.Sets/src/mage/sets/darksteel/PanopticMirror.java index cc850ad7d5..4c565ce4e7 100644 --- a/Mage.Sets/src/mage/sets/darksteel/PanopticMirror.java +++ b/Mage.Sets/src/mage/sets/darksteel/PanopticMirror.java @@ -109,7 +109,7 @@ class PanopticMirrorExileEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (player == null || player.getHand().count(filter, game) == 0 - || !player.chooseUse(this.outcome, choiceText, game)) { + || !player.chooseUse(this.outcome, choiceText, source, game)) { return false; } @@ -177,7 +177,7 @@ class PanopticMirrorCastEffect extends OneShotEffect { } if(cardToCopy != null){ Card copy = game.copyCard(cardToCopy, source, source.getControllerId()); - if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", game)) { + if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) { return controller.cast(copy.getSpellAbility(), game, true); } } diff --git a/Mage.Sets/src/mage/sets/darksteel/SerumPowder.java b/Mage.Sets/src/mage/sets/darksteel/SerumPowder.java index 3b07147d6d..217b49f519 100644 --- a/Mage.Sets/src/mage/sets/darksteel/SerumPowder.java +++ b/Mage.Sets/src/mage/sets/darksteel/SerumPowder.java @@ -87,7 +87,7 @@ class SerumPowderReplaceEffect extends ReplacementEffectImpl { Player controller = game.getPlayer(source.getControllerId()); Card sourceCard = game.getCard(source.getSourceId()); if (controller != null && sourceCard != null) { - if (!controller.chooseUse(outcome, "Exile all cards from hand and draw that many cards?", game)) { + if (!controller.chooseUse(outcome, "Exile all cards from hand and draw that many cards?", source, game)) { return false; } int cardsHand = controller.getHand().size(); diff --git a/Mage.Sets/src/mage/sets/darksteel/SwordOfLightAndShadow.java b/Mage.Sets/src/mage/sets/darksteel/SwordOfLightAndShadow.java index 1d4414a3c4..b090e5ffd8 100644 --- a/Mage.Sets/src/mage/sets/darksteel/SwordOfLightAndShadow.java +++ b/Mage.Sets/src/mage/sets/darksteel/SwordOfLightAndShadow.java @@ -172,7 +172,7 @@ class SwordOfLightAndShadowReturnToHandTargetEffect extends OneShotEffect { return false; } if (!source.getTargets().isEmpty() && targetPointer.getFirst(game, source) != null) { - if (controller.chooseUse(outcome, "Return creature card from graveyard to hand?", game)) { + if (controller.chooseUse(outcome, "Return creature card from graveyard to hand?", source, game)) { for (UUID targetId : targetPointer.getTargets(game, source)) { switch (game.getState().getZone(targetId)) { case GRAVEYARD: diff --git a/Mage.Sets/src/mage/sets/dissension/ResearchDevelopment.java b/Mage.Sets/src/mage/sets/dissension/ResearchDevelopment.java index 353b431a55..959e9e2fc8 100644 --- a/Mage.Sets/src/mage/sets/dissension/ResearchDevelopment.java +++ b/Mage.Sets/src/mage/sets/dissension/ResearchDevelopment.java @@ -102,7 +102,7 @@ class ResearchEffect extends OneShotEffect { StringBuilder textToAsk = new StringBuilder(choiceText); textToAsk.append(" (0)"); int count = 0; - while (player.chooseUse(Outcome.Benefit, textToAsk.toString(), game)) { + while (player.chooseUse(Outcome.Benefit, textToAsk.toString(), source, game)) { Cards cards = player.getSideboard(); if(cards.isEmpty()) { game.informPlayer(player, "You have no cards outside the game."); @@ -172,7 +172,7 @@ class DevelopmentEffect extends OneShotEffect { for (UUID opponentUuid : opponents) { Player opponent = game.getPlayer(opponentUuid); if (opponent != null && opponent.chooseUse(Outcome.Detriment, - "Allow " + player.getLogName() + " to draw a card instead? (" + Integer.toString(i+1) + ")", game)) { + "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); putToken = false; diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/HiddenStrings.java b/Mage.Sets/src/mage/sets/dragonsmaze/HiddenStrings.java index f10ce2e4e7..51132bc9b0 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/HiddenStrings.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/HiddenStrings.java @@ -99,11 +99,11 @@ class HiddenStringsEffect extends OneShotEffect { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { if (permanent.isTapped()) { - if (player.chooseUse(Outcome.Untap, new StringBuilder("Untap ").append(permanent.getName()).append("?").toString(), game)) { + if (player.chooseUse(Outcome.Untap, new StringBuilder("Untap ").append(permanent.getName()).append("?").toString(), source, game)) { permanent.untap(game); } } else { - if (player.chooseUse(Outcome.Tap, new StringBuilder("Tap ").append(permanent.getName()).append("?").toString(), game)) { + if (player.chooseUse(Outcome.Tap, new StringBuilder("Tap ").append(permanent.getName()).append("?").toString(), source, game)) { permanent.tap(game); } } diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/PossibilityStorm.java b/Mage.Sets/src/mage/sets/dragonsmaze/PossibilityStorm.java index 0b75124067..a937018ec3 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/PossibilityStorm.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/PossibilityStorm.java @@ -150,7 +150,7 @@ class PossibilityStormEffect extends OneShotEffect { if (card != null && sharesType(card, spell.getCardType()) && !card.getCardType().contains(CardType.LAND) && card.getSpellAbility().getTargets().canChoose(spellController.getId(), game)) { - if (spellController.chooseUse(Outcome.PlayForFree, "Cast " + card.getLogName() + " without paying cost?", game)) { + if (spellController.chooseUse(Outcome.PlayForFree, "Cast " + card.getLogName() + " without paying cost?", source, game)) { spellController.cast(card.getSpellAbility(), game, true); } } diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/ArashinSovereign.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/ArashinSovereign.java index a34bc3eac6..2b2439a259 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/ArashinSovereign.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/ArashinSovereign.java @@ -94,7 +94,7 @@ class ArashinSovereignEffect extends OneShotEffect { Card sourceCard = game.getCard(source.getSourceId()); if (controller != null && sourceCard != null) { if (game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { - boolean onTop = controller.chooseUse(outcome, "Put " + sourceCard.getName() + " on top of it's owners library (otherwise on bottom)?", game); + boolean onTop = controller.chooseUse(outcome, "Put " + sourceCard.getName() + " on top of it's owners library (otherwise on bottom)?", source, game); controller.moveCardToLibraryWithInfo(sourceCard, source.getSourceId(), game, Zone.GRAVEYARD, onTop, true); } return true; diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DeathmistRaptor.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DeathmistRaptor.java index d6295186c5..098a319ff6 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/DeathmistRaptor.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DeathmistRaptor.java @@ -102,7 +102,7 @@ class DeathmistRaptorEffect extends OneShotEffect { MageObject sourceObject = source.getSourceObjectIfItStillExists(game); if (controller != null && (sourceObject instanceof Card)) { controller.putOntoBattlefieldWithInfo((Card) sourceObject, game, Zone.GRAVEYARD, source.getSourceId(), false, - controller.chooseUse(Outcome.Detriment, "Return " + sourceObject.getLogName() + " face down to battlefield (otherwise face up)?", game)); + controller.chooseUse(Outcome.Detriment, "Return " + sourceObject.getLogName() + " face down to battlefield (otherwise face up)?", source, game)); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/MysticMeditation.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/MysticMeditation.java index 1fcdf2154d..46b1afc78a 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/MysticMeditation.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/MysticMeditation.java @@ -92,7 +92,7 @@ class MysticMeditationEffect extends OneShotEffect { filter.add(new CardTypePredicate(CardType.CREATURE)); if (controller != null && controller.getHand().count(filter, game) > 0 - && controller.chooseUse(Outcome.Discard, "Do you want to discard a creature card? If you don't, you must discard 2 cards", game)) { + && controller.chooseUse(Outcome.Discard, "Do you want to discard a creature card? If you don't, you must discard 2 cards", source, game)) { Cost cost = new DiscardTargetCost(new TargetCardInHand(filter)); if (cost.canPay(source, source.getSourceId(), controller.getId(), game)) { if (cost.pay(source, game, source.getSourceId(), controller.getId(), false)) { diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java index 39e70a117d..a490b0d3a0 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java @@ -121,7 +121,7 @@ class NarsetTranscendentEffect1 extends OneShotEffect { cards.add(card); controller.lookAtCards(sourceObject.getName(), cards, game); if (!card.getCardType().contains(CardType.CREATURE) && !card.getCardType().contains(CardType.LAND)) { - if (controller.chooseUse(outcome, "Reveal " + card.getName() + " and put it into your hand?", game)) { + if (controller.chooseUse(outcome, "Reveal " + card.getName() + " and put it into your hand?", source, game)) { controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); controller.revealCards(sourceObject.getName(), cards, game); } diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/QalSismaBehemoth.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/QalSismaBehemoth.java index 06f698c20a..b32f307659 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/QalSismaBehemoth.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/QalSismaBehemoth.java @@ -104,7 +104,7 @@ class QalSismaBehemothEffect extends ReplacementEffectImpl { } ManaCostsImpl attackBlockTax = new ManaCostsImpl("{2}"); if (attackBlockTax.canPay(source, source.getSourceId(), event.getPlayerId(), game) - && player.chooseUse(Outcome.Neutral, chooseText, game)) { + && player.chooseUse(Outcome.Neutral, chooseText, source, game)) { if (attackBlockTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) { return false; } diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/RevealingWind.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/RevealingWind.java index a057081e31..71108179da 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/RevealingWind.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/RevealingWind.java @@ -101,7 +101,7 @@ class RevealingWindEffect extends OneShotEffect { MageObject sourceObject = source.getSourceObject(game); if (controller != null && sourceObject != null) { while (game.getBattlefield().count(filter, source.getOriginalId(), source.getControllerId(), game) > 0 && - controller.chooseUse(outcome, "Look at a face-down attacking creature?", game)) { + controller.chooseUse(outcome, "Look at a face-down attacking creature?", source, game)) { if (!controller.isInGame()) { return false; } diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/SilumgarsScorn.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/SilumgarsScorn.java index a878897703..f6bbf26fd3 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/SilumgarsScorn.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/SilumgarsScorn.java @@ -132,7 +132,7 @@ class SilumgarsScornCounterEffect extends OneShotEffect { if (condition) { return game.getStack().counter(spell.getId(), source.getSourceId(), game); } - if (!(player.chooseUse(Outcome.Benefit, "Would you like to pay {1} to prevent counter effect?", game) && + if (!(player.chooseUse(Outcome.Benefit, "Would you like to pay {1} to prevent counter effect?", source, game) && new GenericManaCost(1).pay(source, game, spell.getSourceId(), spell.getControllerId(), false))) { return game.getStack().counter(spell.getId(), source.getSourceId(), game); } diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/SwiftWarkite.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/SwiftWarkite.java index 26ba71120c..d3a8b1757e 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/SwiftWarkite.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/SwiftWarkite.java @@ -117,7 +117,7 @@ class SwiftWarkiteEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - if (controller.chooseUse(Outcome.PutCardInPlay, "Put a creature card from your hand? (No = from your graveyard)", game)) { + if (controller.chooseUse(Outcome.PutCardInPlay, "Put a creature card from your hand? (No = from your graveyard)", source, game)) { Target target = new TargetCardInHand(0, 1, filter); controller.choose(outcome, target, source.getSourceId(), game); Card card = controller.getHand().get(target.getFirstTarget(), game); diff --git a/Mage.Sets/src/mage/sets/eventide/Evershrike.java b/Mage.Sets/src/mage/sets/eventide/Evershrike.java index 411fca6c81..f413f47643 100644 --- a/Mage.Sets/src/mage/sets/eventide/Evershrike.java +++ b/Mage.Sets/src/mage/sets/eventide/Evershrike.java @@ -122,7 +122,7 @@ class EvershrikeEffect extends OneShotEffect { filterAuraCard.add(new AuraCardCanAttachToPermanentId(evershrikePermanent.getId())); filterAuraCard.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, xAmount)); int count = controller.getHand().count(filterAuraCard, game); - while (controller.isInGame() && count > 0 && controller.chooseUse(Outcome.Benefit, "Do you wish to put an Aura card from your hand onto Evershrike", game)) { + while (controller.isInGame() && count > 0 && controller.chooseUse(Outcome.Benefit, "Do you wish to put an Aura card from your hand onto Evershrike", source, game)) { TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard); if (controller.choose(Outcome.Benefit, controller.getHand(), targetAura, game)) { Card aura = game.getCard(targetAura.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/eventide/MindwrackLiege.java b/Mage.Sets/src/mage/sets/eventide/MindwrackLiege.java index 43fb85a3b2..eda9db6234 100644 --- a/Mage.Sets/src/mage/sets/eventide/MindwrackLiege.java +++ b/Mage.Sets/src/mage/sets/eventide/MindwrackLiege.java @@ -128,7 +128,7 @@ class MindwrackLiegeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, choiceText, game)) { + if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { return false; } diff --git a/Mage.Sets/src/mage/sets/eventide/RiseOfTheHobgoblins.java b/Mage.Sets/src/mage/sets/eventide/RiseOfTheHobgoblins.java index 7dcda6a51f..a168f00104 100644 --- a/Mage.Sets/src/mage/sets/eventide/RiseOfTheHobgoblins.java +++ b/Mage.Sets/src/mage/sets/eventide/RiseOfTheHobgoblins.java @@ -116,7 +116,7 @@ class RiseOfTheHobgoblinsEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player you = game.getPlayer(source.getControllerId()); ManaCosts cost = new ManaCostsImpl<>("{X}"); - if (you != null && you.chooseUse(Outcome.Neutral, "Do you want to to pay {X}?", game)) { + if (you != null && you.chooseUse(Outcome.Neutral, "Do you want to to pay {X}?", source, game)) { int costX = you.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source); cost.add(new GenericManaCost(costX)); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { diff --git a/Mage.Sets/src/mage/sets/exodus/ErraticPortal.java b/Mage.Sets/src/mage/sets/exodus/ErraticPortal.java index 49b4ef3f46..66f16ccb7c 100644 --- a/Mage.Sets/src/mage/sets/exodus/ErraticPortal.java +++ b/Mage.Sets/src/mage/sets/exodus/ErraticPortal.java @@ -102,7 +102,7 @@ class ErraticPortalEffect extends OneShotEffect { Player player = game.getPlayer(targetCreature.getControllerId()); if (player != null) { cost.clearPaid(); - if (player.chooseUse(Outcome.Benefit, "Pay {1}? (Otherwise " + targetCreature.getLogName() +" will be returned to its owner's hand)", game)) { + if (player.chooseUse(Outcome.Benefit, "Pay {1}? (Otherwise " + targetCreature.getLogName() +" will be returned to its owner's hand)", source, game)) { cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), false); } if (!cost.isPaid()) { diff --git a/Mage.Sets/src/mage/sets/exodus/ExaltedDragon.java b/Mage.Sets/src/mage/sets/exodus/ExaltedDragon.java index 12b39be1e8..f0aa723125 100644 --- a/Mage.Sets/src/mage/sets/exodus/ExaltedDragon.java +++ b/Mage.Sets/src/mage/sets/exodus/ExaltedDragon.java @@ -103,7 +103,7 @@ class ExaltedDragonReplacementEffect extends ReplacementEffectImpl { if ( player != null ) { SacrificeTargetCost attackCost = new SacrificeTargetCost(new TargetControlledPermanent(filter)); if ( attackCost.canPay(source, source.getSourceId(), event.getPlayerId(), game) && - player.chooseUse(Outcome.Neutral, "Sacrifice a land?", game) ) + player.chooseUse(Outcome.Neutral, "Sacrifice a land?", source, game) ) { if (attackCost.pay(source, game, source.getSourceId(), event.getPlayerId(), false) ) { return false; diff --git a/Mage.Sets/src/mage/sets/fatereforged/TemurSabertooth.java b/Mage.Sets/src/mage/sets/fatereforged/TemurSabertooth.java index 9a6f19c383..465bb3dcfd 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/TemurSabertooth.java +++ b/Mage.Sets/src/mage/sets/fatereforged/TemurSabertooth.java @@ -105,7 +105,7 @@ class TemurSabertoothEffect extends OneShotEffect { if (controller != null) { Target target = new TargetPermanent(1,1, filter, true); if (target.canChoose(source.getSourceId(), controller.getId(), game)) { - if (controller.chooseUse(outcome, "Return another creature to hand?", game) && + if (controller.chooseUse(outcome, "Return another creature to hand?", source, game) && controller.chooseTarget(outcome, target, source, game)) { Permanent toHand = game.getPermanent(target.getFirstTarget()); if (toHand != null) { diff --git a/Mage.Sets/src/mage/sets/fatereforged/WriteIntoBeing.java b/Mage.Sets/src/mage/sets/fatereforged/WriteIntoBeing.java index 06df7949b2..8b6397af6c 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/WriteIntoBeing.java +++ b/Mage.Sets/src/mage/sets/fatereforged/WriteIntoBeing.java @@ -112,7 +112,7 @@ class WriteIntoBeingEffect extends OneShotEffect { if (controller.getLibrary().size() > 0) { Card cardToPutBack = controller.getLibrary().getFromTop(game); String position = "on top"; - if (controller.chooseUse(Outcome.Detriment, "Put " + cardToPutBack.getName() + " on bottom of library?", game)) { + if (controller.chooseUse(Outcome.Detriment, "Put " + cardToPutBack.getName() + " on bottom of library?", source, game)) { cardToPutBack.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); position = "on bottom"; } diff --git a/Mage.Sets/src/mage/sets/fifthdawn/DisruptionAura.java b/Mage.Sets/src/mage/sets/fifthdawn/DisruptionAura.java index 2820115cb8..9cb5e3fcf4 100644 --- a/Mage.Sets/src/mage/sets/fifthdawn/DisruptionAura.java +++ b/Mage.Sets/src/mage/sets/fifthdawn/DisruptionAura.java @@ -110,7 +110,7 @@ class DisruptionAuraEffect extends OneShotEffect { String message = CardUtil.replaceSourceName("Pay {this} mana cost ?", permanent.getLogName()); Cost cost = permanent.getManaCost().copy(); - if (player.chooseUse(Outcome.Benefit, message, game)) { + if (player.chooseUse(Outcome.Benefit, message, source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { return true; diff --git a/Mage.Sets/src/mage/sets/fifthdawn/FoldIntoAEther.java b/Mage.Sets/src/mage/sets/fifthdawn/FoldIntoAEther.java index 5304727f9c..7ddcccce95 100644 --- a/Mage.Sets/src/mage/sets/fifthdawn/FoldIntoAEther.java +++ b/Mage.Sets/src/mage/sets/fifthdawn/FoldIntoAEther.java @@ -95,7 +95,7 @@ class FoldIntoAEtherEffect extends OneShotEffect { if (game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game)) { TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard()); if (player != null - && player.chooseUse(Outcome.Neutral, "Put a creature card from your hand in play?", game) + && player.chooseUse(Outcome.Neutral, "Put a creature card from your hand in play?", source, game) && player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/fifthdawn/ReversalOfFortune.java b/Mage.Sets/src/mage/sets/fifthdawn/ReversalOfFortune.java index 05a49050c4..b418addb3d 100644 --- a/Mage.Sets/src/mage/sets/fifthdawn/ReversalOfFortune.java +++ b/Mage.Sets/src/mage/sets/fifthdawn/ReversalOfFortune.java @@ -106,7 +106,7 @@ class ReversalOfFortuneEffect extends OneShotEffect { //If you do, you may cast the copy without paying its mana cost if(card != null){ Card copiedCard = game.copyCard(card, source, source.getControllerId()); - if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", game)) { + if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) { controller.cast(copiedCard.getSpellAbility(), game, true); } } diff --git a/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java b/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java index 422f7065d0..107198b383 100644 --- a/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java +++ b/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java @@ -61,7 +61,6 @@ public class SylvanLibrary extends CardImpl { super(ownerId, 191, "Sylvan Library", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); this.expansionSetCode = "5ED"; - // At the beginning of your draw step, you may draw two additional cards. If you do, choose two cards in your hand drawn this turn. For each of those cards, pay 4 life or put the card on top of your library. this.addAbility(new BeginningOfDrawTriggeredAbility(new SylvanLibraryEffect(), TargetController.YOU, true), new CardsDrawnThisTurnWatcher()); @@ -81,7 +80,7 @@ class SylvanLibraryEffect extends OneShotEffect { public SylvanLibraryEffect() { super(Outcome.LoseLife); - this.staticText = "draw two additional cards. If you do, choose two cards in your hand drawn this turn. For each of those cards, pay 4 life or put the card on top of your library"; + this.staticText = "you may draw two additional cards. If you do, choose two cards in your hand drawn this turn. For each of those cards, pay 4 life or put the card on top of your library"; } public SylvanLibraryEffect(final SylvanLibraryEffect effect) { @@ -111,18 +110,18 @@ class SylvanLibraryEffect extends OneShotEffect { } int numberOfTargets = Math.min(2, cards.size()); if (numberOfTargets > 0) { - TargetCardInHand target = new TargetCardInHand(numberOfTargets, new FilterCard(new StringBuilder(numberOfTargets).append(" cards of cards drawn this turn").toString())); + TargetCardInHand target = new TargetCardInHand(numberOfTargets, new FilterCard(numberOfTargets + " cards of cards drawn this turn")); controller.chooseTarget(outcome, cards, target, source, game); Cards cardsPutBack = new CardsImpl(); - for (UUID cardId :target.getTargets()) { + for (UUID cardId : target.getTargets()) { Card card = cards.get(cardId, game); if (card != null) { if (controller.canPayLifeCost() && controller.getLife() >= 4 - && controller.chooseUse(outcome, new StringBuilder("Pay 4 life for ").append(card.getName()).append("? (Otherwise it's put on top of your library)").toString(), game)) { + && controller.chooseUse(outcome, "Pay 4 life for " + card.getLogName() + "? (Otherwise it's put on top of your library)", source, game)) { controller.loseLife(4, game); - game.informPlayers(new StringBuilder(controller.getLogName()).append(" pays 4 life to keep a card on hand").toString()); + game.informPlayers(controller.getLogName() + " pays 4 life to keep a card on hand"); } else { cardsPutBack.add(card); } @@ -146,7 +145,7 @@ class SylvanLibraryEffect extends OneShotEffect { card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); } if (numberOfCardsToPutBack > 0) { - game.informPlayers(new StringBuilder(controller.getLogName()).append(" puts ").append(numberOfCardsToPutBack).append(" card(s) back to library").toString()); + game.informPlayers(controller.getLogName() + " puts " + numberOfCardsToPutBack + " card(s) back to library"); } } } @@ -160,7 +159,6 @@ class CardsDrawnThisTurnWatcher extends Watcher { private final Set cardsDrawnThisTurn = new HashSet(); - public CardsDrawnThisTurnWatcher() { super("CardsDrawnThisTurnWatcher", WatcherScope.PLAYER); } diff --git a/Mage.Sets/src/mage/sets/fourthedition/ForceOfNature.java b/Mage.Sets/src/mage/sets/fourthedition/ForceOfNature.java index e1e9cd6060..49ae48923a 100644 --- a/Mage.Sets/src/mage/sets/fourthedition/ForceOfNature.java +++ b/Mage.Sets/src/mage/sets/fourthedition/ForceOfNature.java @@ -96,7 +96,7 @@ class ForceOfNatureEffect extends OneShotEffect { if (controller != null) { Cost cost = new ManaCostsImpl("{G}{G}{G}{G}"); String message = "Would you like to pay {G}{G}{G}{G} to prevent taking 8 damage from {this}?"; - if (!(controller.chooseUse(Outcome.Benefit, message, game) + if (!(controller.chooseUse(Outcome.Benefit, message, source, game) && cost.pay(source, game, source.getSourceId(), controller.getId(), false))) { controller.damage(8, source.getSourceId(), game, false, true); } diff --git a/Mage.Sets/src/mage/sets/futuresight/GlitteringWish.java b/Mage.Sets/src/mage/sets/futuresight/GlitteringWish.java index 3f4ea5a174..9f2aa2e6e1 100644 --- a/Mage.Sets/src/mage/sets/futuresight/GlitteringWish.java +++ b/Mage.Sets/src/mage/sets/futuresight/GlitteringWish.java @@ -110,7 +110,7 @@ class GlitteringWishEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - while (player.chooseUse(Outcome.Benefit, choiceText, game)) { + while (player.chooseUse(Outcome.Benefit, choiceText, source, game)) { Cards cards = player.getSideboard(); if(cards.isEmpty()) { game.informPlayer(player, "You have no cards outside the game."); diff --git a/Mage.Sets/src/mage/sets/gatecrash/DiluvianPrimordial.java b/Mage.Sets/src/mage/sets/gatecrash/DiluvianPrimordial.java index 634afc7715..b97e56ead7 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/DiluvianPrimordial.java +++ b/Mage.Sets/src/mage/sets/gatecrash/DiluvianPrimordial.java @@ -127,7 +127,7 @@ class DiluvianPrimordialEffect extends OneShotEffect { if (target instanceof TargetCardInOpponentsGraveyard) { Card targetCard = game.getCard(target.getFirstTarget()); if (targetCard != null) { - if (controller.chooseUse(outcome, "Cast " + targetCard.getLogName() +"?", game)) { + if (controller.chooseUse(outcome, "Cast " + targetCard.getLogName() +"?", source, game)) { // TODO: Handle the case if the cast is not possible, so the replacement effect shouldn't be active ContinuousEffect effect = new DiluvianPrimordialReplacementEffect(); effect.setTargetPointer(new FixedTarget(targetCard.getId())); diff --git a/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java b/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java index 0ec1e13590..40ec318e1b 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java +++ b/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java @@ -126,7 +126,7 @@ class DomriRadeEffect1 extends OneShotEffect { cards.add(card); controller.lookAtCards(sourceObject.getName(), cards, game); if (card.getCardType().contains(CardType.CREATURE)) { - if (controller.chooseUse(outcome, "Reveal " + card.getName() + " and put it into your hand?", game)) { + if (controller.chooseUse(outcome, "Reveal " + card.getName() + " and put it into your hand?", source, game)) { controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); controller.revealCards(sourceObject.getName(), cards, game); } diff --git a/Mage.Sets/src/mage/sets/gatecrash/IllusionistsBracers.java b/Mage.Sets/src/mage/sets/gatecrash/IllusionistsBracers.java index 83a86cc47b..7143298d44 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/IllusionistsBracers.java +++ b/Mage.Sets/src/mage/sets/gatecrash/IllusionistsBracers.java @@ -140,7 +140,7 @@ class CopyActivatedAbilityEffect extends OneShotEffect { newAbility.newId(); game.getStack().push(new StackAbility(newAbility, source.getControllerId())); if (newAbility.getTargets().size() > 0) { - if (controller.chooseUse(newAbility.getEffects().get(0).getOutcome(), "Choose new targets?", game)) { + if (controller.chooseUse(newAbility.getEffects().get(0).getOutcome(), "Choose new targets?", source, game)) { newAbility.getTargets().clearChosen(); if (newAbility.getTargets().chooseTargets(newAbility.getEffects().get(0).getOutcome(), source.getControllerId(), newAbility, game) == false) { return false; diff --git a/Mage.Sets/src/mage/sets/gatecrash/SpellRupture.java b/Mage.Sets/src/mage/sets/gatecrash/SpellRupture.java index 044ed10c37..3fd85eafe8 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/SpellRupture.java +++ b/Mage.Sets/src/mage/sets/gatecrash/SpellRupture.java @@ -99,7 +99,7 @@ class SpellRuptureCounterUnlessPaysEffect extends OneShotEffect { int amount = new greatestPowerCountCreatureYouControl().calculate(game, source, this); GenericManaCost cost = new GenericManaCost(amount); StringBuilder sb = new StringBuilder("Pay {").append(amount).append("}? (otherwise ").append(spell.getName()).append(" will be countered)"); - if (player.chooseUse(Outcome.Benefit, sb.toString(), game)) { + if (player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { cost.pay(source, game, source.getSourceId(), player.getId(), false); } if (!cost.isPaid()) { diff --git a/Mage.Sets/src/mage/sets/gatecrash/UnexpectedResults.java b/Mage.Sets/src/mage/sets/gatecrash/UnexpectedResults.java index 3fb0e6c321..e5a485d81f 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/UnexpectedResults.java +++ b/Mage.Sets/src/mage/sets/gatecrash/UnexpectedResults.java @@ -119,12 +119,12 @@ class UnexpectedResultEffect extends OneShotEffect { controller.revealCards(sourceCard.getName(), new CardsImpl(card), game); if (card.getCardType().contains(CardType.LAND)) { String message = "Put " + card.getName() + " onto the battlefield?"; - if (controller.chooseUse(Outcome.PutLandInPlay, message, game)) { + if (controller.chooseUse(Outcome.PutLandInPlay, message, source, game)) { card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId()); return sourceCard.moveToZone(Zone.HAND, source.getSourceId(), game, false); } } else { - if (controller.chooseUse(outcome, new StringBuilder("Cast ").append(card.getName()).append(" without paying its mana cost?").toString(), game)) { + if (controller.chooseUse(outcome, new StringBuilder("Cast ").append(card.getName()).append(" without paying its mana cost?").toString(), source, game)) { return controller.cast(card.getSpellAbility(), game, true); } } diff --git a/Mage.Sets/src/mage/sets/iceage/MysticRemora.java b/Mage.Sets/src/mage/sets/iceage/MysticRemora.java index 4d9f6ae3ef..c3db898671 100644 --- a/Mage.Sets/src/mage/sets/iceage/MysticRemora.java +++ b/Mage.Sets/src/mage/sets/iceage/MysticRemora.java @@ -145,8 +145,8 @@ class MysticRemoraTriggeredAbility extends TriggeredAbilityImpl { if (controller != null && opponent != null && sourceObject != null) { Cost cost = new GenericManaCost(4); String message = "Would you like to pay {4} to prevent the opponent to draw a card?"; - if (!(opponent.chooseUse(Outcome.Benefit, message, game) && cost.pay(source, game, source.getSourceId(), opponent.getId(), false))) { - if(controller.chooseUse(Outcome.DrawCard, "Draw a card (" + sourceObject.getLogName() +")", game)) { + if (!(opponent.chooseUse(Outcome.Benefit, message, source, game) && cost.pay(source, game, source.getSourceId(), opponent.getId(), false))) { + if(controller.chooseUse(Outcome.DrawCard, "Draw a card (" + sourceObject.getLogName() +")", source, game)) { controller.drawCards(1, game); } } diff --git a/Mage.Sets/src/mage/sets/iceage/SibilantSpirit.java b/Mage.Sets/src/mage/sets/iceage/SibilantSpirit.java index e0e4714d80..d90eb58431 100644 --- a/Mage.Sets/src/mage/sets/iceage/SibilantSpirit.java +++ b/Mage.Sets/src/mage/sets/iceage/SibilantSpirit.java @@ -91,7 +91,7 @@ class SibilantSpiritEffect extends OneShotEffect { UUID defenderId = game.getCombat().getDefenderId(source.getSourceId()); Player defender = game.getPlayer(defenderId); if (defender != null) { - if (defender.chooseUse(outcome, "Draw a card?", game)) { + if (defender.chooseUse(outcome, "Draw a card?", source, game)) { defender.drawCards(1, game); } } diff --git a/Mage.Sets/src/mage/sets/iceage/ZursWeirding.java b/Mage.Sets/src/mage/sets/iceage/ZursWeirding.java index cfc246e3fe..ebee9cfe3d 100644 --- a/Mage.Sets/src/mage/sets/iceage/ZursWeirding.java +++ b/Mage.Sets/src/mage/sets/iceage/ZursWeirding.java @@ -114,7 +114,7 @@ class ZursWeirdingReplacementEffect extends ReplacementEffectImpl { while (!currentPlayer.getId().equals(player.getId())) { if (currentPlayer.canPayLifeCost() && currentPlayer.getLife() >= 2 && - currentPlayer.chooseUse(Outcome.Benefit, message, game)) { + currentPlayer.chooseUse(Outcome.Benefit, message, source, game)) { currentPlayer.loseLife(2, game); player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game); // game.getState().getRevealed().reset(); diff --git a/Mage.Sets/src/mage/sets/innistrad/CaravanVigil.java b/Mage.Sets/src/mage/sets/innistrad/CaravanVigil.java index bfb77513ee..aed1c1e2af 100644 --- a/Mage.Sets/src/mage/sets/innistrad/CaravanVigil.java +++ b/Mage.Sets/src/mage/sets/innistrad/CaravanVigil.java @@ -100,7 +100,7 @@ class CaravanVigilEffect extends OneShotEffect { Cards cards = new CardsImpl(); cards.add(card); if (MorbidCondition.getInstance().apply(game, source) - && controller.chooseUse(Outcome.PutLandInPlay, "Do you wish to put the card onto the battlefield instead?", game)) { + && controller.chooseUse(Outcome.PutLandInPlay, "Do you wish to put the card onto the battlefield instead?", source, game)) { controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); } else { controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); diff --git a/Mage.Sets/src/mage/sets/innistrad/DelverOfSecrets.java b/Mage.Sets/src/mage/sets/innistrad/DelverOfSecrets.java index 71a1d172fb..66fd5b8742 100644 --- a/Mage.Sets/src/mage/sets/innistrad/DelverOfSecrets.java +++ b/Mage.Sets/src/mage/sets/innistrad/DelverOfSecrets.java @@ -109,7 +109,7 @@ class DelverOfSecretsEffect extends OneShotEffect { Cards cards = new CardsImpl(); cards.add(card); player.lookAtCards(sourcePermanent.getName(), cards, game); - if (player.chooseUse(Outcome.DrawCard, "Do you wish to reveal the card at the top of the library?", game)) { + if (player.chooseUse(Outcome.DrawCard, "Do you wish to reveal the card at the top of the library?", source, game)) { player.revealCards(sourcePermanent.getName(), cards, game); if (filter.match(card, game)) { return new TransformSourceEffect(true, true).apply(game, source); diff --git a/Mage.Sets/src/mage/sets/innistrad/GhostQuarter.java b/Mage.Sets/src/mage/sets/innistrad/GhostQuarter.java index c0e0ddaed5..aeba8786b3 100644 --- a/Mage.Sets/src/mage/sets/innistrad/GhostQuarter.java +++ b/Mage.Sets/src/mage/sets/innistrad/GhostQuarter.java @@ -99,7 +99,7 @@ class GhostQuarterEffect extends OneShotEffect { Permanent permanent = (Permanent) game.getPermanentOrLKIBattlefield(source.getFirstTarget()); // if indestructible effect should work also if (permanent != null) { Player player = game.getPlayer(permanent.getControllerId()); - if (player.chooseUse(Outcome.PutLandInPlay, "Do you wish to search for a basic land, put it onto the battlefield and then shuffle your library?", game)) { + if (player.chooseUse(Outcome.PutLandInPlay, "Do you wish to search for a basic land, put it onto the battlefield and then shuffle your library?", source, game)) { TargetCardInLibrary target = new TargetCardInLibrary(new FilterBasicLandCard()); if (player.searchLibrary(target, game)) { Card card = player.getLibrary().getCard(target.getFirstTarget(), game); diff --git a/Mage.Sets/src/mage/sets/innistrad/MentorOfTheMeek.java b/Mage.Sets/src/mage/sets/innistrad/MentorOfTheMeek.java index b1ae0dfe39..e93a09d59c 100644 --- a/Mage.Sets/src/mage/sets/innistrad/MentorOfTheMeek.java +++ b/Mage.Sets/src/mage/sets/innistrad/MentorOfTheMeek.java @@ -25,13 +25,14 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.innistrad; import java.util.UUID; import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; @@ -50,6 +51,7 @@ import mage.filter.predicate.permanent.AnotherPredicate; public class MentorOfTheMeek extends CardImpl { private static final FilterPermanent filter = new FilterControlledCreaturePermanent("another creature with power 2 or less"); + static { filter.add(new AnotherPredicate()); filter.add(new PowerPredicate(Filter.ComparisonType.LessThan, 3)); @@ -65,8 +67,10 @@ public class MentorOfTheMeek extends CardImpl { this.toughness = new MageInt(2); //Whenever another creature with power 2 or less enters the battlefield under your control, you may pay 1. If you do, draw a card. - this.addAbility(new EntersBattlefieldControlledTriggeredAbility( - Zone.BATTLEFIELD, new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}")),filter, true)); + Effect effect = new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}")); + Ability ability = new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, effect, filter, false); + this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/innistrad/MurderOfCrows.java b/Mage.Sets/src/mage/sets/innistrad/MurderOfCrows.java index 1e4a5d8e57..87a3eeedd4 100644 --- a/Mage.Sets/src/mage/sets/innistrad/MurderOfCrows.java +++ b/Mage.Sets/src/mage/sets/innistrad/MurderOfCrows.java @@ -88,7 +88,7 @@ class MurderOfCrowsEffect extends OneShotEffect { @Override 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.", game)) { + 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) { player.discard(1, source, game); } diff --git a/Mage.Sets/src/mage/sets/innistrad/RooftopStorm.java b/Mage.Sets/src/mage/sets/innistrad/RooftopStorm.java index d68c3e3857..c844ff2683 100644 --- a/Mage.Sets/src/mage/sets/innistrad/RooftopStorm.java +++ b/Mage.Sets/src/mage/sets/innistrad/RooftopStorm.java @@ -98,7 +98,7 @@ class RooftopStormCostReductionEffect extends CostModificationEffectImpl { if (sourceCard != null && sourceCard.hasSubtype("Zombie")) { Player player = game.getPlayer(spell.getControllerId()); if (player != null && - (CardUtil.isCheckPlayableMode(spell) || player.chooseUse(Outcome.Benefit, "Pay {0} rather than pay the mana cost for Zombie creature", game))) { + (CardUtil.isCheckPlayableMode(spell) || player.chooseUse(Outcome.Benefit, "Pay {0} rather than pay the mana cost for Zombie creature", source, game))) { spell.getManaCostsToPay().clear(); spell.getManaCostsToPay().addAll(new ManaCostsImpl<>("{0}")); return true; diff --git a/Mage.Sets/src/mage/sets/invasion/FirebrandRanger.java b/Mage.Sets/src/mage/sets/invasion/FirebrandRanger.java index 98ccf3f084..0f293697d6 100644 --- a/Mage.Sets/src/mage/sets/invasion/FirebrandRanger.java +++ b/Mage.Sets/src/mage/sets/invasion/FirebrandRanger.java @@ -107,7 +107,7 @@ class PutLandOnBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutLandInPlay, choiceText, game)) { + if (player == null || !player.chooseUse(Outcome.PutLandInPlay, choiceText, source, game)) { return false; } diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/AthreosGodOfPassage.java b/Mage.Sets/src/mage/sets/journeyintonyx/AthreosGodOfPassage.java index 412b1ecaad..b502416605 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/AthreosGodOfPassage.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/AthreosGodOfPassage.java @@ -130,7 +130,7 @@ class AthreosGodOfPassageReturnEffect extends OneShotEffect { if (opponent != null) { Cost cost = new PayLifeCost(3); if (cost.canPay(source, source.getSourceId(), opponent.getId(), game) - && opponent.chooseUse(outcome, new StringBuilder("Pay 3 live to prevent that ").append(creature.getLogName()).append(" returns to ").append(controller.getLogName()).append("'s hand?").toString(), game)) { + && opponent.chooseUse(outcome, new StringBuilder("Pay 3 live to prevent that ").append(creature.getLogName()).append(" returns to ").append(controller.getLogName()).append("'s hand?").toString(), source, game)) { if (cost.pay(source, game, source.getSourceId(), opponent.getId(), false)) { paid = true; } diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/DakraMystic.java b/Mage.Sets/src/mage/sets/journeyintonyx/DakraMystic.java index 6c9afba1eb..627a22afca 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/DakraMystic.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/DakraMystic.java @@ -103,7 +103,7 @@ class DakraMysticEffect extends OneShotEffect { player.revealCards(player.getLogName(), new CardsImpl(player.getLibrary().getFromTop(game)), game); } } - if (controller.chooseUse(outcome, "Put revealed cards into graveyard?", game)) { + if (controller.chooseUse(outcome, "Put revealed cards into graveyard?", source, game)) { for(UUID playerId: controller.getInRange()) { Player player = game.getPlayer(playerId); if (player != null && player.getLibrary().size() > 0) { diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/DesertersQuarters.java b/Mage.Sets/src/mage/sets/journeyintonyx/DesertersQuarters.java index c68db17f83..41c34c3891 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/DesertersQuarters.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/DesertersQuarters.java @@ -100,14 +100,13 @@ class DesertersQuartersTapTargetEffect extends TapTargetEffect { if (sourcePermanent != null) { sourcePermanent.addConnectedCard("DesertersQuarters", permanent.getId()); } - if (permanent != null) { + if (permanent != null) { permanent.tap(game); } } return true; } - @Override public DesertersQuartersTapTargetEffect copy() { return new DesertersQuartersTapTargetEffect(this); @@ -144,7 +143,7 @@ class DesertersQuartersRestrictionEffect extends RestrictionEffect { } @Override - public boolean canBeUntapped(Permanent permanent, Game game) { + public boolean canBeUntapped(Permanent permanent, Ability source, Game game) { return false; } diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/DiscipleOfDeceit.java b/Mage.Sets/src/mage/sets/journeyintonyx/DiscipleOfDeceit.java index 0604b7b660..e5e87c1bbc 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/DiscipleOfDeceit.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/DiscipleOfDeceit.java @@ -104,7 +104,7 @@ class DiscipleOfDeceitEffect extends OneShotEffect { Cost cost = new DiscardTargetCost(new TargetCardInHand(new FilterNonlandCard())); String message = "Discard a nonland card to search your library?"; if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game) - && player.chooseUse(Outcome.Detriment, message, game)) { + && player.chooseUse(Outcome.Detriment, message, source, game)) { if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { Card card = game.getCard(cost.getTargets().getFirstTarget()); if (card == null) { diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/OppressiveRays.java b/Mage.Sets/src/mage/sets/journeyintonyx/OppressiveRays.java index a22d2e1fd2..22e1057471 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/OppressiveRays.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/OppressiveRays.java @@ -118,7 +118,7 @@ class OppressiveRaysEffect extends ReplacementEffectImpl { } ManaCostsImpl attackBlockTax = new ManaCostsImpl("{3}"); if (attackBlockTax.canPay(source, source.getSourceId(), event.getPlayerId(), game) - && player.chooseUse(Outcome.Neutral, chooseText, game)) { + && player.chooseUse(Outcome.Neutral, chooseText, source, game)) { if (attackBlockTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) { return false; } diff --git a/Mage.Sets/src/mage/sets/judgment/BreakingPoint.java b/Mage.Sets/src/mage/sets/judgment/BreakingPoint.java index c9d4af66bd..7ee870ae3a 100644 --- a/Mage.Sets/src/mage/sets/judgment/BreakingPoint.java +++ b/Mage.Sets/src/mage/sets/judgment/BreakingPoint.java @@ -98,7 +98,7 @@ class BreakingPointDestroyEffect extends OneShotEffect { boolean destroyCreatures = true; for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); - if (player != null && player.chooseUse(Outcome.Detriment, "Have " + spell.getLogName() + " deal 6 damage to you?", game)) { + if (player != null && player.chooseUse(Outcome.Detriment, "Have " + spell.getLogName() + " deal 6 damage to you?", source, game)) { destroyCreatures = false; player.damage(6, source.getSourceId(), game, false, true); game.informPlayers(player.getLogName() + " has " + spell.getName() + " deal 6 to him or her"); diff --git a/Mage.Sets/src/mage/sets/judgment/Browbeat.java b/Mage.Sets/src/mage/sets/judgment/Browbeat.java index fb71c3674c..224518820e 100644 --- a/Mage.Sets/src/mage/sets/judgment/Browbeat.java +++ b/Mage.Sets/src/mage/sets/judgment/Browbeat.java @@ -97,7 +97,7 @@ class BrowbeatDrawEffect extends OneShotEffect { boolean drawCards = true; for(UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)){ Player player = game.getPlayer(playerId); - if (player != null && player.chooseUse(Outcome.Detriment, "Have " + spell.getLogName() + " deal 5 damage to you?", game)){ + if (player != null && player.chooseUse(Outcome.Detriment, "Have " + spell.getLogName() + " deal 5 damage to you?", source, game)){ drawCards = false; player.damage(5, source.getSourceId(), game, false, true); game.informPlayers(player.getLogName() + " has " + spell.getLogName() + " deal 5 to him or her"); diff --git a/Mage.Sets/src/mage/sets/judgment/BurningWish.java b/Mage.Sets/src/mage/sets/judgment/BurningWish.java index 412d18b6db..8036f321e1 100644 --- a/Mage.Sets/src/mage/sets/judgment/BurningWish.java +++ b/Mage.Sets/src/mage/sets/judgment/BurningWish.java @@ -98,7 +98,7 @@ class BurningWishEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - while (player.chooseUse(Outcome.Benefit, choiceText, game)) { + while (player.chooseUse(Outcome.Benefit, choiceText, source, game)) { Cards cards = player.getSideboard(); if(cards.isEmpty()) { game.informPlayer(player, "You have no cards outside the game."); diff --git a/Mage.Sets/src/mage/sets/judgment/CunningWish.java b/Mage.Sets/src/mage/sets/judgment/CunningWish.java index aa28eab96f..3a334aab0d 100644 --- a/Mage.Sets/src/mage/sets/judgment/CunningWish.java +++ b/Mage.Sets/src/mage/sets/judgment/CunningWish.java @@ -98,7 +98,7 @@ class CunningWishEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - while (player.chooseUse(Outcome.Benefit, choiceText, game)) { + while (player.chooseUse(Outcome.Benefit, choiceText, source, game)) { Cards cards = player.getSideboard(); if(cards.isEmpty()) { game.informPlayer(player, "You have no cards outside the game."); diff --git a/Mage.Sets/src/mage/sets/judgment/DeathWish.java b/Mage.Sets/src/mage/sets/judgment/DeathWish.java index 8f083160b8..f612964795 100644 --- a/Mage.Sets/src/mage/sets/judgment/DeathWish.java +++ b/Mage.Sets/src/mage/sets/judgment/DeathWish.java @@ -95,7 +95,7 @@ class DeathWishEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - while (player.chooseUse(Outcome.Benefit, choiceText, game)) { + while (player.chooseUse(Outcome.Benefit, choiceText, source, game)) { Cards cards = player.getSideboard(); if(cards.isEmpty()) { game.informPlayer(player, "You have no cards outside the game."); diff --git a/Mage.Sets/src/mage/sets/judgment/GoldenWish.java b/Mage.Sets/src/mage/sets/judgment/GoldenWish.java index 6d701bd779..2b76472ddf 100644 --- a/Mage.Sets/src/mage/sets/judgment/GoldenWish.java +++ b/Mage.Sets/src/mage/sets/judgment/GoldenWish.java @@ -101,7 +101,7 @@ class GoldenWishEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - while (player.chooseUse(Outcome.Benefit, choiceText, game)) { + while (player.chooseUse(Outcome.Benefit, choiceText, source, game)) { Cards cards = player.getSideboard(); if(cards.isEmpty()) { game.informPlayer(player, "You have no cards outside the game."); diff --git a/Mage.Sets/src/mage/sets/judgment/LivingWish.java b/Mage.Sets/src/mage/sets/judgment/LivingWish.java index 3f83b6ef14..907c97c965 100644 --- a/Mage.Sets/src/mage/sets/judgment/LivingWish.java +++ b/Mage.Sets/src/mage/sets/judgment/LivingWish.java @@ -101,7 +101,7 @@ class LivingWishEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - while (player.chooseUse(Outcome.Benefit, choiceText, game)) { + while (player.chooseUse(Outcome.Benefit, choiceText, source, game)) { Cards cards = player.getSideboard(); if(cards.isEmpty()) { game.informPlayer(player, "You have no cards outside the game."); diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/SeeTheUnwritten.java b/Mage.Sets/src/mage/sets/khansoftarkir/SeeTheUnwritten.java index 248f02ab30..bf66ae2db3 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/SeeTheUnwritten.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/SeeTheUnwritten.java @@ -125,7 +125,7 @@ class SeeTheUnwrittenEffect extends OneShotEffect { if (!cards.isEmpty()) { controller.revealCards(sourceObject.getName(), cards, game); - if (creatureCardsFound > 0 && controller.chooseUse(outcome, "Put creature(s) into play?", game)) { + if (creatureCardsFound > 0 && controller.chooseUse(outcome, "Put creature(s) into play?", source, game)) { int cardsToChoose = Math.min(numberOfCardsToPutIntoPlay, creatureCardsFound); TargetCard target = new TargetCard(cardsToChoose, cardsToChoose, Zone.LIBRARY, filter); if (controller.choose(Outcome.PutCreatureInPlay, cards, target, game)) { diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/VillainousWealth.java b/Mage.Sets/src/mage/sets/khansoftarkir/VillainousWealth.java index aba4dd0782..05f841c726 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/VillainousWealth.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/VillainousWealth.java @@ -113,7 +113,7 @@ class VillainousWealthEffect extends OneShotEffect { } ExileZone exileZone = game.getExile().getExileZone(exileId); while (exileZone != null && exileZone.count(filter, game) > 0 - && controller.chooseUse(Outcome.PlayForFree, "Cast cards exiled with " + mageObject.getLogName() +" without paying its mana cost?", game)) { + && controller.chooseUse(Outcome.PlayForFree, "Cast cards exiled with " + mageObject.getLogName() +" without paying its mana cost?", source, game)) { TargetCardInExile target = new TargetCardInExile(0,1, filter, exileId, false); while (exileZone.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, exileZone, target, game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/legends/ChainLightning.java b/Mage.Sets/src/mage/sets/legends/ChainLightning.java index 7ea83e1c98..21f95b8718 100644 --- a/Mage.Sets/src/mage/sets/legends/ChainLightning.java +++ b/Mage.Sets/src/mage/sets/legends/ChainLightning.java @@ -103,7 +103,7 @@ class ChainLightningEffect extends OneShotEffect { } } if (affectedPlayer != null) { - if (affectedPlayer.chooseUse(Outcome.Copy, "Pay {R}{R} to copy the spell?", game)) { + if (affectedPlayer.chooseUse(Outcome.Copy, "Pay {R}{R} to copy the spell?", source, game)) { Cost cost = new ManaCostsImpl("{R}{R}"); if (cost.pay(source, game, source.getSourceId(), affectedPlayer.getId(), false)) { Spell spell = game.getStack().getSpell(source.getSourceId()); diff --git a/Mage.Sets/src/mage/sets/legends/TheTabernacleAtPendrellVale.java b/Mage.Sets/src/mage/sets/legends/TheTabernacleAtPendrellVale.java index a46fdfceee..c938ac247c 100644 --- a/Mage.Sets/src/mage/sets/legends/TheTabernacleAtPendrellVale.java +++ b/Mage.Sets/src/mage/sets/legends/TheTabernacleAtPendrellVale.java @@ -89,7 +89,7 @@ class DestroySourceUnlessPaysEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(source.getSourceId()); if (player != null && permanent != null) { - if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "?", game)) { + if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "?", source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { return true; diff --git a/Mage.Sets/src/mage/sets/legions/DarkSupplicant.java b/Mage.Sets/src/mage/sets/legions/DarkSupplicant.java index 867129eb40..36d802aa73 100644 --- a/Mage.Sets/src/mage/sets/legions/DarkSupplicant.java +++ b/Mage.Sets/src/mage/sets/legions/DarkSupplicant.java @@ -115,7 +115,7 @@ class DarkSupplicantEffect extends OneShotEffect { return false; } // Library check - if (player.chooseUse(Outcome.Benefit, "Do you want to search your library for Scion of Darkness?", game)) { + if (player.chooseUse(Outcome.Benefit, "Do you want to search your library for Scion of Darkness?", source, game)) { if (player.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { for (UUID cardId : (List) target.getTargets()) { @@ -131,7 +131,7 @@ class DarkSupplicantEffect extends OneShotEffect { player.shuffleLibrary(game); } // Graveyard check - if (player.chooseUse(Outcome.Benefit, "Do you want to search your graveyard for Scion of Darkness?", game)) { + if (player.chooseUse(Outcome.Benefit, "Do you want to search your graveyard for Scion of Darkness?", source, game)) { Cards graveyard = player.getGraveyard().copy(); for (UUID card : graveyard) { Card checkCard = game.getCard(card); @@ -142,7 +142,7 @@ class DarkSupplicantEffect extends OneShotEffect { } } // Hand check - if (player.chooseUse(Outcome.Benefit, "Do you want to search your hand for Scion of Darkness?", game)) { + if (player.chooseUse(Outcome.Benefit, "Do you want to search your hand for Scion of Darkness?", source, game)) { Cards hand = player.getHand().copy(); for (UUID card : hand) { Card checkCard = game.getCard(card); diff --git a/Mage.Sets/src/mage/sets/limitedalpha/DemonicHordes.java b/Mage.Sets/src/mage/sets/limitedalpha/DemonicHordes.java index 09ae87d9e4..b0b6516f12 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/DemonicHordes.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/DemonicHordes.java @@ -109,7 +109,7 @@ class DemonicHordesEffect extends OneShotEffect { if (!sb.toString().toLowerCase().startsWith("exile ") && !sb.toString().toLowerCase().startsWith("return ")) { sb.insert(0, "Pay "); } - if (controller.chooseUse(Outcome.Benefit, sb.toString(), game)) { + if (controller.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { return true; diff --git a/Mage.Sets/src/mage/sets/limitedalpha/NaturalSelection.java b/Mage.Sets/src/mage/sets/limitedalpha/NaturalSelection.java index a9c1236857..3865737233 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/NaturalSelection.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/NaturalSelection.java @@ -121,7 +121,7 @@ class NaturalSelectionEffect extends OneShotEffect { Card card = cards.get(cards.iterator().next(), game); card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); } - if (you.chooseUse(Outcome.Neutral, "You may have that player shuffle his or her library", game)){ + if (you.chooseUse(Outcome.Neutral, "You may have that player shuffle his or her library", source, game)){ player.shuffleLibrary(game); } return true; diff --git a/Mage.Sets/src/mage/sets/limitedalpha/PowerSink.java b/Mage.Sets/src/mage/sets/limitedalpha/PowerSink.java index 6f05318067..38dc92a34b 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/PowerSink.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/PowerSink.java @@ -100,7 +100,7 @@ class PowerSinkCounterUnlessPaysEffect extends OneShotEffect { if (amount > 0) { GenericManaCost cost = new GenericManaCost(amount); StringBuilder sb = new StringBuilder("Pay ").append(cost.getText()).append("?"); - if (player.chooseUse(Outcome.Benefit, sb.toString(), game)) { + if (player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { if (cost.pay(source, game, source.getSourceId(), player.getId(), false)) { game.informPlayers(new StringBuilder(sourceObject.getName()).append(": additional cost was paid").toString()); return true; diff --git a/Mage.Sets/src/mage/sets/lorwyn/Guile.java b/Mage.Sets/src/mage/sets/lorwyn/Guile.java index 6f319450be..4e9977188f 100644 --- a/Mage.Sets/src/mage/sets/lorwyn/Guile.java +++ b/Mage.Sets/src/mage/sets/lorwyn/Guile.java @@ -111,7 +111,7 @@ class GuileReplacementEffect extends ReplacementEffectImpl { if (spell != null && guileController != null) { Card spellCard = spell.getCard(); guileController.moveCardToExileWithInfo(spellCard, null, "", source.getSourceId(), game, Zone.STACK, true); - if (guileController.chooseUse(Outcome.PlayForFree, "Cast that card for free?", game)) { + if (guileController.chooseUse(Outcome.PlayForFree, "Cast that card for free?", source, game)) { guileController.cast(spellCard.getSpellAbility(), game, true); } return true; diff --git a/Mage.Sets/src/mage/sets/lorwyn/HordeOfNotions.java b/Mage.Sets/src/mage/sets/lorwyn/HordeOfNotions.java index de87235ec5..ab05c32d1e 100644 --- a/Mage.Sets/src/mage/sets/lorwyn/HordeOfNotions.java +++ b/Mage.Sets/src/mage/sets/lorwyn/HordeOfNotions.java @@ -115,11 +115,11 @@ class HordeOfNotionsEffect extends OneShotEffect { if (card != null ) { // Probably there is no Elemental land, but who knows if (card.getCardType().contains(CardType.LAND) && controller.canPlayLand() && - controller.chooseUse(outcome, "Play " + card.getName() + " from your graveyard for free?", game)) { + controller.chooseUse(outcome, "Play " + card.getName() + " from your graveyard for free?", source, game)) { controller.playLand(card, game); } else { if (card.getSpellAbility().canChooseTarget(game) && - controller.chooseUse(outcome, "Play " + card.getName() + " from your graveyard for free?", game)) { + controller.chooseUse(outcome, "Play " + card.getName() + " from your graveyard for free?", source, game)) { controller.cast(card.getSpellAbility(), game, true); } } diff --git a/Mage.Sets/src/mage/sets/lorwyn/IncandescentSoulstoke.java b/Mage.Sets/src/mage/sets/lorwyn/IncandescentSoulstoke.java index 995d396e08..1d2c147476 100644 --- a/Mage.Sets/src/mage/sets/lorwyn/IncandescentSoulstoke.java +++ b/Mage.Sets/src/mage/sets/lorwyn/IncandescentSoulstoke.java @@ -122,7 +122,7 @@ class IncandescentSoulstokeEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - if (controller.chooseUse(Outcome.PutCreatureInPlay, choiceText, game)) { + if (controller.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { FilterCard filter = new FilterCreatureCard(); filter.add(new SubtypePredicate(("Elemental"))); TargetCardInHand target = new TargetCardInHand(filter); diff --git a/Mage.Sets/src/mage/sets/lorwyn/RingsOfBrighthearth.java b/Mage.Sets/src/mage/sets/lorwyn/RingsOfBrighthearth.java index 51675f87b0..e591c15973 100644 --- a/Mage.Sets/src/mage/sets/lorwyn/RingsOfBrighthearth.java +++ b/Mage.Sets/src/mage/sets/lorwyn/RingsOfBrighthearth.java @@ -130,7 +130,7 @@ class RingsOfBrighthearthEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); ManaCostsImpl cost = new ManaCostsImpl("{2}"); if (player != null) { - if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "? If you do, copy that ability. You may choose new targets for the copy.", game)) { + if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "? If you do, copy that ability. You may choose new targets for the copy.", source, game)) { if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { Ability ability = (Ability) getValue("stackAbility"); Player controller = game.getPlayer(source.getControllerId()); @@ -140,7 +140,7 @@ class RingsOfBrighthearthEffect extends OneShotEffect { newAbility.newId(); game.getStack().push(new StackAbility(newAbility, source.getControllerId())); if (newAbility.getTargets().size() > 0) { - if (controller.chooseUse(newAbility.getEffects().get(0).getOutcome(), "Choose new targets?", game)) { + if (controller.chooseUse(newAbility.getEffects().get(0).getOutcome(), "Choose new targets?", source, game)) { newAbility.getTargets().clearChosen(); if (newAbility.getTargets().chooseTargets(newAbility.getEffects().get(0).getOutcome(), source.getControllerId(), newAbility, game) == false) { return false; diff --git a/Mage.Sets/src/mage/sets/lorwyn/SilvergillAdept.java b/Mage.Sets/src/mage/sets/lorwyn/SilvergillAdept.java index bf85fd0790..9ec52f20fd 100644 --- a/Mage.Sets/src/mage/sets/lorwyn/SilvergillAdept.java +++ b/Mage.Sets/src/mage/sets/lorwyn/SilvergillAdept.java @@ -27,9 +27,7 @@ */ package mage.sets.lorwyn; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -39,14 +37,15 @@ import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInHand; -import java.util.UUID; - /** * * @author North @@ -106,7 +105,7 @@ class SilvergillAdeptCost extends CostImpl { paid = false; if (player.getHand().count(filter, game) > 0 - && player.chooseUse(Outcome.Benefit, "Reveal a Merfolk card? Otherwise pay {3}.", game)) { + && player.chooseUse(Outcome.Benefit, "Reveal a Merfolk card? Otherwise pay {3}.", ability, game)) { TargetCardInHand target = new TargetCardInHand(filter); if (player.choose(Outcome.Benefit, target, sourceId, game)) { Card card = player.getHand().get(target.getFirstTarget(), game); diff --git a/Mage.Sets/src/mage/sets/magic2010/DjinnOfWishes.java b/Mage.Sets/src/mage/sets/magic2010/DjinnOfWishes.java index 82d9180f71..1ad585e45f 100644 --- a/Mage.Sets/src/mage/sets/magic2010/DjinnOfWishes.java +++ b/Mage.Sets/src/mage/sets/magic2010/DjinnOfWishes.java @@ -110,7 +110,7 @@ class DjinnOfWishesEffect extends OneShotEffect { player.getLibrary().removeFromTop(game); boolean used = false; - if (player.chooseUse(Outcome.PlayForFree, "Play " + card.getName() + " without paying its mana cost?", game)) { + if (player.chooseUse(Outcome.PlayForFree, "Play " + card.getName() + " without paying its mana cost?", source, game)) { if (card.getCardType().contains(CardType.LAND)) { // If the revealed card is a land, you can play it only if it's your turn and you haven't yet played a land this turn. if (game.getActivePlayerId().equals(player.getId()) && player.canPlayLand()) { diff --git a/Mage.Sets/src/mage/sets/magic2010/LurkingPredators.java b/Mage.Sets/src/mage/sets/magic2010/LurkingPredators.java index be9f78607e..9a1a079556 100644 --- a/Mage.Sets/src/mage/sets/magic2010/LurkingPredators.java +++ b/Mage.Sets/src/mage/sets/magic2010/LurkingPredators.java @@ -100,7 +100,7 @@ class LurkingPredatorsEffect extends OneShotEffect { if (card.getCardType().contains(CardType.CREATURE)) { card = player.getLibrary().removeFromTop(game); card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId()); - } else if (player.chooseUse(Outcome.Neutral, "Put " + card.getName() + " on the bottom of your library?", game)) { + } else if (player.chooseUse(Outcome.Neutral, "Put " + card.getName() + " on the bottom of your library?", source, game)) { card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); } } diff --git a/Mage.Sets/src/mage/sets/magic2010/SphinxAmbassador.java b/Mage.Sets/src/mage/sets/magic2010/SphinxAmbassador.java index d695774a91..d45e92ec37 100644 --- a/Mage.Sets/src/mage/sets/magic2010/SphinxAmbassador.java +++ b/Mage.Sets/src/mage/sets/magic2010/SphinxAmbassador.java @@ -124,7 +124,7 @@ class SphinxAmbassadorEffect extends OneShotEffect { game.informPlayers(new StringBuilder(sourcePermanent.getName()).append(", named card: [").append(cardName).append("]").toString()); if (!card.getName().equals(cardName) && card.getCardType().contains(CardType.CREATURE)) { - if (player.chooseUse(outcome, new StringBuilder("Put ").append(card.getName()).append(" onto the battlefield?").toString(), game)) { + if (player.chooseUse(outcome, new StringBuilder("Put ").append(card.getName()).append(" onto the battlefield?").toString(), source, game)) { player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); } } diff --git a/Mage.Sets/src/mage/sets/magic2012/ArachnusSpinner.java b/Mage.Sets/src/mage/sets/magic2012/ArachnusSpinner.java index 8bd0579c31..e4b6948586 100644 --- a/Mage.Sets/src/mage/sets/magic2012/ArachnusSpinner.java +++ b/Mage.Sets/src/mage/sets/magic2012/ArachnusSpinner.java @@ -123,7 +123,7 @@ class ArachnusSpinnerEffect extends OneShotEffect { Card card = null; Zone zone = null; - if (player.chooseUse(Outcome.Neutral, "Search your graveyard for Arachnus Web?", game)) { + if (player.chooseUse(Outcome.Neutral, "Search your graveyard for Arachnus Web?", source, game)) { TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(filter); if (player.choose(Outcome.PutCardInPlay, player.getGraveyard(), target, game)) { card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/magic2012/DoublingChant.java b/Mage.Sets/src/mage/sets/magic2012/DoublingChant.java index 6b66ea382e..339fc133be 100644 --- a/Mage.Sets/src/mage/sets/magic2012/DoublingChant.java +++ b/Mage.Sets/src/mage/sets/magic2012/DoublingChant.java @@ -103,7 +103,7 @@ class DoublingChantEffect extends OneShotEffect { StringBuilder sb = new StringBuilder(); sb.append("Search for ").append(creatureName).append(" in your library?"); - if (player.chooseUse(Outcome.PutCreatureInPlay, sb.toString(), game)) { + if (player.chooseUse(Outcome.PutCreatureInPlay, sb.toString(), source, game)) { FilterCreatureCard filter = new FilterCreatureCard("creature card named" + creatureName); filter.add(new NamePredicate(creatureName)); TargetCardInLibrary target = new TargetCardInLibrary(filter); diff --git a/Mage.Sets/src/mage/sets/magic2013/LilianaOfTheDarkRealms.java b/Mage.Sets/src/mage/sets/magic2013/LilianaOfTheDarkRealms.java index 5eb20f16df..b706cc764c 100644 --- a/Mage.Sets/src/mage/sets/magic2013/LilianaOfTheDarkRealms.java +++ b/Mage.Sets/src/mage/sets/magic2013/LilianaOfTheDarkRealms.java @@ -133,7 +133,7 @@ class LilianaOfTheDarkRealmsEffect extends ContinuousEffectImpl { Player player = game.getPlayer(source.getControllerId()); String message = "Should the target creature get -X/-X instead of +X/+X?"; - if (player != null && player.chooseUse(Outcome.Neutral, message, game)) { + if (player != null && player.chooseUse(Outcome.Neutral, message, source, game)) { this.amount *= -1; } } diff --git a/Mage.Sets/src/mage/sets/magic2013/MindclawShaman.java b/Mage.Sets/src/mage/sets/magic2013/MindclawShaman.java index efb3c3fe93..9a349e30d5 100644 --- a/Mage.Sets/src/mage/sets/magic2013/MindclawShaman.java +++ b/Mage.Sets/src/mage/sets/magic2013/MindclawShaman.java @@ -117,7 +117,7 @@ class MindclawShamanEffect extends OneShotEffect { if (controller.choose(Outcome.Benefit, targetOpponent.getHand(), target, game)) { Card chosenCard = targetOpponent.getHand().get(target.getFirstTarget(), game); if (chosenCard != null) { - if (controller.chooseUse(Outcome.Benefit, "Cast the chosen card?", game)) { + if (controller.chooseUse(Outcome.Benefit, "Cast the chosen card?", source, game)) { controller.cast(chosenCard.getSpellAbility(), game, true); } else { game.informPlayers(sourceObject.getLogName() +": " + controller.getLogName() + " canceled casting the card."); diff --git a/Mage.Sets/src/mage/sets/magic2013/ShimianSpecter.java b/Mage.Sets/src/mage/sets/magic2013/ShimianSpecter.java index 8b38fd97f2..a8753258ab 100644 --- a/Mage.Sets/src/mage/sets/magic2013/ShimianSpecter.java +++ b/Mage.Sets/src/mage/sets/magic2013/ShimianSpecter.java @@ -148,7 +148,7 @@ class ShimianSpecterEffect extends OneShotEffect { // search cards in Library // If the player has no nonland cards in his or her hand, you can still search that player's library and have him or her shuffle it. - if (chosenCard != null || controller.chooseUse(outcome, "Search library anyway?", game)) { + if (chosenCard != null || controller.chooseUse(outcome, "Search library anyway?", source, game)) { TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards); controller.searchLibrary(targetCardsLibrary, game, targetPlayer.getId()); for(UUID cardId: targetCardsLibrary.getTargets()) { diff --git a/Mage.Sets/src/mage/sets/magic2013/Spelltwine.java b/Mage.Sets/src/mage/sets/magic2013/Spelltwine.java index 518d0f0a23..b37080dda6 100644 --- a/Mage.Sets/src/mage/sets/magic2013/Spelltwine.java +++ b/Mage.Sets/src/mage/sets/magic2013/Spelltwine.java @@ -111,7 +111,7 @@ class SpelltwineEffect extends OneShotEffect { controller.moveCardToExileWithInfo(cardTwo, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true); } boolean castCardOne = true; - if (cardOne != null && controller.chooseUse(Outcome.Neutral, "Cast the copy of " + cardOne.getName() + " first?", game)) { + if (cardOne != null && controller.chooseUse(Outcome.Neutral, "Cast the copy of " + cardOne.getName() + " first?", source, game)) { Card copyOne = game.copyCard(cardOne, source, controller.getId()); controller.cast(copyOne.getSpellAbility(), game, true); castCardOne = false; diff --git a/Mage.Sets/src/mage/sets/magic2014/AjanisChosen.java b/Mage.Sets/src/mage/sets/magic2014/AjanisChosen.java index d4f12cbb1f..62e2921c40 100644 --- a/Mage.Sets/src/mage/sets/magic2014/AjanisChosen.java +++ b/Mage.Sets/src/mage/sets/magic2014/AjanisChosen.java @@ -110,7 +110,7 @@ class AjanisChosenEffect extends OneShotEffect { { Permanent oldCreature = game.getPermanent(enchantement.getAttachedTo()); - if(oldCreature != null && enchantement.getSpellAbility().getTargets().get(0).canTarget(tokenPermanent.getId(), game) && player.chooseUse(Outcome.Neutral, "Attach " + enchantement.getName() + " to the token ?", game)) + if(oldCreature != null && enchantement.getSpellAbility().getTargets().get(0).canTarget(tokenPermanent.getId(), game) && player.chooseUse(Outcome.Neutral, "Attach " + enchantement.getName() + " to the token ?", source, game)) { if(oldCreature.removeAttachment(enchantement.getId(), game)){ tokenPermanent.addAttachment(enchantement.getId(), game); diff --git a/Mage.Sets/src/mage/sets/magic2014/ChandraPyromaster.java b/Mage.Sets/src/mage/sets/magic2014/ChandraPyromaster.java index a9f736fb55..1ce15ed3de 100644 --- a/Mage.Sets/src/mage/sets/magic2014/ChandraPyromaster.java +++ b/Mage.Sets/src/mage/sets/magic2014/ChandraPyromaster.java @@ -295,13 +295,13 @@ class ChandraPyromasterEffect3 extends OneShotEffect { Card copy1 = card.copy(); Card copy2 = card.copy(); Card copy3 = card.copy(); - if (copy1 != null && you.chooseUse(outcome, "Do you wish to cast copy 1 of " + card.getName(), game)) { + if (copy1 != null && you.chooseUse(outcome, "Do you wish to cast copy 1 of " + card.getName(), source, game)) { you.cast(copy1.getSpellAbility(), game, true); } - if (copy2 != null && you.chooseUse(outcome, "Do you wish to cast copy 2 of " + card.getName(), game)) { + if (copy2 != null && you.chooseUse(outcome, "Do you wish to cast copy 2 of " + card.getName(), source, game)) { you.cast(copy2.getSpellAbility(), game, true); } - if (copy3 != null && you.chooseUse(outcome, "Do you wish to cast copy 3 of " + card.getName(), game)) { + if (copy3 != null && you.chooseUse(outcome, "Do you wish to cast copy 3 of " + card.getName(), source, game)) { you.cast(copy3.getSpellAbility(), game, true); } return true; diff --git a/Mage.Sets/src/mage/sets/magic2014/EliteArcanist.java b/Mage.Sets/src/mage/sets/magic2014/EliteArcanist.java index a6096095dd..d79a6a5a1b 100644 --- a/Mage.Sets/src/mage/sets/magic2014/EliteArcanist.java +++ b/Mage.Sets/src/mage/sets/magic2014/EliteArcanist.java @@ -176,7 +176,7 @@ class EliteArcanistCopyEffect extends OneShotEffect { if (copiedCard != null) { game.getExile().add(source.getSourceId(), "",copiedCard); game.getState().setZone(copiedCard.getId(), Zone.EXILED); - if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", game)) { + if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) { return controller.cast(copiedCard.getSpellAbility(), game, true); } } diff --git a/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java b/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java index 33dce957c0..a4fc59d7c9 100644 --- a/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java +++ b/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java @@ -143,7 +143,7 @@ class GarrukCallerOfBeastsPutOntoBattlefieldEffect extends OneShotEffect { if (controller.getHand().count(filterGreenCreature, game) > 0) { if (controller.chooseUse(Outcome.PutCreatureInPlay, - "Put a green creature card onto the battlefield?", game)) { + "Put a green creature card onto the battlefield?", source, game)) { Target target = new TargetCardInHand(filterGreenCreature); if (controller.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/magic2014/IntoTheWilds.java b/Mage.Sets/src/mage/sets/magic2014/IntoTheWilds.java index 6317d0a0c7..b08c6e3259 100644 --- a/Mage.Sets/src/mage/sets/magic2014/IntoTheWilds.java +++ b/Mage.Sets/src/mage/sets/magic2014/IntoTheWilds.java @@ -102,7 +102,7 @@ class IntoTheWildsEffect extends OneShotEffect { player.lookAtCards("Into the Wilds", cards, game); if (filter.match(card, game)) { String message = "Put " + card.getName() + " onto the battlefield?"; - if (player.chooseUse(outcome, message, game)) { + if (player.chooseUse(outcome, message, source, game)) { return card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId(), false); } } diff --git a/Mage.Sets/src/mage/sets/magic2014/JacesMindseeker.java b/Mage.Sets/src/mage/sets/magic2014/JacesMindseeker.java index 2c7791d42d..bf8354a286 100644 --- a/Mage.Sets/src/mage/sets/magic2014/JacesMindseeker.java +++ b/Mage.Sets/src/mage/sets/magic2014/JacesMindseeker.java @@ -126,7 +126,7 @@ class JaceMindseekerEffect extends OneShotEffect { if (controller != null) { TargetCard target = new TargetCard(Zone.GRAVEYARD, filter); // zone should be ignored here target.setNotTarget(true); - if (controller.chooseUse(outcome, "Cast an instant or sorcery card from among them for free?", game) + if (controller.chooseUse(outcome, "Cast an instant or sorcery card from among them for free?", source, game) && controller.choose(outcome, cardsToCast, target, game)) { Card card = cardsToCast.get(target.getFirstTarget(), game); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/magic2014/StrionicResonator.java b/Mage.Sets/src/mage/sets/magic2014/StrionicResonator.java index 3b5a1d0fe2..c05126f8ba 100644 --- a/Mage.Sets/src/mage/sets/magic2014/StrionicResonator.java +++ b/Mage.Sets/src/mage/sets/magic2014/StrionicResonator.java @@ -102,7 +102,7 @@ class StrionicResonatorEffect extends OneShotEffect { newAbility.newId(); game.getStack().push(new StackAbility(newAbility, source.getControllerId())); if (newAbility.getTargets().size() > 0) { - if (controller.chooseUse(newAbility.getEffects().get(0).getOutcome(), "Choose new targets?", game)) { + if (controller.chooseUse(newAbility.getEffects().get(0).getOutcome(), "Choose new targets?", source, game)) { newAbility.getTargets().clearChosen(); if (newAbility.getTargets().chooseTargets(newAbility.getEffects().get(0).getOutcome(), source.getControllerId(), newAbility, game) == false) { return false; diff --git a/Mage.Sets/src/mage/sets/magic2015/AEtherspouts.java b/Mage.Sets/src/mage/sets/magic2015/AEtherspouts.java index 20101ee502..c0590adff8 100644 --- a/Mage.Sets/src/mage/sets/magic2015/AEtherspouts.java +++ b/Mage.Sets/src/mage/sets/magic2015/AEtherspouts.java @@ -111,7 +111,7 @@ class AEtherspoutsEffect extends OneShotEffect { ArrayList permanentsToBottom = new ArrayList<>(); for (Permanent permanent:game.getState().getBattlefield().getActivePermanents(new FilterAttackingCreature(), player.getId(), source.getSourceId(), game)) { if (permanent.getOwnerId().equals(player.getId())) { - if (player.chooseUse(outcome, "Put " + permanent.getLogName() + " to the top? (else it goes to bottom)", game)) { + if (player.chooseUse(outcome, "Put " + permanent.getLogName() + " to the top? (else it goes to bottom)", source, game)) { permanentsToTop.add(permanent); game.informPlayers(permanent.getLogName() + " goes to the top of " + player.getLogName() + "'s library"); } else { diff --git a/Mage.Sets/src/mage/sets/magic2015/BoonweaverGiant.java b/Mage.Sets/src/mage/sets/magic2015/BoonweaverGiant.java index bf8f69116f..1207517645 100644 --- a/Mage.Sets/src/mage/sets/magic2015/BoonweaverGiant.java +++ b/Mage.Sets/src/mage/sets/magic2015/BoonweaverGiant.java @@ -108,7 +108,7 @@ class BoonweaverGiantEffect extends OneShotEffect { Card card = null; Zone zone = null; - if (player.chooseUse(Outcome.Neutral, "Search your graveyard for an Aura card?", game)) { + if (player.chooseUse(Outcome.Neutral, "Search your graveyard for an Aura card?", source, game)) { TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(filter); if (player.choose(Outcome.PutCardInPlay, player.getGraveyard(), target, game)) { card = game.getCard(target.getFirstTarget()); @@ -117,7 +117,7 @@ class BoonweaverGiantEffect extends OneShotEffect { } } } - if (card == null && player.chooseUse(Outcome.Neutral, "Search your Hand for an Aura card?", game)) { + if (card == null && player.chooseUse(Outcome.Neutral, "Search your Hand for an Aura card?", source, game)) { TargetCardInHand target = new TargetCardInHand(filter); if (player.choose(Outcome.PutCardInPlay, player.getHand(), target, game)) { card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/magic2015/IndulgentTormentor.java b/Mage.Sets/src/mage/sets/magic2015/IndulgentTormentor.java index 47b279a96e..5918480369 100644 --- a/Mage.Sets/src/mage/sets/magic2015/IndulgentTormentor.java +++ b/Mage.Sets/src/mage/sets/magic2015/IndulgentTormentor.java @@ -101,14 +101,14 @@ class IndulgentTormentorEffect extends OneShotEffect { if (opponent != null) { Cost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent()); if (cost.canPay(source, source.getSourceId(), opponent.getId(), game) - && opponent.chooseUse(outcome, "Sacrifice a creature to prevent the card draw?", game)) { + && opponent.chooseUse(outcome, "Sacrifice a creature to prevent the card draw?", source, game)) { if (cost.pay(source, game, source.getSourceId(), opponent.getId(), false)) { return true; } } cost = new PayLifeCost(3); if (cost.canPay(source, source.getSourceId(), opponent.getId(), game) - && opponent.chooseUse(outcome, "Pay 3 life to prevent the card draw?", game)) { + && opponent.chooseUse(outcome, "Pay 3 life to prevent the card draw?", source, game)) { if (cost.pay(source, game, source.getSourceId(), opponent.getId(), false)) { return true; } diff --git a/Mage.Sets/src/mage/sets/magic2015/KurkeshOnakkeAncient.java b/Mage.Sets/src/mage/sets/magic2015/KurkeshOnakkeAncient.java index 3838c745cd..91c880acb4 100644 --- a/Mage.Sets/src/mage/sets/magic2015/KurkeshOnakkeAncient.java +++ b/Mage.Sets/src/mage/sets/magic2015/KurkeshOnakkeAncient.java @@ -140,7 +140,7 @@ class KurkeshOnakkeAncientEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); ColoredManaCost cost = new ColoredManaCost(ColoredManaSymbol.R); if (player != null) { - if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "? If you do, copy that ability. You may choose new targets for the copy.", game)) { + if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "? If you do, copy that ability. You may choose new targets for the copy.", source, game)) { if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { Ability ability = (Ability) getValue("stackAbility"); Player controller = game.getPlayer(source.getControllerId()); @@ -150,7 +150,7 @@ class KurkeshOnakkeAncientEffect extends OneShotEffect { newAbility.newId(); game.getStack().push(new StackAbility(newAbility, source.getControllerId())); if (newAbility.getTargets().size() > 0) { - if (controller.chooseUse(newAbility.getEffects().get(0).getOutcome(), "Choose new targets?", game)) { + if (controller.chooseUse(newAbility.getEffects().get(0).getOutcome(), "Choose new targets?", source, game)) { newAbility.getTargets().clearChosen(); if (newAbility.getTargets().chooseTargets(newAbility.getEffects().get(0).getOutcome(), source.getControllerId(), newAbility, game) == false) { return false; diff --git a/Mage.Sets/src/mage/sets/magic2015/MasterOfPredicaments.java b/Mage.Sets/src/mage/sets/magic2015/MasterOfPredicaments.java index 07ca8b4566..ff504769e1 100644 --- a/Mage.Sets/src/mage/sets/magic2015/MasterOfPredicaments.java +++ b/Mage.Sets/src/mage/sets/magic2015/MasterOfPredicaments.java @@ -112,7 +112,7 @@ class MasterOfPredicamentsEffect extends OneShotEffect { return false; } boolean guessWrong; - if (attackedPlayer.chooseUse(Outcome.Detriment, "Is the chosen card's converted mana cost greater than 4?", game)) { + if (attackedPlayer.chooseUse(Outcome.Detriment, "Is the chosen card's converted mana cost greater than 4?", source, game)) { game.informPlayers(attackedPlayer.getLogName() + " guessed that the chosen card's converted mana cost is greater than 4"); guessWrong = cardFromHand.getManaCost().convertedManaCost() <= 4; } else { @@ -124,7 +124,7 @@ class MasterOfPredicamentsEffect extends OneShotEffect { if (cardFromHand.getCardType().contains(CardType.LAND)) { // If the revealed card is a land, you can't cast it. So nothing happens } else { - if (controller.chooseUse(outcome, "Cast " + cardFromHand.getName() + " without paying its mana cost?", game)) { + if (controller.chooseUse(outcome, "Cast " + cardFromHand.getName() + " without paying its mana cost?", source, game)) { controller.cast(cardFromHand.getSpellAbility(), game, true); } } diff --git a/Mage.Sets/src/mage/sets/magic2015/Quickling.java b/Mage.Sets/src/mage/sets/magic2015/Quickling.java index c23893233e..21d407e9e7 100644 --- a/Mage.Sets/src/mage/sets/magic2015/Quickling.java +++ b/Mage.Sets/src/mage/sets/magic2015/Quickling.java @@ -103,7 +103,7 @@ class QuicklingEffect extends OneShotEffect { if (controller != null) { boolean targetChosen = false; TargetPermanent target = new TargetPermanent(1, 1, filter, true); - if (target.canChoose(controller.getId(), game) && controller.chooseUse(outcome, "Return another creature you control to its owner's hand?", game)) { + if (target.canChoose(controller.getId(), game) && controller.chooseUse(outcome, "Return another creature you control to its owner's hand?", source, game)) { controller.chooseTarget(Outcome.ReturnToHand, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if ( permanent != null ) { diff --git a/Mage.Sets/src/mage/sets/magicorigins/MizziumMeddler.java b/Mage.Sets/src/mage/sets/magicorigins/MizziumMeddler.java index 9521c64b23..c0a7dc19ae 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/MizziumMeddler.java +++ b/Mage.Sets/src/mage/sets/magicorigins/MizziumMeddler.java @@ -136,7 +136,7 @@ class MizziumMeddlerEffect extends OneShotEffect { twoTimesTarget = true; continue; } - if (name != null && player.chooseUse(Outcome.Neutral, new StringBuilder("Change target from ").append(name).append(" to ").append(sourceObject.getName()).append("?").toString(), game)) { + if (name != null && player.chooseUse(Outcome.Neutral, new StringBuilder("Change target from ").append(name).append(" to ").append(sourceObject.getName()).append("?").toString(), source, game)) { if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) { oldTarget = game.getObject(targets.getFirstTarget()); target.remove(targetId); diff --git a/Mage.Sets/src/mage/sets/masterseditioniv/HasranOgress.java b/Mage.Sets/src/mage/sets/masterseditioniv/HasranOgress.java index f183ab6e5a..ecaabd7409 100644 --- a/Mage.Sets/src/mage/sets/masterseditioniv/HasranOgress.java +++ b/Mage.Sets/src/mage/sets/masterseditioniv/HasranOgress.java @@ -91,7 +91,7 @@ class HasranOgressEffect extends OneShotEffect { if (controller != null) { Cost cost = new ManaCostsImpl("{2}"); String message = "Would you like to pay {2} to prevent taking 3 damage from Hasran Ogress?"; - if (!(controller.chooseUse(Outcome.Benefit, message, game) + if (!(controller.chooseUse(Outcome.Benefit, message, source, game) && cost.pay(source, game, source.getSourceId(), controller.getId(), false))) { controller.damage(3, source.getSourceId(), game, false, true); } diff --git a/Mage.Sets/src/mage/sets/mercadianmasques/HornOfPlenty.java b/Mage.Sets/src/mage/sets/mercadianmasques/HornOfPlenty.java index 49db673214..6873cd06f0 100644 --- a/Mage.Sets/src/mage/sets/mercadianmasques/HornOfPlenty.java +++ b/Mage.Sets/src/mage/sets/mercadianmasques/HornOfPlenty.java @@ -96,7 +96,7 @@ class HornOfPlentyEffect extends OneShotEffect { caster = game.getPlayer(spell.getControllerId()); } if (caster != null) { - if (caster.chooseUse(Outcome.DrawCard, "Pay {1} to draw a card at the beginning of the next end step?", game)) { + if (caster.chooseUse(Outcome.DrawCard, "Pay {1} to draw a card at the beginning of the next end step?", source, game)) { Cost cost = new ManaCostsImpl("{1}"); if (cost.pay(source, game, source.getSourceId(), caster.getId(), false)) { Effect effect = new DrawCardTargetEffect(1); diff --git a/Mage.Sets/src/mage/sets/mirage/AmberPrison.java b/Mage.Sets/src/mage/sets/mirage/AmberPrison.java index 502ac964fb..3653f69be8 100644 --- a/Mage.Sets/src/mage/sets/mirage/AmberPrison.java +++ b/Mage.Sets/src/mage/sets/mirage/AmberPrison.java @@ -59,21 +59,21 @@ import mage.target.TargetPermanent; public class AmberPrison extends CardImpl { private static final FilterPermanent filter = new FilterPermanent("artifact, creature, or land"); - + static { filter.add(Predicates.or( new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.LAND))); } - + public AmberPrison(UUID ownerId) { super(ownerId, 257, "Amber Prison", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{4}"); this.expansionSetCode = "MIR"; // You may choose not to untap Amber Prison during your untap step. this.addAbility(new SkipUntapOptionalAbility()); - + // {4}, {tap}: Tap target artifact, creature, or land. That permanent doesn't untap during its controller's untap step for as long as Amber Prison remains tapped. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AmberPrisonTapTargetEffect(), new GenericManaCost(4)); ability.addCost(new TapSourceCost()); @@ -99,7 +99,7 @@ class AmberPrisonTapTargetEffect extends OneShotEffect { super(Outcome.Tap); this.staticText = "Tap target artifact, creature, or land. That permanent doesn't untap during its controller's untap step for as long as {source} remains tapped."; } - + public AmberPrisonTapTargetEffect(final AmberPrisonTapTargetEffect effect) { super(effect); } @@ -108,7 +108,7 @@ class AmberPrisonTapTargetEffect extends OneShotEffect { public AmberPrisonTapTargetEffect copy() { return new AmberPrisonTapTargetEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); @@ -123,7 +123,7 @@ class AmberPrisonTapTargetEffect extends OneShotEffect { } return true; } - + } class AmberPrisonRestrictionEffect extends RestrictionEffect { @@ -131,7 +131,7 @@ class AmberPrisonRestrictionEffect extends RestrictionEffect { public AmberPrisonRestrictionEffect() { super(Duration.WhileOnBattlefield); } - + public AmberPrisonRestrictionEffect(final AmberPrisonRestrictionEffect effect) { super(effect); } @@ -140,7 +140,7 @@ class AmberPrisonRestrictionEffect extends RestrictionEffect { public AmberPrisonRestrictionEffect copy() { return new AmberPrisonRestrictionEffect(this); } - + @Override public boolean applies(Permanent permanent, Ability source, Game game) { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); @@ -153,12 +153,11 @@ class AmberPrisonRestrictionEffect extends RestrictionEffect { } @Override - public boolean canBeUntapped(Permanent permanent, Game game) { + public boolean canBeUntapped(Permanent permanent, Ability source, Game game) { return false; } - -} +} class AmberPrisonUntapTriggeredAbility extends TriggeredAbilityImpl { @@ -167,11 +166,11 @@ class AmberPrisonUntapTriggeredAbility extends TriggeredAbilityImpl { this.usesStack = false; this.ruleVisible = false; } - + public AmberPrisonUntapTriggeredAbility(final AmberPrisonUntapTriggeredAbility ability) { super(ability); } - + @Override public AmberPrisonUntapTriggeredAbility copy() { return new AmberPrisonUntapTriggeredAbility(this); @@ -193,7 +192,7 @@ class AmberPrisonReleaseOnUntapEffect extends OneShotEffect { public AmberPrisonReleaseOnUntapEffect() { super(Outcome.Detriment); } - + public AmberPrisonReleaseOnUntapEffect(final AmberPrisonReleaseOnUntapEffect effect) { super(effect); } @@ -202,7 +201,7 @@ class AmberPrisonReleaseOnUntapEffect extends OneShotEffect { public AmberPrisonReleaseOnUntapEffect copy() { return new AmberPrisonReleaseOnUntapEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); @@ -212,5 +211,5 @@ class AmberPrisonReleaseOnUntapEffect extends OneShotEffect { } return false; } - + } diff --git a/Mage.Sets/src/mage/sets/mirage/Flash.java b/Mage.Sets/src/mage/sets/mirage/Flash.java index 01c899fc55..02a8f7a074 100644 --- a/Mage.Sets/src/mage/sets/mirage/Flash.java +++ b/Mage.Sets/src/mage/sets/mirage/Flash.java @@ -91,7 +91,7 @@ class FlashEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, choiceText, game)) { + if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { return false; } @@ -103,7 +103,7 @@ class FlashEffect extends OneShotEffect { ManaCosts reducedCost = CardUtil.removeVariableManaCost(CardUtil.reduceCost(card.getManaCost(), 2)); StringBuilder sb = new StringBuilder("Pay ").append(reducedCost.getText()).append("?"); - if (player.chooseUse(Outcome.Benefit, sb.toString(), game)) { + if (player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { reducedCost.clearPaid(); if (reducedCost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { return true; diff --git a/Mage.Sets/src/mage/sets/mirage/IllicitAuction.java b/Mage.Sets/src/mage/sets/mirage/IllicitAuction.java index 88f7483736..472c481860 100644 --- a/Mage.Sets/src/mage/sets/mirage/IllicitAuction.java +++ b/Mage.Sets/src/mage/sets/mirage/IllicitAuction.java @@ -99,7 +99,7 @@ class IllicitAuctionEffect extends GainControlTargetEffect { Player currentPlayer = playerList.getNextInRange(controller, game); while (currentPlayer != winner) { String text = winner.getLogName() + " has bet " + highBid + " life" + (highBid > 1 ? "s" : "") + ". Top the bid?"; - if (currentPlayer.chooseUse(Outcome.Detriment, text, game)) { + if (currentPlayer.chooseUse(Outcome.Detriment, text, source, game)) { int newBid = currentPlayer.getAmount(highBid + 1, Integer.MAX_VALUE, "Choose bid", game); if (newBid > highBid) { highBid = newBid; diff --git a/Mage.Sets/src/mage/sets/mirrodin/CrystalShard.java b/Mage.Sets/src/mage/sets/mirrodin/CrystalShard.java index 03a2101ae5..5b6e779b37 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/CrystalShard.java +++ b/Mage.Sets/src/mage/sets/mirrodin/CrystalShard.java @@ -106,7 +106,7 @@ class CrystalShardEffect extends OneShotEffect { if (player != null) { cost.clearPaid(); final StringBuilder sb = new StringBuilder("Pay {1}? (Otherwise ").append(targetCreature.getName()).append(" will be returned to its owner's hand)"); - if (player.chooseUse(Outcome.Benefit, sb.toString(), game)) { + if (player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), false); } if (!cost.isPaid()) { diff --git a/Mage.Sets/src/mage/sets/mirrodin/FieryGambit.java b/Mage.Sets/src/mage/sets/mirrodin/FieryGambit.java index 9fb75bfa18..25be1b7f87 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/FieryGambit.java +++ b/Mage.Sets/src/mage/sets/mirrodin/FieryGambit.java @@ -95,7 +95,7 @@ class FieryGambitEffect extends OneShotEffect { while (controller.flipCoin(game)) { ++flipsWon; if (!controller.chooseUse(outcome, new StringBuilder("You won ").append(flipsWon).append(flipsWon == 1?" flip.":" flips.") - .append(" Flip another coin?").toString(), game)) { + .append(" Flip another coin?").toString(), source, game)) { controllerStopped = true; break; } diff --git a/Mage.Sets/src/mage/sets/mirrodin/IsochronScepter.java b/Mage.Sets/src/mage/sets/mirrodin/IsochronScepter.java index 2e72355138..c66fe327f6 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/IsochronScepter.java +++ b/Mage.Sets/src/mage/sets/mirrodin/IsochronScepter.java @@ -155,12 +155,12 @@ class IsochronScepterCopyEffect extends OneShotEffect { if (scepter != null && scepter.getImprinted() != null && !scepter.getImprinted().isEmpty()) { Card imprintedInstant = game.getCard(scepter.getImprinted().get(0)); if (imprintedInstant != null && game.getState().getZone(imprintedInstant.getId()).equals(Zone.EXILED)) { - if (controller.chooseUse(outcome, new StringBuilder("Create a copy of ").append(imprintedInstant.getName()).append("?").toString(), game)) { + if (controller.chooseUse(outcome, new StringBuilder("Create a copy of ").append(imprintedInstant.getName()).append("?").toString(), source, game)) { Card copiedCard = game.copyCard(imprintedInstant, source, source.getControllerId()); if (copiedCard != null) { game.getExile().add(source.getSourceId(), "",copiedCard); game.getState().setZone(copiedCard.getId(), Zone.EXILED); - if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", game)) { + if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) { controller.cast(copiedCard.getSpellAbility(), game, true); } } diff --git a/Mage.Sets/src/mage/sets/mirrodin/KrarksThumb.java b/Mage.Sets/src/mage/sets/mirrodin/KrarksThumb.java index fda4d43fcc..36535622b0 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/KrarksThumb.java +++ b/Mage.Sets/src/mage/sets/mirrodin/KrarksThumb.java @@ -86,7 +86,7 @@ class KrarksThumbEffect extends ReplacementEffectImpl { if (!game.isSimulation()) { game.informPlayers("[Flip a coin] " + player.getLogName() + (secondCoinFlip ? " won (head)." : " lost (tail).")); } - if (player.chooseUse(outcome, "Ignore the first coin flip?", game)) { + if (player.chooseUse(outcome, "Ignore the first coin flip?", source, game)) { event.setFlag(secondCoinFlip); game.informPlayers(new StringBuilder(player.getLogName()).append(" ignores the first coin flip.").toString()); } else { diff --git a/Mage.Sets/src/mage/sets/mirrodin/TajNarSwordsmith.java b/Mage.Sets/src/mage/sets/mirrodin/TajNarSwordsmith.java index 355c3c258f..33a834624f 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/TajNarSwordsmith.java +++ b/Mage.Sets/src/mage/sets/mirrodin/TajNarSwordsmith.java @@ -94,7 +94,7 @@ class TajNarSwordsmithEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player != null && player.chooseUse(Outcome.BoostCreature, "Do you want to to pay {X}?", game)) { + if (player != null && player.chooseUse(Outcome.BoostCreature, "Do you want to to pay {X}?", source, game)) { int costX = player.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source); Cost cost = new GenericManaCost(costX); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/DistantMemories.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/DistantMemories.java index aa0efa1501..7277623499 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/DistantMemories.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/DistantMemories.java @@ -103,7 +103,7 @@ class DistantMemoriesEffect extends OneShotEffect { Set opponents = game.getOpponents(source.getControllerId()); for (UUID opponentUuid : opponents) { Player opponent = game.getPlayer(opponentUuid); - if (opponent != null && !putInHand && opponent.chooseUse(Outcome.Neutral, sb.toString(), game)) { + if (opponent != null && !putInHand && opponent.chooseUse(Outcome.Neutral, sb.toString(), source, game)) { putInHand = true; } } diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/Galvanoth.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/Galvanoth.java index bd36a38bb6..7cac9ff0fb 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/Galvanoth.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/Galvanoth.java @@ -92,7 +92,7 @@ class GalvanothEffect extends OneShotEffect { if (card.getCardType().contains(CardType.INSTANT) || card.getCardType().contains(CardType.SORCERY)) { StringBuilder message = new StringBuilder("Cast ").append(card.getName()).append(" without paying its mana cost?"); - if (controller.chooseUse(Outcome.PlayForFree, message.toString(), game)) { + if (controller.chooseUse(Outcome.PlayForFree, message.toString(), source, game)) { controller.getLibrary().removeFromTop(game); controller.cast(card.getSpellAbility(), game, true); } diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/KnowledgePool.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/KnowledgePool.java index d2146f6213..40475118a5 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/KnowledgePool.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/KnowledgePool.java @@ -162,7 +162,7 @@ class KnowledgePoolEffect2 extends OneShotEffect { if (spell != null) { if (spell.moveToExile(source.getSourceId(), "Knowledge Pool Exile", source.getSourceId(), game)) { Player player = game.getPlayer(spell.getControllerId()); - if (player != null && player.chooseUse(Outcome.PlayForFree, "Cast another nonland card exiled with Knowledge Pool without paying that card's mana cost?", game)) { + if (player != null && player.chooseUse(Outcome.PlayForFree, "Cast another nonland card exiled with Knowledge Pool without paying that card's mana cost?", source, game)) { TargetCardInExile target = new TargetCardInExile(filter, source.getSourceId()); while (player.choose(Outcome.PlayForFree, game.getExile().getExileZone(source.getSourceId()), target, game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/Mirrorworks.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/Mirrorworks.java index 7e0ecbd777..6bc55444c9 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/Mirrorworks.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/Mirrorworks.java @@ -144,7 +144,7 @@ class MirrorworksEffect extends OneShotEffect { } if (target != null) { Cost cost = new ManaCostsImpl("{2}"); - if (player.chooseUse(outcome, new StringBuilder("Pay ").append(cost.getText()).append(" and put a token copy of ").append(target.getName()).append(" onto the battlefield").toString(), game)) { + if (player.chooseUse(outcome, new StringBuilder("Pay ").append(cost.getText()).append(" and put a token copy of ").append(target.getName()).append(" onto the battlefield").toString(), source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { if (target instanceof Permanent) { diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/MitoticManipulation.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/MitoticManipulation.java index 142686364c..def18f8114 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/MitoticManipulation.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/MitoticManipulation.java @@ -117,7 +117,7 @@ class MitoticManipulationEffect extends OneShotEffect { } player.lookAtCards("Mitotic Manipulation", cards, game); - if (!cardsFound.isEmpty() && player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put a card on the battlefield?", game)) { + if (!cardsFound.isEmpty() && player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put a card on the battlefield?", source, game)) { TargetCard target = new TargetCard(Zone.PICK, filter); if (player.choose(Outcome.PutCardInPlay, cardsFound, target, game)) { diff --git a/Mage.Sets/src/mage/sets/modernmasters/PetalsOfInsight.java b/Mage.Sets/src/mage/sets/modernmasters/PetalsOfInsight.java index 5c80d722a0..8a75832ee6 100644 --- a/Mage.Sets/src/mage/sets/modernmasters/PetalsOfInsight.java +++ b/Mage.Sets/src/mage/sets/modernmasters/PetalsOfInsight.java @@ -98,7 +98,7 @@ class PetalsOfInsightEffect extends OneShotEffect { } } player.lookAtCards("Petals of Insight", cards, game); - if (player.chooseUse(outcome, "Put the cards on the bottom of your library in any order?", game)) { + if (player.chooseUse(outcome, "Put the cards on the bottom of your library in any order?", source, game)) { player.putCardsOnBottomOfLibrary(cards, game, source, true); Card spellCard = game.getStack().getSpell(source.getSourceId()).getCard(); if (spellCard != null) { diff --git a/Mage.Sets/src/mage/sets/morningtide/LeafCrownedElder.java b/Mage.Sets/src/mage/sets/morningtide/LeafCrownedElder.java index 3280ed71a2..29bf162db7 100644 --- a/Mage.Sets/src/mage/sets/morningtide/LeafCrownedElder.java +++ b/Mage.Sets/src/mage/sets/morningtide/LeafCrownedElder.java @@ -87,7 +87,7 @@ class LeafCrownedElderPlayEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (player != null && card != null) { - if (player.chooseUse(Outcome.PlayForFree, "Play " + card.getName() + " without paying its mana cost?", game)) { + if (player.chooseUse(Outcome.PlayForFree, "Play " + card.getName() + " without paying its mana cost?", source, game)) { if (card.getCardType().contains(CardType.LAND)) { // If the revealed card is a land, you can play it only if it's your turn and you haven't yet played a land this turn. if (game.getActivePlayerId().equals(player.getId()) && player.canPlayLand()) { diff --git a/Mage.Sets/src/mage/sets/nemesis/BelbesPortal.java b/Mage.Sets/src/mage/sets/nemesis/BelbesPortal.java index c596012adb..5b3e8c7cb7 100644 --- a/Mage.Sets/src/mage/sets/nemesis/BelbesPortal.java +++ b/Mage.Sets/src/mage/sets/nemesis/BelbesPortal.java @@ -108,7 +108,7 @@ class BelbesPortalPutCreatureOnBattlefieldEffect extends OneShotEffect { String choiceText = "Put a " + subtype.toLowerCase() + " creature card from your hand onto the battlefield?"; if (player != null) { - if (player.chooseUse(Outcome.PutCreatureInPlay, choiceText, game)) { + if (player.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { FilterCreatureCard creatureTypeFilter = new FilterCreatureCard(); creatureTypeFilter.add(new SubtypePredicate(subtype)); diff --git a/Mage.Sets/src/mage/sets/nemesis/RootwaterThief.java b/Mage.Sets/src/mage/sets/nemesis/RootwaterThief.java index 7329fbab21..d745064168 100644 --- a/Mage.Sets/src/mage/sets/nemesis/RootwaterThief.java +++ b/Mage.Sets/src/mage/sets/nemesis/RootwaterThief.java @@ -99,7 +99,7 @@ class RootwaterThiefEffect extends OneShotEffect { } String message = "Pay {2} to exile a card from damaged player's library?"; Cost cost = new ManaCostsImpl("{2}"); - if(controller.chooseUse(Outcome.Benefit, message, game) && cost.pay(source, game, source.getSourceId(), controller.getId(), false)) + if(controller.chooseUse(Outcome.Benefit, message, source, game) && cost.pay(source, game, source.getSourceId(), controller.getId(), false)) { TargetCardInLibrary target = new TargetCardInLibrary(); if (controller.searchLibrary(target, game, damagedPlayer.getId())) { diff --git a/Mage.Sets/src/mage/sets/newphyrexia/AuriokSurvivors.java b/Mage.Sets/src/mage/sets/newphyrexia/AuriokSurvivors.java index 7137d9740e..a068353203 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/AuriokSurvivors.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/AuriokSurvivors.java @@ -98,7 +98,7 @@ class AuriokSurvivorsEffect extends OneShotEffect { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Player player = game.getPlayer(source.getControllerId()); if (p != null && player != null && sourcePermanent != null) { - if (player.chooseUse(Outcome.Benefit, "Attach " + p.getName() + " to " + sourcePermanent.getName() + "?", game)) { + if (player.chooseUse(Outcome.Benefit, "Attach " + p.getName() + " to " + sourcePermanent.getName() + "?", source, game)) { sourcePermanent.addAttachment(p.getId(), game); } return true; diff --git a/Mage.Sets/src/mage/sets/newphyrexia/BlindZealot.java b/Mage.Sets/src/mage/sets/newphyrexia/BlindZealot.java index 6bee1ff994..e5b269d862 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/BlindZealot.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/BlindZealot.java @@ -108,10 +108,10 @@ class BlindZealotTriggeredAbility extends TriggeredAbilityImpl { if (player != null && sourcePermanent != null) { StringBuilder sb = new StringBuilder(); - sb.append("Do you wish to sacrifice ").append(sourcePermanent.getName()); + sb.append("Do you wish to sacrifice ").append(sourcePermanent.getIdName()); sb.append(" to destroy target creature controlled by "); sb.append(game.getPlayer(event.getTargetId()).getLogName()).append("?"); - if (player.chooseUse(Outcome.DestroyPermanent, sb.toString(), game)) { + if (player.chooseUse(Outcome.DestroyPermanent, sb.toString(), this, game)) { FilterCreaturePermanent filter = new FilterCreaturePermanent(); filter.add(new ControllerIdPredicate(event.getTargetId())); filter.setMessage("creature controlled by " + game.getPlayer(event.getTargetId()).getLogName()); diff --git a/Mage.Sets/src/mage/sets/newphyrexia/HexParasite.java b/Mage.Sets/src/mage/sets/newphyrexia/HexParasite.java index c38d7fc2fd..e1190a24fb 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/HexParasite.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/HexParasite.java @@ -101,7 +101,7 @@ class HexParasiteEffect extends OneShotEffect { int removed = 0; String[] counterNames = permanent.getCounters().keySet().toArray(new String[0]); for (String counterName : counterNames) { - if (player.chooseUse(Outcome.Neutral, "Do you want to remove " + counterName + " counters?", game)) { + if (player.chooseUse(Outcome.Neutral, "Do you want to remove " + counterName + " counters?", source, game)) { if (permanent.getCounters().get(counterName).getCount() == 1 || toRemove == 1) { permanent.getCounters().removeCounter(counterName, 1); } diff --git a/Mage.Sets/src/mage/sets/newphyrexia/NornsAnnex.java b/Mage.Sets/src/mage/sets/newphyrexia/NornsAnnex.java index fef771c08d..6c5c07386a 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/NornsAnnex.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/NornsAnnex.java @@ -103,7 +103,7 @@ class NornsAnnexReplacementEffect extends ReplacementEffectImpl { if (player != null) { ManaCostsImpl propagandaTax = new ManaCostsImpl("{WP}"); if (propagandaTax.canPay(source, source.getSourceId(), event.getPlayerId(), game) - && player.chooseUse(Outcome.Benefit, "Pay to declare attacker?", game)) { + && player.chooseUse(Outcome.Benefit, "Pay to declare attacker?", source, game)) { if (propagandaTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) { return false; } diff --git a/Mage.Sets/src/mage/sets/newphyrexia/PraetorsGrasp.java b/Mage.Sets/src/mage/sets/newphyrexia/PraetorsGrasp.java index 79671b6128..de9c500e10 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/PraetorsGrasp.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/PraetorsGrasp.java @@ -149,7 +149,7 @@ class PraetorsGraspPlayEffect extends AsThoughEffectImpl { if (exileId != null && controller != null) { ExileZone exileZone = game.getExile().getExileZone(exileId); if (exileZone != null && exileZone.contains(cardId)) { - if (controller.chooseUse(outcome, "Play the exiled card?", game)) { + if (controller.chooseUse(outcome, "Play the exiled card?", source, game)) { return true; } } else { @@ -198,7 +198,7 @@ class PraetorsGraspRevealEffect extends AsThoughEffectImpl { Player controller = game.getPlayer(source.getControllerId()); Card card = game.getCard(cardId); if (controller != null && card != null && game.getState().getZone(cardId) == Zone.EXILED) { - if (controller.chooseUse(outcome, "Reveal exiled card?", game)) { + if (controller.chooseUse(outcome, "Reveal exiled card?", source, game)) { Cards cards = new CardsImpl(card); controller.lookAtCards("Exiled with " + sourceObject.getIdName(), cards, game); } diff --git a/Mage.Sets/src/mage/sets/newphyrexia/PsychicSurgery.java b/Mage.Sets/src/mage/sets/newphyrexia/PsychicSurgery.java index 45073f0eb6..35a26e0db7 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/PsychicSurgery.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/PsychicSurgery.java @@ -138,7 +138,7 @@ class PsychicSurgeryEffect extends OneShotEffect { } player.lookAtCards("Psychic Surgery", cards, game); - if (!cards.isEmpty() && player.chooseUse(Outcome.Exile, "Do you wish to exile a card?", game)) { + if (!cards.isEmpty() && player.chooseUse(Outcome.Exile, "Do you wish to exile a card?", source, game)) { TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to exile")); if (player.choose(Outcome.Exile, cards, target, game)) { Card card = cards.get(target.getFirstTarget(), game); diff --git a/Mage.Sets/src/mage/sets/newphyrexia/Spellskite.java b/Mage.Sets/src/mage/sets/newphyrexia/Spellskite.java index 1c8d098634..6c6db8f49c 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/Spellskite.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/Spellskite.java @@ -133,7 +133,7 @@ class SpellskiteEffect extends OneShotEffect { twoTimesTarget = true; continue; } - if (name != null && player.chooseUse(Outcome.Neutral, new StringBuilder("Change target from ").append(name).append(" to ").append(sourceObject.getName()).append("?").toString(), game)) { + if (name != null && player.chooseUse(Outcome.Neutral, new StringBuilder("Change target from ").append(name).append(" to ").append(sourceObject.getName()).append("?").toString(), source, game)) { if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) { oldTarget = game.getObject(targets.getFirstTarget()); target.remove(targetId); diff --git a/Mage.Sets/src/mage/sets/newphyrexia/UnwindingClock.java b/Mage.Sets/src/mage/sets/newphyrexia/UnwindingClock.java index d92ae37450..be78a7a997 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/UnwindingClock.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/UnwindingClock.java @@ -28,6 +28,11 @@ package mage.sets.newphyrexia; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.RestrictionEffect; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -36,11 +41,6 @@ import mage.constants.PhaseStep; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.RestrictionEffect; -import mage.cards.CardImpl; import mage.filter.common.FilterArtifactPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -56,7 +56,7 @@ public class UnwindingClock extends CardImpl { this.expansionSetCode = "NPH"; // Untap all artifacts you control during each other player's untap step. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new UnwindingClockEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new UnwindingClockEffect())); } public UnwindingClock(final UnwindingClock card) { @@ -96,10 +96,10 @@ class UnwindingClockEffect extends ContinuousEffectImpl { if (!applied && layer.equals(Layer.RulesEffects)) { if (!game.getActivePlayerId().equals(source.getControllerId()) && game.getStep().getType() == PhaseStep.UNTAP) { game.getState().setValue(source.getSourceId() + "applied", true); - for (Permanent artifact: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { + for (Permanent artifact : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { boolean untap = true; - for (RestrictionEffect effect: game.getContinuousEffects().getApplicableRestrictionEffects(artifact, game).keySet()) { - untap &= effect.canBeUntapped(artifact, game); + for (RestrictionEffect effect : game.getContinuousEffects().getApplicableRestrictionEffects(artifact, game).keySet()) { + untap &= effect.canBeUntapped(artifact, source, game); } if (untap) { artifact.untap(game); diff --git a/Mage.Sets/src/mage/sets/ninthedition/HuntedWumpus.java b/Mage.Sets/src/mage/sets/ninthedition/HuntedWumpus.java index 6de884915a..83d5ebc28b 100644 --- a/Mage.Sets/src/mage/sets/ninthedition/HuntedWumpus.java +++ b/Mage.Sets/src/mage/sets/ninthedition/HuntedWumpus.java @@ -98,7 +98,7 @@ class HuntedWumpusEffect extends OneShotEffect { if (player != null) { TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard()); if (target.canChoose(source.getSourceId(), playerId, game) - && player.chooseUse(Outcome.Neutral, "Put a creature card from your hand in play?", game) + && player.chooseUse(Outcome.Neutral, "Put a creature card from your hand in play?", source, game) && player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/ninthedition/StorageMatrix.java b/Mage.Sets/src/mage/sets/ninthedition/StorageMatrix.java index 76871a019d..62c863c93e 100644 --- a/Mage.Sets/src/mage/sets/ninthedition/StorageMatrix.java +++ b/Mage.Sets/src/mage/sets/ninthedition/StorageMatrix.java @@ -29,17 +29,17 @@ package mage.sets.ninthedition; import java.util.HashSet; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.PhaseStep; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.RestrictionEffect; import mage.cards.CardImpl; import mage.choices.Choice; import mage.choices.ChoiceImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.PhaseStep; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -68,14 +68,13 @@ public class StorageMatrix extends CardImpl { } } - - class StorageMatrixRestrictionEffect extends RestrictionEffect { private int turn; private boolean applies; private static final HashSet choice = new HashSet<>(); - static{ + + static { choice.add(CardType.ARTIFACT.toString()); choice.add(CardType.CREATURE.toString()); choice.add(CardType.LAND.toString()); @@ -106,8 +105,8 @@ class StorageMatrixRestrictionEffect extends RestrictionEffect { choiceImpl.setMessage("Untap which kind of permanent?"); choiceImpl.setChoices(choice); Player player = game.getPlayer(game.getActivePlayerId()); - if(player != null){ - while(!player.choose(outcome, choiceImpl, game)) { + if (player != null) { + while (!player.choose(outcome, choiceImpl, game)) { if (player.isInGame()) { return false; } @@ -115,11 +114,11 @@ class StorageMatrixRestrictionEffect extends RestrictionEffect { String choosenType = choiceImpl.getChoice(); game.informPlayers(storageMatrix.getLogName() + ": " + player.getLogName() + " chose to untap " + choosenType); - if(choosenType.equals(CardType.ARTIFACT.toString())){ + if (choosenType.equals(CardType.ARTIFACT.toString())) { type = CardType.ARTIFACT; - }else if(choosenType.equals(CardType.LAND.toString())){ + } else if (choosenType.equals(CardType.LAND.toString())) { type = CardType.LAND; - }else{ + } else { type = CardType.CREATURE; } applies = true; @@ -134,7 +133,7 @@ class StorageMatrixRestrictionEffect extends RestrictionEffect { } @Override - public boolean canBeUntapped(Permanent permanent, Game game) { + public boolean canBeUntapped(Permanent permanent, Ability source, Game game) { return false; } diff --git a/Mage.Sets/src/mage/sets/odyssey/BlazingSalvo.java b/Mage.Sets/src/mage/sets/odyssey/BlazingSalvo.java index 86d3a3b388..8a464d8670 100644 --- a/Mage.Sets/src/mage/sets/odyssey/BlazingSalvo.java +++ b/Mage.Sets/src/mage/sets/odyssey/BlazingSalvo.java @@ -88,7 +88,7 @@ class BlazingSalvoEffect extends OneShotEffect { Player player = game.getPlayer(permanent.getControllerId()); if (player != null) { String message = "Have Blazing Salvo do 5 damage to you?"; - if (player.chooseUse(Outcome.Damage, message, game)){ + if (player.chooseUse(Outcome.Damage, message, source, game)){ player.damage(5, source.getSourceId(), game, true, false); } else { permanent.damage(3, source.getSourceId(), game, false, true); diff --git a/Mage.Sets/src/mage/sets/odyssey/DecayingSoil.java b/Mage.Sets/src/mage/sets/odyssey/DecayingSoil.java index 5f0b340da9..aae708d61b 100644 --- a/Mage.Sets/src/mage/sets/odyssey/DecayingSoil.java +++ b/Mage.Sets/src/mage/sets/odyssey/DecayingSoil.java @@ -170,7 +170,7 @@ class DecayingSoilEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - if (player.chooseUse(Outcome.Benefit, " - Pay " + cost.getText() + "?", game)) { + if (player.chooseUse(Outcome.Benefit, " - Pay " + cost.getText() + "?", source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { UUID target = this.getTargetPointer().getFirst(game, source); diff --git a/Mage.Sets/src/mage/sets/odyssey/DelayingShield.java b/Mage.Sets/src/mage/sets/odyssey/DelayingShield.java index 8d62548220..28330c160d 100644 --- a/Mage.Sets/src/mage/sets/odyssey/DelayingShield.java +++ b/Mage.Sets/src/mage/sets/odyssey/DelayingShield.java @@ -138,7 +138,7 @@ class DelayingShieldUpkeepEffect extends OneShotEffect { int numCounters = permanent.getCounters().getCount(CounterType.DELAY); permanent.removeCounters(CounterType.DELAY.createInstance(), game); for (int i = numCounters; i > 0; i--) { - if (player.chooseUse(Outcome.Benefit, "Pay {1}{W}? (" + i + " counters left to pay)", game)) { + if (player.chooseUse(Outcome.Benefit, "Pay {1}{W}? (" + i + " counters left to pay)", source, game)) { Cost cost = new ManaCostsImpl<>("{1}{W}"); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { continue; diff --git a/Mage.Sets/src/mage/sets/odyssey/MoltenInfluence.java b/Mage.Sets/src/mage/sets/odyssey/MoltenInfluence.java index bf2cbc6973..e696078597 100644 --- a/Mage.Sets/src/mage/sets/odyssey/MoltenInfluence.java +++ b/Mage.Sets/src/mage/sets/odyssey/MoltenInfluence.java @@ -98,7 +98,7 @@ class MoltenInfluenceEffect extends OneShotEffect { if (spell != null) { Player player = game.getPlayer(spell.getControllerId()); String message = "Have Molten Influence do 4 damage to you?"; - if (player.chooseUse(Outcome.Damage, message, game)) { + if (player.chooseUse(Outcome.Damage, message, source, game)) { player.damage(4, source.getSourceId(), game, false, true); } else { spell.counter(source.getSourceId(), game); diff --git a/Mage.Sets/src/mage/sets/odyssey/ObstinateFamiliar.java b/Mage.Sets/src/mage/sets/odyssey/ObstinateFamiliar.java index 8112ec8271..4ef53d0238 100644 --- a/Mage.Sets/src/mage/sets/odyssey/ObstinateFamiliar.java +++ b/Mage.Sets/src/mage/sets/odyssey/ObstinateFamiliar.java @@ -109,7 +109,7 @@ class ObstinateFamiliarReplacementEffect extends ReplacementEffectImpl { if (event.getPlayerId().equals(source.getControllerId()) && archmage != null && you != null - && you.chooseUse(Outcome.Benefit, "Would you like to skip drawing a card?", game)) { + && you.chooseUse(Outcome.Benefit, "Would you like to skip drawing a card?", source, game)) { return true; } return false; diff --git a/Mage.Sets/src/mage/sets/odyssey/TaintedPact.java b/Mage.Sets/src/mage/sets/odyssey/TaintedPact.java index 15e8120ff5..09b9c6d6f2 100644 --- a/Mage.Sets/src/mage/sets/odyssey/TaintedPact.java +++ b/Mage.Sets/src/mage/sets/odyssey/TaintedPact.java @@ -100,7 +100,7 @@ class TaintedPactEffect extends OneShotEffect{ break; } names.add(card.getName()); - if (player.chooseUse(outcome, new StringBuilder("Put ").append(card.getName()).append("into your hand?").toString(), game)) { + if (player.chooseUse(outcome, new StringBuilder("Put ").append(card.getName()).append("into your hand?").toString(), source, game)) { //Adds the current card to hand if it is chosen. card.moveToZone(Zone.HAND, source.getSourceId(), game, true); break; diff --git a/Mage.Sets/src/mage/sets/odyssey/ThinkTank.java b/Mage.Sets/src/mage/sets/odyssey/ThinkTank.java index dc8602ec6c..e29391babf 100644 --- a/Mage.Sets/src/mage/sets/odyssey/ThinkTank.java +++ b/Mage.Sets/src/mage/sets/odyssey/ThinkTank.java @@ -97,7 +97,7 @@ class ThinkTankLookLibraryEffect extends OneShotEffect { CardsImpl cards = new CardsImpl(); cards.add(card); controller.lookAtCards("Think Tank", cards, game); - if (controller.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", game)) { + if (controller.chooseUse(Outcome.Neutral, "Do you wish to put the card into your graveyard?", source, game)) { return controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game); } diff --git a/Mage.Sets/src/mage/sets/odyssey/UnifyingTheory.java b/Mage.Sets/src/mage/sets/odyssey/UnifyingTheory.java index df7da318d1..0fba130c3e 100644 --- a/Mage.Sets/src/mage/sets/odyssey/UnifyingTheory.java +++ b/Mage.Sets/src/mage/sets/odyssey/UnifyingTheory.java @@ -98,7 +98,7 @@ class UnifyingTheoryEffect extends OneShotEffect { caster = game.getPlayer(spell.getControllerId()); } if (caster != null) { - if (caster.chooseUse(Outcome.DrawCard, "Pay {2} to draw a card?", game)) { + 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)) { caster.drawCards(1, game); diff --git a/Mage.Sets/src/mage/sets/onslaught/ChainOfVapor.java b/Mage.Sets/src/mage/sets/onslaught/ChainOfVapor.java index 4b15f90207..b03ec15c5a 100644 --- a/Mage.Sets/src/mage/sets/onslaught/ChainOfVapor.java +++ b/Mage.Sets/src/mage/sets/onslaught/ChainOfVapor.java @@ -98,7 +98,7 @@ class ChainOfVaporEffect extends OneShotEffect { return false; } Player player = game.getPlayer(permanent.getControllerId()); - if (player.chooseUse(Outcome.ReturnToHand, "Sacrifice a land to copy this spell?", game)){ + if (player.chooseUse(Outcome.ReturnToHand, "Sacrifice a land to copy this spell?", source, game)){ TargetControlledPermanent target = new TargetControlledPermanent(new FilterControlledLandPermanent()); if (player.chooseTarget(Outcome.Sacrifice, target, source, game)){ Permanent land = game.getPermanent(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/onslaught/DeathMatch.java b/Mage.Sets/src/mage/sets/onslaught/DeathMatch.java index 1709fc2468..02e0c18057 100644 --- a/Mage.Sets/src/mage/sets/onslaught/DeathMatch.java +++ b/Mage.Sets/src/mage/sets/onslaught/DeathMatch.java @@ -101,7 +101,7 @@ class DeathMatchEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getTargets().get(0).getTargetController()); if(player != null) { - if(player.chooseUse(outcome, "Give targeted creature -3/-3 ?", game)) { + if(player.chooseUse(outcome, "Give targeted creature -3/-3 ?", source, game)) { game.addEffect(new BoostTargetEffect(-3, -3, Duration.EndOfTurn), source); } return true; diff --git a/Mage.Sets/src/mage/sets/onslaught/ElvishPioneer.java b/Mage.Sets/src/mage/sets/onslaught/ElvishPioneer.java index 510ba22d63..627da390f2 100644 --- a/Mage.Sets/src/mage/sets/onslaught/ElvishPioneer.java +++ b/Mage.Sets/src/mage/sets/onslaught/ElvishPioneer.java @@ -105,7 +105,7 @@ class PutLandOnBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutLandInPlay, choiceText, game)) { + if (player == null || !player.chooseUse(Outcome.PutLandInPlay, choiceText, source, game)) { return false; } diff --git a/Mage.Sets/src/mage/sets/onslaught/WeirdHarvest.java b/Mage.Sets/src/mage/sets/onslaught/WeirdHarvest.java index 0043bd8802..1be7a060eb 100644 --- a/Mage.Sets/src/mage/sets/onslaught/WeirdHarvest.java +++ b/Mage.Sets/src/mage/sets/onslaught/WeirdHarvest.java @@ -112,7 +112,7 @@ class WeirdHarvestEffect extends OneShotEffect { } private void chooseAndSearchLibrary(List usingPlayers, Player player, int xValue, Ability source, Game game) { - if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for up " + xValue + " creature cards and put them into your hand?", game)) { + if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for up " + xValue + " creature cards and put them into your hand?", source, game)) { usingPlayers.add(player); TargetCardInLibrary target = new TargetCardInLibrary(0, xValue, new FilterCreatureCard()); if (player.searchLibrary(target, game)) { diff --git a/Mage.Sets/src/mage/sets/planarchaos/IntetTheDreamer.java b/Mage.Sets/src/mage/sets/planarchaos/IntetTheDreamer.java index ea9a46de99..88d32915c3 100644 --- a/Mage.Sets/src/mage/sets/planarchaos/IntetTheDreamer.java +++ b/Mage.Sets/src/mage/sets/planarchaos/IntetTheDreamer.java @@ -148,7 +148,7 @@ class IntetTheDreamerEffect extends AsThoughEffectImpl { if (affectedControllerId.equals(source.getControllerId()) && card != null && game.getState().getZone(card.getId()) == Zone.EXILED) { ExileZone zone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter())); if (zone != null && zone.contains(card.getId())) { - if (controller.chooseUse(outcome, "Look at the card?", game)) { + if (controller.chooseUse(outcome, "Look at the card?", source, game)) { Cards cards = new CardsImpl(); cards.add(card); controller.lookAtCards(sourceObject.getName(), cards, game); diff --git a/Mage.Sets/src/mage/sets/planarchaos/Phantasmagorian.java b/Mage.Sets/src/mage/sets/planarchaos/Phantasmagorian.java index 42639488b6..e8e99f9eb6 100644 --- a/Mage.Sets/src/mage/sets/planarchaos/Phantasmagorian.java +++ b/Mage.Sets/src/mage/sets/planarchaos/Phantasmagorian.java @@ -105,7 +105,7 @@ class CounterSourceEffect extends OneShotEffect { if(spell != null){ for(UUID uuid : game.getPlayerList()){ Player player = game.getPlayer(uuid); - if(player.chooseUse(Outcome.Detriment, "Discard three cards to counter " + spell.getName() + "?", game)){ + if(player.chooseUse(Outcome.Detriment, "Discard three cards to counter " + spell.getName() + "?", source, game)){ DiscardTargetCost cost = new DiscardTargetCost(new TargetCardInHand(3, 3, new FilterCard())); if(cost.pay(source, game, source.getSourceId(), uuid, false)){ game.informPlayers(player.getLogName() + " discards 3 cards to counter " + spell.getName() + "."); diff --git a/Mage.Sets/src/mage/sets/planarchaos/ShivanWumpus.java b/Mage.Sets/src/mage/sets/planarchaos/ShivanWumpus.java index ca963a4d41..725ba9ff15 100644 --- a/Mage.Sets/src/mage/sets/planarchaos/ShivanWumpus.java +++ b/Mage.Sets/src/mage/sets/planarchaos/ShivanWumpus.java @@ -100,7 +100,7 @@ class ShivanWumpusEffect extends PutOnLibrarySourceEffect { Player player = game.getPlayer(playerId); if (player != null && cost.canPay(source, source.getSourceId(), playerId, game) - && player.chooseUse(Outcome.Sacrifice, "Sacrifice a land?", game) + && player.chooseUse(Outcome.Sacrifice, "Sacrifice a land?", source, game) && cost.pay(source, game, source.getSourceId(), playerId, true)) { costPaid = true; } diff --git a/Mage.Sets/src/mage/sets/planechase/ThirstForKnowledge.java b/Mage.Sets/src/mage/sets/planechase/ThirstForKnowledge.java index 62d8030910..a7106c6c67 100644 --- a/Mage.Sets/src/mage/sets/planechase/ThirstForKnowledge.java +++ b/Mage.Sets/src/mage/sets/planechase/ThirstForKnowledge.java @@ -93,7 +93,7 @@ class ThirstforKnowledgeEffect extends OneShotEffect { filter.add(new CardTypePredicate(CardType.ARTIFACT)); if (you != null && you.getHand().count(filter, game) > 0 - && you.chooseUse(Outcome.Discard, "Do you want to discard an artifact? If you don't, you must discard 2 cards", game)) { + && you.chooseUse(Outcome.Discard, "Do you want to discard an artifact? If you don't, you must discard 2 cards", source, game)) { Cost cost = new DiscardTargetCost(new TargetCardInHand(filter)); if (cost.canPay(source, source.getSourceId(), you.getId(), game)) { if (cost.pay(source, game, source.getSourceId(), you.getId(), false)) { diff --git a/Mage.Sets/src/mage/sets/prophecy/RhysticStudy.java b/Mage.Sets/src/mage/sets/prophecy/RhysticStudy.java index a6e617a28d..d0864c9e78 100644 --- a/Mage.Sets/src/mage/sets/prophecy/RhysticStudy.java +++ b/Mage.Sets/src/mage/sets/prophecy/RhysticStudy.java @@ -92,8 +92,8 @@ class RhysticStudyDrawEffect extends OneShotEffect { if (controller != null && opponent != null && sourceObject != null) { Cost cost = new GenericManaCost(1); String message = "Would you like to pay {1} to prevent the opponent to draw a card?"; - if (!(opponent.chooseUse(Outcome.Benefit, message, game) && cost.pay(source, game, source.getSourceId(), opponent.getId(), false))) { - if(controller.chooseUse(Outcome.DrawCard, "Draw a card (" + sourceObject.getLogName() +")", game)) { + if (!(opponent.chooseUse(Outcome.Benefit, message, source, game) && cost.pay(source, game, source.getSourceId(), opponent.getId(), false))) { + if(controller.chooseUse(Outcome.DrawCard, "Draw a card (" + sourceObject.getLogName() +")", source, game)) { controller.drawCards(1, game); } } diff --git a/Mage.Sets/src/mage/sets/returntoravnica/DesecrationDemon.java b/Mage.Sets/src/mage/sets/returntoravnica/DesecrationDemon.java index d8ba05431b..325db6aee0 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/DesecrationDemon.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/DesecrationDemon.java @@ -103,7 +103,7 @@ class DesecrationDemonEffect extends OneShotEffect { filter.add(new ControllerPredicate(TargetController.YOU)); TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false); if (target.canChoose(opponent.getId(), game)) { - if (opponent.chooseUse(Outcome.AIDontUseIt, "Sacrifice a creature to tap " + descrationDemon.getLogName() + "and put a +1/+1 counter on it?", game)) + if (opponent.chooseUse(Outcome.AIDontUseIt, "Sacrifice a creature to tap " + descrationDemon.getLogName() + "and put a +1/+1 counter on it?", source, game)) { opponent.choose(Outcome.Sacrifice, target, source.getSourceId(), game); Permanent permanent = game.getPermanent(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/returntoravnica/EpicExperiment.java b/Mage.Sets/src/mage/sets/returntoravnica/EpicExperiment.java index b7f0c5c403..e656a073fb 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/EpicExperiment.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/EpicExperiment.java @@ -110,7 +110,7 @@ class EpicExperimentEffect extends OneShotEffect { filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.LessThan, source.getManaCostsToPay().getX() + 1)); filter.setMessage("instant and sorcery cards with converted mana cost "+ source.getManaCostsToPay().getX() +" or less"); while (epicExperimentExileZone != null && epicExperimentExileZone.count(filter, game) > 0 - && controller.chooseUse(Outcome.PlayForFree, "Cast cards exiled with " + sourceObject.getLogName() + " without paying its mana cost?", game)) { + && controller.chooseUse(Outcome.PlayForFree, "Cast cards exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) { TargetCardInExile target = new TargetCardInExile(filter, source.getSourceId()); while (epicExperimentExileZone.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, epicExperimentExileZone, target, game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/returntoravnica/GrislySalvage.java b/Mage.Sets/src/mage/sets/returntoravnica/GrislySalvage.java index e030085eb5..06535dcba3 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/GrislySalvage.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/GrislySalvage.java @@ -108,7 +108,7 @@ class GrislySalvageEffect extends OneShotEffect { if (!cards.isEmpty()) { controller.revealCards(sourceObject.getName(), cards, game); TargetCard target = new TargetCard(Zone.LIBRARY, filterPutInHand); - if (properCardFound && controller.chooseUse(outcome, "Put a creature or land card from the revealed cards into your hand?", game) && + if (properCardFound && controller.chooseUse(outcome, "Put a creature or land card from the revealed cards into your hand?", source, game) && controller.choose(Outcome.DrawCard, cards, target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/returntoravnica/GuildFeud.java b/Mage.Sets/src/mage/sets/returntoravnica/GuildFeud.java index 1a89c7af15..756e5538fd 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/GuildFeud.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/GuildFeud.java @@ -105,7 +105,7 @@ class GuildFeudEffect extends OneShotEffect { player.revealCards(player.getName() + " top three library cards", topThreeCards, game); Card creatureToBattlefield; if (!topThreeCards.isEmpty()) { - if (player.chooseUse(Outcome.PutCreatureInPlay, "Put a creature card among them to the battlefield?", game)) { + if (player.chooseUse(Outcome.PutCreatureInPlay, "Put a creature card among them to the battlefield?", source, game)) { TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCreatureCard( "creature card to put on the battlefield")); diff --git a/Mage.Sets/src/mage/sets/returntoravnica/IzzetKeyrune.java b/Mage.Sets/src/mage/sets/returntoravnica/IzzetKeyrune.java index d15df63aa4..e296787660 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/IzzetKeyrune.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/IzzetKeyrune.java @@ -92,7 +92,7 @@ public class IzzetKeyrune extends CardImpl { @Override 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.", game)) { + 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) { player.discard(1, source, game); } diff --git a/Mage.Sets/src/mage/sets/returntoravnica/SoulTithe.java b/Mage.Sets/src/mage/sets/returntoravnica/SoulTithe.java index 3c42999000..753401fbf6 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/SoulTithe.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/SoulTithe.java @@ -109,7 +109,7 @@ class SoulTitheSacrificeSourceUnlessPaysEffect extends OneShotEffect { MageObject sourceObject = source.getSourceObject(game); if (player != null && permanent != null && sourceObject != null) { int cmc = permanent.getManaCost().convertedManaCost(); - if (player.chooseUse(Outcome.Benefit, "Pay {" + cmc + "} for " + permanent.getName() + "? (otherwise you sacrifice it)", game)) { + if (player.chooseUse(Outcome.Benefit, "Pay {" + cmc + "} for " + permanent.getName() + "? (otherwise you sacrifice it)", source, game)) { Cost cost = new GenericManaCost(cmc); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { return true; diff --git a/Mage.Sets/src/mage/sets/returntoravnica/SphereOfSafety.java b/Mage.Sets/src/mage/sets/returntoravnica/SphereOfSafety.java index 203b13ab4f..6c9ee272bc 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/SphereOfSafety.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/SphereOfSafety.java @@ -115,7 +115,7 @@ class SphereOfSafetyReplacementEffect extends ReplacementEffectImpl { int ce = countEnchantments.calculate(game, source, this); ManaCostsImpl safetyCosts = new ManaCostsImpl("{"+ ce +"}"); if ( safetyCosts.canPay(source, source.getSourceId(), event.getPlayerId(), game) && - player.chooseUse(Outcome.Benefit, "Pay {"+ ce +"} to declare attacker?", game) ) { + player.chooseUse(Outcome.Benefit, "Pay {"+ ce +"} to declare attacker?", source, game) ) { if (safetyCosts.payOrRollback(source, game, this.getId(), event.getPlayerId())) { return false; } diff --git a/Mage.Sets/src/mage/sets/returntoravnica/UrbanBurgeoning.java b/Mage.Sets/src/mage/sets/returntoravnica/UrbanBurgeoning.java index b108ac9604..166c927fe9 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/UrbanBurgeoning.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/UrbanBurgeoning.java @@ -25,10 +25,17 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.returntoravnica; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.RestrictionEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; import mage.constants.AttachmentType; import mage.constants.CardType; import mage.constants.Duration; @@ -38,14 +45,6 @@ import mage.constants.PhaseStep; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.RestrictionEffect; -import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.abilities.keyword.EnchantAbility; -import mage.cards.CardImpl; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; @@ -59,12 +58,11 @@ public class UrbanBurgeoning extends CardImpl { static final String rule = "Enchanted land has \"Untap this land during each other player's untap step.\""; - public UrbanBurgeoning (UUID ownerId) { + public UrbanBurgeoning(UUID ownerId) { super(ownerId, 138, "Urban Burgeoning", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{G}"); this.expansionSetCode = "RTR"; this.subtype.add("Aura"); - // Enchant land TargetPermanent auraTarget = new TargetLandPermanent(); this.getSpellAbility().addTarget(auraTarget); @@ -77,7 +75,7 @@ public class UrbanBurgeoning extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA, Duration.WhileOnBattlefield, rule))); } - public UrbanBurgeoning (final UrbanBurgeoning card) { + public UrbanBurgeoning(final UrbanBurgeoning card) { super(card); } @@ -114,8 +112,8 @@ class UrbanBurgeoningUntapEffect extends ContinuousEffectImpl { game.getState().setValue(source.getSourceId() + "applied", true); Permanent land = game.getPermanent(source.getSourceId()); boolean untap = true; - for (RestrictionEffect effect: game.getContinuousEffects().getApplicableRestrictionEffects(land, game).keySet()) { - untap &= effect.canBeUntapped(land, game); + for (RestrictionEffect effect : game.getContinuousEffects().getApplicableRestrictionEffects(land, game).keySet()) { + untap &= effect.canBeUntapped(land, source, game); } if (untap) { land.untap(game); diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/HellcarverDemon.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/HellcarverDemon.java index 7a840918c4..0f479e09c9 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/HellcarverDemon.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/HellcarverDemon.java @@ -113,7 +113,7 @@ class HellcarverDemonEffect extends OneShotEffect { } } - while (player != null && player.isInGame() && player.chooseUse(Outcome.PlayForFree, "Cast another nonland card exiled with Hellcarver Demon without paying that card's mana cost?", game)) { + while (player != null && player.isInGame() && player.chooseUse(Outcome.PlayForFree, "Cast another nonland card exiled with Hellcarver Demon without paying that card's mana cost?", source, game)) { TargetCardInExile target = new TargetCardInExile(filter, source.getSourceId()); while (player.choose(Outcome.PlayForFree, game.getExile().getExileZone(source.getSourceId()), target, game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/BloodClock.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/BloodClock.java index af22a86067..6beffb2168 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/BloodClock.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/BloodClock.java @@ -91,7 +91,7 @@ class BloodClockEffect extends OneShotEffect { if (player == null) { return false; } - if (player.getLife() > 2 && player.chooseUse(Outcome.Neutral, "Pay 2 life? If you don't, return a permanent you control to its owner's hand.", game)) { + if (player.getLife() > 2 && player.chooseUse(Outcome.Neutral, "Pay 2 life? If you don't, return a permanent you control to its owner's hand.", source, game)) { player.loseLife(2, game); game.informPlayers(player.getLogName() + " pays 2 life. He will not return a permanent he or she controls."); return true; diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/ChoiceOfDamnations.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/ChoiceOfDamnations.java index b654d9ed6a..b17320ccbb 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/ChoiceOfDamnations.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/ChoiceOfDamnations.java @@ -93,7 +93,7 @@ class ChoiceOfDamnationsEffect extends OneShotEffect { int amount = targetPlayer.getAmount(0, Integer.MAX_VALUE, "Chooses a number", game); Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - if (controller.chooseUse(outcome, "Shall " + targetPlayer.getLogName() + " lose " + amount + " life?", game)) { + if (controller.chooseUse(outcome, "Shall " + targetPlayer.getLogName() + " lose " + amount + " life?", source, game)) { targetPlayer.loseLife(amount, game); } else { int numberPermanents = game.getState().getBattlefield().countAll(new FilterPermanent(), targetPlayer.getId(), game); diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/CowedByWisdom.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/CowedByWisdom.java index 42d10820b9..0176bd77ec 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/CowedByWisdom.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/CowedByWisdom.java @@ -125,7 +125,7 @@ class CowedByWisdomEffect extends ReplacementEffectImpl { } ManaCostsImpl attackBlockTax = new ManaCostsImpl("{" + cardsInHand + "}"); if (attackBlockTax.canPay(source, source.getSourceId(), event.getPlayerId(), game) - && player.chooseUse(Outcome.Neutral, chooseText, game)) { + && player.chooseUse(Outcome.Neutral, chooseText, source, game)) { if (attackBlockTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) { return false; } diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/InameAsOne.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/InameAsOne.java index e7246a9566..395a947b44 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/InameAsOne.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/InameAsOne.java @@ -115,7 +115,7 @@ class InameAsOneEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (controller != null && sourceObject != null) { - if (controller.chooseUse(outcome, "Exile " + sourceObject.getLogName() + " to return Spirit card?", game)) { + if (controller.chooseUse(outcome, "Exile " + sourceObject.getLogName() + " to return Spirit card?", source, game)) { // In a Commander game, you may send Iname to the Command Zone instead of exiling it during the resolution // of its ability. If you do, its ability still works. Iname's ability only requires that you attempted to // exile it, not that it actually gets to the exile zone. This is similar to how destroying a creature diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/PainsReward.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/PainsReward.java index 5d61a72b1c..6da149da12 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/PainsReward.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/PainsReward.java @@ -94,7 +94,7 @@ class PainsRewardEffect extends OneShotEffect { Player currentPlayer = playerList.getNextInRange(controller, game); while (currentPlayer != winner) { String text = winner.getLogName() + " has bet " + highBid + " life" + (highBid > 1 ? "s" : "") + ". Top the bid?"; - if (currentPlayer.chooseUse(Outcome.Detriment, text, game)) { + if (currentPlayer.chooseUse(Outcome.Detriment, text, source, game)) { int newBid = currentPlayer.getAmount(highBid + 1, Integer.MAX_VALUE, "Choose amount of life to bid", game); if (newBid > highBid) { highBid = newBid; diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/NimDeathmantle.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/NimDeathmantle.java index 060d2c1988..45f8b9878c 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/NimDeathmantle.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/NimDeathmantle.java @@ -162,7 +162,7 @@ class NimDeathmantleEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); Permanent equipment = game.getPermanent(source.getSourceId()); if (player != null && equipment != null) { - if (player.chooseUse(Outcome.Benefit, equipment.getName() + " - Pay " + cost.getText() + "?", game)) { + if (player.chooseUse(Outcome.Benefit, equipment.getName() + " - Pay " + cost.getText() + "?", source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { UUID target = targetPointer.getFirst(game, source); diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/PainfulQuandary.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/PainfulQuandary.java index 7fb923d038..8966440f99 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/PainfulQuandary.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/PainfulQuandary.java @@ -92,7 +92,7 @@ class PainfulQuandryEffect extends OneShotEffect { boolean paid = false; Cost cost = new DiscardTargetCost(new TargetCardInHand()); if (cost.canPay(source, source.getSourceId(), player.getId(), game) - && player.chooseUse(Outcome.Detriment, "Discard a card (otherwise you lose 5 life)?", game)) { + && player.chooseUse(Outcome.Detriment, "Discard a card (otherwise you lose 5 life)?", source, game)) { paid = cost.pay(source, game, source.getSourceId(), player.getId(), false); } if (!paid) { diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/RustTick.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/RustTick.java index df5b37004d..db24b40406 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/RustTick.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/RustTick.java @@ -28,10 +28,6 @@ package mage.sets.scarsofmirrodin; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.Mode; @@ -43,11 +39,14 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.RestrictionEffect; import mage.abilities.effects.common.TapTargetEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetArtifactPermanent; - /** * @author nantuko */ @@ -112,7 +111,6 @@ class RustTickTapTargetEffect extends TapTargetEffect { return true; } - @Override public RustTickTapTargetEffect copy() { return new RustTickTapTargetEffect(this); @@ -149,7 +147,7 @@ class RustTickRestrictionEffect extends RestrictionEffect { } @Override - public boolean canBeUntapped(Permanent permanent, Game game) { + public boolean canBeUntapped(Permanent permanent, Ability source, Game game) { return false; } diff --git a/Mage.Sets/src/mage/sets/shadowmoor/DramaticEntrance.java b/Mage.Sets/src/mage/sets/shadowmoor/DramaticEntrance.java index e85f8d1068..c3c0846ab5 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/DramaticEntrance.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/DramaticEntrance.java @@ -98,7 +98,7 @@ class DramaticEntranceEffect extends OneShotEffect { if (controller != null) { if (controller.getHand().count(filter, game) > 0) { if (controller.chooseUse(Outcome.PutCreatureInPlay, - "Put a green creature card onto the battlefield?", game)) { + "Put a green creature card onto the battlefield?", source, game)) { Target target = new TargetCardInHand(filter); if (controller.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/shadowmoor/MemoryPlunder.java b/Mage.Sets/src/mage/sets/shadowmoor/MemoryPlunder.java index c0544f0791..bedbf0ec5e 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/MemoryPlunder.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/MemoryPlunder.java @@ -98,7 +98,7 @@ class MemoryPlunderEffect extends OneShotEffect { Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card != null) { Player player = game.getPlayer(source.getControllerId()); - if (player != null && player.chooseUse(Outcome.Benefit, "Cast " + card.getName() +" without paying cost?", game)) { + if (player != null && player.chooseUse(Outcome.Benefit, "Cast " + card.getName() +" without paying cost?", source, game)) { player.cast(card.getSpellAbility(), game, true); } } diff --git a/Mage.Sets/src/mage/sets/shadowmoor/PlagueOfVermin.java b/Mage.Sets/src/mage/sets/shadowmoor/PlagueOfVermin.java index 9eecc11464..4bf3c7225d 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/PlagueOfVermin.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/PlagueOfVermin.java @@ -106,7 +106,7 @@ class PlagueOfVerminEffect extends OneShotEffect { if (currentPlayer != null && currentPlayer.isInGame() && controller.getInRange().contains(currentPlayer.getId())) { currentLifePaid = 0; totalPaidLife = 0; - if (currentPlayer.chooseUse(Outcome.AIDontUseIt, "Pay life?", game)) { + if (currentPlayer.chooseUse(Outcome.AIDontUseIt, "Pay life?", source, game)) { totalPaidLife = currentPlayer.getAmount(0, controller.getLife(), "Pay how many life?", game); if (totalPaidLife > 0) { currentPlayer.loseLife(totalPaidLife, game); diff --git a/Mage.Sets/src/mage/sets/shadowmoor/PuresightMerrow.java b/Mage.Sets/src/mage/sets/shadowmoor/PuresightMerrow.java index f9b55a50bb..115e6c1f8e 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/PuresightMerrow.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/PuresightMerrow.java @@ -104,7 +104,7 @@ class PuresightMerrowEffect extends OneShotEffect { Cards cards = new CardsImpl(); cards.add(card); controller.lookAtCards("Puresight Merrow", cards, game); - if (controller.chooseUse(Outcome.Removal, "Do you wish to exile the card from the top of your library?", game)) { + if (controller.chooseUse(Outcome.Removal, "Do you wish to exile the card from the top of your library?", source, game)) { controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); } else { game.informPlayers(controller.getLogName() + " puts the card back on top of their library."); diff --git a/Mage.Sets/src/mage/sets/shadowmoor/PutAway.java b/Mage.Sets/src/mage/sets/shadowmoor/PutAway.java index e54f35ad63..df636326b3 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/PutAway.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/PutAway.java @@ -101,7 +101,7 @@ class PutAwayEffect extends OneShotEffect { } if (you != null) { if (card != null - && you.chooseUse(Outcome.Benefit, "Do you wish to shuffle up to one target card from your graveyard into your library?", game) + && you.chooseUse(Outcome.Benefit, "Do you wish to shuffle up to one target card from your graveyard into your library?", source, game) && game.getState().getZone(card.getId()).match(Zone.GRAVEYARD)) { card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); you.shuffleLibrary(game); diff --git a/Mage.Sets/src/mage/sets/shadowmoor/Tyrannize.java b/Mage.Sets/src/mage/sets/shadowmoor/Tyrannize.java index cc9985ed41..12451e7b89 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/Tyrannize.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/Tyrannize.java @@ -91,7 +91,7 @@ class TyrannizeEffect extends OneShotEffect { if (player != null) { Cost cost = new PayLifeCost(7); if (!cost.canPay(source, source.getSourceId(), player.getId(), game) - || !player.chooseUse(Outcome.LoseLife, "Pay 7 life?", game) + || !player.chooseUse(Outcome.LoseLife, "Pay 7 life?", source, game) || !cost.pay(source, game, source.getSourceId(), player.getId(), false)) { for (Card card : player.getHand().getCards(game)) { player.discard(card, source, game); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/AdNauseam.java b/Mage.Sets/src/mage/sets/shardsofalara/AdNauseam.java index 492703bbd9..80ee8b645b 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/AdNauseam.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/AdNauseam.java @@ -89,7 +89,7 @@ class AdNauseamEffect extends OneShotEffect { if (controller == null || sourceCard == null) { return false; } - while (controller.chooseUse(outcome, message, game) && controller.getLibrary().size() > 0) { + while (controller.chooseUse(outcome, message, source, game) && controller.getLibrary().size() > 0) { Card card = controller.getLibrary().removeFromTop(game); if (card != null) { controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/BrilliantUltimatum.java b/Mage.Sets/src/mage/sets/shardsofalara/BrilliantUltimatum.java index 590adf790e..1f7020d841 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/BrilliantUltimatum.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/BrilliantUltimatum.java @@ -138,7 +138,7 @@ class BrilliantUltimatumEffect extends OneShotEffect { boolean choice = you.choosePile(Outcome.PlayForFree, "Which pile (play for free)?", pileOne, pileTwo, game); if (choice) { game.informPlayer(you, you.getLogName() + " chose Pile 1."); - while (!pileOne.isEmpty() && you.chooseUse(Outcome.PlayForFree, "Do you want to play a card from Pile 1?", game)) { + while (!pileOne.isEmpty() && you.chooseUse(Outcome.PlayForFree, "Do you want to play a card from Pile 1?", source, game)) { TargetCard targetExiledCard = new TargetCard(Zone.EXILED, new FilterCard()); if (you.chooseTarget(Outcome.PlayForFree, pile1, targetExiledCard, source, game)) { Card card = pile1.get(targetExiledCard.getFirstTarget(), game); @@ -157,7 +157,7 @@ class BrilliantUltimatumEffect extends OneShotEffect { } } else { game.informPlayer(you, you.getLogName() + " chose Pile 2."); - while (!pileTwo.isEmpty() && you.chooseUse(Outcome.PlayForFree, "Do you want to play a card from Pile 2?", game)) { + while (!pileTwo.isEmpty() && you.chooseUse(Outcome.PlayForFree, "Do you want to play a card from Pile 2?", source, game)) { TargetCard targetExiledCard = new TargetCard(Zone.EXILED, new FilterCard()); if (you.chooseTarget(Outcome.PlayForFree, pile2, targetExiledCard, source, game)) { Card card = pile2.get(targetExiledCard.getFirstTarget(), game); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/ClarionUltimatum.java b/Mage.Sets/src/mage/sets/shardsofalara/ClarionUltimatum.java index db50b5b57a..180c48059a 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/ClarionUltimatum.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/ClarionUltimatum.java @@ -109,7 +109,7 @@ class ClarionUltimatumEffect extends OneShotEffect { StringBuilder sb = new StringBuilder(); sb.append("Search for ").append(cardName).append(" in your library?"); - if (player.chooseUse(Outcome.PutCardInPlay, sb.toString(), game)) { + if (player.chooseUse(Outcome.PutCardInPlay, sb.toString(), source, game)) { FilterCard filter = new FilterCard("card named " + cardName); filter.add(new NamePredicate(cardName)); TargetCardInLibrary target = new TargetCardInLibrary(filter); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/CovenantOfMinds.java b/Mage.Sets/src/mage/sets/shardsofalara/CovenantOfMinds.java index e1f822f5e5..963bd22a4f 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/CovenantOfMinds.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/CovenantOfMinds.java @@ -106,7 +106,7 @@ class CovenantOfMindsEffect extends OneShotEffect { sb.append(" If you don't, those cards are put into his graveyard and he will draw five cards."); Zone zone = Zone.GRAVEYARD; - if (opponent.chooseUse(Outcome.Neutral, sb.toString(), game)) { + if (opponent.chooseUse(Outcome.Neutral, sb.toString(), source, game)) { zone = Zone.HAND; } else { player.drawCards(5, game); @@ -118,7 +118,7 @@ class CovenantOfMindsEffect extends OneShotEffect { } else { StringBuilder sb = new StringBuilder(); sb.append(player.getLogName()).append("'s library is empty? Do you want him to draw five cards?"); - if (!opponent.chooseUse(Outcome.Benefit, sb.toString(), game)) { + if (!opponent.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { player.drawCards(5, game); } } diff --git a/Mage.Sets/src/mage/sets/shardsofalara/FlameblastDragon.java b/Mage.Sets/src/mage/sets/shardsofalara/FlameblastDragon.java index 2f8ef49e6f..4b364427ca 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/FlameblastDragon.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/FlameblastDragon.java @@ -92,7 +92,7 @@ class FlameblastDragonEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); ManaCosts cost = new ManaCostsImpl("{X}{R}"); if (player != null) { - if (player.chooseUse(Outcome.Damage, "Pay " + cost.getText() + "? If you do, Flameblast Dragon deals X damage to target creature or player", game)) { + if (player.chooseUse(Outcome.Damage, "Pay " + cost.getText() + "? If you do, Flameblast Dragon deals X damage to target creature or player", source, game)) { int costX = player.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source); cost.add(new GenericManaCost(costX)); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { diff --git a/Mage.Sets/src/mage/sets/shardsofalara/GiftOfTheGargantuan.java b/Mage.Sets/src/mage/sets/shardsofalara/GiftOfTheGargantuan.java index 19a205b9b4..68c2b74275 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/GiftOfTheGargantuan.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/GiftOfTheGargantuan.java @@ -112,7 +112,7 @@ class GiftOfTheGargantuanEffect extends OneShotEffect { } player.lookAtCards("Gift of the Gargantuan", cards, game); - if ((creatureCardFound || landCardFound) && player.chooseUse(Outcome.DrawCard, "Do you wish to reveal a creature card and/or a land card and put them into your hand?", game)) { + if ((creatureCardFound || landCardFound) && player.chooseUse(Outcome.DrawCard, "Do you wish to reveal a creature card and/or a land card and put them into your hand?", source, game)) { Cards revealedCards = new CardsImpl(); TargetCard target = new TargetCard(Zone.PICK, new FilterCreatureCard("creature card to reveal and put into your hand")); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/PrinceOfThralls.java b/Mage.Sets/src/mage/sets/shardsofalara/PrinceOfThralls.java index 80f01f08aa..20d8e4118b 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/PrinceOfThralls.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/PrinceOfThralls.java @@ -142,7 +142,7 @@ class PrinceOfThrallsEffect extends OneShotEffect { Player opponent = game.getPlayer(permanent.getControllerId()); if (opponent != null && card != null && permanent != null && source.getControllerId() != null) { PayLifeCost cost = new PayLifeCost(3); - if (opponent.chooseUse(Outcome.Neutral, cost.getText() + " or " + permanent.getName() + " comes back into the battlefield under opponents control", game)) { + if (opponent.chooseUse(Outcome.Neutral, cost.getText() + " or " + permanent.getName() + " comes back into the battlefield under opponents control", source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), opponent.getId(), true)) { return true; diff --git a/Mage.Sets/src/mage/sets/stronghold/CrovaxTheCursed.java b/Mage.Sets/src/mage/sets/stronghold/CrovaxTheCursed.java index 903d9c6f3c..e52f5a3b31 100644 --- a/Mage.Sets/src/mage/sets/stronghold/CrovaxTheCursed.java +++ b/Mage.Sets/src/mage/sets/stronghold/CrovaxTheCursed.java @@ -111,7 +111,7 @@ class CrovaxTheCursedEffect extends OneShotEffect { if (controller != null) { Permanent sourceObject = (Permanent) source.getSourceObjectIfItStillExists(game); int creatures = game.getBattlefield().countAll(new FilterCreaturePermanent(), source.getControllerId(), game); - if (creatures > 0 && controller.chooseUse(outcome, "Sacrifice a creature?", game)) { + if (creatures > 0 && controller.chooseUse(outcome, "Sacrifice a creature?", source, game)) { if (new SacrificeControllerEffect(new FilterCreaturePermanent(), 1, "").apply(game, source)) { if (sourceObject != null) { sourceObject.getCounters().addCounter(CounterType.P1P1.createInstance()); diff --git a/Mage.Sets/src/mage/sets/stronghold/MoxDiamond.java b/Mage.Sets/src/mage/sets/stronghold/MoxDiamond.java index 5438cfc2f5..2f0a268e56 100644 --- a/Mage.Sets/src/mage/sets/stronghold/MoxDiamond.java +++ b/Mage.Sets/src/mage/sets/stronghold/MoxDiamond.java @@ -102,7 +102,7 @@ class MoxDiamondReplacementEffect extends ReplacementEffectImpl { TargetCardInHand target = new TargetCardInHand(new FilterLandCard()); Cost cost = new DiscardTargetCost(target); if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game) && - player.chooseUse(outcome, "Discard land? (Otherwise Mox Diamond goes to graveyard)", game) && + player.chooseUse(outcome, "Discard land? (Otherwise Mox Diamond goes to graveyard)", source, game) && player.chooseTarget(Outcome.Discard, target, source, game)){ player.discard(game.getCard(target.getFirstTarget()), source, game); return false; diff --git a/Mage.Sets/src/mage/sets/tempest/DreamCache.java b/Mage.Sets/src/mage/sets/tempest/DreamCache.java index 3a3c54336c..6d223175be 100644 --- a/Mage.Sets/src/mage/sets/tempest/DreamCache.java +++ b/Mage.Sets/src/mage/sets/tempest/DreamCache.java @@ -87,7 +87,7 @@ class DreamCacheEffect extends OneShotEffect { if (player != null) { player.drawCards(3, game); - boolean putOnTop = player.chooseUse(Outcome.Neutral, "Put cards on top?", game); + boolean putOnTop = player.chooseUse(Outcome.Neutral, "Put cards on top?", source, game); putInLibrary(player, source, game, putOnTop); putInLibrary(player, source, game, putOnTop); diff --git a/Mage.Sets/src/mage/sets/tempest/Lobotomy.java b/Mage.Sets/src/mage/sets/tempest/Lobotomy.java index 039f4ec719..38c80b5016 100644 --- a/Mage.Sets/src/mage/sets/tempest/Lobotomy.java +++ b/Mage.Sets/src/mage/sets/tempest/Lobotomy.java @@ -141,7 +141,7 @@ class LobotomyEffect extends OneShotEffect { // search cards in Library // If the player has no nonland cards in his or her hand, you can still search that player's library and have him or her shuffle it. - if (chosenCard != null || controller.chooseUse(outcome, "Search library anyway?", game)) { + if (chosenCard != null || controller.chooseUse(outcome, "Search library anyway?", source, game)) { TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards); controller.searchLibrary(targetCardsLibrary, game, targetPlayer.getId()); for(UUID cardId: targetCardsLibrary.getTargets()) { diff --git a/Mage.Sets/src/mage/sets/tempest/Magmasaur.java b/Mage.Sets/src/mage/sets/tempest/Magmasaur.java index 74139e6e26..c305535b67 100644 --- a/Mage.Sets/src/mage/sets/tempest/Magmasaur.java +++ b/Mage.Sets/src/mage/sets/tempest/Magmasaur.java @@ -109,7 +109,7 @@ class MagmasaurEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent sourceObject = (Permanent)source.getSourceObjectIfItStillExists(game); if (sourceObject != null && controller != null) { - if (controller.chooseUse(outcome, "Remove a +1/+1 counter from " + sourceObject.getLogName() + "?", game)) { + if (controller.chooseUse(outcome, "Remove a +1/+1 counter from " + sourceObject.getLogName() + "?", source, game)) { sourceObject.getCounters().removeCounter(CounterType.P1P1, 1); } else { int counters = sourceObject.getCounters().getCount(CounterType.P1P1); diff --git a/Mage.Sets/src/mage/sets/tempest/Propaganda.java b/Mage.Sets/src/mage/sets/tempest/Propaganda.java index d366094f9b..e4f36fd168 100644 --- a/Mage.Sets/src/mage/sets/tempest/Propaganda.java +++ b/Mage.Sets/src/mage/sets/tempest/Propaganda.java @@ -25,21 +25,19 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.tempest; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; @@ -50,14 +48,14 @@ import mage.players.Player; */ public class Propaganda extends CardImpl { - public Propaganda (UUID ownerId) { + public Propaganda(UUID ownerId) { super(ownerId, 80, "Propaganda", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); this.expansionSetCode = "TMP"; this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PropagandaReplacementEffect())); } - public Propaganda (final Propaganda card) { + public Propaganda(final Propaganda card) { super(card); } @@ -71,12 +69,12 @@ class PropagandaReplacementEffect extends ReplacementEffectImpl { private static final String effectText = "Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you"; - PropagandaReplacementEffect ( ) { + PropagandaReplacementEffect() { super(Duration.WhileOnBattlefield, Outcome.Neutral); staticText = effectText; } - PropagandaReplacementEffect ( PropagandaReplacementEffect effect ) { + PropagandaReplacementEffect(PropagandaReplacementEffect effect) { super(effect); } @@ -100,12 +98,11 @@ class PropagandaReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player player = game.getPlayer(event.getPlayerId()); - if ( player != null ) { + if (player != null) { ManaCostsImpl attackTax = new ManaCostsImpl("{2}"); - if ( attackTax.canPay(source, source.getSourceId(), event.getPlayerId(), game) && - player.chooseUse(Outcome.Neutral, "Pay {2} to attack player?", game) ) - { - if (attackTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId()) ) { + if (attackTax.canPay(source, source.getSourceId(), event.getPlayerId(), game) + && player.chooseUse(Outcome.Neutral, "Pay {2} to attack player?", source, game)) { + if (attackTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) { return false; } } @@ -113,7 +110,7 @@ class PropagandaReplacementEffect extends ReplacementEffectImpl { } return false; } - + @Override public PropagandaReplacementEffect copy() { return new PropagandaReplacementEffect(this); diff --git a/Mage.Sets/src/mage/sets/tempest/VhatiIlDal.java b/Mage.Sets/src/mage/sets/tempest/VhatiIlDal.java index 9e5aa3941e..5eaf3bb968 100644 --- a/Mage.Sets/src/mage/sets/tempest/VhatiIlDal.java +++ b/Mage.Sets/src/mage/sets/tempest/VhatiIlDal.java @@ -100,7 +100,7 @@ class VhatiIlDalEffect extends OneShotEffect { if (controller != null) { DynamicValue power = null; DynamicValue toughness = null; - if (controller.chooseUse(outcome, "Set power? (otherwise toughness is set)", game)) { + if (controller.chooseUse(outcome, "Set power? (otherwise toughness is set)", source, game)) { power = new StaticValue(1); } else { toughness = new StaticValue(1); diff --git a/Mage.Sets/src/mage/sets/tempestremastered/Cannibalize.java b/Mage.Sets/src/mage/sets/tempestremastered/Cannibalize.java index 6a4df481c1..937f4e7430 100644 --- a/Mage.Sets/src/mage/sets/tempestremastered/Cannibalize.java +++ b/Mage.Sets/src/mage/sets/tempestremastered/Cannibalize.java @@ -103,7 +103,7 @@ class CannibalizeEffect extends OneShotEffect { for(UUID targetId: getTargetPointer().getTargets(game, source)) { Permanent creature = game.getPermanent(targetId); if (creature != null) { - if ((count == 0 && controller.chooseUse(Outcome.Exile, "Exile " + creature.getLogName() +"?", game)) + if ((count == 0 && controller.chooseUse(Outcome.Exile, "Exile " + creature.getLogName() +"?", source, game)) || (count == 1 && !exileDone)) { controller.moveCardToExileWithInfo(creature, null, "", source.getSourceId(), game, Zone.BATTLEFIELD, true); exileDone = true; diff --git a/Mage.Sets/src/mage/sets/tenthedition/Abundance.java b/Mage.Sets/src/mage/sets/tenthedition/Abundance.java index d81ea8fd0a..767dceb20f 100644 --- a/Mage.Sets/src/mage/sets/tenthedition/Abundance.java +++ b/Mage.Sets/src/mage/sets/tenthedition/Abundance.java @@ -97,7 +97,7 @@ class AbundanceReplacementEffect extends ReplacementEffectImpl { Player player = game.getPlayer(event.getPlayerId()); if (player != null) { FilterCard filter = new FilterCard(); - if (player.chooseUse(Outcome.Benefit, "Choose land? (No = nonland)", game)) { + if (player.chooseUse(Outcome.Benefit, "Choose land? (No = nonland)", source, game)) { filter.add(new CardTypePredicate(CardType.LAND)); } else { @@ -128,7 +128,7 @@ class AbundanceReplacementEffect extends ReplacementEffectImpl { if (event.getPlayerId().equals(source.getControllerId())) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - return player.chooseUse(Outcome.Benefit, "Choose land or nonland?", game); + return player.chooseUse(Outcome.Benefit, "Choose land or nonland?", source, game); } } return false; diff --git a/Mage.Sets/src/mage/sets/tenthedition/WindbornMuse.java b/Mage.Sets/src/mage/sets/tenthedition/WindbornMuse.java index d028b292dd..e1d70ddfef 100644 --- a/Mage.Sets/src/mage/sets/tenthedition/WindbornMuse.java +++ b/Mage.Sets/src/mage/sets/tenthedition/WindbornMuse.java @@ -107,7 +107,7 @@ class WindbornMuseReplacementEffect extends ReplacementEffectImpl { if ( player != null && event.getTargetId().equals(source.getControllerId())) { ManaCostsImpl attackTax = new ManaCostsImpl("{2}"); if ( attackTax.canPay(source, source.getSourceId(), event.getPlayerId(), game) && - player.chooseUse(Outcome.Benefit, "Pay {2} to attack player?", game) ) + player.chooseUse(Outcome.Benefit, "Pay {2} to attack player?", source, game) ) { if (attackTax.payOrRollback(source, game, this.getId(), event.getPlayerId())) { return false; diff --git a/Mage.Sets/src/mage/sets/theros/PsychicIntrusion.java b/Mage.Sets/src/mage/sets/theros/PsychicIntrusion.java index d2ae49b8cc..31c62eccfc 100644 --- a/Mage.Sets/src/mage/sets/theros/PsychicIntrusion.java +++ b/Mage.Sets/src/mage/sets/theros/PsychicIntrusion.java @@ -108,7 +108,7 @@ class PsychicIntrusionExileEffect extends OneShotEffect { int cardsHand = opponent.getHand().count(filter, game); boolean fromHand = false; if (cardsGraveyard > 0 && cardsHand > 0) { - if (controller.chooseUse(Outcome.Detriment, "Exile card from opponents Hand?", game)) { + if (controller.chooseUse(Outcome.Detriment, "Exile card from opponents Hand?", source, game)) { fromHand = true; } } else { diff --git a/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java b/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java index 1a3d5084ec..eb88827dd9 100644 --- a/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java +++ b/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java @@ -116,7 +116,7 @@ class HypergenesisEffect extends OneShotEffect { } target.clearChosen(); if (target.canChoose(source.getSourceId(), currentPlayer.getId(), game) - && currentPlayer.chooseUse(outcome, "Put card from your hand to play?", game)) { + && currentPlayer.chooseUse(outcome, "Put card from your hand to play?", source, game)) { if (target.chooseTarget(outcome, currentPlayer.getId(), source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/timespiral/PardicDragon.java b/Mage.Sets/src/mage/sets/timespiral/PardicDragon.java index db3e13a78a..4e02dcd684 100644 --- a/Mage.Sets/src/mage/sets/timespiral/PardicDragon.java +++ b/Mage.Sets/src/mage/sets/timespiral/PardicDragon.java @@ -114,7 +114,7 @@ class PardicDragonEffect extends OneShotEffect { Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source)); Card sourceCard = game.getCard(source.getSourceId()); if (opponent != null && sourceCard != null) { - if (opponent.chooseUse(outcome, new StringBuilder("Put a time counter on ").append(sourceCard.getName()).append("?").toString(), game)) { + if (opponent.chooseUse(outcome, new StringBuilder("Put a time counter on ").append(sourceCard.getName()).append("?").toString(), source, game)) { sourceCard.addCounters(CounterType.TIME.createInstance(), game); } return true; diff --git a/Mage.Sets/src/mage/sets/unlimitededition/TimeVault.java b/Mage.Sets/src/mage/sets/unlimitededition/TimeVault.java index f81de7e109..422b4c0618 100644 --- a/Mage.Sets/src/mage/sets/unlimitededition/TimeVault.java +++ b/Mage.Sets/src/mage/sets/unlimitededition/TimeVault.java @@ -119,7 +119,7 @@ class TimeVaultReplacementEffect extends ReplacementEffectImpl { Player player = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(source.getSourceId()); if (player != null && permanent != null) { - if (player.chooseUse(Outcome.Untap, "Skip your turn to untap " + permanent.getName() + "?", game)) { + if (player.chooseUse(Outcome.Untap, "Skip your turn to untap " + permanent.getName() + "?", source, game)) { permanent.untap(game); game.informPlayers(player.getLogName() + " skips his or her turn to untap " + permanent.getLogName()); return true; diff --git a/Mage.Sets/src/mage/sets/urzaslegacy/SlowMotion.java b/Mage.Sets/src/mage/sets/urzaslegacy/SlowMotion.java index 0f98a4ef56..ffe52f2251 100644 --- a/Mage.Sets/src/mage/sets/urzaslegacy/SlowMotion.java +++ b/Mage.Sets/src/mage/sets/urzaslegacy/SlowMotion.java @@ -106,7 +106,7 @@ class SacrificeEquipedUnlessPaysEffect extends OneShotEffect { Permanent equipped = game.getPermanent(equipment.getAttachedTo()); Player player = game.getPlayer(equipped.getControllerId()); if (player != null && equipped != null) { - if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "? (Or " + equipped.getName() + " will be sacrificed.)", game)) { + if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "? (Or " + equipped.getName() + " will be sacrificed.)", source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), equipped.getControllerId(), false)) { return true; diff --git a/Mage.Sets/src/mage/sets/urzassaga/Catastrophe.java b/Mage.Sets/src/mage/sets/urzassaga/Catastrophe.java index 517a6bfbb0..9e24751609 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/Catastrophe.java +++ b/Mage.Sets/src/mage/sets/urzassaga/Catastrophe.java @@ -85,7 +85,7 @@ class CatastropheEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - if (controller.chooseUse(outcome, "Destroy all lands? (otherwise all creatures are destroyed)", game)) { + if (controller.chooseUse(outcome, "Destroy all lands? (otherwise all creatures are destroyed)", source, game)) { for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterLandPermanent(), controller.getId(), source.getSourceId(), game)) { permanent.destroy(source.getSourceId(), game, permanent.getCardType().contains(CardType.CREATURE)); } diff --git a/Mage.Sets/src/mage/sets/urzassaga/CopperGnomes.java b/Mage.Sets/src/mage/sets/urzassaga/CopperGnomes.java index f9a351faed..2971de2eda 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/CopperGnomes.java +++ b/Mage.Sets/src/mage/sets/urzassaga/CopperGnomes.java @@ -95,7 +95,7 @@ class PutArtifactOnBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutCardInPlay, choiceText, game)) { + if (player == null || !player.chooseUse(Outcome.PutCardInPlay, choiceText, source, game)) { return false; } diff --git a/Mage.Sets/src/mage/sets/urzassaga/Fecundity.java b/Mage.Sets/src/mage/sets/urzassaga/Fecundity.java index 488fa3ab47..f5d5f95917 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/Fecundity.java +++ b/Mage.Sets/src/mage/sets/urzassaga/Fecundity.java @@ -86,7 +86,7 @@ class FecundityEffect extends OneShotEffect { if (permanent != null) { Player controller = game.getPlayer(permanent.getControllerId()); if (controller != null) { - if (controller.chooseUse(outcome, "Draw a card?", game)) { + if (controller.chooseUse(outcome, "Draw a card?", source, game)) { controller.drawCards(1, game); } return true; diff --git a/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java b/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java index b347b38e6a..21b6a65168 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java +++ b/Mage.Sets/src/mage/sets/urzassaga/ShowAndTell.java @@ -109,7 +109,7 @@ class ShowAndTellEffect extends OneShotEffect { for(UUID playerId: game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - if (player.chooseUse(outcome, "Put an artifact, creature, enchantment, or land card from hand onto the battlefield?", game)) { + if (player.chooseUse(outcome, "Put an artifact, creature, enchantment, or land card from hand onto the battlefield?", source, game)) { target.clearChosen(); if (player.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/urzassaga/SneakAttack.java b/Mage.Sets/src/mage/sets/urzassaga/SneakAttack.java index c06fc177a5..1b447cb9f4 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/SneakAttack.java +++ b/Mage.Sets/src/mage/sets/urzassaga/SneakAttack.java @@ -99,7 +99,7 @@ class SneakAttackEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - if (player.chooseUse(Outcome.PutCreatureInPlay, choiceText, game)) { + if (player.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard()); if (player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/vintagemasters/Eureka.java b/Mage.Sets/src/mage/sets/vintagemasters/Eureka.java index 6d6d850e44..1900a95d1f 100644 --- a/Mage.Sets/src/mage/sets/vintagemasters/Eureka.java +++ b/Mage.Sets/src/mage/sets/vintagemasters/Eureka.java @@ -104,7 +104,7 @@ class EurekaEffect extends OneShotEffect { target.clearChosen(); if (target.canChoose(source.getSourceId(), currentPlayer.getId(), game) - && currentPlayer.chooseUse(outcome, "Put permanent from your hand to play?", game)) { + && currentPlayer.chooseUse(outcome, "Put permanent from your hand to play?", source, game)) { if (target.chooseTarget(outcome, currentPlayer.getId(), source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/vintagemasters/NorwoodPriestess.java b/Mage.Sets/src/mage/sets/vintagemasters/NorwoodPriestess.java index 0c0e924ea3..423afe9b1c 100644 --- a/Mage.Sets/src/mage/sets/vintagemasters/NorwoodPriestess.java +++ b/Mage.Sets/src/mage/sets/vintagemasters/NorwoodPriestess.java @@ -104,7 +104,7 @@ class NorwoodPriestessEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, choiceText, game)) { + if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { return false; } diff --git a/Mage.Sets/src/mage/sets/vintagemasters/PleaForPower.java b/Mage.Sets/src/mage/sets/vintagemasters/PleaForPower.java index 1561a1a2ff..76d1b0032a 100644 --- a/Mage.Sets/src/mage/sets/vintagemasters/PleaForPower.java +++ b/Mage.Sets/src/mage/sets/vintagemasters/PleaForPower.java @@ -87,7 +87,7 @@ class PleaForPowerEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - if (player.chooseUse(Outcome.ExtraTurn, "Choose time?", game)) { + if (player.chooseUse(Outcome.ExtraTurn, "Choose time?", source, game)) { timeCount++; game.informPlayers(player.getLogName() + " has chosen: time"); } else { diff --git a/Mage.Sets/src/mage/sets/visions/ElephantGrass.java b/Mage.Sets/src/mage/sets/visions/ElephantGrass.java index bbbe371753..2c10185b73 100644 --- a/Mage.Sets/src/mage/sets/visions/ElephantGrass.java +++ b/Mage.Sets/src/mage/sets/visions/ElephantGrass.java @@ -126,7 +126,7 @@ class ElephantGrassReplacementEffect2 extends ReplacementEffectImpl { if ( player != null && event.getTargetId().equals(source.getControllerId())) { ManaCostsImpl attackCost = new ManaCostsImpl("{2}"); if ( attackCost.canPay(source, source.getSourceId(), event.getPlayerId(), game) && - player.chooseUse(Outcome.Benefit, "Pay {2} to attack player?", game) ) { + player.chooseUse(Outcome.Benefit, "Pay {2} to attack player?", source, game) ) { if (attackCost.payOrRollback(source, game, this.getId(), event.getPlayerId())) { return false; } diff --git a/Mage.Sets/src/mage/sets/visions/PhyrexianMarauder.java b/Mage.Sets/src/mage/sets/visions/PhyrexianMarauder.java index 0fa8143600..6d13d24901 100644 --- a/Mage.Sets/src/mage/sets/visions/PhyrexianMarauder.java +++ b/Mage.Sets/src/mage/sets/visions/PhyrexianMarauder.java @@ -141,7 +141,7 @@ class PhyrexianMarauderPayEffect extends ReplacementEffectImpl { } ManaCostsImpl attackTax = new ManaCostsImpl<>("{" + xValue + "}"); if (attackTax.canPay(source, source.getSourceId(), event.getPlayerId(), game) - && player.chooseUse(Outcome.Neutral, chooseText, game)) { + && player.chooseUse(Outcome.Neutral, chooseText, source, game)) { if (attackTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) { return false; } diff --git a/Mage.Sets/src/mage/sets/visions/WandOfDenial.java b/Mage.Sets/src/mage/sets/visions/WandOfDenial.java index 1ccd7901d5..d694a55cd6 100644 --- a/Mage.Sets/src/mage/sets/visions/WandOfDenial.java +++ b/Mage.Sets/src/mage/sets/visions/WandOfDenial.java @@ -98,7 +98,7 @@ class WandOfDenialEffect extends OneShotEffect { if (!card.getCardType().contains(CardType.LAND) && controller.canPayLifeCost() && controller.getLife() >= 2 - && controller.chooseUse(Outcome.Neutral, "Pay 2 life to put " + card.getLogName() + " into graveyard?", game)) { + && controller.chooseUse(Outcome.Neutral, "Pay 2 life to put " + card.getLogName() + " into graveyard?", source, game)) { controller.loseLife(2, game); controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game); } diff --git a/Mage.Sets/src/mage/sets/weatherlight/LlanowarSentinel.java b/Mage.Sets/src/mage/sets/weatherlight/LlanowarSentinel.java index 840ab9ae1d..bf5a00bb21 100644 --- a/Mage.Sets/src/mage/sets/weatherlight/LlanowarSentinel.java +++ b/Mage.Sets/src/mage/sets/weatherlight/LlanowarSentinel.java @@ -92,7 +92,7 @@ class LlanowarSentinelEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if(player != null) { - if(player.chooseUse(Outcome.BoostCreature, "Do you want to to pay {1}{G}?", game)) { + if(player.chooseUse(Outcome.BoostCreature, "Do you want to to pay {1}{G}?", source, game)) { Cost cost = new ManaCostsImpl("{1}{G}"); if(cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { FilterCard filter = new FilterCard("card named Llanowar Sentinel"); diff --git a/Mage.Sets/src/mage/sets/weatherlight/Tariff.java b/Mage.Sets/src/mage/sets/weatherlight/Tariff.java index 5c9b110948..f3ec4cd417 100644 --- a/Mage.Sets/src/mage/sets/weatherlight/Tariff.java +++ b/Mage.Sets/src/mage/sets/weatherlight/Tariff.java @@ -117,7 +117,7 @@ class TariffEffect extends OneShotEffect { ManaCost manaCost = CardUtil.removeVariableManaCost(creatureToPayFor.getManaCost()); String message = new StringBuilder("Pay ").append(manaCost.getText()).append(" (otherwise sacrifice ") .append(creatureToPayFor.getName()).append(")?").toString(); - if (player.chooseUse(Outcome.Benefit, message, game)) { + if (player.chooseUse(Outcome.Benefit, message, source, game)) { if (manaCost.pay(source, game, source.getSourceId(), player.getId(), false)) { game.informPlayers(new StringBuilder(sourceObject != null ? sourceObject.getName() : "") .append(": ").append(player.getLogName()).append(" has paid").toString()); diff --git a/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java b/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java index a2d920cfae..77ae649901 100644 --- a/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java +++ b/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java @@ -122,7 +122,7 @@ class JaceTheMindSculptorEffect1 extends OneShotEffect { Cards cards = new CardsImpl(); cards.add(card); controller.lookAtCards("Jace, the Mind Sculptor", cards, game); - if (controller.chooseUse(outcome, "Do you wish to put card on the bottom of player's library?", game)) { + if (controller.chooseUse(outcome, "Do you wish to put card on the bottom of player's library?", source, game)) { controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, false, false); } else { game.informPlayers(controller.getLogName() + " puts the card back on top of the library."); diff --git a/Mage.Sets/src/mage/sets/worldwake/QuestForUlasTemple.java b/Mage.Sets/src/mage/sets/worldwake/QuestForUlasTemple.java index 0a35620815..d4ae627af1 100644 --- a/Mage.Sets/src/mage/sets/worldwake/QuestForUlasTemple.java +++ b/Mage.Sets/src/mage/sets/worldwake/QuestForUlasTemple.java @@ -105,7 +105,7 @@ class QuestForUlasTempleEffect extends OneShotEffect { Cards cards = new CardsImpl(card); controller.lookAtCards(sourcePermanent.getName(), cards, game); if (card.getCardType().contains(CardType.CREATURE)) { - if (controller.chooseUse(Outcome.DrawCard, "Do you wish to reveal the creature card at the top of the library?", game)) { + if (controller.chooseUse(Outcome.DrawCard, "Do you wish to reveal the creature card at the top of the library?", source, game)) { controller.revealCards(sourcePermanent.getName(), cards, game); Permanent questForUlasTemple = game.getPermanent(source.getSourceId()); if (questForUlasTemple != null) { @@ -178,7 +178,7 @@ class QuestForUlasTempleEffect2 extends OneShotEffect { if (controller != null) { TargetCardInHand target = new TargetCardInHand(filter); if (target.canChoose(source.getSourceId(), controller.getId(), game) - &&controller.chooseUse(Outcome.PutCreatureInPlay, query, game)) { + &&controller.chooseUse(Outcome.PutCreatureInPlay, query, source, game)) { if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/worldwake/StoneforgeMystic.java b/Mage.Sets/src/mage/sets/worldwake/StoneforgeMystic.java index 714e5b4a1f..6d1f9a9bae 100644 --- a/Mage.Sets/src/mage/sets/worldwake/StoneforgeMystic.java +++ b/Mage.Sets/src/mage/sets/worldwake/StoneforgeMystic.java @@ -126,7 +126,7 @@ class StoneforgeMysticEffect extends OneShotEffect { if (controller != null) { Target target = new TargetCardInHand(filter); if (target.canChoose(source.getSourceId(), source.getControllerId(), game) - && controller.chooseUse(outcome, "Put an Equipment from your hand to battlefield?", game) + && controller.chooseUse(outcome, "Put an Equipment from your hand to battlefield?", source, game) && controller.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/worldwake/TalusPaladin.java b/Mage.Sets/src/mage/sets/worldwake/TalusPaladin.java index 792062bd19..b8fa537cf4 100644 --- a/Mage.Sets/src/mage/sets/worldwake/TalusPaladin.java +++ b/Mage.Sets/src/mage/sets/worldwake/TalusPaladin.java @@ -145,7 +145,7 @@ class TalusPaladinEffect extends OneShotEffect { if (taluspPaladin != null) { StringBuilder sb = new StringBuilder(); sb.append("Put a +1/+1 counter on Talus Paladin?"); - if (!player.chooseUse(Outcome.Benefit, sb.toString(), game)) { + if (!player.chooseUse(Outcome.Benefit, sb.toString(), source, game)) { return false; } taluspPaladin.addCounters(CounterType.P1P1.createInstance(), game); diff --git a/Mage.Sets/src/mage/sets/zendikar/ArchmageAscension.java b/Mage.Sets/src/mage/sets/zendikar/ArchmageAscension.java index dab9c4578f..0142944763 100644 --- a/Mage.Sets/src/mage/sets/zendikar/ArchmageAscension.java +++ b/Mage.Sets/src/mage/sets/zendikar/ArchmageAscension.java @@ -193,6 +193,6 @@ class ArchmageAscensionReplacementEffect extends ReplacementEffectImpl { && archmage != null && archmage.getCounters().getCount(CounterType.QUEST) >= 6 && you != null - && you.chooseUse(Outcome.Benefit, "Would you like to search your library instead of drawing a card?", game); + && you.chooseUse(Outcome.Benefit, "Would you like to search your library instead of drawing a card?", source, game); } } diff --git a/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java b/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java index e7451fd3a2..9ccf7a83cf 100644 --- a/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java +++ b/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java @@ -208,7 +208,7 @@ class ChandraAblazeEffect5 extends OneShotEffect { String message = "Play red instant or sorcery card from your graveyard without paying its mana cost?"; Set cards = player.getGraveyard().getCards(filter, game); TargetCardInGraveyard target = new TargetCardInGraveyard(filter); - while (!cards.isEmpty() && player.chooseUse(outcome, message, game)) { + while (!cards.isEmpty() && player.chooseUse(outcome, message, source, game)) { target.clearChosen(); if (player.choose(outcome, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/sets/zendikar/Electropotence.java b/Mage.Sets/src/mage/sets/zendikar/Electropotence.java index dd00e4e921..ce2b9795af 100644 --- a/Mage.Sets/src/mage/sets/zendikar/Electropotence.java +++ b/Mage.Sets/src/mage/sets/zendikar/Electropotence.java @@ -130,7 +130,7 @@ class ElectropotenceEffect extends OneShotEffect { Permanent creature = game.getPermanentOrLKIBattlefield(creatureId); Player controller = game.getPlayer(source.getControllerId()); if (creature != null && controller != null) { - if (controller.chooseUse(Outcome.Damage, "Pay {2}{R} to do the damage?", game)) { + if (controller.chooseUse(Outcome.Damage, "Pay {2}{R} to do the damage?", source, game)) { // if (controller.chooseUse(Outcome.Damage, "Pay {2}{R}? If you do, " + creature.getName() + " deals damage equal to its power to target creature or player.", game)) { ManaCosts manaCosts = new ManaCostsImpl("{2}{R}"); if (manaCosts.pay(source, game, source.getSourceId(), controller.getId(), false)) { diff --git a/Mage.Sets/src/mage/sets/zendikar/ExplorersScope.java b/Mage.Sets/src/mage/sets/zendikar/ExplorersScope.java index f4733ff67b..7ced325384 100644 --- a/Mage.Sets/src/mage/sets/zendikar/ExplorersScope.java +++ b/Mage.Sets/src/mage/sets/zendikar/ExplorersScope.java @@ -104,7 +104,7 @@ class ExplorersScopeEffect extends OneShotEffect { controller.lookAtCards(sourceObject.getIdName(), cards, game); if (card.getCardType().contains(CardType.LAND)) { String message = "Put " + card.getLogName() + " onto the battlefield tapped?"; - if (controller.chooseUse(Outcome.PutLandInPlay, message, game)) { + if (controller.chooseUse(Outcome.PutLandInPlay, message, source, game)) { card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId(), true); } } diff --git a/Mage.Sets/src/mage/sets/zendikar/HellkiteCharger.java b/Mage.Sets/src/mage/sets/zendikar/HellkiteCharger.java index 503f7f9ab3..9586ec1a36 100644 --- a/Mage.Sets/src/mage/sets/zendikar/HellkiteCharger.java +++ b/Mage.Sets/src/mage/sets/zendikar/HellkiteCharger.java @@ -97,7 +97,7 @@ class HellkiteChargerEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (player != null) { ManaCosts cost = new ManaCostsImpl("{5}{R}{R}"); - if (player.chooseUse(Outcome.Damage, "Pay " + cost.getText() + "?", game)) { + if (player.chooseUse(Outcome.Damage, "Pay " + cost.getText() + "?", source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { new UntapAllControllerEffect(new FilterAttackingCreature(),"").apply(game, source); diff --git a/Mage.Sets/src/mage/sets/zendikar/LorthosTheTidemaker.java b/Mage.Sets/src/mage/sets/zendikar/LorthosTheTidemaker.java index 8fa56dd5e0..d6f4e02af7 100644 --- a/Mage.Sets/src/mage/sets/zendikar/LorthosTheTidemaker.java +++ b/Mage.Sets/src/mage/sets/zendikar/LorthosTheTidemaker.java @@ -102,7 +102,7 @@ class LorthosTheTideMakerEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (player != null) { Cost cost = new ManaCostsImpl("{8}"); - if (player.chooseUse(Outcome.Tap, "Pay " + cost.getText() + " and " + staticText, game)) { + if (player.chooseUse(Outcome.Tap, "Pay " + cost.getText() + " and " + staticText, source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { for (UUID target : this.targetPointer.getTargets(game, source)) { diff --git a/Mage.Tests/src/test/java/org/mage/test/player/RandomPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/RandomPlayer.java index 148c3c3497..5cfb1bafde 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/RandomPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/RandomPlayer.java @@ -346,7 +346,7 @@ public class RandomPlayer extends ComputerPlayer { } @Override - public boolean chooseUse(Outcome outcome, String message, Game game) { + public boolean chooseUse(Outcome outcome, String message, Ability source, Game game) { return rnd.nextBoolean(); } 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 e694401346..b0904aeb2c 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 @@ -793,7 +793,7 @@ public class TestPlayer implements Player { } @Override - public boolean chooseUse(Outcome outcome, String message, Game game) { + public boolean chooseUse(Outcome outcome, String message, Ability source, Game game) { if (!choices.isEmpty()) { if (choices.get(0).equals("No")) { choices.remove(0); diff --git a/Mage/src/mage/MageObjectImpl.java b/Mage/src/mage/MageObjectImpl.java index 1d0c6400bc..f9402ad3df 100644 --- a/Mage/src/mage/MageObjectImpl.java +++ b/Mage/src/mage/MageObjectImpl.java @@ -104,7 +104,7 @@ public abstract class MageObjectImpl implements MageObject { @Override public String getLogName() { - return GameLog.getColoredObjectName(this); + return GameLog.getColoredObjectIdName(this); } @Override diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index ad2bf78df8..a255e8a0c4 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -346,7 +346,7 @@ public abstract class AbilityImpl implements Ability { for (Cost cost : optionalCosts) { if (cost instanceof ManaCost) { cost.clearPaid(); - if (controller.chooseUse(Outcome.Benefit, "Pay optional cost " + cost.getText() + "?", game)) { + if (controller.chooseUse(Outcome.Benefit, "Pay optional cost " + cost.getText() + "?", this, game)) { manaCostsToPay.add((ManaCost) cost); } } @@ -576,7 +576,7 @@ public abstract class AbilityImpl implements Ability { protected boolean useAlternativeCost(Game game) { for (AlternativeCost cost : alternativeCosts) { if (cost.isAvailable(game, this)) { - if (game.getPlayer(this.controllerId).chooseUse(Outcome.Neutral, "Use alternative cost " + cost.getName(), game)) { + if (game.getPlayer(this.controllerId).chooseUse(Outcome.Neutral, "Use alternative cost " + cost.getName(), this, game)) { return cost.pay(this, game, sourceId, controllerId, false); } } @@ -1013,9 +1013,9 @@ public abstract class AbilityImpl implements Ability { if (object instanceof StackAbility) { Card card = game.getCard(((StackAbility) object).getSourceId()); if (card != null) { - sb.append(GameLog.getColoredObjectName(card)); + sb.append(GameLog.getColoredObjectIdName(card)); } else { - sb.append(GameLog.getColoredObjectName(object)); + sb.append(GameLog.getColoredObjectIdName(object)); } } else { if (object instanceof Spell) { @@ -1027,7 +1027,7 @@ public abstract class AbilityImpl implements Ability { } sb.append(getOptionalTextSuffix(game, spell)); } else { - sb.append(GameLog.getColoredObjectName(object)); + sb.append(GameLog.getColoredObjectIdName(object)); } } } else { diff --git a/Mage/src/mage/abilities/TriggeredAbilityImpl.java b/Mage/src/mage/abilities/TriggeredAbilityImpl.java index c07195414b..78745f0f5c 100644 --- a/Mage/src/mage/abilities/TriggeredAbilityImpl.java +++ b/Mage/src/mage/abilities/TriggeredAbilityImpl.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.abilities; import java.util.UUID; @@ -80,24 +79,19 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge // TODO: Implement for all TriggeredAbilities so this default method can be removed /*@Override - public boolean checkEventType(GameEvent event, Game game) { - return true; - }*/ - + public boolean checkEventType(GameEvent event, Game game) { + return true; + }*/ @Override public boolean resolve(Game game) { - MageObject object = game.getObject(sourceId); if (optional) { + MageObject object = game.getObject(getSourceId()); Player player = game.getPlayer(this.getControllerId()); - StringBuilder sb = new StringBuilder(); - if (object != null) { - sb.append("Use the following ability from ").append(object.getLogName()).append("? "); - sb.append(this.getRule(object.getLogName())); - } - else { - sb.append("Use the following ability? ").append(this.getRule()); - } - if (!player.chooseUse(getEffects().get(0).getOutcome(), sb.toString(), game)) { + if (player != null) { + if (!player.chooseUse(getEffects().get(0).getOutcome(), (object != null ? this.getRule(object.getLogName()) : this.getRule()), this, game)) { + return false; + } + } else { return false; } } @@ -116,11 +110,11 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge sb.append("Ability triggers: ").append(object.getLogName()).append(" - ").append(this.getRule(object.getLogName())); } else { sb.append("Ability triggers: ").append(this.getRule()); - } + } String targetText = getTargetDescriptionForLog(getTargets(), game); if (!targetText.isEmpty()) { sb.append(" - ").append(targetText); - } + } return sb.toString(); } @@ -162,18 +156,22 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge @Override public boolean isInUseableZone(Game game, MageObject source, GameEvent event) { - + /** - * 603.6. Trigger events that involve objects changing zones are called “zone-change triggers.” - * Many abilities with zone-change triggers attempt to do something to that object after it - * changes zones. During resolution, these abilities look for the object in the zone that - * it moved to. If the object is unable to be found in the zone it went to, the part of the - * ability attempting to do something to the object will fail to do anything. The ability could - * be unable to find the object because the object never entered the specified zone, because it - * left the zone before the ability resolved, or because it is in a zone that is hidden from - * a player, such as a library or an opponent’s hand. (This rule applies even if the object - * leaves the zone and returns again before the ability resolves.) The most common zone-change - * triggers are enters-the-battlefield triggers and leaves-the-battlefield triggers. + * 603.6. Trigger events that involve objects changing zones are called + * “zone-change triggers.” Many abilities with zone-change triggers + * attempt to do something to that object after it changes zones. During + * resolution, these abilities look for the object in the zone that it + * moved to. If the object is unable to be found in the zone it went to, + * the part of the ability attempting to do something to the object will + * fail to do anything. The ability could be unable to find the object + * because the object never entered the specified zone, because it left + * the zone before the ability resolved, or because it is in a zone that + * is hidden from a player, such as a library or an opponent’s hand. + * (This rule applies even if the object leaves the zone and returns + * again before the ability resolves.) The most common zone-change + * triggers are enters-the-battlefield triggers and + * leaves-the-battlefield triggers. */ if (event != null && event.getTargetId() != null && event.getTargetId().equals(getSourceId())) { switch (event.getType()) { @@ -182,18 +180,18 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge if (event.getType().equals(EventType.DESTROYED_PERMANENT)) { source = game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD); } else { - if (((ZoneChangeEvent)event).getTarget() != null) { - source = ((ZoneChangeEvent)event).getTarget(); - } else { - source = game.getLastKnownInformation(getSourceId(), ((ZoneChangeEvent)event).getZone()); + if (((ZoneChangeEvent) event).getTarget() != null) { + source = ((ZoneChangeEvent) event).getTarget(); + } else { + source = game.getLastKnownInformation(getSourceId(), ((ZoneChangeEvent) event).getZone()); } } - + case PHASED_OUT: case PHASED_IN: - if (this.zone == Zone.ALL || game.getLastKnownInformation(getSourceId(), zone) != null) { - return this.hasSourceObjectAbility(game, source, event); - } + if (this.zone == Zone.ALL || game.getLastKnownInformation(getSourceId(), zone) != null) { + return this.hasSourceObjectAbility(game, source, event); + } } } return super.isInUseableZone(game, source, event); diff --git a/Mage/src/mage/abilities/abilityword/KinshipAbility.java b/Mage/src/mage/abilities/abilityword/KinshipAbility.java index d040323225..82716be27d 100644 --- a/Mage/src/mage/abilities/abilityword/KinshipAbility.java +++ b/Mage/src/mage/abilities/abilityword/KinshipAbility.java @@ -127,7 +127,7 @@ class KinshipBaseEffect extends OneShotEffect { Cards cards = new CardsImpl(card); controller.lookAtCards(sourcePermanent.getName(), cards, game); if (CardUtil.shareSubtypes(sourcePermanent, card)) { - if (controller.chooseUse(outcome,new StringBuilder("Kinship - Reveal ").append(card.getLogName()).append("?").toString(), game)) { + if (controller.chooseUse(outcome,new StringBuilder("Kinship - Reveal ").append(card.getLogName()).append("?").toString(), source, game)) { controller.revealCards(sourcePermanent.getName(), cards, game); for (Effect effect: kinshipEffects) { effect.setTargetPointer(new FixedTarget(card.getId())); diff --git a/Mage/src/mage/abilities/common/PutIntoGraveFromAnywhereSourceAbility.java b/Mage/src/mage/abilities/common/PutIntoGraveFromAnywhereSourceAbility.java index f0f56848cb..625a5e1364 100644 --- a/Mage/src/mage/abilities/common/PutIntoGraveFromAnywhereSourceAbility.java +++ b/Mage/src/mage/abilities/common/PutIntoGraveFromAnywhereSourceAbility.java @@ -148,7 +148,7 @@ class PutIntoGraveFromAnywhereEffect extends ReplacementEffectImpl { if (controller == null || object == null) { return false; } - if (!controller.chooseUse(outcome, new StringBuilder("Use effect of ").append(object.getLogName()).append("?").toString(), game)) { + if (!controller.chooseUse(outcome, new StringBuilder("Use effect of ").append(object.getLogName()).append("?").toString(), source, game)) { return false; } } diff --git a/Mage/src/mage/abilities/common/delayed/PactDelayedTriggeredAbility.java b/Mage/src/mage/abilities/common/delayed/PactDelayedTriggeredAbility.java index e6564c2cc0..e922c99382 100644 --- a/Mage/src/mage/abilities/common/delayed/PactDelayedTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/delayed/PactDelayedTriggeredAbility.java @@ -98,7 +98,7 @@ class PactEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "?", game)) { + if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + "?", source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)){ return true; diff --git a/Mage/src/mage/abilities/costs/AlternativeCostSourceAbility.java b/Mage/src/mage/abilities/costs/AlternativeCostSourceAbility.java index a041c5cec2..adad581065 100644 --- a/Mage/src/mage/abilities/costs/AlternativeCostSourceAbility.java +++ b/Mage/src/mage/abilities/costs/AlternativeCostSourceAbility.java @@ -70,12 +70,14 @@ public class AlternativeCostSourceAbility extends StaticAbility implements Alter } /** - * + * * @param cost alternate cost to pay - * @param condition only if the condition is true it's possible to use the alternate costs + * @param condition only if the condition is true it's possible to use the + * alternate costs * @param rule if != null used as rule text * @param filter filters the cards this alternate cost can be applied to - * @param onlyMana if true only the mana costs are replaced by this costs, other costs stay untouched + * @param onlyMana if true only the mana costs are replaced by this costs, + * other costs stay untouched */ public AlternativeCostSourceAbility(Cost cost, Condition condition, String rule, FilterCard filter, boolean onlyMana) { super(Zone.ALL, null); @@ -86,7 +88,7 @@ public class AlternativeCostSourceAbility extends StaticAbility implements Alter this.filter = filter; this.onlyMana = onlyMana; } - + public AlternativeCostSourceAbility(Condition condition, String rule, FilterCard filter, boolean onlyMana, DynamicCost dynamicCost) { super(Zone.ALL, null); this.setRuleAtTheTop(true); @@ -109,14 +111,14 @@ public class AlternativeCostSourceAbility extends StaticAbility implements Alter @Override public void addCost(Cost cost) { - AlternativeCost2 alternativeCost = convertToAlternativeCost(cost); - if(alternativeCost != null) { - this.alternateCosts.add(alternativeCost); - } + AlternativeCost2 alternativeCost = convertToAlternativeCost(cost); + if (alternativeCost != null) { + this.alternateCosts.add(alternativeCost); + } } private AlternativeCost2 convertToAlternativeCost(Cost cost) { - return cost != null ? new AlternativeCost2Impl(null, cost.getText(), cost) : null; + return cost != null ? new AlternativeCost2Impl(null, cost.getText(), cost) : null; } @Override @@ -143,26 +145,25 @@ public class AlternativeCostSourceAbility extends StaticAbility implements Alter } Player player = game.getPlayer(ability.getControllerId()); if (player != null) { - Costs alternativeCosts; - if(dynamicCost != null) { - alternativeCosts = new CostsImpl<>(); - alternativeCosts.add(convertToAlternativeCost(dynamicCost.getCost(ability, game))); - } else { - alternativeCosts = this.alternateCosts; - } - - String costChoiceText; - if(dynamicCost != null) { - costChoiceText = dynamicCost.getText(ability, game); - } else { - costChoiceText = alternativeCosts.isEmpty() ? "Cast without paying its mana cost?" : "Pay alternative costs? (" + alternativeCosts.getText() +")"; - } - - - if (alternativeCosts.canPay(ability, ability.getSourceId(), ability.getControllerId(), game) && - player.chooseUse(Outcome.Benefit, costChoiceText, game)) { + Costs alternativeCosts; + if (dynamicCost != null) { + alternativeCosts = new CostsImpl<>(); + alternativeCosts.add(convertToAlternativeCost(dynamicCost.getCost(ability, game))); + } else { + alternativeCosts = this.alternateCosts; + } + + String costChoiceText; + if (dynamicCost != null) { + costChoiceText = dynamicCost.getText(ability, game); + } else { + costChoiceText = alternativeCosts.isEmpty() ? "Cast without paying its mana cost?" : "Pay alternative costs? (" + alternativeCosts.getText() + ")"; + } + + if (alternativeCosts.canPay(ability, ability.getSourceId(), ability.getControllerId(), game) + && player.chooseUse(Outcome.Benefit, costChoiceText, this, game)) { ability.getManaCostsToPay().clear(); - if(!onlyMana) { + if (!onlyMana) { ability.getCosts().clear(); } for (Cost cost : alternativeCosts) { @@ -189,13 +190,13 @@ public class AlternativeCostSourceAbility extends StaticAbility implements Alter @Override public boolean isActivated(Ability source, Game game) { - Costs alternativeCosts; - if(dynamicCost != null) { - alternativeCosts = new CostsImpl<>(); - alternativeCosts.add(convertToAlternativeCost(dynamicCost.getCost(source, game))); - } else { - alternativeCosts = this.alternateCosts; - } + Costs alternativeCosts; + if (dynamicCost != null) { + alternativeCosts = new CostsImpl<>(); + alternativeCosts.add(convertToAlternativeCost(dynamicCost.getCost(source, game))); + } else { + alternativeCosts = this.alternateCosts; + } for (AlternativeCost2 cost : alternativeCosts) { if (cost.isActivated(game)) { return true; @@ -206,7 +207,7 @@ public class AlternativeCostSourceAbility extends StaticAbility implements Alter @Override public String getCastMessageSuffix(Game game) { - return alternateCosts.isEmpty() ? " without paying it's mana costs":" using alternative casting costs"; + return alternateCosts.isEmpty() ? " without paying it's mana costs" : " using alternative casting costs"; } @Override @@ -227,7 +228,7 @@ public class AlternativeCostSourceAbility extends StaticAbility implements Alter } int numberCosts = 0; String remarkText = ""; - for (AlternativeCost2 alternativeCost : alternateCosts) { + for (AlternativeCost2 alternativeCost : alternateCosts) { if (numberCosts == 0) { if (alternativeCost.getCost() instanceof ManaCost) { sb.append("pay "); @@ -261,5 +262,5 @@ public class AlternativeCostSourceAbility extends StaticAbility implements Alter alterCosts.addAll(alternateCosts); return alterCosts; } - + } diff --git a/Mage/src/mage/abilities/costs/OrCost.java b/Mage/src/mage/abilities/costs/OrCost.java index 92d3499887..2c5a7740e7 100644 --- a/Mage/src/mage/abilities/costs/OrCost.java +++ b/Mage/src/mage/abilities/costs/OrCost.java @@ -1,35 +1,33 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.abilities.costs; import java.util.UUID; - import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCost; import mage.constants.Outcome; @@ -37,13 +35,8 @@ import mage.game.Game; import mage.players.Player; import mage.target.Targets; -/** - * - * @author LevelX2 - */ - - public class OrCost implements Cost { + private Cost firstCost; private Cost secondCost; private String description; @@ -92,12 +85,12 @@ public class OrCost implements Cost { if (selectedCost == null) { Player controller = game.getPlayer(controllerId); if (controller != null) { - StringBuilder sb = new StringBuilder(); + StringBuilder sb = new StringBuilder(); if (firstCost instanceof ManaCost) { sb.append("Pay "); } sb.append(firstCost.getText()).append("?"); - if (controller.chooseUse(Outcome.Detriment, sb.toString(), game)) { + if (controller.chooseUse(Outcome.Detriment, sb.toString(), ability, game)) { selectedCost = firstCost; } else { selectedCost = secondCost; diff --git a/Mage/src/mage/abilities/costs/common/RevealTargetFromHandCost.java b/Mage/src/mage/abilities/costs/common/RevealTargetFromHandCost.java index 23c0fd4333..492a07fff1 100644 --- a/Mage/src/mage/abilities/costs/common/RevealTargetFromHandCost.java +++ b/Mage/src/mage/abilities/costs/common/RevealTargetFromHandCost.java @@ -29,12 +29,13 @@ package mage.abilities.costs.common; import java.util.UUID; -import mage.constants.Outcome; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.costs.CostImpl; import mage.cards.Card; import mage.cards.Cards; import mage.cards.CardsImpl; +import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInHand; @@ -46,7 +47,7 @@ public class RevealTargetFromHandCost extends CostImpl { public RevealTargetFromHandCost(TargetCardInHand target) { this.addTarget(target); - this.text = (target.getNumberOfTargets() == 0 ?"you may ":"") + "reveal " + target.getTargetName(); + this.text = (target.getNumberOfTargets() == 0 ? "you may " : "") + "reveal " + target.getTargetName(); } public RevealTargetFromHandCost(final RevealTargetFromHandCost cost) { @@ -70,8 +71,9 @@ public class RevealTargetFromHandCost extends CostImpl { cards.add(card); } } - if (numberCardsRevealed > 0 ) { - player.revealCards("card cost", cards, game); + if (numberCardsRevealed > 0) { + MageObject baseObject = game.getBaseObject(sourceId); + player.revealCards(baseObject == null ? "card cost" : baseObject.getIdName(), cards, game); } if (targets.get(0).getNumberOfTargets() <= numberCardsRevealed) { paid = true; // e.g. for optional additional costs. example: Dragonlord's Prerogative also true if 0 cards shown diff --git a/Mage/src/mage/abilities/decorator/ConditionalRestrictionEffect.java b/Mage/src/mage/abilities/decorator/ConditionalRestrictionEffect.java index d829e3a85b..20ae54c777 100644 --- a/Mage/src/mage/abilities/decorator/ConditionalRestrictionEffect.java +++ b/Mage/src/mage/abilities/decorator/ConditionalRestrictionEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.decorator; import mage.abilities.Ability; @@ -42,8 +41,7 @@ import mage.game.permanent.Permanent; * * @author LevelX2 */ - -public class ConditionalRestrictionEffect extends RestrictionEffect { +public class ConditionalRestrictionEffect extends RestrictionEffect { protected RestrictionEffect effect; protected RestrictionEffect otherwiseEffect; @@ -55,7 +53,7 @@ public class ConditionalRestrictionEffect extends RestrictionEffect { public ConditionalRestrictionEffect(RestrictionEffect effect, Condition condition) { this(Duration.WhileOnBattlefield, effect, condition, null); } - + public ConditionalRestrictionEffect(Duration duration, RestrictionEffect effect, Condition condition, RestrictionEffect otherwiseEffect) { super(duration); this.effectType = EffectType.RESTRICTION; @@ -93,7 +91,6 @@ public class ConditionalRestrictionEffect extends RestrictionEffect { initDone = true; } - @Override public boolean applies(Permanent permanent, Ability source, Game game) { if (!initDone) { // if simpleStaticAbility, init won't be called @@ -102,7 +99,7 @@ public class ConditionalRestrictionEffect extends RestrictionEffect { conditionState = condition.apply(game, source); if (conditionState) { effect.setTargetPointer(this.targetPointer); - return effect.applies(permanent, source,game); + return effect.applies(permanent, source, game); } else if (otherwiseEffect != null) { otherwiseEffect.setTargetPointer(this.targetPointer); return otherwiseEffect.applies(permanent, source, game); @@ -147,11 +144,11 @@ public class ConditionalRestrictionEffect extends RestrictionEffect { } @Override - public boolean canBeUntapped(Permanent permanent, Game game) { + public boolean canBeUntapped(Permanent permanent, Ability source, Game game) { if (conditionState) { - return effect.canBeUntapped(permanent, game); + return effect.canBeUntapped(permanent, source, game); } else if (otherwiseEffect != null) { - return otherwiseEffect.canBeUntapped(permanent, game); + return otherwiseEffect.canBeUntapped(permanent, source, game); } return true; } diff --git a/Mage/src/mage/abilities/effects/AsTurnedFaceUpEffect.java b/Mage/src/mage/abilities/effects/AsTurnedFaceUpEffect.java index 9df6bf2eef..3709ad2fa2 100644 --- a/Mage/src/mage/abilities/effects/AsTurnedFaceUpEffect.java +++ b/Mage/src/mage/abilities/effects/AsTurnedFaceUpEffect.java @@ -85,7 +85,7 @@ public class AsTurnedFaceUpEffect extends ReplacementEffectImpl { if (controller == null || object == null) { return false; } - if (!controller.chooseUse(outcome, new StringBuilder("Use effect of ").append(object.getLogName()).append("?").toString(), game)) { + if (!controller.chooseUse(outcome, new StringBuilder("Use effect of ").append(object.getLogName()).append("?").toString(), source, game)) { return false; } } diff --git a/Mage/src/mage/abilities/effects/ContinuousEffects.java b/Mage/src/mage/abilities/effects/ContinuousEffects.java index 333e964da8..b19c442092 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffects.java @@ -628,7 +628,7 @@ public class ContinuousEffects implements Serializable { if (spliceAbilities.size() > 0) { Player controller = game.getPlayer(abilityToModify.getControllerId()); - if (controller.chooseUse(Outcome.Benefit, "Splice a card?", game)) { + if (controller.chooseUse(Outcome.Benefit, "Splice a card?", abilityToModify, game)) { Cards cardsToReveal = new CardsImpl(); do { FilterCard filter = new FilterCard("a card to splice"); @@ -655,7 +655,7 @@ public class ContinuousEffects implements Serializable { spliceAbilities.remove(selectedAbility); } } - } while (!spliceAbilities.isEmpty() && controller.chooseUse(Outcome.Benefit, "Splice another card?", game)); + } while (!spliceAbilities.isEmpty() && controller.chooseUse(Outcome.Benefit, "Splice another card?", abilityToModify, game)); controller.revealCards("Spliced cards", cardsToReveal, game); } } diff --git a/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java b/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java index 92dbfa7aa0..90bdfaf14c 100644 --- a/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java @@ -111,7 +111,7 @@ public class EntersBattlefieldEffect extends ReplacementEffectImpl { if (controller == null || object == null) { return false; } - if (!controller.chooseUse(outcome, new StringBuilder("Use effect of ").append(object.getLogName()).append("?").toString(), game)) { + if (!controller.chooseUse(outcome, new StringBuilder("Use effect of ").append(object.getLogName()).append("?").toString(), source, game)) { return false; } } diff --git a/Mage/src/mage/abilities/effects/PlaneswalkerRedirectionEffect.java b/Mage/src/mage/abilities/effects/PlaneswalkerRedirectionEffect.java index 2ec88278ea..7f2ee3c504 100644 --- a/Mage/src/mage/abilities/effects/PlaneswalkerRedirectionEffect.java +++ b/Mage/src/mage/abilities/effects/PlaneswalkerRedirectionEffect.java @@ -77,7 +77,7 @@ public class PlaneswalkerRedirectionEffect extends RedirectionEffect { Player player = game.getPlayer(playerId); if (target != null && player != null) { int numPlaneswalkers = game.getBattlefield().countAll(filter, target.getId(), game); - if (numPlaneswalkers > 0 && player.chooseUse(outcome, "Redirect damage to planeswalker?", game)) { + if (numPlaneswalkers > 0 && player.chooseUse(outcome, "Redirect damage to planeswalker?", source, game)) { redirectTarget = new TargetPermanent(filter); if (numPlaneswalkers == 1) { List planeswalker = game.getBattlefield().getAllActivePermanents(filter, target.getId(), game); diff --git a/Mage/src/mage/abilities/effects/RestrictionEffect.java b/Mage/src/mage/abilities/effects/RestrictionEffect.java index 87df553a36..47f89ec602 100644 --- a/Mage/src/mage/abilities/effects/RestrictionEffect.java +++ b/Mage/src/mage/abilities/effects/RestrictionEffect.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects; import java.util.UUID; @@ -48,7 +47,7 @@ public abstract class RestrictionEffect extends ContinuousEffectImpl { public RestrictionEffect(Duration duration, Outcome outcome) { super(duration, outcome); - this.effectType = EffectType.RESTRICTION; + this.effectType = EffectType.RESTRICTION; } public RestrictionEffect(final RestrictionEffect effect) { @@ -65,7 +64,7 @@ public abstract class RestrictionEffect extends ContinuousEffectImpl { public boolean canAttack(Game game) { return true; } - + public boolean canAttack(UUID defenderId, Ability source, Game game) { return true; } @@ -80,22 +79,23 @@ public abstract class RestrictionEffect extends ContinuousEffectImpl { /** * Called for all attackers after all blocking decisions are made - * + * * @param attacker * @param source * @param game - * @return true = block is ok false = block is not valid (human: back to defining blockers, AI: remove blocker) + * @return true = block is ok false = block is not valid (human: back to + * defining blockers, AI: remove blocker) */ public boolean canBeBlockedCheckAfter(Permanent attacker, Ability source, Game game) { return true; } - - public boolean canBeUntapped(Permanent permanent, Game game) { + + public boolean canBeUntapped(Permanent permanent, Ability source, Game game) { return true; } public boolean canUseActivatedAbilities(Permanent permanent, Ability source, Game game) { return true; } - + } diff --git a/Mage/src/mage/abilities/effects/common/AmplifyEffect.java b/Mage/src/mage/abilities/effects/common/AmplifyEffect.java index 2cfb394c77..a06e008ad7 100644 --- a/Mage/src/mage/abilities/effects/common/AmplifyEffect.java +++ b/Mage/src/mage/abilities/effects/common/AmplifyEffect.java @@ -109,7 +109,7 @@ public class AmplifyEffect extends ReplacementEffectImpl { filter.add(filterSubtypes.get(0)); } if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0){ - if (controller.chooseUse(outcome, "Reveal cards to Amplify?", game)) { + if (controller.chooseUse(outcome, "Reveal cards to Amplify?", source, game)) { TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter); if (controller.chooseTarget(outcome, target, source, game) && !target.getTargets().isEmpty()) { Cards cards = new CardsImpl(); diff --git a/Mage/src/mage/abilities/effects/common/CastCardFromOutsideTheGameEffect.java b/Mage/src/mage/abilities/effects/common/CastCardFromOutsideTheGameEffect.java index 8498cc29c0..5dbef2a742 100644 --- a/Mage/src/mage/abilities/effects/common/CastCardFromOutsideTheGameEffect.java +++ b/Mage/src/mage/abilities/effects/common/CastCardFromOutsideTheGameEffect.java @@ -73,7 +73,7 @@ public class CastCardFromOutsideTheGameEffect extends OneShotEffect { return false; } - while (player.chooseUse(Outcome.Benefit, choiceText, game)) { + while (player.chooseUse(Outcome.Benefit, choiceText, source, game)) { Cards cards = player.getSideboard(); if (cards.isEmpty()) { if (!game.isSimulation()) diff --git a/Mage/src/mage/abilities/effects/common/CipherEffect.java b/Mage/src/mage/abilities/effects/common/CipherEffect.java index 8bdc853a65..d4bbdb20a2 100644 --- a/Mage/src/mage/abilities/effects/common/CipherEffect.java +++ b/Mage/src/mage/abilities/effects/common/CipherEffect.java @@ -89,7 +89,7 @@ public class CipherEffect extends OneShotEffect { TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(); if (controller != null) { if (target.canChoose(source.getControllerId(), game) - && controller.chooseUse(outcome, "Cipher this spell to a creature?", game)) { + && controller.chooseUse(outcome, "Cipher this spell to a creature?", source, game)) { controller.chooseTarget(outcome, target, source, game); Card sourceCard = game.getCard(source.getSourceId()); Permanent targetCreature = game.getPermanent(target.getFirstTarget()); diff --git a/Mage/src/mage/abilities/effects/common/ClashEffect.java b/Mage/src/mage/abilities/effects/common/ClashEffect.java index 145faf5175..71b22bfa96 100644 --- a/Mage/src/mage/abilities/effects/common/ClashEffect.java +++ b/Mage/src/mage/abilities/effects/common/ClashEffect.java @@ -25,10 +25,10 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common; import java.io.ObjectStreamException; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.MageSingleton; import mage.abilities.effects.Effect; @@ -47,54 +47,72 @@ import mage.target.Target; import mage.target.common.TargetOpponent; /** - 1. The controller of the spell or ability chooses an opponent. (This doesn't target the opponent.) - 2. Each player involved in the clash reveals the top card of his or her library. - 3. The converted mana costs of the revealed cards are noted. - 4. In turn order, each player involved in the clash chooses to put his or her revealed card on either the top or bottom of his or her library. (Note that the player whose turn it is does this first, not necessarily the controller of the clash spell or ability.) When the second player makes this decision, he or she will know what the first player chose. Then all cards are moved at the same time. - 5. The clash is over. If one player in the clash revealed a card with a higher converted mana cost than all other cards revealed in the clash, that player wins the clash. - 6. If any abilities trigger when a player clashes, they trigger and wait to be put on the stack. - 7. The clash spell or ability finishes resolving. That usually involves a bonus gained by the controller of the clash spell or ability if he or she won the clash. - 8. Abilities that triggered during the clash are put on the stack. - - There are no draws or losses in a clash. Either you win it or you don't. - Each spell or ability with clash says what happens if you (the controller of that spell or ability) win the clash. Typically, if you don't win the clash, nothing happens. - If no one reveals a card with a higher converted mana cost (for example, each player reveals a card with converted mana cost 2), no one wins the clash. - An X in a revealed card's mana cost is treated as 0. - A card without a mana cost (such as a land) has a converted mana cost of 0. - If one or more of the clashing players reveals a split card, each of the split card's converted mana costs is considered individually. In this way, it's possible for multiple players to win a clash. For example, if Player A reveals a split card with converted mana costs 1 and 3, and Player B reveals a card with converted mana cost 2, they'll both win. (Player A's card has a higher converted mana cost than Player B's card, since 3 is greater than 2. Player B's card has a higher converted mana cost than Player A's card, since 2 is greater than 1.) - + * 1. The controller of the spell or ability chooses an opponent. (This doesn't + * target the opponent.) 2. Each player involved in the clash reveals the top + * card of his or her library. 3. The converted mana costs of the revealed cards + * are noted. 4. In turn order, each player involved in the clash chooses to put + * his or her revealed card on either the top or bottom of his or her library. + * (Note that the player whose turn it is does this first, not necessarily the + * controller of the clash spell or ability.) When the second player makes this + * decision, he or she will know what the first player chose. Then all cards are + * moved at the same time. 5. The clash is over. If one player in the clash + * revealed a card with a higher converted mana cost than all other cards + * revealed in the clash, that player wins the clash. 6. If any abilities + * trigger when a player clashes, they trigger and wait to be put on the stack. + * 7. The clash spell or ability finishes resolving. That usually involves a + * bonus gained by the controller of the clash spell or ability if he or she won + * the clash. 8. Abilities that triggered during the clash are put on the stack. + * + * There are no draws or losses in a clash. Either you win it or you don't. Each + * spell or ability with clash says what happens if you (the controller of that + * spell or ability) win the clash. Typically, if you don't win the clash, + * nothing happens. If no one reveals a card with a higher converted mana cost + * (for example, each player reveals a card with converted mana cost 2), no one + * wins the clash. An X in a revealed card's mana cost is treated as 0. A card + * without a mana cost (such as a land) has a converted mana cost of 0. If one + * or more of the clashing players reveals a split card, each of the split + * card's converted mana costs is considered individually. In this way, it's + * possible for multiple players to win a clash. For example, if Player A + * reveals a split card with converted mana costs 1 and 3, and Player B reveals + * a card with converted mana cost 2, they'll both win. (Player A's card has a + * higher converted mana cost than Player B's card, since 3 is greater than 2. + * Player B's card has a higher converted mana cost than Player A's card, since + * 2 is greater than 1.) + * * @author LevelX2 */ - public class ClashEffect extends OneShotEffect implements MageSingleton { - - private static final ClashEffect fINSTANCE = new ClashEffect(); + + private static final ClashEffect fINSTANCE = new ClashEffect(); private Object readResolve() throws ObjectStreamException { return fINSTANCE; - } - + } + private ClashEffect() { super(Outcome.Benefit); this.staticText = "Clash with an opponent"; } - + public static ClashEffect getInstance() { return fINSTANCE; - } + } + public ClashEffect(final ClashEffect effect) { super(effect); } - + @Override public ClashEffect copy() { return new ClashEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null && !game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.CLASH, controller.getId(), controller.getId()))) { + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null + && !game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.CLASH, controller.getId(), controller.getId()))) { // choose opponent Target target = new TargetOpponent(true); target.setTargetName("an opponent to clash with"); @@ -110,11 +128,11 @@ public class ClashEffect extends OneShotEffect implements MageSingleton { // Reveal top cards of involved players StringBuilder message = new StringBuilder("Clash: "); message.append(controller.getLogName()); - if (controller.getLibrary().size() > 0) { + if (controller.getLibrary().size() > 0) { Cards cards = new CardsImpl(); cardController = controller.getLibrary().getFromTop(game); cards.add(cardController); - controller.revealCards("for clash by " + controller.getLogName(), cards, game); + controller.revealCards(sourceObject.getIdName() + ": Clash card of " + controller.getName(), cards, game); cmcController = cardController.getManaCost().convertedManaCost(); message.append(" (").append(cmcController).append(")"); } else { @@ -125,7 +143,7 @@ public class ClashEffect extends OneShotEffect implements MageSingleton { Cards cards = new CardsImpl(); cardOpponent = opponent.getLibrary().getFromTop(game); cards.add(cardOpponent); - opponent.revealCards("for clash by " + opponent.getLogName(), cards, game); + opponent.revealCards(sourceObject.getIdName() + ": Clash card of " + opponent.getName(), cards, game); cmcOpponent = cardOpponent.getManaCost().convertedManaCost(); message.append(" (").append(cmcOpponent).append(")"); } else { @@ -141,37 +159,37 @@ public class ClashEffect extends OneShotEffect implements MageSingleton { game.informPlayer(controller, opponent.getLogName() + " won the clash!"); } else { message.append(" no winner "); - } + } game.informPlayers(message.toString()); - } + } // decide to put the cards on top or on the buttom of library in turn order beginning with the active player in turn order PlayerList playerList = game.getPlayerList().copy(); playerList.setCurrent(game.getActivePlayerId()); do { Player current = playerList.getCurrent(game); if (cardController != null && current.getId().equals(controller.getId())) { - topController = current.chooseUse(Outcome.Detriment, "Put " + cardController.getLogName() + " back on top of your library? (otherwise it goes to bottom)" , game); - } + topController = current.chooseUse(Outcome.Detriment, "Put " + cardController.getLogName() + " back on top of your library? (otherwise it goes to bottom)", source, game); + } if (cardOpponent != null && current.getId().equals(opponent.getId())) { - topOpponent = current.chooseUse(Outcome.Detriment, "Put " + cardOpponent.getLogName() + " back on top of your library? (otherwise it goes to bottom)" , game); - } + topOpponent = current.chooseUse(Outcome.Detriment, "Put " + cardOpponent.getLogName() + " back on top of your library? (otherwise it goes to bottom)", source, game); + } } while (!playerList.getNext(game).getId().equals(game.getActivePlayerId())); // put the cards back to library - if (cardController != null) { + if (cardController != null) { controller.moveCardToLibraryWithInfo(cardController, source.getSourceId(), game, Zone.LIBRARY, topController, true); } - if (cardOpponent != null) { + if (cardOpponent != null) { opponent.moveCardToLibraryWithInfo(cardOpponent, source.getSourceId(), game, Zone.LIBRARY, topOpponent, true); } game.fireEvent(new GameEvent(EventType.CLASHED, opponent.getId(), source.getSourceId(), controller.getId(), 0, cmcController > cmcOpponent)); // set opponent to DoIfClashWonEffect - for (Effect effect :source.getEffects()) { + for (Effect effect : source.getEffects()) { if (effect instanceof DoIfClashWonEffect) { effect.setValue("clashOpponent", opponent); - } - } + } + } return cmcController > cmcOpponent; - } + } } } return false; diff --git a/Mage/src/mage/abilities/effects/common/CounterUnlessPaysEffect.java b/Mage/src/mage/abilities/effects/common/CounterUnlessPaysEffect.java index 947eae394c..be63142eb3 100644 --- a/Mage/src/mage/abilities/effects/common/CounterUnlessPaysEffect.java +++ b/Mage/src/mage/abilities/effects/common/CounterUnlessPaysEffect.java @@ -93,7 +93,7 @@ public class CounterUnlessPaysEffect extends OneShotEffect { message = costToPay.getText() + " to prevent counter effect?"; } costToPay.clearPaid(); - if (!(player.chooseUse(Outcome.Benefit, message, game) && costToPay.pay(source, game, spell.getSourceId(), spell.getControllerId(), false))) { + if (!(player.chooseUse(Outcome.Benefit, message, source, game) && costToPay.pay(source, game, spell.getSourceId(), spell.getControllerId(), false))) { return game.getStack().counter(spell.getId(), source.getSourceId(), game); } return true; diff --git a/Mage/src/mage/abilities/effects/common/DevourEffect.java b/Mage/src/mage/abilities/effects/common/DevourEffect.java index 0820df2579..1d02ab1733 100644 --- a/Mage/src/mage/abilities/effects/common/DevourEffect.java +++ b/Mage/src/mage/abilities/effects/common/DevourEffect.java @@ -136,7 +136,7 @@ public class DevourEffect extends ReplacementEffectImpl { if (!target.canChoose(source.getSourceId(), source.getControllerId(), game)) { return false; } - if (controller.chooseUse(Outcome.Detriment, "Devour creatures?", game)) { + if (controller.chooseUse(Outcome.Detriment, "Devour creatures?", source, game)) { controller.chooseTarget(Outcome.Detriment, target, source, game); if (target.getTargets().size() > 0) { List> cardSubtypes = new ArrayList<>(); diff --git a/Mage/src/mage/abilities/effects/common/DoIfClashWonEffect.java b/Mage/src/mage/abilities/effects/common/DoIfClashWonEffect.java index e33f58311d..356692e44f 100644 --- a/Mage/src/mage/abilities/effects/common/DoIfClashWonEffect.java +++ b/Mage/src/mage/abilities/effects/common/DoIfClashWonEffect.java @@ -79,7 +79,7 @@ public class DoIfClashWonEffect extends OneShotEffect { message = CardUtil.replaceSourceName(message, mageObject.getLogName()); } - if (chooseUseText == null || player.chooseUse(executingEffect.getOutcome(), message, game)) { + if (chooseUseText == null || player.chooseUse(executingEffect.getOutcome(), message, source, game)) { if (ClashEffect.getInstance().apply(game, source)) { if (setTargetPointerToClashedOpponent) { Object opponent = getValue("clashOpponent"); diff --git a/Mage/src/mage/abilities/effects/common/DoIfCostPaid.java b/Mage/src/mage/abilities/effects/common/DoIfCostPaid.java index 344e6aadc6..000ee2e275 100644 --- a/Mage/src/mage/abilities/effects/common/DoIfCostPaid.java +++ b/Mage/src/mage/abilities/effects/common/DoIfCostPaid.java @@ -14,6 +14,7 @@ import mage.players.Player; import mage.util.CardUtil; public class DoIfCostPaid extends OneShotEffect { + protected Effects executingEffects = new Effects(); private final Cost cost; private String chooseUseText; @@ -39,7 +40,7 @@ public class DoIfCostPaid extends OneShotEffect { public void addEffect(Effect effect) { executingEffects.add(effect); } - + @Override public boolean apply(Game game, Ability source) { Player player = getPayingPlayer(game, source); @@ -48,28 +49,27 @@ public class DoIfCostPaid extends OneShotEffect { String message; if (chooseUseText == null) { String effectText = executingEffects.getText(source.getModes().getMode()); - if (effectText.length() > 0 && effectText.charAt(effectText.length()-1)=='.') { - effectText = effectText.substring(0, effectText.length()-1); + if (effectText.length() > 0 && effectText.charAt(effectText.length() - 1) == '.') { + effectText = effectText.substring(0, effectText.length() - 1); } - message = getCostText() +" and " + effectText + "?"; + message = getCostText() + " and " + effectText + "?"; } else { message = chooseUseText; } message = CardUtil.replaceSourceName(message, mageObject.getLogName()); boolean result = true; - if (cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(executingEffects.get(0).getOutcome(), message, game)) { + if (cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(executingEffects.get(0).getOutcome(), message, source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), player.getId(), false)) { - - for(Effect effect: executingEffects) { + for (Effect effect : executingEffects) { effect.setTargetPointer(this.targetPointer); if (effect instanceof OneShotEffect) { result &= effect.apply(game, source); - } - else { + } else { game.addEffect((ContinuousEffect) effect, source); } } + player.resetStoredBookmark(game); // otherwise you can undo card drawn with Mentor of the Meek } } return result; @@ -108,4 +108,3 @@ public class DoIfCostPaid extends OneShotEffect { return new DoIfCostPaid(this); } } - diff --git a/Mage/src/mage/abilities/effects/common/DoUnlessAnyPlayerPaysEffect.java b/Mage/src/mage/abilities/effects/common/DoUnlessAnyPlayerPaysEffect.java index 5cea6d5782..c7e8ab933d 100644 --- a/Mage/src/mage/abilities/effects/common/DoUnlessAnyPlayerPaysEffect.java +++ b/Mage/src/mage/abilities/effects/common/DoUnlessAnyPlayerPaysEffect.java @@ -91,7 +91,7 @@ public class DoUnlessAnyPlayerPaysEffect extends OneShotEffect { // check if any player is willing to pay for (UUID playerId: controller.getInRange()) { Player player = game.getPlayer(playerId); - if (player != null && cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, game)) { + if (player != null && cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), player.getId(), false)) { if (!game.isSimulation()) diff --git a/Mage/src/mage/abilities/effects/common/DrawCardTargetEffect.java b/Mage/src/mage/abilities/effects/common/DrawCardTargetEffect.java index d6cb79f40c..6443cc2efb 100644 --- a/Mage/src/mage/abilities/effects/common/DrawCardTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/DrawCardTargetEffect.java @@ -90,7 +90,7 @@ public class DrawCardTargetEffect extends OneShotEffect { if (upTo) { cardsToDraw = player.getAmount(0, cardsToDraw, "Draw how many cards?", game); } - if (!optional || player.chooseUse(outcome, "Use draw effect?", game)) { + if (!optional || player.chooseUse(outcome, "Use draw effect?", source, game)) { player.drawCards(cardsToDraw, game); } return true; diff --git a/Mage/src/mage/abilities/effects/common/DrawDiscardControllerEffect.java b/Mage/src/mage/abilities/effects/common/DrawDiscardControllerEffect.java index 73e05f62eb..20f1d46d6e 100644 --- a/Mage/src/mage/abilities/effects/common/DrawDiscardControllerEffect.java +++ b/Mage/src/mage/abilities/effects/common/DrawDiscardControllerEffect.java @@ -82,7 +82,7 @@ public class DrawDiscardControllerEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - if (!optional || player.chooseUse(outcome, "Use draw, then discard effect?", game)) { + if (!optional || player.chooseUse(outcome, "Use draw, then discard effect?", source, game)) { player.drawCards(cardsToDraw, game); player.discard(cardsToDiscard, false, source, game); } diff --git a/Mage/src/mage/abilities/effects/common/EnterBattlefieldPayCostOrPutGraveyardEffect.java b/Mage/src/mage/abilities/effects/common/EnterBattlefieldPayCostOrPutGraveyardEffect.java index b3f4001b7b..f485ee25c0 100644 --- a/Mage/src/mage/abilities/effects/common/EnterBattlefieldPayCostOrPutGraveyardEffect.java +++ b/Mage/src/mage/abilities/effects/common/EnterBattlefieldPayCostOrPutGraveyardEffect.java @@ -78,7 +78,7 @@ public class EnterBattlefieldPayCostOrPutGraveyardEffect extends ReplacementEffe if (player != null && cost != null && sourceObject != null){ boolean replace = true; if (cost.canPay(source, source.getSourceId(), player.getId(), game)) { - if (player.chooseUse(outcome, cost.getText() + "? (otherwise " + sourceObject.getLogName() + " is put into graveyard)", game)) { + if (player.chooseUse(outcome, cost.getText() + "? (otherwise " + sourceObject.getLogName() + " is put into graveyard)", source, game)) { cost.clearPaid(); replace = !cost.pay(source, game, source.getSourceId(), source.getControllerId(), false); } diff --git a/Mage/src/mage/abilities/effects/common/HideawayPlayEffect.java b/Mage/src/mage/abilities/effects/common/HideawayPlayEffect.java index 63358fb60c..15ba5f0aa3 100644 --- a/Mage/src/mage/abilities/effects/common/HideawayPlayEffect.java +++ b/Mage/src/mage/abilities/effects/common/HideawayPlayEffect.java @@ -70,7 +70,7 @@ public class HideawayPlayEffect extends OneShotEffect { if (card.getCardType().contains(CardType.LAND)) { // If the revealed card is a land, you can play it only if it's your turn and you haven't yet played a land this turn. if (game.getActivePlayerId().equals(source.getControllerId()) && controller.canPlayLand()) { - if (controller.chooseUse(Outcome.Benefit, "Play " + card.getLogName() + " from Exile?", game)) { + if (controller.chooseUse(Outcome.Benefit, "Play " + card.getLogName() + " from Exile?", source, game)) { card.setFaceDown(false, game); return controller.playLand(card, game); } @@ -82,7 +82,7 @@ public class HideawayPlayEffect extends OneShotEffect { // The land's last ability allows you to play the removed card as part of the resolution of that ability. // Timing restrictions based on the card's type are ignored (for instance, if it's a creature or sorcery). // Other play restrictions are not (such as "Play [this card] only during combat"). - if (controller.chooseUse(Outcome.Benefit, "Cast "+ card.getLogName() + " without paying it's mana cost?", game)) { + if (controller.chooseUse(Outcome.Benefit, "Cast "+ card.getLogName() + " without paying it's mana cost?", source, game)) { card.setFaceDown(false, game); return controller.cast(card.getSpellAbility(), game, true); } diff --git a/Mage/src/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java b/Mage/src/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java index eb80a1b122..8812148046 100644 --- a/Mage/src/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java +++ b/Mage/src/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java @@ -127,7 +127,7 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff protected void actionWithSelectedCards(Cards cards, Game game, Ability source, String windowName) { Player player = game.getPlayer(source.getControllerId()); if (player != null && foundCardsToPick > 0) { - if (!optional || player.chooseUse(Outcome.DrawCard, getMayText(), game)) { + if (!optional || player.chooseUse(Outcome.DrawCard, getMayText(), source, game)) { FilterCard pickFilter = filter.copy(); pickFilter.setMessage(getPickText()); TargetCard target = new TargetCard((upTo ? 0:numberToPick.calculate(game, source, this)),numberToPick.calculate(game, source, this), Zone.PICK, pickFilter); diff --git a/Mage/src/mage/abilities/effects/common/LookLibraryControllerEffect.java b/Mage/src/mage/abilities/effects/common/LookLibraryControllerEffect.java index 517179592e..c32ff30e18 100644 --- a/Mage/src/mage/abilities/effects/common/LookLibraryControllerEffect.java +++ b/Mage/src/mage/abilities/effects/common/LookLibraryControllerEffect.java @@ -27,8 +27,6 @@ */ package mage.abilities.effects.common; -import mage.constants.Outcome; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.SpellAbility; @@ -38,6 +36,8 @@ import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.Cards; import mage.cards.CardsImpl; +import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -142,7 +142,7 @@ public class LookLibraryControllerEffect extends OneShotEffect { player.setTopCardRevealed(topCardRevealed); - this.mayShuffle(player, game); + this.mayShuffle(player, source, game); return true; } @@ -162,19 +162,19 @@ public class LookLibraryControllerEffect extends OneShotEffect { * @param game */ protected void putCardsBack(Ability source, Player player, Cards cards, Game game) { - switch(targetZoneLookedCards) { - case LIBRARY: + switch (targetZoneLookedCards) { + case LIBRARY: if (putOnTop) { player.putCardsOnTopOfLibrary(cards, game, source, true); } else { player.putCardsOnBottomOfLibrary(cards, game, source, true); } break; - case GRAVEYARD: + case GRAVEYARD: player.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game); break; default: - // not supported yet + // not supported yet } } @@ -184,8 +184,8 @@ public class LookLibraryControllerEffect extends OneShotEffect { * @param player * @param game */ - protected void mayShuffle(Player player, Game game) { - if (this.mayShuffleAfter && player.chooseUse(Outcome.Benefit, "Shuffle your library?", game)) { + protected void mayShuffle(Player player, Ability source, Game game) { + if (this.mayShuffleAfter && player.chooseUse(Outcome.Benefit, "Shuffle your library?", source, game)) { player.shuffleLibrary(game); } } @@ -226,7 +226,6 @@ public class LookLibraryControllerEffect extends OneShotEffect { sb.append(", where {X} is the number of cards ").append(numberOfCards.getMessage()); } - if (!middleText.isEmpty()) { sb.append(middleText); } else if (numberLook > 1) { diff --git a/Mage/src/mage/abilities/effects/common/LookLibraryMayPutToBottomEffect.java b/Mage/src/mage/abilities/effects/common/LookLibraryMayPutToBottomEffect.java index b352e9042d..3b4ea2dad6 100644 --- a/Mage/src/mage/abilities/effects/common/LookLibraryMayPutToBottomEffect.java +++ b/Mage/src/mage/abilities/effects/common/LookLibraryMayPutToBottomEffect.java @@ -45,7 +45,7 @@ public class LookLibraryMayPutToBottomEffect extends OneShotEffect { return false; } controller.lookAtCards(sourceObject.getName(), new CardsImpl(card), game); - boolean toBottom = controller.chooseUse(outcome, "Put card on the bottom of your library?", game); + boolean toBottom = controller.chooseUse(outcome, "Put card on the bottom of your library?", source, game); return controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, !toBottom, false); } return true; diff --git a/Mage/src/mage/abilities/effects/common/MayTapOrUntapTargetEffect.java b/Mage/src/mage/abilities/effects/common/MayTapOrUntapTargetEffect.java index 5b20678ab0..9e2c9523a6 100644 --- a/Mage/src/mage/abilities/effects/common/MayTapOrUntapTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/MayTapOrUntapTargetEffect.java @@ -26,11 +26,11 @@ public class MayTapOrUntapTargetEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (target != null && player != null) { if (target.isTapped()) { - if (player.chooseUse(Outcome.Untap, "Untap that permanent?", game)) { + if (player.chooseUse(Outcome.Untap, "Untap that permanent?", source, game)) { target.untap(game); } } else { - if (player.chooseUse(Outcome.Tap, "Tap that permanent?", game)) { + if (player.chooseUse(Outcome.Tap, "Tap that permanent?", source, game)) { target.tap(game); } } diff --git a/Mage/src/mage/abilities/effects/common/PutCreatureOnBattlefieldEffect.java b/Mage/src/mage/abilities/effects/common/PutCreatureOnBattlefieldEffect.java index 14f106c56b..9d5d1572fd 100644 --- a/Mage/src/mage/abilities/effects/common/PutCreatureOnBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/common/PutCreatureOnBattlefieldEffect.java @@ -34,7 +34,7 @@ public class PutCreatureOnBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, choiceText, game)) { + if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { return false; } diff --git a/Mage/src/mage/abilities/effects/common/PutLandFromHandOntoBattlefieldEffect.java b/Mage/src/mage/abilities/effects/common/PutLandFromHandOntoBattlefieldEffect.java index a2c3ad8e11..8d819291cc 100644 --- a/Mage/src/mage/abilities/effects/common/PutLandFromHandOntoBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/common/PutLandFromHandOntoBattlefieldEffect.java @@ -67,7 +67,7 @@ public class PutLandFromHandOntoBattlefieldEffect extends OneShotEffect { if (controller != null) { Target target = new TargetCardInHand(new FilterLandCard("land card")); if (target.canChoose(source.getSourceId(), source.getControllerId(), game) && - controller.chooseUse(outcome, "Put land onto battlefield?", game) && + controller.chooseUse(outcome, "Put land onto battlefield?", source, game) && controller.choose(outcome, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { diff --git a/Mage/src/mage/abilities/effects/common/PutOntoBattlefieldTargetEffect.java b/Mage/src/mage/abilities/effects/common/PutOntoBattlefieldTargetEffect.java index f08e185309..bebb9cee5e 100644 --- a/Mage/src/mage/abilities/effects/common/PutOntoBattlefieldTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/PutOntoBattlefieldTargetEffect.java @@ -75,7 +75,7 @@ public class PutOntoBattlefieldTargetEffect extends OneShotEffect { if (controller == null || !controller.chooseUse(Outcome.PutCreatureInPlay, new StringBuilder("Put ") .append(source.getTargets() != null ? source.getTargets().get(0).getTargetName() : "target") - .append(" onto the battlefield?").toString(), game)) { + .append(" onto the battlefield?").toString(), source, game)) { return false; } } diff --git a/Mage/src/mage/abilities/effects/common/SacrificeSourceUnlessPaysEffect.java b/Mage/src/mage/abilities/effects/common/SacrificeSourceUnlessPaysEffect.java index 8b82bdbf89..e9f188f41e 100644 --- a/Mage/src/mage/abilities/effects/common/SacrificeSourceUnlessPaysEffect.java +++ b/Mage/src/mage/abilities/effects/common/SacrificeSourceUnlessPaysEffect.java @@ -42,7 +42,7 @@ public class SacrificeSourceUnlessPaysEffect extends OneShotEffect { } String message = CardUtil.replaceSourceName(sb.toString(), sourceObject.getLogName()); message = Character.toUpperCase(message.charAt(0)) + message.substring(1); - if (player.chooseUse(Outcome.Benefit, message, game)) { + if (player.chooseUse(Outcome.Benefit, message, source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { return true; diff --git a/Mage/src/mage/abilities/effects/common/SkipUntapOptionalSourceEffect.java b/Mage/src/mage/abilities/effects/common/SkipUntapOptionalSourceEffect.java index a251a0cba7..9db9a0de61 100644 --- a/Mage/src/mage/abilities/effects/common/SkipUntapOptionalSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/SkipUntapOptionalSourceEffect.java @@ -39,8 +39,6 @@ import mage.players.Player; * * @author LevelX2 */ - - public class SkipUntapOptionalSourceEffect extends RestrictionEffect { public SkipUntapOptionalSourceEffect() { @@ -54,15 +52,15 @@ public class SkipUntapOptionalSourceEffect extends RestrictionEffect { @Override public boolean applies(Permanent permanent, Ability source, Game game) { - return permanent.getId().equals(source.getSourceId()) && - permanent.getControllerId().equals(game.getActivePlayerId()) && // your untap step + return permanent.getId().equals(source.getSourceId()) + && permanent.getControllerId().equals(game.getActivePlayerId()) && // your untap step permanent.isTapped(); } @Override - public boolean canBeUntapped(Permanent permanent, Game game) { + public boolean canBeUntapped(Permanent permanent, Ability source, Game game) { Player player = game.getPlayer(permanent.getControllerId()); - return player != null && player.chooseUse(Outcome.Benefit, "Untap " + permanent.getLogName() + "?", game); + return player != null && player.chooseUse(Outcome.Benefit, "Untap " + permanent.getLogName() + "?", source, game); } @Override diff --git a/Mage/src/mage/abilities/effects/common/TapSourceUnlessPaysEffect.java b/Mage/src/mage/abilities/effects/common/TapSourceUnlessPaysEffect.java index 0cec8d1336..55bc3ad99e 100644 --- a/Mage/src/mage/abilities/effects/common/TapSourceUnlessPaysEffect.java +++ b/Mage/src/mage/abilities/effects/common/TapSourceUnlessPaysEffect.java @@ -61,7 +61,7 @@ public class TapSourceUnlessPaysEffect extends OneShotEffect { Permanent permanent = game.getPermanent(source.getSourceId()); if (player != null && permanent != null) { if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game) - && player.chooseUse(Outcome.Benefit, cost.getText() + "? (otherwise " + permanent.getName() + " becomes tapped)", game)) { + && player.chooseUse(Outcome.Benefit, cost.getText() + "? (otherwise " + permanent.getName() + " becomes tapped)", source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { return true; diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesColorOrColorsTargetEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesColorOrColorsTargetEffect.java index 8aac40950b..8739315474 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BecomesColorOrColorsTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesColorOrColorsTargetEffect.java @@ -73,7 +73,7 @@ public class BecomesColorOrColorsTargetEffect extends OneShotEffect { if (controller != null && target != null) { for (int i = 0; i < 5; i++) { - if (!controller.chooseUse(Outcome.Neutral, "Do you wish to choose another color?", game)) { + if (!controller.chooseUse(Outcome.Neutral, "Do you wish to choose another color?", source, game)) { break; } ChoiceColor choiceColor = new ChoiceColor(); diff --git a/Mage/src/mage/abilities/effects/common/continuous/BoostControlledEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BoostControlledEffect.java index b06cd3440a..197e1b040d 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BoostControlledEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BoostControlledEffect.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.abilities.effects.common.continuous; import java.util.Iterator; @@ -83,7 +82,8 @@ public class BoostControlledEffect extends ContinuousEffectImpl { * @param toughness * @param duration * @param filter - * @param lockedIn if true, power and toughness will be calculated only once, when the ability resolves + * @param lockedIn if true, power and toughness will be calculated only + * once, when the ability resolves * @param excludeSource */ public BoostControlledEffect(DynamicValue power, DynamicValue toughness, Duration duration, FilterCreaturePermanent filter, boolean excludeSource, boolean lockedIn) { @@ -129,7 +129,7 @@ public class BoostControlledEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { if (this.affectedObjectsSet) { - for (Iterator it = affectedObjectList.iterator(); it.hasNext();) { + for (Iterator it = affectedObjectList.iterator(); it.hasNext();) { Permanent permanent = it.next().getPermanent(game); if (permanent != null) { permanent.addPower(power.calculate(game, source, this)); @@ -154,19 +154,19 @@ public class BoostControlledEffect extends ContinuousEffectImpl { String message = null; StringBuilder sb = new StringBuilder(); if (excludeSource) { - sb.append("Other "); + sb.append("other "); } sb.append(filter.getMessage()); sb.append(" you control get "); String p = power.toString(); - if(!p.startsWith("-")) { + if (!p.startsWith("-")) { sb.append("+"); } sb.append(p).append("/"); String t = toughness.toString(); - if(!t.startsWith("-")){ - if(p.startsWith("-")) { + if (!t.startsWith("-")) { + if (p.startsWith("-")) { sb.append("-"); } else { sb.append("+"); @@ -174,7 +174,7 @@ public class BoostControlledEffect extends ContinuousEffectImpl { } sb.append(t); - sb.append((duration==Duration.EndOfTurn?" until end of turn":"")); + sb.append((duration == Duration.EndOfTurn ? " until end of turn" : "")); if (t.equals("X")) { message = toughness.getMessage(); } else if (p.equals("X")) { diff --git a/Mage/src/mage/abilities/effects/common/continuous/CommanderReplacementEffect.java b/Mage/src/mage/abilities/effects/common/continuous/CommanderReplacementEffect.java index 7d0a1fc6b2..daa86a6abe 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/CommanderReplacementEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/CommanderReplacementEffect.java @@ -132,7 +132,7 @@ public class CommanderReplacementEffect extends ReplacementEffectImpl { Permanent permanent = ((ZoneChangeEvent)event).getTarget(); if (permanent != null) { Player player = game.getPlayer(permanent.getOwnerId()); - if (player != null && player.chooseUse(Outcome.Benefit, "Move commander to command zone?", game)){ + if (player != null && player.chooseUse(Outcome.Benefit, "Move commander to command zone?", source, game)){ boolean result = permanent.moveToZone(Zone.COMMAND, source.getSourceId(), game, false); if (!game.isSimulation()) game.informPlayers(player.getLogName() + " has moved his or her commander to the command zone"); @@ -152,7 +152,7 @@ public class CommanderReplacementEffect extends ReplacementEffectImpl { } if (card != null) { Player player = game.getPlayer(card.getOwnerId()); - if (player != null && player.chooseUse(Outcome.Benefit, "Move commander to command zone?", game)){ + if (player != null && player.chooseUse(Outcome.Benefit, "Move commander to command zone?", source, game)){ boolean result = card.moveToZone(Zone.COMMAND, source.getSourceId(), game, false); if (!game.isSimulation()) game.informPlayers(player.getLogName() + " has moved his or her commander to the command zone"); diff --git a/Mage/src/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java b/Mage/src/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java index 806001cd79..2513b9a9f5 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common.continuous; import mage.abilities.Ability; @@ -73,10 +72,10 @@ public class UntapAllDuringEachOtherPlayersUntapStepEffect extends ContinuousEff if (!applied && layer.equals(Layer.RulesEffects)) { if (!game.getActivePlayerId().equals(source.getControllerId()) && game.getStep().getType() == PhaseStep.UNTAP) { game.getState().setValue(source.getSourceId() + "applied", true); - for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { boolean untap = true; - for (RestrictionEffect effect: game.getContinuousEffects().getApplicableRestrictionEffects(permanent, game).keySet()) { - untap &= effect.canBeUntapped(permanent, game); + for (RestrictionEffect effect : game.getContinuousEffects().getApplicableRestrictionEffects(permanent, game).keySet()) { + untap &= effect.canBeUntapped(permanent, source, game); } if (untap) { permanent.untap(game); diff --git a/Mage/src/mage/abilities/keyword/BuybackAbility.java b/Mage/src/mage/abilities/keyword/BuybackAbility.java index 827aed84ff..321a7de0a8 100644 --- a/Mage/src/mage/abilities/keyword/BuybackAbility.java +++ b/Mage/src/mage/abilities/keyword/BuybackAbility.java @@ -28,8 +28,6 @@ package mage.abilities.keyword; import java.util.Iterator; - -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; @@ -43,6 +41,7 @@ import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.Card; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; @@ -51,16 +50,16 @@ import mage.players.Player; /** * 702.25. Buyback * - * 702.25a Buyback appears on some instants and sorceries. It represents two static - * abilities that function while the spell is on the stack. "Buyback [cost]" means - * "You may pay an additional [cost] as you cast this spell" and "If the buyback - * cost was paid, put this spell into its owner's hand instead of into that player's - * graveyard as it resolves." Paying a spell's buyback cost follows the rules for - * paying additional costs in rules 601.2b and 601.2e-g. + * 702.25a Buyback appears on some instants and sorceries. It represents two + * static abilities that function while the spell is on the stack. "Buyback + * [cost]" means "You may pay an additional [cost] as you cast this spell" and + * "If the buyback cost was paid, put this spell into its owner's hand instead + * of into that player's graveyard as it resolves." Paying a spell's buyback + * cost follows the rules for paying additional costs in rules 601.2b and + * 601.2e-g. * * @author LevelX2 */ - public class BuybackAbility extends StaticAbility implements OptionalAdditionalSourceCosts { private static final String keywordText = "Buyback"; @@ -69,25 +68,25 @@ public class BuybackAbility extends StaticAbility implements OptionalAdditionalS protected OptionalAdditionalCost buybackCost; public BuybackAbility(String manaString) { - super(Zone.STACK, new BuybackEffect()); - this.buybackCost = new OptionalAdditionalCostImpl(keywordText, reminderTextMana, new ManaCostsImpl(manaString)); - setRuleAtTheTop(true); + super(Zone.STACK, new BuybackEffect()); + this.buybackCost = new OptionalAdditionalCostImpl(keywordText, reminderTextMana, new ManaCostsImpl(manaString)); + setRuleAtTheTop(true); } - + public BuybackAbility(Cost cost) { - super(Zone.STACK, new BuybackEffect()); - this.buybackCost = new OptionalAdditionalCostImpl(keywordText, "-", reminderTextCost, cost); - setRuleAtTheTop(true); + super(Zone.STACK, new BuybackEffect()); + this.buybackCost = new OptionalAdditionalCostImpl(keywordText, "-", reminderTextCost, cost); + setRuleAtTheTop(true); } public BuybackAbility(final BuybackAbility ability) { - super(ability); - buybackCost = ability.buybackCost; + super(ability); + buybackCost = ability.buybackCost; } @Override public BuybackAbility copy() { - return new BuybackAbility(this); + return new BuybackAbility(this); } @Override @@ -117,7 +116,7 @@ public class BuybackAbility extends StaticAbility implements OptionalAdditionalS if (player != null) { this.resetBuyback(); if (buybackCost != null) { - if (player.chooseUse(Outcome.Benefit,new StringBuilder("Pay ").append(buybackCost.getText(false)).append(" ?").toString(), game)) { + if (player.chooseUse(Outcome.Benefit, new StringBuilder("Pay ").append(buybackCost.getText(false)).append(" ?").toString(), ability, game)) { buybackCost.activate(); for (Iterator it = ((Costs) buybackCost).iterator(); it.hasNext();) { Cost cost = (Cost) it.next(); @@ -133,7 +132,6 @@ public class BuybackAbility extends StaticAbility implements OptionalAdditionalS } } - @Override public String getRule() { StringBuilder sb = new StringBuilder(); @@ -186,8 +184,8 @@ class BuybackEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getTargetId().equals(source.getSourceId())) { - ZoneChangeEvent zEvent = (ZoneChangeEvent)event; - if (zEvent.getFromZone() == Zone.STACK ) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone() == Zone.STACK) { return true; } } @@ -210,4 +208,4 @@ class BuybackEffect extends ReplacementEffectImpl { return false; } -} \ No newline at end of file +} diff --git a/Mage/src/mage/abilities/keyword/CascadeAbility.java b/Mage/src/mage/abilities/keyword/CascadeAbility.java index 1274da1a3f..c4b6318f83 100644 --- a/Mage/src/mage/abilities/keyword/CascadeAbility.java +++ b/Mage/src/mage/abilities/keyword/CascadeAbility.java @@ -114,7 +114,7 @@ public class CascadeAbility extends TriggeredAbilityImpl { player.getLibrary().reset(); if (card != null) { - if (player.chooseUse(outcome, "Use cascade effect on " + card.getName() + "?", game)) { + if (player.chooseUse(outcome, "Use cascade effect on " + card.getName() + "?", source, game)) { if(player.cast(card.getSpellAbility(), game, true)){ exile.remove(card.getId()); } diff --git a/Mage/src/mage/abilities/keyword/ConspireAbility.java b/Mage/src/mage/abilities/keyword/ConspireAbility.java index 311b659709..fe470c425f 100644 --- a/Mage/src/mage/abilities/keyword/ConspireAbility.java +++ b/Mage/src/mage/abilities/keyword/ConspireAbility.java @@ -126,7 +126,7 @@ public class ConspireAbility extends StaticAbility implements OptionalAdditional Player player = game.getPlayer(controllerId); if (player != null) { this.resetConspire(); - if (player.chooseUse(Outcome.Benefit, new StringBuilder("Pay ").append(conspireCost.getText(false)).append(" ?").toString(), game)) { + if (player.chooseUse(Outcome.Benefit, new StringBuilder("Pay ").append(conspireCost.getText(false)).append(" ?").toString(), ability, game)) { conspireCost.activate(); for (Iterator it = ((Costs) conspireCost).iterator(); it.hasNext();) { Cost cost = (Cost) it.next(); @@ -245,8 +245,9 @@ class ConspireEffect extends OneShotEffect { copy.setCopiedSpell(true); game.getStack().push(copy); copy.chooseNewTargets(game, source.getControllerId()); - if (!game.isSimulation()) + if (!game.isSimulation()) { game.informPlayers(new StringBuilder(controller.getLogName()).append(copy.getActivatedMessage(game)).toString()); + } return true; } } diff --git a/Mage/src/mage/abilities/keyword/CumulativeUpkeepAbility.java b/Mage/src/mage/abilities/keyword/CumulativeUpkeepAbility.java index 196daf5ace..199c853610 100644 --- a/Mage/src/mage/abilities/keyword/CumulativeUpkeepAbility.java +++ b/Mage/src/mage/abilities/keyword/CumulativeUpkeepAbility.java @@ -107,7 +107,7 @@ class CumulativeUpkeepEffect extends OneShotEffect { for(int i = 0 ; i < ageCounter; i++){ totalCost.add((ManaCost) cumulativeCost.copy()); } - if (player.chooseUse(Outcome.Benefit, "Pay " + totalCost.getText() + "?", game)) { + if (player.chooseUse(Outcome.Benefit, "Pay " + totalCost.getText() + "?", source, game)) { totalCost.clearPaid(); if (totalCost.payOrRollback(source, game, source.getSourceId(), source.getControllerId())){ return true; @@ -121,7 +121,7 @@ class CumulativeUpkeepEffect extends OneShotEffect { for(int i = 0 ; i < ageCounter; i++){ totalCost.add(cumulativeCost.copy()); } - if (player.chooseUse(Outcome.Benefit, totalCost.getText() + "?", game)) { + if (player.chooseUse(Outcome.Benefit, totalCost.getText() + "?", source, game)) { totalCost.clearPaid(); int bookmark = game.bookmarkState(); if (totalCost.pay(source, game, source.getSourceId(), source.getControllerId(), false)){ diff --git a/Mage/src/mage/abilities/keyword/DashAbility.java b/Mage/src/mage/abilities/keyword/DashAbility.java index a80b5f5079..4072e1a856 100644 --- a/Mage/src/mage/abilities/keyword/DashAbility.java +++ b/Mage/src/mage/abilities/keyword/DashAbility.java @@ -67,7 +67,7 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts protected List alternativeSourceCosts = new LinkedList<>(); // needed to check activation status, if card changes zone after casting it - private int zoneChangeCounter = 0; + private int zoneChangeCounter = 0; public DashAbility(Card card, String manaString) { super(Zone.ALL, null); @@ -75,7 +75,7 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts this.addDashCost(manaString); Ability ability = new EntersBattlefieldAbility( new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.Custom, false), - DashedCondition.getInstance(), false, "",""); + DashedCondition.getInstance(), false, "", ""); Effect effect = new ReturnToHandTargetEffect(); effect.setText("return the dashed creature from the battlefield to its owner's hand"); effect.setTargetPointer(new FixedTarget(card.getId())); @@ -85,24 +85,24 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts } public DashAbility(final DashAbility ability) { - super(ability); - this.alternativeSourceCosts.addAll(ability.alternativeSourceCosts); - this.zoneChangeCounter = ability.zoneChangeCounter; + super(ability); + this.alternativeSourceCosts.addAll(ability.alternativeSourceCosts); + this.zoneChangeCounter = ability.zoneChangeCounter; } @Override public DashAbility copy() { - return new DashAbility(this); + return new DashAbility(this); } public final AlternativeCost2 addDashCost(String manaString) { - AlternativeCost2 evokeCost = new AlternativeCost2Impl(KEYWORD, REMINDER_TEXT, new ManaCostsImpl(manaString)); - alternativeSourceCosts.add(evokeCost); - return evokeCost; + AlternativeCost2 evokeCost = new AlternativeCost2Impl(KEYWORD, REMINDER_TEXT, new ManaCostsImpl(manaString)); + alternativeSourceCosts.add(evokeCost); + return evokeCost; } public void resetDash() { - for (AlternativeCost2 cost: alternativeSourceCosts) { + for (AlternativeCost2 cost : alternativeSourceCosts) { cost.reset(); } zoneChangeCounter = 0; @@ -111,9 +111,9 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts @Override public boolean isActivated(Ability ability, Game game) { Card card = game.getCard(sourceId); - if (card != null && card.getZoneChangeCounter(game) <= zoneChangeCounter +1) { - for (AlternativeCost2 cost: alternativeSourceCosts) { - if(cost.isActivated(game)) { + if (card != null && card.getZoneChangeCounter(game) <= zoneChangeCounter + 1) { + for (AlternativeCost2 cost : alternativeSourceCosts) { + if (cost.isActivated(game)) { return true; } } @@ -132,9 +132,9 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts Player player = game.getPlayer(controllerId); if (player != null) { this.resetDash(); - for (AlternativeCost2 dashCost: alternativeSourceCosts) { - if (dashCost.canPay(ability, sourceId, controllerId, game) && - player.chooseUse(Outcome.Benefit, new StringBuilder(KEYWORD).append(" the creature for ").append(dashCost.getText(true)).append(" ?").toString(), game)) { + for (AlternativeCost2 dashCost : alternativeSourceCosts) { + if (dashCost.canPay(ability, sourceId, controllerId, game) + && player.chooseUse(Outcome.Benefit, new StringBuilder(KEYWORD).append(" the creature for ").append(dashCost.getText(true)).append(" ?").toString(), ability, game)) { activateDash(dashCost, game); ability.getManaCostsToPay().clear(); ability.getCosts().clear(); @@ -168,23 +168,23 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts @Override public String getRule() { - StringBuilder sb = new StringBuilder(); - int numberCosts = 0; - String remarkText = ""; - for (AlternativeCost2 dashCost: alternativeSourceCosts) { - if (numberCosts == 0) { - sb.append(dashCost.getText(false)); - remarkText = dashCost.getReminderText(); - } else { - sb.append(" and/or ").append(dashCost.getText(true)); - } - ++numberCosts; - } - if (numberCosts == 1) { + StringBuilder sb = new StringBuilder(); + int numberCosts = 0; + String remarkText = ""; + for (AlternativeCost2 dashCost : alternativeSourceCosts) { + if (numberCosts == 0) { + sb.append(dashCost.getText(false)); + remarkText = dashCost.getReminderText(); + } else { + sb.append(" and/or ").append(dashCost.getText(true)); + } + ++numberCosts; + } + if (numberCosts == 1) { sb.append(" ").append(remarkText); - } + } - return sb.toString(); + return sb.toString(); } @Override @@ -203,7 +203,7 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts @Override public Costs getCosts() { Costs alterCosts = new CostsImpl<>(); - for (AlternativeCost2 aCost: alternativeSourceCosts) { + for (AlternativeCost2 aCost : alternativeSourceCosts) { alterCosts.add(aCost.getCost()); } return alterCosts; diff --git a/Mage/src/mage/abilities/keyword/DredgeAbility.java b/Mage/src/mage/abilities/keyword/DredgeAbility.java index 62f77f3ada..afed19ef46 100644 --- a/Mage/src/mage/abilities/keyword/DredgeAbility.java +++ b/Mage/src/mage/abilities/keyword/DredgeAbility.java @@ -98,7 +98,7 @@ class DredgeEffect extends ReplacementEffectImpl { Player player = game.getPlayer(source.getControllerId()); if (player != null && player.getLibrary().size() >= amount && player.chooseUse(outcome, new StringBuilder("Dredge ").append(sourceCard.getLogName()). - append("? (").append(amount).append(" cards go from top of library to graveyard)").toString(), game)) { + append("? (").append(amount).append(" cards go from top of library to graveyard)").toString(), source, game)) { if (!game.isSimulation()) { game.informPlayers(new StringBuilder(player.getLogName()).append(" dreges ").append(sourceCard.getLogName()).toString()); } diff --git a/Mage/src/mage/abilities/keyword/EchoAbility.java b/Mage/src/mage/abilities/keyword/EchoAbility.java index 6b1d318678..6b8a129a80 100644 --- a/Mage/src/mage/abilities/keyword/EchoAbility.java +++ b/Mage/src/mage/abilities/keyword/EchoAbility.java @@ -145,7 +145,7 @@ class EchoEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && source.getSourceObjectIfItStillExists(game) != null) { - if (controller.chooseUse(Outcome.Benefit, "Pay " + cost.getText() /* + " or sacrifice " + permanent.getName() */ + "?", game)) { + if (controller.chooseUse(Outcome.Benefit, "Pay " + cost.getText() /* + " or sacrifice " + permanent.getName() */ + "?", source, game)) { cost.clearPaid(); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { return true; diff --git a/Mage/src/mage/abilities/keyword/EntwineAbility.java b/Mage/src/mage/abilities/keyword/EntwineAbility.java index 475324cae6..141fd25162 100644 --- a/Mage/src/mage/abilities/keyword/EntwineAbility.java +++ b/Mage/src/mage/abilities/keyword/EntwineAbility.java @@ -28,8 +28,6 @@ package mage.abilities.keyword; import java.util.Iterator; - -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; @@ -40,24 +38,24 @@ import mage.abilities.costs.OptionalAdditionalCostImpl; import mage.abilities.costs.OptionalAdditionalModeSourceCosts; import mage.abilities.costs.mana.ManaCostsImpl; import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; import mage.players.Player; /** * 702.40. Entwine * - * 702.40a Entwine is a static ability of modal spells (see rule 700.2) that functions - * while the spell is on the stack. "Entwine [cost]" means "You may choose all modes - * of this spell instead of just one. If you do, you pay an additional [cost]." Using - * the entwine ability follows the rules for choosing modes and paying additional costs - * in rules 601.2b and 601.2e-g. + * 702.40a Entwine is a static ability of modal spells (see rule 700.2) that + * functions while the spell is on the stack. "Entwine [cost]" means "You may + * choose all modes of this spell instead of just one. If you do, you pay an + * additional [cost]." Using the entwine ability follows the rules for choosing + * modes and paying additional costs in rules 601.2b and 601.2e-g. * - * 702.40b If the entwine cost was paid, follow the text of each of the modes in the order - * written on the card when the spell resolves. + * 702.40b If the entwine cost was paid, follow the text of each of the modes in + * the order written on the card when the spell resolves. * * @author LevelX2 */ - public class EntwineAbility extends StaticAbility implements OptionalAdditionalModeSourceCosts { private static final String keywordText = "Entwine"; @@ -65,24 +63,24 @@ public class EntwineAbility extends StaticAbility implements OptionalAdditionalM protected OptionalAdditionalCost additionalCost; public EntwineAbility(String manaString) { - super(Zone.STACK, null); - this.additionalCost = new OptionalAdditionalCostImpl(keywordText, reminderText, new ManaCostsImpl(manaString)); + super(Zone.STACK, null); + this.additionalCost = new OptionalAdditionalCostImpl(keywordText, reminderText, new ManaCostsImpl(manaString)); } public EntwineAbility(Cost cost) { - super(Zone.STACK, null); - this.additionalCost = new OptionalAdditionalCostImpl(keywordText, "-", reminderText, cost); - setRuleAtTheTop(true); + super(Zone.STACK, null); + this.additionalCost = new OptionalAdditionalCostImpl(keywordText, "-", reminderText, cost); + setRuleAtTheTop(true); } public EntwineAbility(final EntwineAbility ability) { - super(ability); - additionalCost = ability.additionalCost; + super(ability); + additionalCost = ability.additionalCost; } @Override public EntwineAbility copy() { - return new EntwineAbility(this); + return new EntwineAbility(this); } @Override @@ -112,7 +110,7 @@ public class EntwineAbility extends StaticAbility implements OptionalAdditionalM if (player != null) { this.resetCosts(); if (additionalCost != null) { - if (player.chooseUse(Outcome.Benefit,new StringBuilder("Pay ").append(additionalCost.getText(false)).append(" ?").toString(), game)) { + if (player.chooseUse(Outcome.Benefit, new StringBuilder("Pay ").append(additionalCost.getText(false)).append(" ?").toString(), ability, game)) { additionalCost.activate(); for (Iterator it = ((Costs) additionalCost).iterator(); it.hasNext();) { Cost cost = (Cost) it.next(); @@ -130,7 +128,6 @@ public class EntwineAbility extends StaticAbility implements OptionalAdditionalM } } - @Override public String getRule() { StringBuilder sb = new StringBuilder(); diff --git a/Mage/src/mage/abilities/keyword/EvokeAbility.java b/Mage/src/mage/abilities/keyword/EvokeAbility.java index 7be2dbeec5..4141a987c2 100644 --- a/Mage/src/mage/abilities/keyword/EvokeAbility.java +++ b/Mage/src/mage/abilities/keyword/EvokeAbility.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.abilities.keyword; import java.util.Iterator; @@ -55,7 +54,6 @@ import mage.players.Player; * * @author LevelX2 */ - public class EvokeAbility extends StaticAbility implements AlternativeSourceCosts { protected static final String EVOKE_KEYWORD = "Evoke"; @@ -64,7 +62,7 @@ public class EvokeAbility extends StaticAbility implements AlternativeSourceCost protected List evokeCosts = new LinkedList<>(); // needed to check activation status, if card changes zone after casting it - private int zoneChangeCounter = 0; + private int zoneChangeCounter = 0; public EvokeAbility(Card card, String manaString) { super(Zone.ALL, null); @@ -77,24 +75,24 @@ public class EvokeAbility extends StaticAbility implements AlternativeSourceCost } public EvokeAbility(final EvokeAbility ability) { - super(ability); - this.evokeCosts.addAll(ability.evokeCosts); - this.zoneChangeCounter = ability.zoneChangeCounter; + super(ability); + this.evokeCosts.addAll(ability.evokeCosts); + this.zoneChangeCounter = ability.zoneChangeCounter; } @Override public EvokeAbility copy() { - return new EvokeAbility(this); + return new EvokeAbility(this); } - + public final AlternativeCost2 addEvokeCost(String manaString) { - AlternativeCost2 evokeCost = new AlternativeCost2Impl(EVOKE_KEYWORD, REMINDER_TEXT, new ManaCostsImpl(manaString)); - evokeCosts.add(evokeCost); - return evokeCost; + AlternativeCost2 evokeCost = new AlternativeCost2Impl(EVOKE_KEYWORD, REMINDER_TEXT, new ManaCostsImpl(manaString)); + evokeCosts.add(evokeCost); + return evokeCost; } public void resetEvoke() { - for (AlternativeCost2 cost: evokeCosts) { + for (AlternativeCost2 cost : evokeCosts) { cost.reset(); } zoneChangeCounter = 0; @@ -103,30 +101,30 @@ public class EvokeAbility extends StaticAbility implements AlternativeSourceCost @Override public boolean isActivated(Ability ability, Game game) { Card card = game.getCard(sourceId); - if (card != null && card.getZoneChangeCounter(game) <= zoneChangeCounter +1) { - for (AlternativeCost2 cost: evokeCosts) { - if(cost.isActivated(game)) { + if (card != null && card.getZoneChangeCounter(game) <= zoneChangeCounter + 1) { + for (AlternativeCost2 cost : evokeCosts) { + if (cost.isActivated(game)) { return true; } } } return false; } - + @Override public boolean isAvailable(Ability source, Game game) { return true; } - + @Override public boolean askToActivateAlternativeCosts(Ability ability, Game game) { if (ability instanceof SpellAbility) { Player player = game.getPlayer(controllerId); if (player != null) { this.resetEvoke(); - for (AlternativeCost2 evokeCost: evokeCosts) { - if (evokeCost.canPay(ability, sourceId, controllerId, game) && - player.chooseUse(Outcome.Benefit, new StringBuilder(EVOKE_KEYWORD).append(" the creature for ").append(evokeCost.getText(true)).append(" ?").toString(), game)) { + for (AlternativeCost2 evokeCost : evokeCosts) { + if (evokeCost.canPay(ability, sourceId, controllerId, game) + && player.chooseUse(Outcome.Benefit, new StringBuilder(EVOKE_KEYWORD).append(" the creature for ").append(evokeCost.getText(true)).append(" ?").toString(), ability, game)) { activateEvoke(evokeCost, game); ability.getManaCostsToPay().clear(); ability.getCosts().clear(); @@ -160,23 +158,23 @@ public class EvokeAbility extends StaticAbility implements AlternativeSourceCost @Override public String getRule() { - StringBuilder sb = new StringBuilder(); - int numberCosts = 0; - String remarkText = ""; - for (AlternativeCost2 evokeCost: evokeCosts) { - if (numberCosts == 0) { - sb.append(evokeCost.getText(false)); - remarkText = evokeCost.getReminderText(); - } else { - sb.append(" and/or ").append(evokeCost.getText(true)); - } - ++numberCosts; - } - if (numberCosts == 1) { + StringBuilder sb = new StringBuilder(); + int numberCosts = 0; + String remarkText = ""; + for (AlternativeCost2 evokeCost : evokeCosts) { + if (numberCosts == 0) { + sb.append(evokeCost.getText(false)); + remarkText = evokeCost.getReminderText(); + } else { + sb.append(" and/or ").append(evokeCost.getText(true)); + } + ++numberCosts; + } + if (numberCosts == 1) { sb.append(" ").append(remarkText); - } + } - return sb.toString(); + return sb.toString(); } @Override @@ -191,13 +189,13 @@ public class EvokeAbility extends StaticAbility implements AlternativeSourceCost } return sb.toString(); } - + @Override public Costs getCosts() { Costs alterCosts = new CostsImpl<>(); - for (AlternativeCost2 aCost: evokeCosts) { + for (AlternativeCost2 aCost : evokeCosts) { alterCosts.add(aCost.getCost()); } return alterCosts; - } + } } diff --git a/Mage/src/mage/abilities/keyword/ExtortAbility.java b/Mage/src/mage/abilities/keyword/ExtortAbility.java index 1a910c230f..d700e55738 100644 --- a/Mage/src/mage/abilities/keyword/ExtortAbility.java +++ b/Mage/src/mage/abilities/keyword/ExtortAbility.java @@ -101,7 +101,7 @@ class ExtortEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(source.getSourceId()); if (player != null && permanent != null) { - if (player.chooseUse(Outcome.Damage, new StringBuilder("Extort opponents? (").append(permanent.getName()).append(")").toString(), game)) { + if (player.chooseUse(Outcome.Damage, new StringBuilder("Extort opponents? (").append(permanent.getName()).append(")").toString(), source, game)) { Cost cost = new ManaCostsImpl("{W/B}"); if (cost.pay(source, game, source.getSourceId(), player.getId(), false)) { int loseLife = 0; diff --git a/Mage/src/mage/abilities/keyword/KickerAbility.java b/Mage/src/mage/abilities/keyword/KickerAbility.java index ada8a8248f..5ff7303443 100644 --- a/Mage/src/mage/abilities/keyword/KickerAbility.java +++ b/Mage/src/mage/abilities/keyword/KickerAbility.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.abilities.keyword; import java.util.HashMap; @@ -52,33 +51,31 @@ import mage.players.Player; /** * - * 20121001 702.31. Kicker - * 702.31a Kicker is a static ability that functions while the spell with kicker - * is on the stack. "Kicker [cost]" means "You may pay an additional [cost] - * as you cast this spell." Paying a spell's kicker cost(s) follows the - * rules for paying additional costs in rules 601.2b and 601.2e-g. - * 702.31b The phrase "Kicker [cost 1] and/or [cost 2]" means the same thing as - * "Kicker [cost 1], kicker [cost 2]." - * 702.31c Multikicker is a variant of the kicker ability. "Multikicker [cost]" - * means "You may pay an additional [cost] any number of times as you cast - * this spell." A multikicker cost is a kicker cost. - * 702.31d If a spell's controller declares the intention to pay any of that spell's - * kicker costs, that spell has been "kicked." If a spell has two kicker - * costs or has multikicker, it may be kicked multiple times. See rule 601.2b. - * 702.31e Objects with kicker or multikicker have additional abilities that specify - * what happens if they are kicked. These abilities are linked to the kicker - * or multikicker abilities printed on that object: they can refer only to - * those specific kicker or multikicker abilities. See rule 607, - * "Linked Abilities." - * 702.31f Objects with more than one kicker cost have abilities that each correspond - * to a specific kicker cost. They contain the phrases "if it was kicked with - * its [A] kicker" and "if it was kicked with its [B] kicker," where A and B - * are the first and second kicker costs listed on the card, respectively. Each - * of those abilities is linked to the appropriate kicker ability. - * 702.31g If part of a spell's ability has its effect only if that spell was kicked, - * and that part of the ability includes any targets, the spell's controller - * chooses those targets only if that spell was kicked. Otherwise, the spell is - * cast as if it did not have those targets. See rule 601.2c. + * 20121001 702.31. Kicker 702.31a Kicker is a static ability that functions + * while the spell with kicker is on the stack. "Kicker [cost]" means "You may + * pay an additional [cost] as you cast this spell." Paying a spell's kicker + * cost(s) follows the rules for paying additional costs in rules 601.2b and + * 601.2e-g. 702.31b The phrase "Kicker [cost 1] and/or [cost 2]" means the same + * thing as "Kicker [cost 1], kicker [cost 2]." 702.31c Multikicker is a variant + * of the kicker ability. "Multikicker [cost]" means "You may pay an additional + * [cost] any number of times as you cast this spell." A multikicker cost is a + * kicker cost. 702.31d If a spell's controller declares the intention to pay + * any of that spell's kicker costs, that spell has been "kicked." If a spell + * has two kicker costs or has multikicker, it may be kicked multiple times. See + * rule 601.2b. 702.31e Objects with kicker or multikicker have additional + * abilities that specify what happens if they are kicked. These abilities are + * linked to the kicker or multikicker abilities printed on that object: they + * can refer only to those specific kicker or multikicker abilities. See rule + * 607, "Linked Abilities." 702.31f Objects with more than one kicker cost have + * abilities that each correspond to a specific kicker cost. They contain the + * phrases "if it was kicked with its [A] kicker" and "if it was kicked with its + * [B] kicker," where A and B are the first and second kicker costs listed on + * the card, respectively. Each of those abilities is linked to the appropriate + * kicker ability. 702.31g If part of a spell's ability has its effect only if + * that spell was kicked, and that part of the ability includes any targets, the + * spell's controller chooses those targets only if that spell was kicked. + * Otherwise, the spell is cast as if it did not have those targets. See rule + * 601.2c. * * @author LevelX2 * @@ -90,61 +87,61 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo protected static final String KICKER_REMINDER_COST = "(You may {cost} in addition to any other costs as you cast this spell.)"; protected Map activations = new HashMap<>(); // zoneChangeCounter, activations - + protected String keywordText; protected String reminderText; protected List kickerCosts = new LinkedList<>(); - private int xManaValue = 0; + private int xManaValue = 0; public KickerAbility(String manaString) { - this(KICKER_KEYWORD, KICKER_REMINDER_MANA); - this.addKickerCost(manaString); + this(KICKER_KEYWORD, KICKER_REMINDER_MANA); + this.addKickerCost(manaString); } public KickerAbility(Cost cost) { - this(KICKER_KEYWORD, KICKER_REMINDER_COST); - this.addKickerCost(cost); + this(KICKER_KEYWORD, KICKER_REMINDER_COST); + this.addKickerCost(cost); } public KickerAbility(String keywordText, String reminderText) { - super(Zone.STACK, null); - name = keywordText; - this.keywordText = keywordText; - this.reminderText = reminderText; - setRuleAtTheTop(true); + super(Zone.STACK, null); + name = keywordText; + this.keywordText = keywordText; + this.reminderText = reminderText; + setRuleAtTheTop(true); } public KickerAbility(final KickerAbility ability) { - super(ability); - this.kickerCosts.addAll(ability.kickerCosts); - this.keywordText = ability.keywordText; - this.reminderText = ability.reminderText; - this.xManaValue = ability.xManaValue; - this.activations.putAll(ability.activations); + super(ability); + this.kickerCosts.addAll(ability.kickerCosts); + this.keywordText = ability.keywordText; + this.reminderText = ability.reminderText; + this.xManaValue = ability.xManaValue; + this.activations.putAll(ability.activations); } @Override public KickerAbility copy() { - return new KickerAbility(this); + return new KickerAbility(this); } public final OptionalAdditionalCost addKickerCost(String manaString) { - OptionalAdditionalCost kickerCost = new OptionalAdditionalCostImpl(keywordText, reminderText, new ManaCostsImpl(manaString)); - kickerCosts.add(kickerCost); - return kickerCost; + OptionalAdditionalCost kickerCost = new OptionalAdditionalCostImpl(keywordText, reminderText, new ManaCostsImpl(manaString)); + kickerCosts.add(kickerCost); + return kickerCost; } public final OptionalAdditionalCost addKickerCost(Cost cost) { - OptionalAdditionalCost kickerCost = new OptionalAdditionalCostImpl(keywordText, "-", reminderText, cost); - kickerCosts.add(kickerCost); - return kickerCost; + OptionalAdditionalCost kickerCost = new OptionalAdditionalCostImpl(keywordText, "-", reminderText, cost); + kickerCosts.add(kickerCost); + return kickerCost; } public void resetKicker(Game game, Ability source) { String key = getActivationKey(source, "", game); - activations.remove(key); - for (OptionalAdditionalCost cost: kickerCosts) { + activations.remove(key); + for (OptionalAdditionalCost cost : kickerCosts) { cost.reset(); } } @@ -152,7 +149,7 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo public int getXManaValue() { return xManaValue; } - + public int getKickedCounter(Game game, Ability source) { String key = getActivationKey(source, "", game); if (activations.containsKey(key)) { @@ -169,7 +166,7 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo return false; } - public List getKickerCosts () { + public List getKickerCosts() { return kickerCosts; } @@ -186,50 +183,50 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo int zcc = source.getSourceObjectZoneChangeCounter(); if (source.getSourceObjectZoneChangeCounter() == 0) { zcc = game.getState().getZoneChangeCounter(source.getSourceId()); - } + } if (zcc > 0 && (source.getAbilityType().equals(AbilityType.TRIGGERED) || source.getAbilityType().equals(AbilityType.STATIC))) { --zcc; } - return String.valueOf(zcc) + ((kickerCosts.size() > 1) ? costText :""); + return String.valueOf(zcc) + ((kickerCosts.size() > 1) ? costText : ""); } - + @Override public void addOptionalAdditionalCosts(Ability ability, Game game) { if (ability instanceof SpellAbility) { Player player = game.getPlayer(controllerId); if (player != null) { this.resetKicker(game, ability); - for (OptionalAdditionalCost kickerCost: kickerCosts) { + for (OptionalAdditionalCost kickerCost : kickerCosts) { boolean again = true; while (player.isInGame() && again) { String times = ""; if (kickerCost.isRepeatable()) { int activatedCount = getKickedCounter(game, ability); - times = Integer.toString(activatedCount + 1) + (activatedCount == 0 ? " time ":" times "); + times = Integer.toString(activatedCount + 1) + (activatedCount == 0 ? " time " : " times "); } - if (kickerCost.canPay(ability, sourceId, controllerId, game) && - player.chooseUse(Outcome.Benefit, "Pay " + times + kickerCost.getText(false) + " ?", game)) { + if (kickerCost.canPay(ability, sourceId, controllerId, game) + && player.chooseUse(Outcome.Benefit, "Pay " + times + kickerCost.getText(false) + " ?", ability, game)) { this.activateKicker(kickerCost, ability, game); for (Iterator it = ((Costs) kickerCost).iterator(); it.hasNext();) { Cost cost = (Cost) it.next(); if (cost instanceof ManaCostsImpl) { - List varCosts = ((ManaCostsImpl)cost).getVariableCosts(); + List varCosts = ((ManaCostsImpl) cost).getVariableCosts(); if (!varCosts.isEmpty()) { // use only first variable cost xManaValue = game.getPlayer(this.controllerId).announceXMana(varCosts.get(0).getMinX(), Integer.MAX_VALUE, "Announce kicker value for " + varCosts.get(0).getText(), game, this); // kicker variable X costs handled internally as multikicker with {1} cost (no multikicker on card) if (!game.isSimulation()) { - game.informPlayers(game.getPlayer(this.controllerId).getLogName() + " announced a value of " + xManaValue +" for " + " kicker X "); + game.informPlayers(game.getPlayer(this.controllerId).getLogName() + " announced a value of " + xManaValue + " for " + " kicker X "); } ability.getManaCostsToPay().add(new GenericManaCost(xManaValue)); } else { - ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy()); + ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy()); } } else { ability.getCosts().add(cost.copy()); } } - + again = kickerCost.isRepeatable(); } else { again = false; @@ -240,26 +237,25 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo } } - @Override public String getRule() { - StringBuilder sb = new StringBuilder(); - int numberKicker = 0; - String remarkText = ""; - for (OptionalAdditionalCost kickerCost: kickerCosts) { - if (numberKicker == 0) { - sb.append(kickerCost.getText(false)); - remarkText = kickerCost.getReminderText(); - } else { - sb.append(" and/or ").append(kickerCost.getText(true)); - } - ++numberKicker; - } - if (numberKicker == 1) { + StringBuilder sb = new StringBuilder(); + int numberKicker = 0; + String remarkText = ""; + for (OptionalAdditionalCost kickerCost : kickerCosts) { + if (numberKicker == 0) { + sb.append(kickerCost.getText(false)); + remarkText = kickerCost.getReminderText(); + } else { + sb.append(" and/or ").append(kickerCost.getText(true)); + } + ++numberKicker; + } + if (numberKicker == 1) { sb.append(" ").append(remarkText); - } + } - return sb.toString(); + return sb.toString(); } @Override diff --git a/Mage/src/mage/abilities/keyword/MadnessAbility.java b/Mage/src/mage/abilities/keyword/MadnessAbility.java index f8e1ff0f5c..b7ceb209ca 100644 --- a/Mage/src/mage/abilities/keyword/MadnessAbility.java +++ b/Mage/src/mage/abilities/keyword/MadnessAbility.java @@ -88,7 +88,7 @@ class MadnessReplacementEffect extends ReplacementEffectImpl { if (controller != null) { Card card = game.getCard(event.getTargetId()); if (card != null) { - if (controller.chooseUse(outcome, "Move " + card.getLogName() + " to exile to cast it by Madness?", game)) { + if (controller.chooseUse(outcome, "Move " + card.getLogName() + " to exile to cast it by Madness?", source, game)) { controller.moveCardToExileWithInfo(card, source.getSourceId(), "Madness", source.getSourceId(), game, ((ZoneChangeEvent) event).getFromZone(), true); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.MADNESS_CARD_EXILED, card.getId(), card.getId(),controller.getId())); return true; diff --git a/Mage/src/mage/abilities/keyword/MorphAbility.java b/Mage/src/mage/abilities/keyword/MorphAbility.java index 362be6c619..cba284786e 100644 --- a/Mage/src/mage/abilities/keyword/MorphAbility.java +++ b/Mage/src/mage/abilities/keyword/MorphAbility.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.abilities.keyword; import java.util.Iterator; @@ -58,42 +57,44 @@ import mage.players.Player; /** * 702.36. Morph * - * 702.36a Morph is a static ability that functions in any zone from which you could play - * the card it’s on, and the morph effect works any time the card is face down. - * "Morph [cost]" means "You may cast this card as a 2/2 face-down creature, with no text, - * no name, no subtypes, and no mana cost by paying {3} rather than paying its mana cost." - * (See rule 707, "Face-Down Spells and Permanents.") + * 702.36a Morph is a static ability that functions in any zone from which you + * could play the card it’s on, and the morph effect works any time the card is + * face down. "Morph [cost]" means "You may cast this card as a 2/2 face-down + * creature, with no text, no name, no subtypes, and no mana cost by paying {3} + * rather than paying its mana cost." (See rule 707, "Face-Down Spells and + * Permanents.") * - * 702.36b To cast a card using its morph ability, turn it face down. It becomes a 2/2 - * face-down creature card, with no text, no name, no subtypes, and no mana cost. Any - * effects or prohibitions that would apply to casting a card with these characteristics - * (and not the face-up card’s characteristics) are applied to casting this card. These - * values are the copiable values of that object’s characteristics. (See rule 613, - * "Interaction of Continuous Effects," and rule 706, "Copying Objects.") Put it onto the - * stack (as a face-down spell with the same characteristics), and pay {3} rather than pay - * its mana cost. This follows the rules for paying alternative costs. You can use morph - * to cast a card from any zone from which you could normally play it. When the spell - * resolves, it enters the battlefield with the same characteristics the spell had. The - * morph effect applies to the face-down object wherever it is, and it ends when the - * permanent is turned face up. # + * 702.36b To cast a card using its morph ability, turn it face down. It becomes + * a 2/2 face-down creature card, with no text, no name, no subtypes, and no + * mana cost. Any effects or prohibitions that would apply to casting a card + * with these characteristics (and not the face-up card’s characteristics) are + * applied to casting this card. These values are the copiable values of that + * object’s characteristics. (See rule 613, "Interaction of Continuous Effects," + * and rule 706, "Copying Objects.") Put it onto the stack (as a face-down spell + * with the same characteristics), and pay {3} rather than pay its mana cost. + * This follows the rules for paying alternative costs. You can use morph to + * cast a card from any zone from which you could normally play it. When the + * spell resolves, it enters the battlefield with the same characteristics the + * spell had. The morph effect applies to the face-down object wherever it is, + * and it ends when the permanent is turned face up. # * - * 702.36c You can’t cast a card face down if it doesn’t have morph. + * 702.36c You can’t cast a card face down if it doesn’t have morph. * - * 702.36d If you have priority, you may turn a face-down permanent you control face up. - * This is a special action; it doesn’t use the stack (see rule 115). To do this, show - * all players what the permanent’s morph cost would be if it were face up, pay that cost, - * then turn the permanent face up. (If the permanent wouldn’t have a morph cost if it - * were face up, it can’t be turned face up this way.) The morph effect on it ends, and - * it regains its normal characteristics. Any abilities relating to the permanent entering - * the battlefield don’t trigger when it’s turned face up and don’t have any effect, because - * the permanent has already entered the battlefield. + * 702.36d If you have priority, you may turn a face-down permanent you control + * face up. This is a special action; it doesn’t use the stack (see rule 115). + * To do this, show all players what the permanent’s morph cost would be if it + * were face up, pay that cost, then turn the permanent face up. (If the + * permanent wouldn’t have a morph cost if it were face up, it can’t be turned + * face up this way.) The morph effect on it ends, and it regains its normal + * characteristics. Any abilities relating to the permanent entering the + * battlefield don’t trigger when it’s turned face up and don’t have any effect, + * because the permanent has already entered the battlefield. * - * 702.36e See rule 707, "Face-Down Spells and Permanents," for more information on how to - * cast cards with morph. + * 702.36e See rule 707, "Face-Down Spells and Permanents," for more information + * on how to cast cards with morph. * * @author LevelX2 */ - public class MorphAbility extends StaticAbility implements AlternativeSourceCosts { protected static final String ABILITY_KEYWORD = "Morph"; @@ -104,9 +105,9 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost protected AlternativeCost2Impl alternateCosts = new AlternativeCost2Impl(ABILITY_KEYWORD, REMINDER_TEXT, new GenericManaCost(3)); protected Costs morphCosts; // needed to check activation status, if card changes zone after casting it - private int zoneChangeCounter = 0; - private boolean megamorph; - + private int zoneChangeCounter = 0; + private boolean megamorph; + public MorphAbility(Card card, Cost morphCost) { this(card, createCosts(morphCost)); } @@ -118,7 +119,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost public MorphAbility(Card card, Costs morphCosts) { this(card, morphCosts, false); } - + public MorphAbility(Card card, Costs morphCosts, boolean megamorph) { super(Zone.HAND, null); this.morphCosts = morphCosts; @@ -129,9 +130,9 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost sb.append(ABILITY_KEYWORD_MEGA).append(" "); } else { sb.append(ABILITY_KEYWORD).append(" "); - } - name = ABILITY_KEYWORD; - for (Cost cost :morphCosts) { + } + name = ABILITY_KEYWORD; + for (Cost cost : morphCosts) { if (!(cost instanceof ManaCosts)) { sb.append("- "); break; @@ -143,10 +144,10 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost } else { sb.append(REMINDER_TEXT); } - + ruleText = sb.toString(); - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BecomesFaceDownCreatureEffect(morphCosts, (megamorph ? FaceDownType.MEGAMORPHED :FaceDownType.MORPHED))); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BecomesFaceDownCreatureEffect(morphCosts, (megamorph ? FaceDownType.MEGAMORPHED : FaceDownType.MORPHED))); ability.setWorksFaceDown(true); ability.setRuleVisible(false); addSubAbility(ability); @@ -154,12 +155,12 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost } public MorphAbility(final MorphAbility ability) { - super(ability); - this.zoneChangeCounter = ability.zoneChangeCounter; - this.ruleText = ability.ruleText; - this.alternateCosts = ability.alternateCosts.copy(); - this.morphCosts = ability.morphCosts; // can't be changed - this.megamorph = ability.megamorph; + super(ability); + this.zoneChangeCounter = ability.zoneChangeCounter; + this.ruleText = ability.ruleText; + this.alternateCosts = ability.alternateCosts.copy(); + this.morphCosts = ability.morphCosts; // can't be changed + this.megamorph = ability.megamorph; } private static Costs createCosts(Cost cost) { @@ -170,11 +171,11 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost @Override public MorphAbility copy() { - return new MorphAbility(this); + return new MorphAbility(this); } public void resetMorph() { - alternateCosts.reset(); + alternateCosts.reset(); zoneChangeCounter = 0; } @@ -185,7 +186,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost @Override public boolean isActivated(Ability ability, Game game) { Card card = game.getCard(sourceId); - if (card != null && card.getZoneChangeCounter(game) <= zoneChangeCounter +1) { + if (card != null && card.getZoneChangeCounter(game) <= zoneChangeCounter + 1) { return alternateCosts.isActivated(game); } return false; @@ -205,7 +206,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost this.resetMorph(); spell.setFaceDown(true, game); // so only the back is visible if (alternateCosts.canPay(ability, sourceId, controllerId, game)) { - if (player.chooseUse(Outcome.Benefit, new StringBuilder("Cast this card as a 2/2 face-down creature for ").append(getCosts().getText()).append(" ?").toString(), game)) { + if (player.chooseUse(Outcome.Benefit, "Cast this card as a 2/2 face-down creature for " + getCosts().getText() + " ?", ability, game)) { activateMorph(game); // change mana costs ability.getManaCostsToPay().clear(); @@ -213,7 +214,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost for (Iterator it = this.alternateCosts.iterator(); it.hasNext();) { Cost cost = (Cost) it.next(); if (cost instanceof ManaCost) { - ability.getManaCostsToPay().add((ManaCost)cost.copy()); + ability.getManaCostsToPay().add((ManaCost) cost.copy()); } else { ability.getCosts().add(cost.copy()); } @@ -231,12 +232,12 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost } } } - if (ability.getAbilityType().equals(AbilityType.PLAY_LAND)) { + if (ability.getAbilityType().equals(AbilityType.PLAY_LAND)) { Player player = game.getPlayer(controllerId); if (player != null) { this.resetMorph(); if (alternateCosts.canPay(ability, sourceId, controllerId, game)) { - if (player.chooseUse(Outcome.Benefit, new StringBuilder("Cast this card as a 2/2 face-down creature for ").append(getCosts().getText()).append(" ?").toString(), game)) { + if (player.chooseUse(Outcome.Benefit, new StringBuilder("Cast this card as a 2/2 face-down creature for ").append(getCosts().getText()).append(" ?").toString(), ability, game)) { activateMorph(game); // change mana costs ability.getManaCostsToPay().clear(); @@ -244,7 +245,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost for (Iterator it = this.alternateCosts.iterator(); it.hasNext();) { Cost cost = (Cost) it.next(); if (cost instanceof ManaCost) { - ability.getManaCostsToPay().add((ManaCost)cost.copy()); + ability.getManaCostsToPay().add((ManaCost) cost.copy()); } else { ability.getCosts().add(cost.copy()); } @@ -292,7 +293,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost public Costs getCosts() { return alternateCosts; } - + public static void setPermanentToFaceDownCreature(MageObject mageObject) { mageObject.getPower().initValue(2); mageObject.getToughness().initValue(2); @@ -305,13 +306,9 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost mageObject.getSupertype().clear(); mageObject.getManaCost().clear(); if (mageObject instanceof Permanent) { - ((Permanent)mageObject).setExpansionSetCode(""); - ((Permanent)mageObject).setRarity(Rarity.NA); + ((Permanent) mageObject).setExpansionSetCode(""); + ((Permanent) mageObject).setRarity(Rarity.NA); } - + } } - - - - diff --git a/Mage/src/mage/abilities/keyword/OfferingAbility.java b/Mage/src/mage/abilities/keyword/OfferingAbility.java index 0ecb7ec5ec..97f737e4cf 100644 --- a/Mage/src/mage/abilities/keyword/OfferingAbility.java +++ b/Mage/src/mage/abilities/keyword/OfferingAbility.java @@ -159,7 +159,7 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl { Card spellToCast = game.getCard(source.getSourceId()); Player player = game.getPlayer(source.getControllerId()); if (player != null && !CardUtil.isCheckPlayableMode(affectedAbility) && - player.chooseUse(Outcome.Benefit, "Offer a " + filter.getMessage() + " to cast " + spellToCast.getName() + "?", game)) { + player.chooseUse(Outcome.Benefit, "Offer a " + filter.getMessage() + " to cast " + spellToCast.getName() + "?", source, game)) { Target target = new TargetControlledCreaturePermanent(1,1,filter,true); player.chooseTarget(Outcome.Sacrifice, target, source, game); if (!target.isChosen()) { diff --git a/Mage/src/mage/abilities/keyword/ProwlAbility.java b/Mage/src/mage/abilities/keyword/ProwlAbility.java index fb752f990b..1f0d53f630 100644 --- a/Mage/src/mage/abilities/keyword/ProwlAbility.java +++ b/Mage/src/mage/abilities/keyword/ProwlAbility.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.abilities.keyword; import java.util.Iterator; @@ -50,16 +49,16 @@ import mage.watchers.common.ProwlWatcher; /** * 702.74. Prowl # - * - * 702.74a Prowl is a static ability that functions on the stack. "Prowl [cost]" means - * "You may pay [cost] rather than pay this spell's mana cost if a player was dealt combat - * damage this turn by a source that, at the time it dealt that damage, was under your - * control and had any of this spell's creature types." Paying a spell's prowl cost follows - * the rules for paying alternative costs in rules 601.2b and 601.2e-g + * + * 702.74a Prowl is a static ability that functions on the stack. "Prowl [cost]" + * means "You may pay [cost] rather than pay this spell's mana cost if a player + * was dealt combat damage this turn by a source that, at the time it dealt that + * damage, was under your control and had any of this spell's creature types." + * Paying a spell's prowl cost follows the rules for paying alternative costs in + * rules 601.2b and 601.2e-g * * @author LevelX2 */ - public class ProwlAbility extends StaticAbility implements AlternativeSourceCosts { private static final String PROWL_KEYWORD = "Prowl"; @@ -77,43 +76,43 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost } public ProwlAbility(final ProwlAbility ability) { - super(ability); - this.prowlCosts.addAll(ability.prowlCosts); - this.reminderText = ability.reminderText; + super(ability); + this.prowlCosts.addAll(ability.prowlCosts); + this.reminderText = ability.reminderText; } @Override public ProwlAbility copy() { - return new ProwlAbility(this); + return new ProwlAbility(this); } public final AlternativeCost2 addProwlCost(String manaString) { - AlternativeCost2 prowlCost = new AlternativeCost2Impl(PROWL_KEYWORD, reminderText, new ManaCostsImpl(manaString)); - prowlCosts.add(prowlCost); - return prowlCost; + AlternativeCost2 prowlCost = new AlternativeCost2Impl(PROWL_KEYWORD, reminderText, new ManaCostsImpl(manaString)); + prowlCosts.add(prowlCost); + return prowlCost; } public void resetProwl() { - for (AlternativeCost2 cost: prowlCosts) { + for (AlternativeCost2 cost : prowlCosts) { cost.reset(); } } @Override public boolean isActivated(Ability ability, Game game) { - for (AlternativeCost2 cost: prowlCosts) { - if(cost.isActivated(game)) { + for (AlternativeCost2 cost : prowlCosts) { + if (cost.isActivated(game)) { return true; } } return false; } - + @Override public boolean isAvailable(Ability source, Game game) { return true; } - + @Override public boolean askToActivateAlternativeCosts(Ability ability, Game game) { if (ability instanceof SpellAbility) { @@ -124,7 +123,7 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost throw new IllegalArgumentException("Params can't be null"); } boolean canProwl = false; - for (String subtype: card.getSubtype()) { + for (String subtype : card.getSubtype()) { if (prowlWatcher.hasSubtypeMadeCombatDamage(ability.getControllerId(), subtype)) { canProwl = true; break; @@ -132,9 +131,9 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost } if (canProwl) { this.resetProwl(); - for (AlternativeCost2 prowlCost: prowlCosts) { - if (prowlCost.canPay(ability, sourceId, controllerId, game) && - player.chooseUse(Outcome.Benefit, new StringBuilder("Cast for ").append(PROWL_KEYWORD).append(" cost ").append(prowlCost.getText(true)).append(" ?").toString(), game)) { + for (AlternativeCost2 prowlCost : prowlCosts) { + if (prowlCost.canPay(ability, sourceId, controllerId, game) + && player.chooseUse(Outcome.Benefit, new StringBuilder("Cast for ").append(PROWL_KEYWORD).append(" cost ").append(prowlCost.getText(true)).append(" ?").toString(), ability, game)) { prowlCost.activate(); ability.getManaCostsToPay().clear(); ability.getCosts().clear(); @@ -155,23 +154,23 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost @Override public String getRule() { - StringBuilder sb = new StringBuilder(); - int numberCosts = 0; - String remarkText = ""; - for (AlternativeCost2 prowlCost: prowlCosts) { - if (numberCosts == 0) { - sb.append(prowlCost.getText(false)); - remarkText = prowlCost.getReminderText(); - } else { - sb.append(" and/or ").append(prowlCost.getText(true)); - } - ++numberCosts; - } - if (numberCosts == 1) { + StringBuilder sb = new StringBuilder(); + int numberCosts = 0; + String remarkText = ""; + for (AlternativeCost2 prowlCost : prowlCosts) { + if (numberCosts == 0) { + sb.append(prowlCost.getText(false)); + remarkText = prowlCost.getReminderText(); + } else { + sb.append(" and/or ").append(prowlCost.getText(true)); + } + ++numberCosts; + } + if (numberCosts == 1) { sb.append(" ").append(remarkText); - } + } - return sb.toString(); + return sb.toString(); } @Override @@ -190,12 +189,12 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost private void setReminderText(Card card) { StringBuilder sb = new StringBuilder("(You may cast this for its prowl cost if you dealt combat damage to a player this turn with a "); int i = 0; - for (String subtype: card.getSubtype()) { + for (String subtype : card.getSubtype()) { i++; sb.append(subtype); if (card.getSubtype().size() > 1 && i < card.getSubtype().size()) { sb.append(" or "); - } + } } sb.append(".)"); @@ -205,7 +204,7 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost @Override public Costs getCosts() { Costs alterCosts = new CostsImpl<>(); - for (AlternativeCost2 aCost: prowlCosts) { + for (AlternativeCost2 aCost : prowlCosts) { alterCosts.add(aCost.getCost()); } return alterCosts; diff --git a/Mage/src/mage/abilities/keyword/ReplicateAbility.java b/Mage/src/mage/abilities/keyword/ReplicateAbility.java index c78f079044..4607b39af1 100644 --- a/Mage/src/mage/abilities/keyword/ReplicateAbility.java +++ b/Mage/src/mage/abilities/keyword/ReplicateAbility.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.abilities.keyword; import java.util.Iterator; @@ -54,7 +53,6 @@ import mage.players.Player; * * @author LevelX2 */ - public class ReplicateAbility extends StaticAbility implements OptionalAdditionalSourceCosts { private static final String keywordText = "Replicate"; @@ -62,21 +60,21 @@ public class ReplicateAbility extends StaticAbility implements OptionalAdditiona protected OptionalAdditionalCost additionalCost; public ReplicateAbility(Card card, String manaString) { - super(Zone.STACK, null); - this.additionalCost = new OptionalAdditionalCostImpl(keywordText, reminderTextMana, new ManaCostsImpl(manaString)); - this.additionalCost.setRepeatable(true); - setRuleAtTheTop(true); - addSubAbility(new ReplicateTriggeredAbility()); + super(Zone.STACK, null); + this.additionalCost = new OptionalAdditionalCostImpl(keywordText, reminderTextMana, new ManaCostsImpl(manaString)); + this.additionalCost.setRepeatable(true); + setRuleAtTheTop(true); + addSubAbility(new ReplicateTriggeredAbility()); } public ReplicateAbility(final ReplicateAbility ability) { - super(ability); - additionalCost = ability.additionalCost; + super(ability); + additionalCost = ability.additionalCost; } @Override public ReplicateAbility copy() { - return new ReplicateAbility(this); + return new ReplicateAbility(this); } @Override @@ -119,10 +117,10 @@ public class ReplicateAbility extends StaticAbility implements OptionalAdditiona String times = ""; if (additionalCost.isRepeatable()) { int numActivations = additionalCost.getActivateCount(); - times = Integer.toString(numActivations + 1) + (numActivations == 0 ? " time ":" times "); + times = Integer.toString(numActivations + 1) + (numActivations == 0 ? " time " : " times "); } - if (additionalCost.canPay(ability, sourceId, controllerId, game) && - player.chooseUse(Outcome.Benefit, new StringBuilder("Pay ").append(times).append(additionalCost.getText(false)).append(" ?").toString(), game)) { + if (additionalCost.canPay(ability, sourceId, controllerId, game) + && player.chooseUse(Outcome.Benefit, new StringBuilder("Pay ").append(times).append(additionalCost.getText(false)).append(" ?").toString(), ability, game)) { additionalCost.activate(); for (Iterator it = ((Costs) additionalCost).iterator(); it.hasNext();) { Cost cost = (Cost) it.next(); @@ -140,7 +138,6 @@ public class ReplicateAbility extends StaticAbility implements OptionalAdditiona } } - @Override public String getRule() { StringBuilder sb = new StringBuilder(); @@ -179,6 +176,7 @@ class ReplicateTriggeredAbility extends TriggeredAbilityImpl { private ReplicateTriggeredAbility(final ReplicateTriggeredAbility ability) { super(ability); } + @Override public ReplicateTriggeredAbility copy() { return new ReplicateTriggeredAbility(this); @@ -196,7 +194,7 @@ class ReplicateTriggeredAbility extends TriggeredAbilityImpl { if (spell instanceof Spell) { Card card = game.getCard(spell.getSourceId()); if (card != null) { - for (Ability ability: card.getAbilities()) { + for (Ability ability : card.getAbilities()) { if (ability instanceof ReplicateAbility) { if (((ReplicateAbility) ability).isActivated()) { for (Effect effect : this.getEffects()) { @@ -215,7 +213,7 @@ class ReplicateTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Replicate (When you cast this spell, copy it for each time you paid its replicate cost. You may choose new targets for the copies.)" ; + return "Replicate (When you cast this spell, copy it for each time you paid its replicate cost. You may choose new targets for the copies.)"; } } @@ -239,7 +237,7 @@ class ReplicateCopyEffect extends OneShotEffect { // reset replicate now so the copies don't report x times Replicate Card card = game.getCard(spell.getSourceId()); if (card != null) { - for (Ability ability: card.getAbilities()) { + for (Ability ability : card.getAbilities()) { if (ability instanceof ReplicateAbility) { if (((ReplicateAbility) ability).isActivated()) { ((ReplicateAbility) ability).resetReplicate(); @@ -254,8 +252,9 @@ class ReplicateCopyEffect extends OneShotEffect { copy.setCopiedSpell(true); game.getStack().push(copy); copy.chooseNewTargets(game, source.getControllerId()); - if (!game.isSimulation()) + if (!game.isSimulation()) { game.informPlayers(new StringBuilder(controller.getLogName()).append(copy.getActivatedMessage(game)).toString()); + } } return true; } diff --git a/Mage/src/mage/abilities/keyword/TributeAbility.java b/Mage/src/mage/abilities/keyword/TributeAbility.java index 5c31ca8ab3..ad5ad5b6b7 100644 --- a/Mage/src/mage/abilities/keyword/TributeAbility.java +++ b/Mage/src/mage/abilities/keyword/TributeAbility.java @@ -118,7 +118,7 @@ class TributeEffect extends OneShotEffect { sb.append(sourcePermanent.getName()); sb.append(" (add ").append(CardUtil.numberToText(tributeValue)).append(" +1/+1 counter"); sb.append(tributeValue > 1 ? "s":"").append(" to it)?"); - if (opponent.chooseUse(outcome, sb.toString(), game)) { + if (opponent.chooseUse(outcome, sb.toString(), source, game)) { if (!game.isSimulation()) game.informPlayers(opponent.getLogName() + " pays tribute to " + sourcePermanent.getLogName()); game.getState().setValue("tributeValue" + source.getSourceId(), "yes"); diff --git a/Mage/src/mage/abilities/keyword/UnleashAbility.java b/Mage/src/mage/abilities/keyword/UnleashAbility.java index 023b276fa1..45112f075b 100644 --- a/Mage/src/mage/abilities/keyword/UnleashAbility.java +++ b/Mage/src/mage/abilities/keyword/UnleashAbility.java @@ -111,7 +111,7 @@ class UnleashReplacementEffect extends ReplacementEffectImpl { Permanent creature = game.getPermanent(event.getTargetId()); Player controller = game.getPlayer(source.getControllerId()); if (creature != null && controller != null) { - if (controller.chooseUse(outcome, "Unleash "+ creature.getName() +"?", game)) { + if (controller.chooseUse(outcome, "Unleash "+ creature.getName() +"?", source, game)) { if (!game.isSimulation()) game.informPlayers(controller.getLogName() + " unleashes " + creature.getName()); creature.addCounters(CounterType.P1P1.createInstance(), game); diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java index 8f9f4ee18a..e36d8fa0b2 100644 --- a/Mage/src/mage/cards/CardImpl.java +++ b/Mage/src/mage/cards/CardImpl.java @@ -753,7 +753,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { if (name.isEmpty()) { return GameLog.getNeutralColoredText("face down card"); } else { - return GameLog.getColoredObjectName(this); + return GameLog.getColoredObjectIdName(this); } } diff --git a/Mage/src/mage/game/Game.java b/Mage/src/mage/game/Game.java index 40c78f0512..e3b00cd8b4 100644 --- a/Mage/src/mage/game/Game.java +++ b/Mage/src/mage/game/Game.java @@ -1,33 +1,40 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.game; +import java.io.Serializable; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; import mage.MageItem; import mage.MageObject; import mage.abilities.Ability; @@ -44,6 +51,7 @@ import mage.cards.decks.Deck; import mage.choices.Choice; import mage.constants.Duration; import mage.constants.MultiplayerAttackOption; +import mage.constants.PlayerAction; import mage.constants.RangeOfInfluence; import mage.constants.Zone; import mage.game.combat.Combat; @@ -66,176 +74,281 @@ import mage.players.PlayerList; import mage.players.Players; import mage.util.functions.ApplyToPermanent; -import java.io.Serializable; -import java.util.*; -import mage.constants.PlayerAction; - public interface Game extends MageItem, Serializable { MatchType getGameType(); + int getNumPlayers(); + int getLife(); + RangeOfInfluence getRangeOfInfluence(); + MultiplayerAttackOption getAttackOption(); //game data methods void loadCards(Set cards, UUID ownerId); + Collection getCards(); + Object getCustomData(); + void setCustomData(Object data); + GameOptions getOptions(); + MageObject getObject(UUID objectId); + + MageObject getBaseObject(UUID objectId); + MageObject getEmblem(UUID objectId); + UUID getControllerId(UUID objectId); + Permanent getPermanent(UUID permanentId); + Permanent getPermanentOrLKIBattlefield(UUID permanentId); - Map> getLKI(); + + Map> getLKI(); + Card getCard(UUID cardId); + Ability getAbility(UUID abilityId, UUID sourceId); + void setZone(UUID objectId, Zone zone); + void addPlayer(Player player, Deck deck) throws GameException; + Player getPlayer(UUID playerId); + Players getPlayers(); + PlayerList getPlayerList(); - + /** * Returns a Set of opponents in range for the given playerId - * + * * @param playerId - * @return + * @return */ Set getOpponents(UUID playerId); - + /** * Checks if the given playerToCheckId is an opponent of player - * - * @param player + * + * @param player * @param playerToCheckId - * @return + * @return */ boolean isOpponent(Player player, UUID playerToCheckId); - + Turn getTurn(); + Phase getPhase(); + Step getStep(); + int getTurnNum(); + boolean isMainPhase(); + boolean canPlaySorcery(UUID playerId); + UUID getActivePlayerId(); + UUID getPriorityPlayerId(); + boolean gameOver(UUID playerId); + boolean hasEnded(); + Battlefield getBattlefield(); + SpellStack getStack(); + Exile getExile(); + Combat getCombat(); + GameState getState(); + String getWinner(); + void setDraw(UUID playerId); + boolean isADraw(); + ContinuousEffects getContinuousEffects(); + GameStates getGameStates(); + void loadGameStates(GameStates states); + Game copy(); + boolean isSimulation(); + void setSimulation(boolean simulation); + MageObject getLastKnownInformation(UUID objectId, Zone zone); + MageObject getLastKnownInformation(UUID objectId, Zone zone, int zoneChangeCounter); + boolean getShortLivingLKI(UUID objectId, Zone zone); + void rememberLKI(UUID objectId, Zone zone, MageObject object); + void resetLKI(); + void resetShortLivingLKI(); + void setLosingPlayer(Player player); + Player getLosingPlayer(); + void setStateCheckRequired(); + boolean getStateCheckRequired(); //client event methods void addTableEventListener(Listener listener); + void addPlayerQueryEventListener(Listener listener); + void fireAskPlayerEvent(UUID playerId, String message); + void fireChooseChoiceEvent(UUID playerId, Choice choice); + void fireSelectTargetEvent(UUID playerId, String message, Set targets, boolean required, Map options); + void fireSelectTargetEvent(UUID playerId, String message, Cards cards, boolean required, Map options); + void fireSelectTargetEvent(UUID playerId, String message, List abilities); + void fireSelectTargetEvent(UUID playerId, String message, List perms, boolean required); + void fireSelectEvent(UUID playerId, String message); + void fireSelectEvent(UUID playerId, String message, Map options); + void firePriorityEvent(UUID playerId); + void firePlayManaEvent(UUID playerId, String message); + void firePlayXManaEvent(UUID playerId, String message); + void fireGetChoiceEvent(UUID playerId, String message, MageObject object, List choices); + void fireGetModeEvent(UUID playerId, String message, Map modes); + void fireGetAmountEvent(UUID playerId, String message, int min, int max); + void fireChoosePileEvent(UUID playerId, String message, List pile1, List pile2); + void fireInformEvent(String message); + void fireStatusEvent(String message, boolean withTime); + void fireUpdatePlayersEvent(); + void informPlayers(String message); + void informPlayer(Player player, String message); + void debugMessage(String message); + void fireErrorEvent(String message, Exception ex); + void fireGameEndInfo(); //game event methods void fireEvent(GameEvent event); + /** - * The events are stored until the resolution of the current effect ends - * and fired then all together (e.g. X lands enter the battlefield from Scapeshift) + * The events are stored until the resolution of the current effect ends and + * fired then all together (e.g. X lands enter the battlefield from + * Scapeshift) + * * @param event */ void addSimultaneousEvent(GameEvent event); + boolean replaceEvent(GameEvent event); /** * Creates and fires an damage prevention event * - * @param damageEvent damage event that will be replaced (instanceof check will be done) + * @param damageEvent damage event that will be replaced (instanceof check + * will be done) * @param source ability that's the source of the prevention effect * @param game * @param amountToPrevent max preventable amount * @return true prevention was successfull / false prevention was replaced */ PreventionEffectData preventDamage(GameEvent damageEvent, Ability source, Game game, int amountToPrevent); + /** * Creates and fires an damage prevention event * - * @param event damage event that will be replaced (instanceof check will be done) + * @param event damage event that will be replaced (instanceof check will be + * done) * @param source ability that's the source of the prevention effect * @param game - * @param preventAllDamage true if there is no limit to the damage that can be prevented + * @param preventAllDamage true if there is no limit to the damage that can + * be prevented * @return true prevention was successfull / false prevention was replaced */ PreventionEffectData preventDamage(GameEvent event, Ability source, Game game, boolean preventAllDamage); void start(UUID choosingPlayerId); + void resume(); + void pause(); + boolean isPaused(); + void end(); + void cleanUp(); /* * Gives back the number of cards the player has after the next mulligan */ + int mulliganDownTo(UUID playerId); + void mulligan(UUID playerId); + void endMulligan(UUID playerId); + // void quit(UUID playerId); + void timerTimeout(UUID playerId); + void idleTimeout(UUID playerId); + void concede(UUID playerId); + void setManaPaymentMode(UUID playerId, boolean autoPayment); + void setManaPaymentModeRestricted(UUID playerId, boolean autoPaymentRestricted); + void undo(UUID playerId); + void emptyManaPools(); + void addEffect(ContinuousEffect continuousEffect, Ability source); + void addEmblem(Emblem emblem, Ability source); + void addEmblem(Emblem emblem, Ability source, UUID toPlayerId); + void addCommander(Commander commander); + void addPermanent(Permanent permanent); // priority method - void sendPlayerAction(PlayerAction playerAction, UUID playerId); + void sendPlayerAction(PlayerAction playerAction, UUID playerId); /** * This version supports copying of copies of any depth. @@ -249,53 +362,74 @@ public interface Game extends MageItem, Serializable { Permanent copyPermanent(Permanent copyFromPermanent, Permanent copyToPermanent, Ability source, ApplyToPermanent applier); Permanent copyPermanent(Duration duration, Permanent copyFromPermanent, Permanent copyToPermanent, Ability source, ApplyToPermanent applier); - + Card copyCard(Card cardToCopy, Ability source, UUID newController); void addTriggeredAbility(TriggeredAbility ability); + UUID addDelayedTriggeredAbility(DelayedTriggeredAbility delayedAbility); + void applyEffects(); + boolean checkStateAndTriggered(); + void playPriority(UUID activePlayerId, boolean resuming); + boolean endTurn(); int doAction(MageAction action); //game transaction methods void saveState(boolean bookmark); + int bookmarkState(); + void restoreState(int bookmark, String context); + void removeBookmark(int bookmark); + int getSavedStateSize(); + boolean isSaveGame(); + void setSaveGame(boolean saveGame); - + // game options void setGameOptions(GameOptions options); // game times Date getStartTime(); + Date getEndTime(); // game cheats (for tests only) void cheat(UUID ownerId, Map commands); + void cheat(UUID ownerId, List library, List hand, List battlefield, List graveyard); // controlling the behaviour of replacement effects void setScopeRelevant(boolean scopeRelevant); + public boolean getScopeRelevant(); // players' timers void initTimer(UUID playerId); - void resumeTimer(UUID playerId); - void pauseTimer(UUID playerId); - int getPriorityTime(); - void setPriorityTime(int priorityTime); - UUID getStartingPlayerId(); - - void saveRollBackGameState(); - boolean canRollbackTurns(int turnsToRollback); - void rollbackTurns(int turnsToRollback); - boolean executingRollback(); -} + void resumeTimer(UUID playerId); + + void pauseTimer(UUID playerId); + + int getPriorityTime(); + + void setPriorityTime(int priorityTime); + + UUID getStartingPlayerId(); + + void saveRollBackGameState(); + + boolean canRollbackTurns(int turnsToRollback); + + void rollbackTurns(int turnsToRollback); + + boolean executingRollback(); +} diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index f9a2930de5..b04ec05c9f 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.game; import java.io.IOException; @@ -132,7 +131,7 @@ import org.apache.log4j.Logger; public abstract class GameImpl implements Game, Serializable { private static final int ROLLBACK_TURNS_MAX = 4; - + private static final transient Logger logger = Logger.getLogger(GameImpl.class); private static final FilterPermanent filterAura = new FilterPermanent(); @@ -155,19 +154,18 @@ public abstract class GameImpl implements Game, Serializable { private static Random rnd = new Random(); - private transient Object customData; protected boolean simulation = false; - protected final UUID id; - + protected final UUID id; + protected boolean ready; protected transient TableEventSource tableEventSource = new TableEventSource(); protected transient PlayerQueryEventSource playerQueryEventSource = new PlayerQueryEventSource(); protected Map gameCards = new HashMap<>(); - - protected Map> lki = new EnumMap<>(Zone.class); + + protected Map> lki = new EnumMap<>(Zone.class); protected Map> lkiExtended = new HashMap<>(); // Used to check if an object was moved by the current effect in resolution (so Wrath like effect can be handled correctly) protected Map> shortLivingLKI = new EnumMap<>(Zone.class); @@ -283,19 +281,19 @@ public abstract class GameImpl implements Game, Serializable { @Override public void loadCards(Set cards, UUID ownerId) { - for (Card card: cards) { + for (Card card : cards) { if (card instanceof PermanentCard) { - card = ((PermanentCard)card).getCard(); + card = ((PermanentCard) card).getCard(); } card.setOwnerId(ownerId); gameCards.put(card.getId(), card); state.addCard(card); if (card.isSplitCard()) { - Card leftCard = ((SplitCard)card).getLeftHalfCard(); + Card leftCard = ((SplitCard) card).getLeftHalfCard(); leftCard.setOwnerId(ownerId); gameCards.put(leftCard.getId(), leftCard); state.addCard(leftCard); - Card rightCard = ((SplitCard)card).getRightHalfCard(); + Card rightCard = ((SplitCard) card).getRightHalfCard(); rightCard.setOwnerId(ownerId); gameCards.put(rightCard.getId(), rightCard); state.addCard(rightCard); @@ -332,7 +330,7 @@ public abstract class GameImpl implements Game, Serializable { return state.getPlayer(playerId); } - @Override + @Override public MageObject getObject(UUID objectId) { if (objectId == null) { return null; @@ -343,7 +341,7 @@ public abstract class GameImpl implements Game, Serializable { state.setZone(objectId, Zone.BATTLEFIELD); return object; } - for (StackObject item: state.getStack()) { + for (StackObject item : state.getStack()) { if (item.getId().equals(objectId)) { state.setZone(objectId, Zone.STACK); return item; @@ -374,6 +372,40 @@ public abstract class GameImpl implements Game, Serializable { return object; } + /** + * Get permanent, card or command object (not spell or ability on the stack) + * + * @param objectId + * @return + */ + @Override + public MageObject getBaseObject(UUID objectId) { + if (objectId == null) { + return null; + } + MageObject object; + if (state.getBattlefield().containsPermanent(objectId)) { + object = state.getBattlefield().getPermanent(objectId); + return object; + } + for (CommandObject commandObject : state.getCommand()) { + if (commandObject instanceof Commander && commandObject.getId().equals(objectId)) { + return commandObject; + } + } + object = getCard(objectId); + if (object == null) { + for (CommandObject commandObject : state.getCommand()) { + if (commandObject.getId().equals(objectId)) { + return commandObject; + } + } + // can be an ability of a sacrificed Token trying to get it's source object + object = getLastKnownInformation(objectId, Zone.BATTLEFIELD); + } + return object; + } + @Override public MageObject getEmblem(UUID objectId) { if (objectId == null) { @@ -395,24 +427,24 @@ public abstract class GameImpl implements Game, Serializable { MageObject object = getObject(objectId); if (object != null) { if (object instanceof StackObject) { - return ((StackObject)object).getControllerId(); + return ((StackObject) object).getControllerId(); } else if (object instanceof Permanent) { - return ((Permanent)object).getControllerId(); + return ((Permanent) object).getControllerId(); } else if (object instanceof CommandObject) { - return ((CommandObject)object).getControllerId(); - } + return ((CommandObject) object).getControllerId(); + } UUID controllerId = getContinuousEffects().getControllerOfSourceId(objectId); if (controllerId != null) { return controllerId; } // TODO: When is a player the damage source itself? If not possible remove this Player player = getPlayer(objectId); - if (player != null){ + if (player != null) { return player.getId(); } // No object with controller found so return owner if possible if (object instanceof Card) { - return ((Card)object).getOwnerId(); + return ((Card) object).getOwnerId(); } } return null; @@ -457,7 +489,6 @@ public abstract class GameImpl implements Game, Serializable { // public Zone getZone(UUID objectId) { // return state.getZone(objectId); // } - @Override public void setZone(UUID objectId, Zone zone) { state.setZone(objectId, zone); @@ -483,8 +514,8 @@ public abstract class GameImpl implements Game, Serializable { } /** - * Starts check if game is over or - * if playerId is given let the player concede. + * Starts check if game is over or if playerId is given let the player + * concede. * * @param playerId * @return @@ -494,21 +525,20 @@ public abstract class GameImpl implements Game, Serializable { if (playerId == null) { boolean result = checkIfGameIsOver(); return result; - } else { + } else { logger.debug("Game over for player Id: " + playerId + " gameId " + getId()); leave(playerId); return true; } } - private boolean checkIfGameIsOver() { if (state.isGameOver()) { return true; } int remainingPlayers = 0; int numLosers = 0; - for (Player player: state.getPlayers().values()) { + for (Player player : state.getPlayers().values()) { if (!player.hasLeft()) { remainingPlayers++; } @@ -520,11 +550,11 @@ public abstract class GameImpl implements Game, Serializable { end(); if (remainingPlayers == 0 && logger.isDebugEnabled()) { logger.debug("DRAW for gameId: " + getId()); - for (Player player: state.getPlayers().values()) { - logger.debug("-- " + player.getName() + " left: " + (player.hasLeft() ? "Y":"N") + " lost: " + (player.hasLost()? "Y":"N")); - } + for (Player player : state.getPlayers().values()) { + logger.debug("-- " + player.getName() + " left: " + (player.hasLeft() ? "Y" : "N") + " lost: " + (player.hasLost() ? "Y" : "N")); + } } - for (Player player: state.getPlayers().values()) { + for (Player player : state.getPlayers().values()) { if (!player.hasLeft() && !player.hasLost()) { logger.debug(new StringBuilder("Player ").append(player.getName()).append(" has won gameId: ").append(this.getId())); player.won(this); @@ -550,7 +580,7 @@ public abstract class GameImpl implements Game, Serializable { if (winnerId == null) { return "Game is a draw"; } - return "Player "+ state.getPlayer(winnerId).getName() + " is the winner"; + return "Player " + state.getPlayer(winnerId).getName() + " is the winner"; } @Override @@ -576,7 +606,7 @@ public abstract class GameImpl implements Game, Serializable { if (!simulation && !this.hasEnded()) { // if player left or game is over no undo is possible - this could lead to wrong winner if (bookmark != 0) { if (!savedStates.contains(bookmark - 1)) { - throw new UnsupportedOperationException("It was not possible to do the requested undo operation (bookmark " + (bookmark -1) + " does not exist) context: " + context); + throw new UnsupportedOperationException("It was not possible to do the requested undo operation (bookmark " + (bookmark - 1) + " does not exist) context: " + context); } int stateNum = savedStates.get(bookmark - 1); removeBookmark(bookmark); @@ -677,16 +707,16 @@ public abstract class GameImpl implements Game, Serializable { winnerId = findWinnersAndLosers(); StringBuilder sb = new StringBuilder("GAME END gameId: ").append(this.getId()).append(" "); int count = 0; - for (Player player: this.getState().getPlayers().values()) { + for (Player player : this.getState().getPlayers().values()) { if (count > 0) { sb.append(" - "); } sb.append("[").append(player.getName()).append(" => "); - sb.append(player.hasWon() ? "W":""); - sb.append(player.hasLost()? "L":""); - sb.append(player.hasQuit() ? "Q":""); - sb.append(player.hasIdleTimeout() ? "I":""); - sb.append(player.hasTimerTimeout() ? "T":""); + sb.append(player.hasWon() ? "W" : ""); + sb.append(player.hasLost() ? "L" : ""); + sb.append(player.hasQuit() ? "Q" : ""); + sb.append(player.hasIdleTimeout() ? "I" : ""); + sb.append(player.hasTimerTimeout() ? "T" : ""); sb.append("]"); count++; } @@ -715,12 +745,12 @@ public abstract class GameImpl implements Game, Serializable { } state.setTurnId(null); state.setExtraTurn(false); - + } - + private TurnMod getNextExtraTurn() { boolean checkForExtraTurn = true; - while(checkForExtraTurn) { + while (checkForExtraTurn) { TurnMod extraTurn = getState().getTurnMods().getNextExtraTurn(); if (extraTurn != null) { GameEvent event = new GameEvent(GameEvent.EventType.EXTRA_TURN, extraTurn.getId(), null, extraTurn.getPlayerId()); @@ -733,20 +763,20 @@ public abstract class GameImpl implements Game, Serializable { } return null; } - + private boolean playTurn(Player player) { do { if (executingRollback) { executingRollback = false; player = getPlayer(state.getActivePlayerId()); - for (Player playerObject: getPlayers().values()) { + for (Player playerObject : getPlayers().values()) { if (playerObject.isInGame()) { playerObject.abortReset(); } } } else { state.setActivePlayerId(player.getId()); - saveRollBackGameState(); + saveRollBackGameState(); } this.logStartOfTurn(player); if (checkStopOnTurnOption()) { @@ -754,7 +784,7 @@ public abstract class GameImpl implements Game, Serializable { } state.getTurn().play(this, player); } while (executingRollback); - + if (isPaused() || gameOver(null)) { return false; } @@ -763,7 +793,6 @@ public abstract class GameImpl implements Game, Serializable { return true; } - private void logStartOfTurn(Player player) { StringBuilder sb = new StringBuilder("Turn ").append(state.getTurnNum()).append(" "); sb.append(player.getLogName()); @@ -796,7 +825,7 @@ public abstract class GameImpl implements Game, Serializable { } protected void init(UUID choosingPlayerId) { - for (Player player: state.getPlayers().values()) { + for (Player player : state.getPlayers().values()) { player.beginTurn(this); // init only if match is with timer (>0) and time left was not set yet (== MAX_VALUE). // otherwise the priorityTimeLeft is set in {@link MatchImpl.initGame) @@ -817,7 +846,7 @@ public abstract class GameImpl implements Game, Serializable { //20091005 - 103.1 if (!gameOptions.skipInitShuffling) { //don't shuffle in test mode for card injection on top of player's libraries - for (Player player: state.getPlayers().values()) { + for (Player player : state.getPlayers().values()) { player.shuffleLibrary(this); } } @@ -831,7 +860,7 @@ public abstract class GameImpl implements Game, Serializable { } if (choosingPlayer == null) { choosingPlayerId = pickChoosingPlayer(); - choosingPlayer = getPlayer(choosingPlayerId); + choosingPlayer = getPlayer(choosingPlayerId); } getState().setChoosingPlayerId(choosingPlayerId); // needed to start/stop the timer if active if (choosingPlayer != null && choosingPlayer.choose(Outcome.Benefit, targetPlayer, null, this)) { @@ -845,15 +874,14 @@ public abstract class GameImpl implements Game, Serializable { } message.append(" takes the first turn"); - this.informPlayers(message.toString()); + this.informPlayers(message.toString()); } else { // not possible to choose starting player, stop here return; } - //20091005 - 103.3 - for (UUID playerId: state.getPlayerList(startingPlayerId)) { + for (UUID playerId : state.getPlayerList(startingPlayerId)) { Player player = getPlayer(playerId); if (!gameOptions.testMode || player.getLife() == 0) { player.initLife(this.getLife()); @@ -903,7 +931,7 @@ public abstract class GameImpl implements Game, Serializable { } while (!mulliganPlayers.isEmpty()); getState().setChoosingPlayerId(null); Watchers watchers = state.getWatchers(); - // add default watchers + // add default watchers for (UUID playerId : state.getPlayerList(startingPlayerId)) { watchers.add(new PlayerDamagedBySourceWatcher(playerId)); watchers.add(new BloodthirstWatcher(playerId)); @@ -916,18 +944,18 @@ public abstract class GameImpl implements Game, Serializable { watchers.add(new DamageDoneWatcher()); //20100716 - 103.5 - for (UUID playerId: state.getPlayerList(startingPlayerId)) { + for (UUID playerId : state.getPlayerList(startingPlayerId)) { Player player = getPlayer(playerId); - for (Card card: player.getHand().getCards(this)) { + for (Card card : player.getHand().getCards(this)) { if (player.getHand().contains(card.getId())) { if (card.getAbilities().containsKey(LeylineAbility.getInstance().getId())) { - if (player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getName() + " on the battlefield?", this)) { + if (player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getName() + " on the battlefield?", null, this)) { card.putOntoBattlefield(this, Zone.HAND, null, player.getId()); } } - for (Ability ability: card.getAbilities()) { + for (Ability ability : card.getAbilities()) { if (ability instanceof ChancellorAbility) { - if (player.chooseUse(Outcome.PutCardInPlay, "Do you wish to reveal " + card.getName() + "?", this)) { + if (player.chooseUse(Outcome.PutCardInPlay, "Do you wish to reveal " + card.getName() + "?", ability, this)) { Cards cards = new CardsImpl(); cards.add(card); player.revealCards("Revealed", cards, this); @@ -936,7 +964,7 @@ public abstract class GameImpl implements Game, Serializable { } if (ability instanceof GemstoneCavernsAbility) { if (!playerId.equals(startingPlayerId)) { - if (player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getName() + " into play?", this)) { + if (player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getName() + " into play?", ability, this)) { Cards cards = new CardsImpl(); cards.add(card); player.revealCards("Revealed", cards, this); @@ -952,7 +980,7 @@ public abstract class GameImpl implements Game, Serializable { protected UUID findWinnersAndLosers() { UUID winnerIdFound = null; - for (Player player: state.getPlayers().values()) { + for (Player player : state.getPlayers().values()) { if (player.hasWon()) { logger.debug(player.getName() + " has won gameId: " + getId()); winnerIdFound = player.getId(); @@ -965,7 +993,7 @@ public abstract class GameImpl implements Game, Serializable { break; } } - for (Player player: state.getPlayers().values()) { + for (Player player : state.getPlayers().values()) { if (winnerIdFound != null && !player.getId().equals(winnerIdFound) && !player.hasLost()) { player.lost(this); } @@ -974,7 +1002,7 @@ public abstract class GameImpl implements Game, Serializable { } protected void endOfTurn() { - for (Player player: getPlayers().values()) { + for (Player player : getPlayers().values()) { player.endOfTurn(this); } state.getWatchers().reset(); @@ -1003,7 +1031,7 @@ public abstract class GameImpl implements Game, Serializable { logger.debug("END of gameId: " + this.getId()); endTime = new Date(); state.endGame(); - for (Player player: state.getPlayers().values()) { + for (Player player : state.getPlayers().values()) { player.abort(); } } @@ -1021,7 +1049,7 @@ public abstract class GameImpl implements Game, Serializable { if (freeMulligans > 0) { if (usedFreeMulligans != null && usedFreeMulligans.containsKey(player.getId())) { int used = usedFreeMulligans.get(player.getId()); - if (used < freeMulligans ) { + if (used < freeMulligans) { deduction = 0; } } else { @@ -1032,7 +1060,7 @@ public abstract class GameImpl implements Game, Serializable { } @Override - public void endMulligan(UUID playerId){ + public void endMulligan(UUID playerId) { } @Override @@ -1046,9 +1074,9 @@ public abstract class GameImpl implements Game, Serializable { if (freeMulligans > 0) { if (usedFreeMulligans != null && usedFreeMulligans.containsKey(player.getId())) { int used = usedFreeMulligans.get(player.getId()); - if (used < freeMulligans ) { + if (used < freeMulligans) { deduction = 0; - usedFreeMulligans.put(player.getId(), used+1); + usedFreeMulligans.put(player.getId(), used + 1); } } else { deduction = 0; @@ -1057,9 +1085,9 @@ public abstract class GameImpl implements Game, Serializable { } fireInformEvent(new StringBuilder(player.getLogName()) .append(" mulligans") - .append(deduction == 0 ? " for free and draws ":" down to ") + .append(deduction == 0 ? " for free and draws " : " down to ") .append(Integer.toString(numCards - deduction)) - .append(numCards - deduction == 1? " card":" cards").toString()); + .append(numCards - deduction == 1 ? " card" : " cards").toString()); player.drawCards(numCards - deduction, this); } @@ -1072,7 +1100,6 @@ public abstract class GameImpl implements Game, Serializable { // } // } // } - @Override public synchronized void timerTimeout(UUID playerId) { Player player = state.getPlayer(playerId); @@ -1115,15 +1142,14 @@ public abstract class GameImpl implements Game, Serializable { } } } - + @Override public void sendPlayerAction(PlayerAction playerAction, UUID playerId) { Player player = state.getPlayer(playerId); if (player != null) { player.sendPlayerAction(playerAction, this); - } + } } - @Override public synchronized void setManaPaymentMode(UUID playerId, boolean autoPayment) { @@ -1132,27 +1158,26 @@ public abstract class GameImpl implements Game, Serializable { player.getManaPool().setAutoPayment(autoPayment); } } - + @Override public synchronized void setManaPaymentModeRestricted(UUID playerId, boolean autoPaymentRestricted) { Player player = state.getPlayer(playerId); if (player != null) { player.getManaPool().setAutoPaymentRestricted(autoPaymentRestricted); } - } + } @Override public void playPriority(UUID activePlayerId, boolean resuming) { int bookmark = 0; clearAllBookmarks(); try { - applyEffects(); + applyEffects(); while (!isPaused() && !gameOver(null) && !this.getTurn().isEndTurnRequested()) { if (!resuming) { state.getPlayers().resetPassed(); state.getPlayerList().setCurrent(activePlayerId); - } - else { + } else { state.getPlayerList().setCurrent(this.getPriorityPlayerId()); } fireUpdatePlayersEvent(); @@ -1171,14 +1196,14 @@ public abstract class GameImpl implements Game, Serializable { applyEffects(); if (state.getStack().isEmpty()) { resetLKI(); - } + } saveState(false); if (isPaused() || gameOver(null)) { return; } // resetPassed should be called if player performs any action if (player.priority(this)) { - if(executingRollback()) { + if (executingRollback()) { return; } applyEffects(); @@ -1201,15 +1226,14 @@ public abstract class GameImpl implements Game, Serializable { applyEffects(); state.getPlayers().resetPassed(); fireUpdatePlayersEvent(); - resetShortLivingLKI(); + resetShortLivingLKI(); break; } else { resetLKI(); return; } } - } - catch (Exception ex) { + } catch (Exception ex) { logger.fatal("Game exception gameId: " + getId(), ex); ex.printStackTrace(); this.fireErrorEvent("Game exception occurred: ", ex); @@ -1237,19 +1261,19 @@ public abstract class GameImpl implements Game, Serializable { top.resolve(this); } finally { if (top != null) { - state.getStack().remove(top); // seems partly redundant because move card from stack to grave is already done and the stack removed + state.getStack().remove(top); // seems partly redundant because move card from stack to grave is already done and the stack removed rememberLKI(top.getSourceId(), Zone.STACK, top); if (!getTurn().isEndTurnRequested()) { while (state.hasSimultaneousEvents()) { state.handleSimultaneousEvent(this); } - } + } } } } protected boolean allPassed() { - for (Player player: state.getPlayers().values()) { + for (Player player : state.getPlayers().values()) { if (!player.isPassed() && player.isInGame()) { return false; } @@ -1259,7 +1283,7 @@ public abstract class GameImpl implements Game, Serializable { @Override public void emptyManaPools() { - for (Player player: getPlayers().values()) { + for (Player player : getPlayers().values()) { player.getManaPool().emptyPool(this); } } @@ -1302,9 +1326,8 @@ public abstract class GameImpl implements Game, Serializable { state.addCommandObject(newEmblem); } - @Override - public void addCommander(Commander commander){ + public void addCommander(Commander commander) { state.addCommandObject(commander); } @@ -1331,14 +1354,14 @@ public abstract class GameImpl implements Game, Serializable { MageObject oldBluePrint = ((CopyEffect) effect).getTarget(); if (oldBluePrint instanceof Permanent) { // copy it and apply the applier if any - newBluePrint = ((Permanent)oldBluePrint).copy(); + newBluePrint = ((Permanent) oldBluePrint).copy(); } } } } // if it was no copy of copy take the target itself if (newBluePrint == null) { - newBluePrint = copyFromPermanent.copy(); + newBluePrint = copyFromPermanent.copy(); newBluePrint.reset(this); //getState().addCard(permanent); if (copyFromPermanent.isMorphed() || copyFromPermanent.isManifested()) { @@ -1347,7 +1370,7 @@ public abstract class GameImpl implements Game, Serializable { newBluePrint.assignNewId(); if (copyFromPermanent.isTransformed()) { TransformAbility.transform(newBluePrint, copyFromPermanent.getSecondCardFace(), this); - } + } } if (applier != null) { applier.apply(this, newBluePrint); @@ -1358,7 +1381,6 @@ public abstract class GameImpl implements Game, Serializable { newEffect.setApplier(applier); Ability newAbility = source.copy(); newEffect.init(newAbility, this); - state.addEffect(newEffect, newAbility); return newBluePrint; @@ -1376,8 +1398,7 @@ public abstract class GameImpl implements Game, Serializable { Ability manaAbiltiy = ability.copy(); manaAbiltiy.activate(this, false); manaAbiltiy.resolve(this); - } - else { + } else { TriggeredAbility newAbility = ability.copy(); newAbility.newId(); state.addTriggeredAbility(newAbility); @@ -1394,26 +1415,28 @@ public abstract class GameImpl implements Game, Serializable { } /** - * 116.5. Each time a player would get priority, the game first performs all applicable state-based actions as a single event (see rule 704, - * “State-Based Actions”), then repeats this process until no state-based actions are performed. Then triggered abilities are put on the stack - * (see rule 603, “Handling Triggered Abilities”). These steps repeat in order until no further state-based actions are performed and no abilities - * trigger. Then the player who would have received priority does so. - * - * @return - */ - + * 116.5. Each time a player would get priority, the game first performs all + * applicable state-based actions as a single event (see rule 704, + * “State-Based Actions”), then repeats this process until no state-based + * actions are performed. Then triggered abilities are put on the stack (see + * rule 603, “Handling Triggered Abilities”). These steps repeat in order + * until no further state-based actions are performed and no abilities + * trigger. Then the player who would have received priority does so. + * + * @return + */ @Override public boolean checkStateAndTriggered() { boolean trigger = !getTurn().isEndTurnRequested(); boolean somethingHappened = false; //20091005 - 115.5 while (!isPaused() && !gameOver(null)) { - if (!checkStateBasedActions() ) { + if (!checkStateBasedActions()) { // nothing happened so check triggers if (trigger) { state.handleSimultaneousEvent(this); } - if (isPaused() || gameOver(null) || !trigger || !checkTriggered()) { + if (isPaused() || gameOver(null) || !trigger || !checkTriggered()) { break; } } @@ -1422,15 +1445,16 @@ public abstract class GameImpl implements Game, Serializable { } return somethingHappened; } + /** - * Sets the waiting triggered abilities (if there are any) - * to the stack in the choosen order by player + * Sets the waiting triggered abilities (if there are any) to the stack in + * the choosen order by player * * @return */ public boolean checkTriggered() { boolean played = false; - for (UUID playerId: state.getPlayerList(state.getActivePlayerId())) { + for (UUID playerId : state.getPlayerList(state.getActivePlayerId())) { Player player = getPlayer(playerId); while (player.isInGame()) { // player can die or win caused by triggered abilities or leave the game List abilities = state.getTriggered(player.getId()); @@ -1452,8 +1476,7 @@ public abstract class GameImpl implements Game, Serializable { if (abilities.size() == 1) { state.removeTriggeredAbility(abilities.get(0)); played |= player.triggerAbility(abilities.get(0), this); - } - else { + } else { TriggeredAbility ability = player.chooseTriggeredAbility(abilities, this); if (ability != null) { state.removeTriggeredAbility(ability); @@ -1466,17 +1489,21 @@ public abstract class GameImpl implements Game, Serializable { } /** - * 116.5. Each time a player would get priority, the game first performs all applicable state-based actions as a single event (see rule 704, - * “State-Based Actions”), then repeats this process until no state-based actions are performed. Then triggered abilities are put on the stack - * (see rule 603, “Handling Triggered Abilities”). These steps repeat in order until no further state-based actions are performed and no abilities - * trigger. Then the player who would have received priority does so. - * @return + * 116.5. Each time a player would get priority, the game first performs all + * applicable state-based actions as a single event (see rule 704, + * “State-Based Actions”), then repeats this process until no state-based + * actions are performed. Then triggered abilities are put on the stack (see + * rule 603, “Handling Triggered Abilities”). These steps repeat in order + * until no further state-based actions are performed and no abilities + * trigger. Then the player who would have received priority does so. + * + * @return */ protected boolean checkStateBasedActions() { boolean somethingHappened = false; //20091005 - 704.5a/704.5b/704.5c - for (Player player: state.getPlayers().values()) { + for (Player player : state.getPlayers().values()) { if (!player.hasLost() && ((player.getLife() <= 0 && player.canLoseByZeroOrLessLife()) || player.isEmptyDraw() @@ -1494,7 +1521,7 @@ public abstract class GameImpl implements Game, Serializable { if (zone != Zone.BATTLEFIELD && zone != Zone.STACK) { switch (zone) { case GRAVEYARD: - for(Player player: getPlayers().values()) { + for (Player player : getPlayers().values()) { if (player.getGraveyard().contains(card.getId())) { player.getGraveyard().remove(card); break; @@ -1502,7 +1529,7 @@ public abstract class GameImpl implements Game, Serializable { } break; case HAND: - for(Player player: getPlayers().values()) { + for (Player player : getPlayers().values()) { if (player.getHand().contains(card.getId())) { player.getHand().remove(card); break; @@ -1510,7 +1537,7 @@ public abstract class GameImpl implements Game, Serializable { } break; case LIBRARY: - for(Player player: getPlayers().values()) { + for (Player player : getPlayers().values()) { if (player.getLibrary().getCard(card.getId(), this) != null) { player.getLibrary().remove(card.getId(), this); break; @@ -1524,11 +1551,11 @@ public abstract class GameImpl implements Game, Serializable { copiedCards.remove(); } } - + List planeswalkers = new ArrayList<>(); List legendary = new ArrayList<>(); List worldEnchantment = new ArrayList<>(); - for (Permanent perm: getBattlefield().getAllActivePermanents()) { + for (Permanent perm : getBattlefield().getAllActivePermanents()) { if (perm.getCardType().contains(CardType.CREATURE)) { //20091005 - 704.5f if (perm.getToughness().getValue() <= 0) { @@ -1536,8 +1563,7 @@ public abstract class GameImpl implements Game, Serializable { somethingHappened = true; continue; } - } - //20091005 - 704.5g/704.5h + } //20091005 - 704.5g/704.5h else if (perm.getToughness().getValue() <= perm.getDamage() || perm.isDeathtouched()) { if (perm.destroy(null, this, false)) { somethingHappened = true; @@ -1587,8 +1613,7 @@ public abstract class GameImpl implements Game, Serializable { somethingHappened = true; } } - } - else { + } else { if (perm.getSpellAbility().getTargets().isEmpty()) { Permanent enchanted = this.getPermanent(perm.getAttachedTo()); logger.error("Aura without target: " + perm.getName() + " attached to " + (enchanted == null ? " null" : enchanted.getName())); @@ -1608,11 +1633,10 @@ public abstract class GameImpl implements Game, Serializable { somethingHappened = true; } } - } - else { + } else { Filter auraFilter = perm.getSpellAbility().getTargets().get(0).getFilter(); if (auraFilter instanceof FilterControlledCreaturePermanent) { - if (!((FilterControlledCreaturePermanent)auraFilter).match(attachedTo, perm.getId(), perm.getControllerId(), this) + if (!((FilterControlledCreaturePermanent) auraFilter).match(attachedTo, perm.getId(), perm.getControllerId(), this) || attachedTo.cantBeEnchantedBy(perm, this)) { if (movePermanentToGraveyardWithInfo(perm)) { somethingHappened = true; @@ -1634,15 +1658,13 @@ public abstract class GameImpl implements Game, Serializable { } } } - } - else if (target instanceof TargetPlayer) { + } else if (target instanceof TargetPlayer) { Player attachedToPlayer = getPlayer(perm.getAttachedTo()); if (attachedToPlayer == null) { if (movePermanentToGraveyardWithInfo(perm)) { somethingHappened = true; } - } - else { + } else { Filter auraFilter = perm.getSpellAbility().getTargets().get(0).getFilter(); if (!auraFilter.match(attachedToPlayer, this) || attachedToPlayer.hasProtectionFrom(perm, this)) { if (movePermanentToGraveyardWithInfo(perm)) { @@ -1677,8 +1699,7 @@ public abstract class GameImpl implements Game, Serializable { Permanent land = getPermanent(perm.getAttachedTo()); if (land == null || !land.getAttachments().contains(perm.getId())) { perm.attachTo(null, this); - } - else if (!land.getCardType().contains(CardType.LAND) || land.hasProtectionFrom(perm, this)) { + } else if (!land.getCardType().contains(CardType.LAND) || land.hasProtectionFrom(perm, this)) { if (land.removeAttachment(perm.getId(), this)) { somethingHappened = true; } @@ -1691,11 +1712,11 @@ public abstract class GameImpl implements Game, Serializable { if (perm.getAttachments().size() > 0) { for (UUID attachmentId : perm.getAttachments()) { Permanent attachment = getPermanent(attachmentId); - if (attachment != null && - (attachment.getCardType().contains(CardType.CREATURE) || - !(attachment.getSubtype().contains("Aura") - || attachment.getSubtype().contains("Equipment") - || attachment.getSubtype().contains("Fortification")))) { + if (attachment != null + && (attachment.getCardType().contains(CardType.CREATURE) + || !(attachment.getSubtype().contains("Aura") + || attachment.getSubtype().contains("Equipment") + || attachment.getSubtype().contains("Fortification")))) { if (perm.removeAttachment(attachment.getId(), this)) { somethingHappened = true; break; @@ -1719,8 +1740,8 @@ public abstract class GameImpl implements Game, Serializable { // chooses one of them, and the rest are put into their owners' graveyards. // This is called the "planeswalker uniqueness rule." if (planeswalkers.size() > 1) { //don't bother checking if less than 2 planeswalkers in play - for (Permanent planeswalker: planeswalkers) { - for (String planeswalkertype: planeswalker.getSubtype()) { + for (Permanent planeswalker : planeswalkers) { + for (String planeswalkertype : planeswalker.getSubtype()) { FilterPlaneswalkerPermanent filterPlaneswalker = new FilterPlaneswalkerPermanent(); filterPlaneswalker.add(new SubtypePredicate(planeswalkertype)); filterPlaneswalker.add(new ControllerIdPredicate(planeswalker.getControllerId())); @@ -1730,7 +1751,7 @@ public abstract class GameImpl implements Game, Serializable { Target targetPlaneswalkerToKeep = new TargetPermanent(filterPlaneswalker); targetPlaneswalkerToKeep.setTargetName(new StringBuilder(planeswalker.getName()).append(" to keep?").toString()); controller.chooseTarget(Outcome.Benefit, targetPlaneswalkerToKeep, null, this); - for (Permanent dupPlaneswalker: this.getBattlefield().getActivePermanents(filterPlaneswalker, planeswalker.getControllerId(), this)) { + for (Permanent dupPlaneswalker : this.getBattlefield().getActivePermanents(filterPlaneswalker, planeswalker.getControllerId(), this)) { if (!targetPlaneswalkerToKeep.getTargets().contains(dupPlaneswalker.getId())) { movePermanentToGraveyardWithInfo(dupPlaneswalker); } @@ -1747,7 +1768,7 @@ public abstract class GameImpl implements Game, Serializable { // This is called the "legend rule." if (legendary.size() > 1) { //don't bother checking if less than 2 legends in play - for (Permanent legend: legendary) { + for (Permanent legend : legendary) { FilterPermanent filterLegendName = new FilterPermanent(); filterLegendName.add(new SupertypePredicate("Legendary")); filterLegendName.add(new NamePredicate(legend.getName())); @@ -1758,7 +1779,7 @@ public abstract class GameImpl implements Game, Serializable { Target targetLegendaryToKeep = new TargetPermanent(filterLegendName); targetLegendaryToKeep.setTargetName(new StringBuilder(legend.getName()).append(" to keep (Legendary Rule)?").toString()); controller.chooseTarget(Outcome.Benefit, targetLegendaryToKeep, null, this); - for (Permanent dupLegend: getBattlefield().getActivePermanents(filterLegendName, legend.getControllerId(), this)) { + for (Permanent dupLegend : getBattlefield().getActivePermanents(filterLegendName, legend.getControllerId(), this)) { if (!targetLegendaryToKeep.getTargets().contains(dupLegend.getId())) { movePermanentToGraveyardWithInfo(dupLegend); } @@ -1769,21 +1790,21 @@ public abstract class GameImpl implements Game, Serializable { } } //704.5m - World Enchantments - if (worldEnchantment.size() > 1) { + if (worldEnchantment.size() > 1) { int newestCard = -1; Permanent newestPermanent = null; - for (Permanent permanent :worldEnchantment) { + for (Permanent permanent : worldEnchantment) { if (newestCard == -1) { newestCard = permanent.getCreateOrder(); newestPermanent = permanent; } else if (newestCard < permanent.getCreateOrder()) { newestCard = permanent.getCreateOrder(); newestPermanent = permanent; - } else if(newestCard == permanent.getCreateOrder()) { + } else if (newestCard == permanent.getCreateOrder()) { newestPermanent = null; } } - for (Permanent permanent :worldEnchantment) { + for (Permanent permanent : worldEnchantment) { if (newestPermanent != permanent) { movePermanentToGraveyardWithInfo(permanent); somethingHappened = true; @@ -1819,9 +1840,8 @@ public abstract class GameImpl implements Game, Serializable { String message; if (this.canPlaySorcery(playerId)) { message = "Play spells and abilities."; - } - else { - message = "Play instants and activated abilities."; + } else { + message = "Play instants and activated abilities."; } playerQueryEventSource.select(playerId, message); } @@ -1834,7 +1854,6 @@ public abstract class GameImpl implements Game, Serializable { playerQueryEventSource.select(playerId, message); } - @Override public synchronized void fireSelectEvent(UUID playerId, String message, Map options) { if (simulation) { @@ -1979,7 +1998,7 @@ public abstract class GameImpl implements Game, Serializable { } logger.trace("fireUpdatePlayersEvent"); tableEventSource.fireTableEvent(EventType.UPDATE, null, this); - getState().clearLookedAt(); + getState().clearLookedAt(); getState().clearRevealed(); } @@ -2058,22 +2077,23 @@ public abstract class GameImpl implements Game, Serializable { } /** - * 800.4a When a player leaves the game, all objects (see rule 109) owned by that player leave - * the game and any effects which give that player control of any objects or players end. Then, - * if that player controlled any objects on the stack not represented by cards, those objects - * cease to exist. Then, if there are any objects still controlled by that player, those objects - * are exiled. This is not a state-based action. It happens as soon as the player leaves the game. - * If the player who left the game had priority at the time he or she left, priority passes to - * the next player in turn order who's still in the game. # + * 800.4a When a player leaves the game, all objects (see rule 109) owned by + * that player leave the game and any effects which give that player control + * of any objects or players end. Then, if that player controlled any + * objects on the stack not represented by cards, those objects cease to + * exist. Then, if there are any objects still controlled by that player, + * those objects are exiled. This is not a state-based action. It happens as + * soon as the player leaves the game. If the player who left the game had + * priority at the time he or she left, priority passes to the next player + * in turn order who's still in the game. # * * @param playerId */ - protected void leave(UUID playerId) { Player player = getPlayer(playerId); if (player == null || player.hasLeft()) { - logger.debug("Player already left " + (player != null ? player.getName():playerId)); + logger.debug("Player already left " + (player != null ? player.getName() : playerId)); return; } logger.debug("Start leave game: " + player.getName()); @@ -2114,12 +2134,12 @@ public abstract class GameImpl implements Game, Serializable { } // Then, if there are any objects still controlled by that player, those objects are exiled. List permanents = this.getBattlefield().getAllActivePermanents(playerId); - for(Permanent permanent : permanents) { + for (Permanent permanent : permanents) { permanent.moveToExile(null, "", null, this); } // Remove cards from the player in all exile zones - for (ExileZone exile: this.getExile().getExileZones()) { + for (ExileZone exile : this.getExile().getExileZones()) { for (Iterator it = exile.iterator(); it.hasNext();) { Card card = this.getCard(it.next()); if (card != null && card.getOwnerId().equals(playerId)) { @@ -2129,8 +2149,8 @@ public abstract class GameImpl implements Game, Serializable { } Iterator it = gameCards.entrySet().iterator(); - while(it.hasNext()) { - Entry entry = (Entry) it.next(); + while (it.hasNext()) { + Entry entry = (Entry) it.next(); Card card = entry.getValue(); if (card.getOwnerId().equals(playerId)) { it.remove(); @@ -2139,7 +2159,6 @@ public abstract class GameImpl implements Game, Serializable { // 801.2c The particular players within each player‘s range of influence are determined as each turn begins. // So no update of range if influence yet - } @Override @@ -2229,7 +2248,6 @@ public abstract class GameImpl implements Game, Serializable { } - protected void removeCreaturesFromCombat() { //20091005 - 511.3 getCombat().endCombat(this); @@ -2250,8 +2268,9 @@ public abstract class GameImpl implements Game, Serializable { } /** - * Gets last known information about object in the zone. - * At the moment doesn't take into account zone (it is expected that it doesn't really matter, if not, then Map> should be used instead). + * Gets last known information about object in the zone. At the moment + * doesn't take into account zone (it is expected that it doesn't really + * matter, if not, then Map> should be used instead). * * Can return null. * @@ -2262,17 +2281,17 @@ public abstract class GameImpl implements Game, Serializable { @Override public MageObject getLastKnownInformation(UUID objectId, Zone zone) { /*if (!lki.containsKey(objectId)) { - return getCard(objectId); - }*/ + return getCard(objectId); + }*/ Map lkiMap = lki.get(zone); if (lkiMap != null) { MageObject object = lkiMap.get(objectId); if (object != null) { return object.copy(); } - for (MageObject mageObject:lkiMap.values()) { + for (MageObject mageObject : lkiMap.values()) { if (mageObject instanceof Spell) { - if (((Spell)mageObject).getCard().getId().equals(objectId)) { + if (((Spell) mageObject).getCard().getId().equals(objectId)) { return mageObject; } } @@ -2335,7 +2354,7 @@ public abstract class GameImpl implements Game, Serializable { idSet = new HashSet<>(); shortLivingLKI.put(zone, idSet); } - idSet.add(objectId); + idSet.add(objectId); if (object instanceof Permanent) { Map lkiExtendedMap = lkiExtended.get(objectId); if (lkiExtendedMap != null) { @@ -2393,7 +2412,6 @@ public abstract class GameImpl implements Game, Serializable { } } - } break; } @@ -2403,7 +2421,7 @@ public abstract class GameImpl implements Game, Serializable { } @Override - public Map> getLKI() { + public Map> getLKI() { return lki; } @@ -2433,7 +2451,7 @@ public abstract class GameImpl implements Game, Serializable { PermanentCard permanent = new PermanentCard(card.getCard(), ownerId, this); getBattlefield().addPermanent(permanent); permanent.entersBattlefield(permanent.getId(), this, Zone.OUTSIDE, false); - ((PermanentImpl)permanent).removeSummoningSickness(); + ((PermanentImpl) permanent).removeSummoningSickness(); if (card.isTapped()) { permanent.setTapped(true); } @@ -2541,7 +2559,6 @@ public abstract class GameImpl implements Game, Serializable { this.saveGame = saveGame; } - public void setStartMessage(String startMessage) { this.startMessage = startMessage; } @@ -2581,7 +2598,7 @@ public abstract class GameImpl implements Game, Serializable { public UUID getStartingPlayerId() { return startingPlayerId; } - + @Override public int getLife() { return startLife; @@ -2591,7 +2608,7 @@ public abstract class GameImpl implements Game, Serializable { public void setDraw(UUID playerId) { Player player = getPlayer(playerId); if (player != null) { - for (UUID playerToSetId :player.getInRange()) { + for (UUID playerToSetId : player.getInRange()) { Player playerToDraw = getPlayer(playerToSetId); playerToDraw.lostForced(this); } @@ -2601,7 +2618,7 @@ public abstract class GameImpl implements Game, Serializable { @Override public void saveRollBackGameState() { if (gameOptions.rollbackTurnsAllowed) { - int toDelete = getTurnNum()- ROLLBACK_TURNS_MAX; + int toDelete = getTurnNum() - ROLLBACK_TURNS_MAX; if (toDelete > 0 && gameStatesRollBack.containsKey(toDelete)) { gameStatesRollBack.remove(toDelete); } @@ -2620,12 +2637,12 @@ public abstract class GameImpl implements Game, Serializable { if (gameOptions.rollbackTurnsAllowed) { int turnToGoTo = getTurnNum() - turnsToRollback; if (turnToGoTo < 1 || !gameStatesRollBack.containsKey(turnToGoTo)) { - informPlayers(GameLog.getPlayerRequestColoredText("Player request: It's not possible to rollback " + turnsToRollback +" turn(s)")); + informPlayers(GameLog.getPlayerRequestColoredText("Player request: It's not possible to rollback " + turnsToRollback + " turn(s)")); } else { - GameState restore = gameStatesRollBack.get(turnToGoTo); + GameState restore = gameStatesRollBack.get(turnToGoTo); if (restore != null) { informPlayers(GameLog.getPlayerRequestColoredText("Player request: Rolling back to start of turn " + restore.getTurnNum())); - for (Player playerObject: getPlayers().values()) { + for (Player playerObject : getPlayers().values()) { if (playerObject.isHuman() && playerObject.isInGame()) { playerObject.abort(); } @@ -2639,7 +2656,7 @@ public abstract class GameImpl implements Game, Serializable { } } } - + @Override public boolean executingRollback() { return executingRollback; diff --git a/Mage/src/mage/game/combat/CombatGroup.java b/Mage/src/mage/game/combat/CombatGroup.java index 3a07906c56..1c50ff3d1b 100644 --- a/Mage/src/mage/game/combat/CombatGroup.java +++ b/Mage/src/mage/game/combat/CombatGroup.java @@ -1,31 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.game.combat; import java.io.Serializable; @@ -87,13 +86,13 @@ public class CombatGroup implements Serializable, Copyable { } public boolean hasFirstOrDoubleStrike(Game game) { - for (UUID permId: attackers) { + for (UUID permId : attackers) { Permanent attacker = game.getPermanent(permId); if (attacker != null && hasFirstOrDoubleStrike(attacker)) { return true; } } - for (UUID permId: blockers) { + for (UUID permId : blockers) { Permanent blocker = game.getPermanent(permId); if (blocker != null && hasFirstOrDoubleStrike(blocker)) { return true; @@ -138,20 +137,18 @@ public class CombatGroup implements Serializable, Copyable { if (attackers.size() > 0 && (!first || hasFirstOrDoubleStrike(game))) { if (blockers.isEmpty()) { unblockedDamage(first, game); - } - else { + } else { Permanent attacker = game.getPermanent(attackers.get(0)); if (attacker.getAbilities().containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId())) { Player player = game.getPlayer(attacker.getControllerId()); - if (player.chooseUse(Outcome.Damage, "Do you wish to assign damage for " + attacker.getLogName() + " as though it weren't blocked?", game)) { + if (player.chooseUse(Outcome.Damage, "Do you wish to assign damage for " + attacker.getLogName() + " as though it weren't blocked?", null, game)) { blocked = false; unblockedDamage(first, game); } } if (blockers.size() == 1) { singleBlockerDamage(first, game); - } - else { + } else { multiBlockerDamage(first, game); } } @@ -162,8 +159,7 @@ public class CombatGroup implements Serializable, Copyable { if (blockers.size() > 0 && (!first || hasFirstOrDoubleStrike(game))) { if (attackers.size() == 1) { singleAttackerDamage(first, game); - } - else { + } else { multiAttackerDamage(first, game); } } @@ -185,7 +181,8 @@ public class CombatGroup implements Serializable, Copyable { } /** - * Determines if permanent can damage in current (First Strike or not) combat damage step + * Determines if permanent can damage in current (First Strike or not) + * combat damage step * * @param perm Permanent to check * @param first First strike or common combat damage step @@ -196,8 +193,7 @@ public class CombatGroup implements Serializable, Copyable { if (first) { // should have first strike or double strike return hasFirstOrDoubleStrike(perm); - } - // if now not first strike combat + } // if now not first strike combat else { if (hasFirstStrike(perm)) { // if it has first strike in non FS combat damage step @@ -211,7 +207,7 @@ public class CombatGroup implements Serializable, Copyable { } private void unblockedDamage(boolean first, Game game) { - for (UUID attackerId: attackers) { + for (UUID attackerId : attackers) { Permanent attacker = game.getPermanent(attackerId); if (canDamage(attacker, first)) { //20091005 - 510.1c, 702.17c @@ -222,8 +218,6 @@ public class CombatGroup implements Serializable, Copyable { } } - - private void singleBlockerDamage(boolean first, Game game) { //TODO: handle banding Permanent blocker = game.getPermanent(blockers.get(0)); @@ -241,8 +235,7 @@ public class CombatGroup implements Serializable, Copyable { } if (lethalDamage >= damage) { blocker.markDamage(damage, attacker.getId(), game, true, true); - } - else { + } else { Player player = game.getPlayer(attacker.getControllerId()); int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getName(), game); blocker.markDamage(damageAssigned, attacker.getId(), game, true, true); @@ -251,13 +244,12 @@ public class CombatGroup implements Serializable, Copyable { defenderDamage(attacker, damage, game); } } - } - else { + } else { blocker.markDamage(damage, attacker.getId(), game, true, true); } } if (canDamage(blocker, first)) { - if (blocker.getBlocking() == 1) { // blocking several creatures handled separately + if (blocker.getBlocking() == 1) { // blocking several creatures handled separately attacker.markDamage(blockerDamage, blocker.getId(), game, true, true); } } @@ -275,7 +267,7 @@ public class CombatGroup implements Serializable, Copyable { if (canDamage(attacker, first)) { // must be set before attacker damage marking because of effects like Test of Faith Map blockerPower = new HashMap<>(); - for (UUID blockerId: blockerOrder) { + for (UUID blockerId : blockerOrder) { Permanent blocker = game.getPermanent(blockerId); if (canDamage(blocker, first)) { if (blocker.getBlocking() == 1) { // blocking several creatures handled separately @@ -285,7 +277,7 @@ public class CombatGroup implements Serializable, Copyable { } Map assigned = new HashMap<>(); if (blocked) { - for (UUID blockerId: blockerOrder) { + for (UUID blockerId : blockerOrder) { Permanent blocker = game.getPermanent(blockerId); int lethalDamage; if (attacker.getAbilities().containsKey(DeathtouchAbility.getInstance().getId())) { @@ -309,7 +301,7 @@ public class CombatGroup implements Serializable, Copyable { assigned.put(blockerOrder.get(0), assigned.get(blockerOrder.get(0)) + damage); } } - for (UUID blockerId: blockerOrder) { + for (UUID blockerId : blockerOrder) { Integer power = blockerPower.get(blockerId); if (power != null) { attacker.markDamage(power, blockerId, game, true, true); @@ -320,7 +312,7 @@ public class CombatGroup implements Serializable, Copyable { blocker.markDamage(entry.getValue(), attacker.getId(), game, true, true); } } else { - for (UUID blockerId: blockerOrder) { + for (UUID blockerId : blockerOrder) { Permanent blocker = game.getPermanent(blockerId); if (canDamage(blocker, first)) { attacker.markDamage(getDamageValueFromPermanent(blocker, game), blocker.getId(), game, true, true); @@ -331,11 +323,12 @@ public class CombatGroup implements Serializable, Copyable { /** * Damages attacking creatures by a creature that blocked several ones - * Damages only attackers as blocker was damage in {@link #singleBlockerDamage}. + * Damages only attackers as blocker was damage in + * {@link #singleBlockerDamage}. * * Handles abilities like "{this} an block any number of creatures.". * - * @param first + * @param first * @param game */ private void singleAttackerDamage(boolean first, Game game) { @@ -351,7 +344,8 @@ public class CombatGroup implements Serializable, Copyable { /** * Damages attacking creatures by a creature that blocked several ones - * Damages only attackers as blocker was damage in either {@link #singleBlockerDamage} or {@link #multiBlockerDamage}. + * Damages only attackers as blocker was damage in either + * {@link #singleBlockerDamage} or {@link #multiBlockerDamage}. * * Handles abilities like "{this} an block any number of creatures.". * @@ -368,7 +362,7 @@ public class CombatGroup implements Serializable, Copyable { if (canDamage(blocker, first)) { Map assigned = new HashMap<>(); - for (UUID attackerId: attackerOrder) { + for (UUID attackerId : attackerOrder) { Permanent attacker = game.getPermanent(attackerId); int lethalDamage; if (blocker.getAbilities().containsKey(DeathtouchAbility.getInstance().getId())) { @@ -398,8 +392,7 @@ public class CombatGroup implements Serializable, Copyable { if (defender != null) { defender.markDamage(amount, attacker.getId(), game, true, true); } - } - else { + } else { Player defender = game.getPlayer(defenderId); defender.damage(amount, attacker.getId(), game, true, true); } @@ -407,10 +400,10 @@ public class CombatGroup implements Serializable, Copyable { public boolean canBlock(Permanent blocker, Game game) { // player can't block if another player is attacked - if (!defendingPlayerId.equals(blocker.getControllerId()) ) { + if (!defendingPlayerId.equals(blocker.getControllerId())) { return false; } - for (UUID attackerId: attackers) { + for (UUID attackerId : attackers) { if (!blocker.canBlock(attackerId, game)) { return false; } @@ -419,7 +412,7 @@ public class CombatGroup implements Serializable, Copyable { } public void addBlocker(UUID blockerId, UUID playerId, Game game) { - for (UUID attackerId: attackers) { + for (UUID attackerId : attackers) { if (game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARE_BLOCKER, attackerId, blockerId, playerId))) { return; } @@ -445,10 +438,9 @@ public class CombatGroup implements Serializable, Copyable { if (blockerList.size() == 1) { blockerOrder.add(blockerList.get(0)); break; - } - else { + } else { List blockerPerms = new ArrayList<>(); - for (UUID blockerId: blockerList) { + for (UUID blockerId : blockerList) { blockerPerms.add(game.getPermanent(blockerId)); } UUID blockerId = player.chooseBlockerOrder(blockerPerms, this, blockerOrder, game); @@ -469,10 +461,9 @@ public class CombatGroup implements Serializable, Copyable { if (attackerList.size() == 1) { attackerOrder.add(attackerList.get(0)); break; - } - else { + } else { List attackerPerms = new ArrayList<>(); - for (UUID attackerId: attackerList) { + for (UUID attackerId : attackerList) { attackerPerms.add(game.getPermanent(attackerId)); } UUID attackerId = player.chooseAttackerOrder(attackerPerms, game); @@ -484,7 +475,7 @@ public class CombatGroup implements Serializable, Copyable { public int totalAttackerDamage(Game game) { int total = 0; - for (UUID attackerId: attackers) { + for (UUID attackerId : attackers) { total += getDamageValueFromPermanent(game.getPermanent(attackerId), game); } return total; @@ -517,13 +508,13 @@ public class CombatGroup implements Serializable, Copyable { return; } for (UUID blockerId : blockers) { - for (UUID attackerId: attackers) { + for (UUID attackerId : attackers) { game.fireEvent(GameEvent.getEvent(GameEvent.EventType.BLOCKER_DECLARED, attackerId, blockerId, players.get(blockerId))); } } - - if(!blockers.isEmpty()) { - for (UUID attackerId: attackers) { + + if (!blockers.isEmpty()) { + for (UUID attackerId : attackers) { game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKED, attackerId, null)); } } @@ -536,12 +527,13 @@ public class CombatGroup implements Serializable, Copyable { } if (blockersCount == 1) { List toBeRemoved = new ArrayList<>(); - for (UUID blockerId: getBlockers()) { + for (UUID blockerId : getBlockers()) { Permanent blocker = game.getPermanent(blockerId); if (blocker != null && blocker.getAbilities().containsKey(CantBlockAloneAbility.getInstance().getId())) { blockWasLegal = false; - if (!game.isSimulation()) + if (!game.isSimulation()) { game.informPlayers(blocker.getLogName() + " can't block alone. Removing it from combat."); + } toBeRemoved.add(blockerId); } } @@ -567,8 +559,9 @@ public class CombatGroup implements Serializable, Copyable { blockers.clear(); blockerOrder.clear(); this.blocked = false; - if (!game.isSimulation()) + if (!game.isSimulation()) { game.informPlayers(attacker.getLogName() + " can't be blocked except by " + attacker.getMinBlockedBy() + " or more creatures. Blockers discarded."); + } blockWasLegal = false; } // Check if there are to many blockers (maxBlockedBy = 0 means no restrictions) @@ -582,20 +575,23 @@ public class CombatGroup implements Serializable, Copyable { blockers.clear(); blockerOrder.clear(); this.blocked = false; - if (!game.isSimulation()) + if (!game.isSimulation()) { game.informPlayers(new StringBuilder(attacker.getLogName()) - .append(" can't be blocked by more than ").append(attacker.getMaxBlockedBy()) - .append(attacker.getMaxBlockedBy()==1?" creature.":" creatures.") - .append(" Blockers discarded.").toString()); + .append(" can't be blocked by more than ").append(attacker.getMaxBlockedBy()) + .append(attacker.getMaxBlockedBy() == 1 ? " creature." : " creatures.") + .append(" Blockers discarded.").toString()); + } blockWasLegal = false; } } return blockWasLegal; } + /** - * There are effects that let creatures assigns combat damage equal to its toughness rather than its power. - * So this method takes this into account to get the value of damage a creature will assign + * There are effects that let creatures assigns combat damage equal to its + * toughness rather than its power. So this method takes this into account + * to get the value of damage a creature will assign * * @param permanent * @param game @@ -610,14 +606,15 @@ public class CombatGroup implements Serializable, Copyable { } /** - * There are effects, that set an attacker to be blcoked. - * Therefore this setter can be used. - * @param blocked + * There are effects, that set an attacker to be blcoked. Therefore this + * setter can be used. + * + * @param blocked */ public void setBlocked(boolean blocked) { this.blocked = blocked; } - + @Override public CombatGroup copy() { return new CombatGroup(this); diff --git a/Mage/src/mage/game/command/Commander.java b/Mage/src/mage/game/command/Commander.java index ff0a556526..f3265532cf 100644 --- a/Mage/src/mage/game/command/Commander.java +++ b/Mage/src/mage/game/command/Commander.java @@ -106,7 +106,7 @@ public class Commander implements CommandObject{ @Override public String getLogName() { - return GameLog.getColoredObjectName(this); + return GameLog.getColoredObjectIdName(this); } @Override diff --git a/Mage/src/mage/game/command/Emblem.java b/Mage/src/mage/game/command/Emblem.java index 79d74ca888..3321f3ead7 100644 --- a/Mage/src/mage/game/command/Emblem.java +++ b/Mage/src/mage/game/command/Emblem.java @@ -106,7 +106,7 @@ public class Emblem implements CommandObject { @Override public String getLogName() { - return GameLog.getColoredObjectName(this); + return GameLog.getColoredObjectIdName(this); } @Override diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 51eea8e9cc..c44b666bff 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -1300,7 +1300,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { return GameLog.getNeutralColoredText("a creature without name"); } } - return GameLog.getColoredObjectName(this); + return GameLog.getColoredObjectIdName(this); } @Override diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 2ae5dd56c7..6674065caf 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -354,7 +354,7 @@ public class Spell extends StackObjImpl implements Card { @Override public String getLogName() { - return GameLog.getColoredObjectName(card); + return GameLog.getColoredObjectIdName(card); } @Override diff --git a/Mage/src/mage/game/stack/StackAbility.java b/Mage/src/mage/game/stack/StackAbility.java index 021ac659db..0ab2eeb7ba 100644 --- a/Mage/src/mage/game/stack/StackAbility.java +++ b/Mage/src/mage/game/stack/StackAbility.java @@ -132,7 +132,7 @@ public class StackAbility extends StackObjImpl implements Ability { @Override public String getLogName() { - return GameLog.getColoredObjectName(this); + return GameLog.getColoredObjectIdName(this); } @Override diff --git a/Mage/src/mage/game/stack/StackObjImpl.java b/Mage/src/mage/game/stack/StackObjImpl.java index c4889dc1c9..c2a725153a 100644 --- a/Mage/src/mage/game/stack/StackObjImpl.java +++ b/Mage/src/mage/game/stack/StackObjImpl.java @@ -37,38 +37,38 @@ public abstract class StackObjImpl implements StackObject { public boolean chooseNewTargets(Game game, UUID playerId) { return chooseNewTargets(game, playerId, false, false, null); } - + /** * 114.6. Some effects allow a player to change the target(s) of a spell or * ability, and other effects allow a player to choose new targets for a - * spell or ability. - * - * 114.6a If an effect allows a player to "change the - * target(s)" of a spell or ability, each target can be changed only to - * another legal target. If a target can't be changed to another legal - * target, the original target is unchanged, even if the original target is - * itself illegal by then. If all the targets aren't changed to other legal - * targets, none of them are changed. - * - * 114.6b If an effect allows a player to "change a target" of a - * spell or ability, the process described in rule 114.6a - * is followed, except that only one of those targets may be changed - * (rather than all of them or none of them). - * - * 114.6c If an effect allows a - * player to "change any targets" of a spell or ability, the process - * described in rule 114.6a is followed, except that any number of those - * targets may be changed (rather than all of them or none of them). - * - * 114.6d If an effect allows a player to "choose new targets" for a spell or - * ability, the player may leave any number of the targets unchanged, even - * if those targets would be illegal. If the player chooses to change some - * or all of the targets, the new targets must be legal and must not cause - * any unchanged targets to become illegal. - * - * 114.6e When changing targets or - * choosing new targets for a spell or ability, only the final set of - * targets is evaluated to determine whether the change is legal. + * spell or ability. + * + * 114.6a If an effect allows a player to "change the target(s)" of a spell + * or ability, each target can be changed only to another legal target. If a + * target can't be changed to another legal target, the original target is + * unchanged, even if the original target is itself illegal by then. If all + * the targets aren't changed to other legal targets, none of them are + * changed. + * + * 114.6b If an effect allows a player to "change a target" of a spell or + * ability, the process described in rule 114.6a is followed, except that + * only one of those targets may be changed (rather than all of them or none + * of them). + * + * 114.6c If an effect allows a player to "change any targets" of a spell or + * ability, the process described in rule 114.6a is followed, except that + * any number of those targets may be changed (rather than all of them or + * none of them). + * + * 114.6d If an effect allows a player to "choose new targets" for a spell + * or ability, the player may leave any number of the targets unchanged, + * even if those targets would be illegal. If the player chooses to change + * some or all of the targets, the new targets must be legal and must not + * cause any unchanged targets to become illegal. + * + * 114.6e When changing targets or choosing new targets for a spell or + * ability, only the final set of targets is evaluated to determine whether + * the change is legal. * * Example: Arc Trail is a sorcery that reads "Arc Trail deals 2 damage to * target creature or player and 1 damage to another target creature or @@ -92,10 +92,14 @@ public abstract class StackObjImpl implements StackObject { * targets will be, the copy is put onto the stack with those targets. * * @param game - * @param targetControllerId - player that can/has to change the target of the spell - * @param forceChange - does only work for targets with maximum of one targetId - * @param onlyOneTarget - 114.6b one target must be changed to another target - * @param filterNewTarget restriction for the new target, if null nothing is cheched + * @param targetControllerId - player that can/has to change the target of + * the spell + * @param forceChange - does only work for targets with maximum of one + * targetId + * @param onlyOneTarget - 114.6b one target must be changed to another + * target + * @param filterNewTarget restriction for the new target, if null nothing is + * cheched * @return */ @Override @@ -105,8 +109,8 @@ public abstract class StackObjImpl implements StackObject { StringBuilder newTargetDescription = new StringBuilder(); // Fused split spells or spells where "Splice on Arcane" was used can have more than one ability Abilities objectAbilities = new AbilitiesImpl<>(); - if (this instanceof Spell) { - objectAbilities.addAll(((Spell)this).getSpellAbilities()); + if (this instanceof Spell) { + objectAbilities.addAll(((Spell) this).getSpellAbilities()); } else { objectAbilities.addAll(getAbilities()); } @@ -119,7 +123,7 @@ public abstract class StackObjImpl implements StackObject { // clear the old target and copy all targets from new target target.clearChosen(); for (UUID targetId : newTarget.getTargets()) { - target.addTarget(targetId, newTarget.getTargetAmount(targetId), ability, game, false); + target.addTarget(targetId, newTarget.getTargetAmount(targetId), ability, game, false); } } @@ -137,30 +141,30 @@ public abstract class StackObjImpl implements StackObject { /** * Handles the change of one target instance of a mode - * + * * @param targetController - player that can choose the new target * @param ability * @param mode * @param target * @param forceChange * @param game - * @return + * @return */ private Target chooseNewTarget(Player targetController, Ability ability, Mode mode, Target target, boolean forceChange, FilterPermanent filterNewTarget, Game game) { Target newTarget = target.copy(); if (!targetController.getId().equals(getControllerId())) { newTarget.setTargetController(targetController.getId()); // target controller for the change is different from spell controller newTarget.setAbilityController(getControllerId()); - } + } newTarget.clearChosen(); for (UUID targetId : target.getTargets()) { String targetNames = getNamesOftargets(targetId, game); // change the target? if (targetNames != null - && (forceChange || targetController.chooseUse(mode.getEffects().get(0).getOutcome(), "Change this target: " + targetNames + "?", game))) { + && (forceChange || targetController.chooseUse(mode.getEffects().get(0).getOutcome(), "Change this target: " + targetNames + "?", ability, game))) { Set possibleTargets = target.possibleTargets(this.getSourceId(), getControllerId(), game); // choose exactly one other target - already targeted objects are not counted - if (forceChange && possibleTargets != null && possibleTargets.size() > 1) { // controller of spell must be used (e.g. TargetOpponent) + if (forceChange && possibleTargets != null && possibleTargets.size() > 1) { // controller of spell must be used (e.g. TargetOpponent) int iteration = 0; do { if (iteration > 0 && !game.isSimulation()) { @@ -168,36 +172,36 @@ public abstract class StackObjImpl implements StackObject { } iteration++; newTarget.clearChosen(); - - newTarget.chooseTarget(mode.getEffects().get(0).getOutcome(), getControllerId(), ability, game); - // check target restriction + + newTarget.chooseTarget(mode.getEffects().get(0).getOutcome(), getControllerId(), ability, game); + // check target restriction if (newTarget.getFirstTarget() != null && filterNewTarget != null) { Permanent newTargetPermanent = game.getPermanent(newTarget.getFirstTarget()); if (newTargetPermanent == null || !filterNewTarget.match(newTargetPermanent, game)) { - game.informPlayer(targetController, "Target does not fullfil the target requirements (" + filterNewTarget.getMessage() +")"); + game.informPlayer(targetController, "Target does not fullfil the target requirements (" + filterNewTarget.getMessage() + ")"); newTarget.clearChosen(); } - } + } } while (targetController.isInGame() && (targetId.equals(newTarget.getFirstTarget()) || newTarget.getTargets().size() != 1)); - // choose a new target + // choose a new target } else { // build a target definition with exactly one possible target to select that replaces old target Target tempTarget = target.copy(); if (target instanceof TargetAmount) { - ((TargetAmount)tempTarget).setAmountDefinition(new StaticValue(target.getTargetAmount(targetId))); + ((TargetAmount) tempTarget).setAmountDefinition(new StaticValue(target.getTargetAmount(targetId))); } tempTarget.setMinNumberOfTargets(1); tempTarget.setMaxNumberOfTargets(1); if (!targetController.getId().equals(getControllerId())) { tempTarget.setTargetController(targetController.getId()); - tempTarget.setAbilityController(getControllerId()); + tempTarget.setAbilityController(getControllerId()); } boolean again; do { again = false; tempTarget.clearChosen(); if (!tempTarget.chooseTarget(mode.getEffects().get(0).getOutcome(), getControllerId(), ability, game)) { - if (targetController.chooseUse(Outcome.Benefit, "No target object selected. Reset to original target?", game)) { + if (targetController.chooseUse(Outcome.Benefit, "No target object selected. Reset to original target?", ability, game)) { // use previous target no target was selected newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false); } else { @@ -206,43 +210,41 @@ public abstract class StackObjImpl implements StackObject { } else { // if possible add the alternate Target - it may not be included in the old definition nor in the already selected targets of the new definition if (newTarget.getTargets().contains(tempTarget.getFirstTarget()) || target.getTargets().contains(tempTarget.getFirstTarget())) { - if(targetController.isHuman()) { + if (targetController.isHuman()) { game.informPlayer(targetController, "This target was already selected from origin spell. You can only keep this target!"); again = true; } else { newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false); } } else if (!target.canTarget(getControllerId(), tempTarget.getFirstTarget(), ability, game)) { - if(targetController.isHuman()) { + if (targetController.isHuman()) { game.informPlayer(targetController, "This target is not valid!"); again = true; } else { // keep the old newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false); - } + } } else if (newTarget.getFirstTarget() != null && filterNewTarget != null) { Permanent newTargetPermanent = game.getPermanent(newTarget.getFirstTarget()); if (newTargetPermanent == null || !filterNewTarget.match(newTargetPermanent, game)) { - game.informPlayer(targetController, "This target does not fullfil the target requirements (" + filterNewTarget.getMessage() +")"); + game.informPlayer(targetController, "This target does not fullfil the target requirements (" + filterNewTarget.getMessage() + ")"); again = true; - } + } } else { // valid target was selected, add it to the new target definition newTarget.addTarget(tempTarget.getFirstTarget(), target.getTargetAmount(targetId), ability, game, false); } } } while (again && targetController.isInGame()); - } - } - // keep the target - else { + } + } // keep the target + else { newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false); } - } + } return newTarget; } - - + private String getNamesOftargets(UUID targetId, Game game) { MageObject object = game.getObject(targetId); String name = null; @@ -256,5 +258,5 @@ public abstract class StackObjImpl implements StackObject { } return name; } - + } diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index b6e8fe3d77..d9b3a914f7 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -439,7 +439,7 @@ public interface Player extends MageItem, Copyable { boolean chooseMulligan(Game game); - boolean chooseUse(Outcome outcome, String message, Game game); + boolean chooseUse(Outcome outcome, String message, Ability source, Game game); boolean choose(Outcome outcome, Choice choice, Game game); diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index fdbfe6d6db..4fcd9df58f 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -1326,7 +1326,7 @@ public abstract class PlayerImpl implements Player, Serializable { int current = 0, last = cards.size(); for (Card card : cards.getCards(game)) { current++; - sb.append(card.getLogName()); + sb.append(GameLog.getColoredObjectName(card)); if (current < last) { sb.append(", "); } @@ -1373,7 +1373,7 @@ public abstract class PlayerImpl implements Player, Serializable { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) { boolean untap = true; for (RestrictionEffect effect : game.getContinuousEffects().getApplicableRestrictionEffects(permanent, game).keySet()) { - untap &= effect.canBeUntapped(permanent, game); + untap &= effect.canBeUntapped(permanent, null, game); } if (untap) { canBeUntapped.add(permanent); @@ -1482,7 +1482,7 @@ public abstract class PlayerImpl implements Player, Serializable { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) { boolean untap = true; for (RestrictionEffect effect : game.getContinuousEffects().getApplicableRestrictionEffects(permanent, game).keySet()) { - untap &= effect.canBeUntapped(permanent, game); + untap &= effect.canBeUntapped(permanent, null, game); } if (untap) { permanent.untap(game); @@ -2960,7 +2960,7 @@ public abstract class PlayerImpl implements Player, Serializable { boolean chooseOrder = false; if (userData.askMoveToGraveOrder()) { if (cards.size() > 3) { - chooseOrder = choosingPlayer.chooseUse(Outcome.Neutral, "Would you like to choose the order the cards go to graveyard?", game); + chooseOrder = choosingPlayer.chooseUse(Outcome.Neutral, "Would you like to choose the order the cards go to graveyard?", source, game); } } if (chooseOrder) { diff --git a/Mage/src/mage/util/GameLog.java b/Mage/src/mage/util/GameLog.java index 082178a116..544b0a2d35 100644 --- a/Mage/src/mage/util/GameLog.java +++ b/Mage/src/mage/util/GameLog.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.util; import mage.MageObject; @@ -36,64 +35,66 @@ import mage.ObjectColor; * @author LevelX2 */ public class GameLog { - - static final String LOG_COLOR_PLAYER = "#20B2AA"; // LightSeaGreen - static final String LOG_COLOR_PLAYER_REQUEST = "#D2691E"; // Chocolate - static final String LOG_COLOR_PLAYER_CONFIRM = "#D2691E"; // Chocolate + + static final String LOG_COLOR_PLAYER = "#20B2AA"; // LightSeaGreen + static final String LOG_COLOR_PLAYER_REQUEST = "#D2691E"; // Chocolate + static final String LOG_COLOR_PLAYER_CONFIRM = "#D2691E"; // Chocolate static final String LOG_COLOR_GREEN = "#90EE90"; // LightGreen - static final String LOG_COLOR_RED = "#FF6347"; // Tomato + static final String LOG_COLOR_RED = "#FF6347"; // Tomato static final String LOG_COLOR_BLUE = "#87CEFA"; // LightSkyBlue static final String LOG_COLOR_BLACK = "#696969"; // DimGray // "#5F9EA0"; // CadetBlue - static final String LOG_COLOR_WHITE = "#F0E68C"; // Khaki - static final String LOG_COLOR_MULTI = "#DAA520"; // GoldenRod - static final String LOG_COLOR_COLORLESS = "#B0C4DE"; // LightSteelBlue - static final String LOG_COLOR_NEUTRAL = "#F0F8FF"; // AliceBlue - - - + static final String LOG_COLOR_WHITE = "#F0E68C"; // Khaki + static final String LOG_COLOR_MULTI = "#DAA520"; // GoldenRod + static final String LOG_COLOR_COLORLESS = "#B0C4DE"; // LightSteelBlue + static final String LOG_COLOR_NEUTRAL = "#F0F8FF"; // AliceBlue + public static String replaceNameByColoredName(MageObject mageObject, String text) { - return text.replaceAll(mageObject.getName(), getColoredObjectName(mageObject)); + return text.replaceAll(mageObject.getName(), getColoredObjectIdName(mageObject)); } - public static String getColoredObjectName(MageObject mageObject) { - return "" + mageObject.getName() + " ["+mageObject.getId().toString().substring(0,3) + "]"; + public static String getColoredObjectName(MageObject mageObject) { + return "" + mageObject.getName() + ""; } - public static String getNeutralColoredText(String text) { + public static String getColoredObjectIdName(MageObject mageObject) { + return "" + mageObject.getName() + " [" + mageObject.getId().toString().substring(0, 3) + "]"; + } + + public static String getNeutralColoredText(String text) { return "" + text + ""; } - public static String getColoredPlayerName(String name) { + public static String getColoredPlayerName(String name) { return "" + name + ""; } - - public static String getPlayerRequestColoredText(String name) { + + public static String getPlayerRequestColoredText(String name) { return "" + name + ""; } - public static String getPlayerConfirmColoredText(String name) { + public static String getPlayerConfirmColoredText(String name) { return "" + name + ""; } - public static String getSmallSecondLineText(String text) { + public static String getSmallSecondLineText(String text) { return "
" + text + "
"; } private static String getColorName(ObjectColor objectColor) { if (objectColor.isMulticolored()) { return LOG_COLOR_MULTI; - } else if (objectColor.isColorless()){ + } else if (objectColor.isColorless()) { return LOG_COLOR_COLORLESS; - } else if (objectColor.isRed()){ + } else if (objectColor.isRed()) { return LOG_COLOR_RED; - } else if (objectColor.isGreen()){ + } else if (objectColor.isGreen()) { return LOG_COLOR_GREEN; - } else if (objectColor.isBlue()){ + } else if (objectColor.isBlue()) { return LOG_COLOR_BLUE; - } else if (objectColor.isWhite()){ + } else if (objectColor.isWhite()) { return LOG_COLOR_WHITE; } else { - return LOG_COLOR_BLACK; + return LOG_COLOR_BLACK; } } } diff --git a/Mage/src/mage/util/ManaUtil.java b/Mage/src/mage/util/ManaUtil.java index 7dd8627c7b..6b8e006292 100644 --- a/Mage/src/mage/util/ManaUtil.java +++ b/Mage/src/mage/util/ManaUtil.java @@ -1,18 +1,23 @@ package mage.util; -import mage.Mana; -import mage.ManaSymbol; -import mage.abilities.costs.mana.ManaCost; -import mage.abilities.costs.mana.ManaSymbols; -import mage.abilities.mana.*; - import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Set; import java.util.UUID; import mage.MageObject; +import mage.Mana; +import mage.ManaSymbol; import mage.abilities.Ability; import mage.abilities.costs.mana.AlternateManaPaymentAbility; +import mage.abilities.costs.mana.ManaCost; +import mage.abilities.costs.mana.ManaSymbols; +import mage.abilities.mana.BasicManaAbility; +import mage.abilities.mana.BlackManaAbility; +import mage.abilities.mana.BlueManaAbility; +import mage.abilities.mana.GreenManaAbility; +import mage.abilities.mana.ManaAbility; +import mage.abilities.mana.RedManaAbility; +import mage.abilities.mana.WhiteManaAbility; import mage.cards.Card; import mage.game.Game; @@ -21,29 +26,32 @@ import mage.game.Game; */ public class ManaUtil { - private ManaUtil() {} + private ManaUtil() { + } /** - * In case the choice of mana to be produced is obvious, let's discard all other abilities. + * In case the choice of mana to be produced is obvious, let's discard all + * other abilities. * - * Example: - * Pay {W}{R} + * Example: Pay {W}{R} * - * Land produces {W} or {G}. + * Land produces {W} or {G}. * - * No need to ask what player wants to choose. - * {W} mana ability should be left only. + * No need to ask what player wants to choose. {W} mana ability should be + * left only. * * But we CAN do auto choice only in case we have basic mana abilities. - * Example: - * we should pay {1} and we have Cavern of Souls that can produce {1} or any mana of creature type choice. - * We can't simply auto choose {1} as the second mana ability also makes spell uncounterable. + * Example: we should pay {1} and we have Cavern of Souls that can produce + * {1} or any mana of creature type choice. We can't simply auto choose {1} + * as the second mana ability also makes spell uncounterable. * - * In case we can't auto choose we'll simply return the useableAbilities map back to caller without any modification. + * In case we can't auto choose we'll simply return the useableAbilities map + * back to caller without any modification. * * @param unpaid Mana we need to pay. Can be null (it is for X costs now). * @param useableAbilities List of mana abilities permanent may produce - * @return List of mana abilities permanent may produce and are reasonable for unpaid mana + * @return List of mana abilities permanent may produce and are reasonable + * for unpaid mana */ public static LinkedHashMap tryToAutoPay(ManaCost unpaid, LinkedHashMap useableAbilities) { @@ -55,8 +63,7 @@ public class ManaUtil { } } - - if (unpaid != null) { + if (unpaid != null) { ManaSymbols symbols = ManaSymbols.buildFromManaCost(unpaid); Mana unpaidMana = unpaid.getMana(); @@ -339,10 +346,10 @@ public class ManaUtil { return useableAbilities; } - + /** - * This activates the special button inthe feedback panel of the client - * if there exists special ways to pay the mana (e.g. Delve, Convoke) + * This activates the special button inthe feedback panel of the client if + * there exists special ways to pay the mana (e.g. Delve, Convoke) * * @param source ability the mana costs have to be paid for * @param game @@ -350,17 +357,26 @@ public class ManaUtil { * @return message to be shown in human players feedback area */ public static String addSpecialManaPayAbilities(Ability source, Game game, ManaCost unpaid) { + MageObject baseObject = game.getPermanent(source.getSourceId()); + if (baseObject == null) { + baseObject = game.getCard(source.getSourceId()); + } // check for special mana payment possibilities - MageObject mageObject = source.getSourceObject(game); - if (mageObject instanceof Card) { - for (Ability ability :((Card)mageObject).getAbilities(game)) { + MageObject mageObject = source.getSourceObject(game); + if (mageObject instanceof Card) { + for (Ability ability : ((Card) mageObject).getAbilities(game)) { if (ability instanceof AlternateManaPaymentAbility) { ((AlternateManaPaymentAbility) ability).addSpecialAction(source, game, unpaid); } } - return unpaid.getText() + "
" + mageObject.getLogName() + "
"; + if (baseObject == null) { + baseObject = mageObject; + } + } + if (baseObject != null) { + return unpaid.getText() + "
" + baseObject.getLogName() + "
"; } else { return unpaid.getText(); } - } + } } diff --git a/Mage/src/mage/watchers/common/MiracleWatcher.java b/Mage/src/mage/watchers/common/MiracleWatcher.java index 847be13193..d981691877 100644 --- a/Mage/src/mage/watchers/common/MiracleWatcher.java +++ b/Mage/src/mage/watchers/common/MiracleWatcher.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.watchers.common; import java.util.HashMap; @@ -45,8 +44,8 @@ import mage.players.Player; import mage.watchers.Watcher; /** - * Counts amount of cards drawn this turn by players. - * Asks players about Miracle ability to be activated if it the first card drawn this turn. + * Counts amount of cards drawn this turn by players. Asks players about Miracle + * ability to be activated if it the first card drawn this turn. * * @author noxx */ @@ -99,9 +98,9 @@ public class MiracleWatcher extends Watcher { Cards cards = new CardsImpl(); cards.add(card); controller.lookAtCards("Miracle", cards, game); - if (controller.chooseUse(Outcome.Benefit, "Reveal " + card.getLogName() + " to be able to use Miracle?", game)) { + if (controller.chooseUse(Outcome.Benefit, "Reveal " + card.getLogName() + " to be able to use Miracle?", ability, game)) { controller.revealCards("Miracle", cards, game); - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.MIRACLE_CARD_REVEALED, card.getId(), card.getId(),controller.getId())); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.MIRACLE_CARD_REVEALED, card.getId(), card.getId(), controller.getId())); break; } } @@ -110,7 +109,6 @@ public class MiracleWatcher extends Watcher { } } - @Override public void reset() { amountOfCardsDrawnThisTurn.clear(); diff --git a/Mage/src/mage/watchers/common/SoulbondWatcher.java b/Mage/src/mage/watchers/common/SoulbondWatcher.java index c86e9b8fe2..4806133c74 100644 --- a/Mage/src/mage/watchers/common/SoulbondWatcher.java +++ b/Mage/src/mage/watchers/common/SoulbondWatcher.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.watchers.common; import mage.abilities.keyword.SoulbondAbility; @@ -34,7 +33,6 @@ import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.WatcherScope; -import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicates; @@ -79,7 +77,7 @@ public class SoulbondWatcher extends Watcher { Cards cards = new CardsImpl(); cards.add(permanent); controller.lookAtCards("Soulbond", cards, game); - if (controller.chooseUse(Outcome.Benefit, "Use Soulbond?", game)) { + if (controller.chooseUse(Outcome.Benefit, "Use Soulbond?", null, game)) { TargetControlledPermanent target = new TargetControlledPermanent(filter); target.setNotTarget(true); if (target.canChoose(permanent.getId(), controller.getId(), game)) { @@ -88,8 +86,9 @@ public class SoulbondWatcher extends Watcher { if (chosen != null) { chosen.setPairedCard(permanent.getId()); permanent.setPairedCard(chosen.getId()); - if (!game.isSimulation()) + if (!game.isSimulation()) { game.informPlayers(new StringBuilder(controller.getLogName()).append(" souldbonds ").append(permanent.getLogName()).append(" with ").append(chosen.getName()).toString()); + } } } } @@ -110,11 +109,12 @@ public class SoulbondWatcher extends Watcher { Cards cards = new CardsImpl(); cards.add(chosen); controller.lookAtCards("Soulbond", cards, game); - if (controller.chooseUse(Outcome.Benefit, "Use Soulbond for recent " + permanent.getLogName() + "?", game)) { + if (controller.chooseUse(Outcome.Benefit, "Use Soulbond for recent " + permanent.getLogName() + "?", null, game)) { chosen.setPairedCard(permanent.getId()); permanent.setPairedCard(chosen.getId()); - if (!game.isSimulation()) + if (!game.isSimulation()) { game.informPlayers(new StringBuilder(controller.getLogName()).append(" souldbonds ").append(permanent.getLogName()).append(" with ").append(chosen.getName()).toString()); + } break; } }