Please test! Some changes to the display of user choices, showing also a longer text in tooltip window.

This commit is contained in:
LevelX2 2015-06-28 21:55:48 +02:00
parent cac04616f3
commit df3e6db569
352 changed files with 2277 additions and 2034 deletions

View file

@ -1,12 +1,17 @@
package mage.client.components; package mage.client.components;
import mage.client.util.Command; import java.awt.Color;
import java.awt.Dimension;
import javax.swing.*; import java.awt.Font;
import java.awt.*; 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.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import java.awt.font.FontRenderContext; import java.awt.font.FontRenderContext;
import javax.swing.JPanel;
import mage.client.util.Command;
/** /**
* Image button with hover. * 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); static final Font textSetFontBold = new Font("Arial", Font.BOLD, 14);
private boolean useMiniFont = false; private boolean useMiniFont = false;
private boolean alignTextLeft = false;
public HoverButton(String text, Image image, Rectangle size) { public HoverButton(String text, Image image, Rectangle size) {
this(text, image, image, null, image, size); this(text, image, image, null, image, size);
if (image == null) { if (image == null) {
@ -113,7 +120,7 @@ public class HoverButton extends JPanel implements MouseListener {
} }
topTextOffsetX = calculateOffsetForTop(g2d, topText); topTextOffsetX = calculateOffsetForTop(g2d, topText);
g2d.setColor(textBGColor); g2d.setColor(textBGColor);
g2d.drawString(topText, topTextOffsetX+1, 13); g2d.drawString(topText, topTextOffsetX + 1, 13);
g2d.setColor(textColor); g2d.setColor(textColor);
g2d.drawString(topText, topTextOffsetX, 12); g2d.drawString(topText, topTextOffsetX, 12);
} }
@ -148,7 +155,11 @@ public class HoverButton extends JPanel implements MouseListener {
frc = g2d.getFontRenderContext(); frc = g2d.getFontRenderContext();
textWidth = (int) textFontMini.getStringBounds(text, frc).getWidth(); textWidth = (int) textFontMini.getStringBounds(text, frc).getWidth();
} }
textOffsetX = (imageSize.width - textWidth) / 2; if (alignTextLeft) {
textOffsetX = 0;
} else {
textOffsetX = (imageSize.width - textWidth) / 2;
}
} }
return textOffsetX; return textOffsetX;
} }
@ -277,4 +288,8 @@ public class HoverButton extends JPanel implements MouseListener {
this.textAlwaysVisible = textAlwaysVisible; this.textAlwaysVisible = textAlwaysVisible;
} }
public void setAlignTextLeft(boolean alignTextLeft) {
this.alignTextLeft = alignTextLeft;
}
} }

View file

@ -1,19 +1,16 @@
package mage.client.components; 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.ManaSymbols;
import org.mage.card.arcane.UI; import org.mage.card.arcane.UI;
import javax.swing.*;
import java.awt.*;
import javax.swing.text.JTextComponent;
/** /**
* Component for displaying text in mage. * Component for displaying text in mage. Supports drawing mana symbols.
* Supports drawing mana symbols.
* *
* @author nantuko * @author nantuko
*/ */
public class MageTextArea extends JEditorPane { public class MageTextArea extends JEditorPane {
public MageTextArea() { public MageTextArea() {
@ -27,10 +24,10 @@ public class MageTextArea extends JEditorPane {
@Override @Override
public void setText(String text) { 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) { if (text == null) {
return; return;
} }
@ -38,23 +35,36 @@ public class MageTextArea extends JEditorPane {
final StringBuilder buffer = new StringBuilder(512); final StringBuilder buffer = new StringBuilder(512);
// Dialog is a java logical font family, so it should work on all systems // Dialog is a java logical font family, so it should work on all systems
buffer.append("<html><body style='font-family:Dialog;font-size:"); buffer.append("<html><body style='font-family:Dialog;font-size:");
buffer.append(fontSize); buffer.append(16);
buffer.append("pt;margin:3px 3px 3px 3px;color: #FFFFFF'><b><center>"); buffer.append("pt;margin:3px 3px 3px 3px;color: #FFFFFF'><b><center>");
text = text.replaceAll("#([^#]+)#", "<i>$1</i>"); // Don't know what it does (easy italc?) but it bugs with multiple #HTML color codes (LevelX2)
//text = text.replaceAll("#([^#]+)#", "<i>$1</i>");
//text = text.replaceAll("\\s*//\\s*", "<hr width='50%'>"); //text = text.replaceAll("\\s*//\\s*", "<hr width='50%'>");
text = text.replace("\r\n", "<div style='font-size:5pt'></div>"); text = text.replace("\r\n", "<div style='font-size:5pt'></div>");
final String basicText = ManaSymbols.replaceSymbolsWithHTML(text, ManaSymbols.Type.PAY);
if (text.length() > 0) { if (text.length() > 0) {
buffer.append(ManaSymbols.replaceSymbolsWithHTML(text, ManaSymbols.Type.PAY)); buffer.append(basicText);
} }
buffer.append("</b></center></body></html>"); buffer.append("</b></center></body></html>");
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() { public void run() {
MageTextArea.super.setText(buffer.toString()); String promptText = buffer.toString();
//System.out.println(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'><p width='400'>")
// .replace("</body>", "</p></body>");
String tooltip = "<html><center><body style='font-family:Dialog;font-size:14;color: #FFFFFF'><p width='500'>" + basicText + "</p></body></html>";
MageTextArea.super.setToolTipText(tooltip);
} else {
MageTextArea.super.setToolTipText(null);
}
setCaretPosition(0); setCaretPosition(0);
} }
}); });

View file

@ -112,6 +112,25 @@ public class CardInfoWindowDialog extends MageDialog {
cards.cleanUp(); 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) { public void loadCards(SimpleCardsView showCards, BigCard bigCard, UUID gameId) {
cards.loadCards(showCards, bigCard, gameId); cards.loadCards(showCards, bigCard, gameId);
showAndPositionWindow(); showAndPositionWindow();
@ -120,8 +139,9 @@ public class CardInfoWindowDialog extends MageDialog {
public void loadCards(CardsView showCards, BigCard bigCard, UUID gameId) { public void loadCards(CardsView showCards, BigCard bigCard, UUID gameId) {
cards.loadCards(showCards, bigCard, gameId, null); cards.loadCards(showCards, bigCard, gameId, null);
if (showType.equals(ShowType.GRAVEYARD)) { if (showType.equals(ShowType.GRAVEYARD)) {
setTitle(name + "'s Graveyard (" + showCards.size() + ")"); String titel = name + "'s Graveyard (" + showCards.size() + ")";
this.setTitelBarToolTip(name); setTitle(titel);
this.setTitelBarToolTip(titel);
} }
showAndPositionWindow(); 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. * 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 * WARNING: Do NOT modify this code. The content of this method is always

View file

@ -1150,21 +1150,21 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" alignment="0" pref="590" max="32767" attributes="0"/> <Component id="avatarPane" alignment="0" pref="590" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" alignment="0" pref="359" max="32767" attributes="0"/> <Component id="avatarPane" alignment="0" pref="359" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1"> <Container class="javax.swing.JScrollPane" name="avatarPane">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents> <SubComponents>
<Container class="javax.swing.JPanel" name="jPanel9"> <Container class="javax.swing.JPanel" name="avatarPanel">
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
@ -1256,6 +1256,14 @@
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
<SubComponents> <SubComponents>
<Component class="javax.swing.JLabel" name="jLabel12">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="1"/>
</Property>
<Property name="text" type="java.lang.String" value="Choose your avatar:"/>
</Properties>
</Component>
<Container class="javax.swing.JPanel" name="jPanel10"> <Container class="javax.swing.JPanel" name="jPanel10">
<Properties> <Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
@ -1328,14 +1336,6 @@
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
</Container> </Container>
<Component class="javax.swing.JLabel" name="jLabel12">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="1"/>
</Property>
<Property name="text" type="java.lang.String" value="Choose your avatar:"/>
</Properties>
</Component>
<Container class="javax.swing.JPanel" name="jPanel12"> <Container class="javax.swing.JPanel" name="jPanel12">
<Properties> <Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">

View file

@ -420,12 +420,12 @@ public class PreferencesDialog extends javax.swing.JDialog {
txtBattlefieldIBGMPath = new javax.swing.JTextField(); txtBattlefieldIBGMPath = new javax.swing.JTextField();
btnBattlefieldBGMBrowse = new javax.swing.JButton(); btnBattlefieldBGMBrowse = new javax.swing.JButton();
tabAvatars = new javax.swing.JPanel(); tabAvatars = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane(); avatarPane = new javax.swing.JScrollPane();
jPanel9 = new javax.swing.JPanel(); avatarPanel = new javax.swing.JPanel();
jLabel12 = new javax.swing.JLabel();
jPanel10 = new javax.swing.JPanel(); jPanel10 = new javax.swing.JPanel();
jPanel13 = new javax.swing.JPanel(); jPanel13 = new javax.swing.JPanel();
jPanel11 = new javax.swing.JPanel(); jPanel11 = new javax.swing.JPanel();
jLabel12 = new javax.swing.JLabel();
jPanel12 = new javax.swing.JPanel(); jPanel12 = new javax.swing.JPanel();
jPanel14 = new javax.swing.JPanel(); jPanel14 = new javax.swing.JPanel();
jPanel15 = new javax.swing.JPanel(); jPanel15 = new javax.swing.JPanel();
@ -1190,6 +1190,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabsPanel.addTab("Sounds", tabSounds); 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)); 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); 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) .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)); 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); 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) .addGap(0, 100, Short.MAX_VALUE)
); );
javax.swing.GroupLayout jPanel9Layout = new javax.swing.GroupLayout(jPanel9); javax.swing.GroupLayout avatarPanelLayout = new javax.swing.GroupLayout(avatarPanel);
jPanel9.setLayout(jPanel9Layout); avatarPanel.setLayout(avatarPanelLayout);
jPanel9Layout.setHorizontalGroup( avatarPanelLayout.setHorizontalGroup(
jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addComponent(jLabel12)) .addComponent(jLabel12))
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addGap(30, 30, 30) .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(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(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)) .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) .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(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(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))) .addComponent(jPanel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addGap(20, 20, 20) .addGap(20, 20, 20)
.addComponent(jPanel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(33, 33, 33) .addGap(33, 33, 33)
.addComponent(jPanel17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jPanel17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(jLabel13)))) .addComponent(jLabel13))))
.addGap(32, 32, 32) .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(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(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(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)))) .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)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
jPanel9Layout.setVerticalGroup( avatarPanelLayout.setVerticalGroup(
jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addComponent(jLabel12) .addComponent(jLabel12)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .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(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(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)) .addComponent(jPanel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(26, 26, 26) .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(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(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)) .addComponent(jPanel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(23, 23, 23) .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(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(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)) .addComponent(jPanel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18) .addGap(18, 18, 18)
.addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(jPanel9Layout.createSequentialGroup() .addGroup(avatarPanelLayout.createSequentialGroup()
.addComponent(jLabel13) .addComponent(jLabel13)
.addGap(18, 18, 18) .addGap(18, 18, 18)
.addComponent(jPanel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .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)) .addGap(25, 25, 25))
); );
jScrollPane1.setViewportView(jPanel9); avatarPane.setViewportView(avatarPanel);
javax.swing.GroupLayout tabAvatarsLayout = new javax.swing.GroupLayout(tabAvatars); javax.swing.GroupLayout tabAvatarsLayout = new javax.swing.GroupLayout(tabAvatars);
tabAvatars.setLayout(tabAvatarsLayout); tabAvatars.setLayout(tabAvatarsLayout);
tabAvatarsLayout.setHorizontalGroup( tabAvatarsLayout.setHorizontalGroup(
tabAvatarsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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.setVerticalGroup(
tabAvatarsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 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); tabsPanel.addTab("Avatars", tabAvatars);
@ -2423,7 +2423,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static UserData getUserData() { public static UserData getUserData() {
return new UserData(UserGroup.PLAYER, return new UserData(UserGroup.PLAYER,
getSelectedAvatar(), PreferencesDialog.selectedAvatarId,
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_ANY_ZONE, "true").equals("true"), 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_ALLOW_REQUEST_SHOW_HAND_CARDS, "true").equals("true"),
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_CONFIRM_EMPTY_MANA_POOL, "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 // 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 btnBattlefieldBGMBrowse;
private javax.swing.JButton btnBrowseBackgroundImage; private javax.swing.JButton btnBrowseBackgroundImage;
private javax.swing.JButton btnBrowseBattlefieldImage; 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 jPanel19;
private javax.swing.JPanel jPanel20; private javax.swing.JPanel jPanel20;
private javax.swing.JPanel jPanel21; private javax.swing.JPanel jPanel21;
private javax.swing.JPanel jPanel9;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JLabel labelPreferedImageLanguage; private javax.swing.JLabel labelPreferedImageLanguage;
private javax.swing.JLabel lblProxyPassword; private javax.swing.JLabel lblProxyPassword;
private javax.swing.JLabel lblProxyPort; private javax.swing.JLabel lblProxyPort;

View file

@ -1,37 +1,36 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
/* /*
* FeedbackPanel.java * FeedbackPanel.java
* *
* Created on 23-Dec-2009, 9:54:01 PM * Created on 23-Dec-2009, 9:54:01 PM
*/ */
package mage.client.game; package mage.client.game;
import java.awt.Component; import java.awt.Component;
@ -61,6 +60,7 @@ public class FeedbackPanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(FeedbackPanel.class); private static final Logger logger = Logger.getLogger(FeedbackPanel.class);
public enum FeedbackMode { public enum FeedbackMode {
INFORM, QUESTION, CONFIRM, CANCEL, SELECT, END INFORM, QUESTION, CONFIRM, CANCEL, SELECT, END
} }
@ -73,7 +73,9 @@ public class FeedbackPanel extends javax.swing.JPanel {
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor(); private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
/** Creates new form FeedbackPanel */ /**
* Creates new form FeedbackPanel
*/
public FeedbackPanel() { public FeedbackPanel() {
//initComponents(); //initComponents();
customInitComponents(); customInitComponents();
@ -170,7 +172,7 @@ public class FeedbackPanel extends javax.swing.JPanel {
while (c != null && !(c instanceof GamePane)) { while (c != null && !(c instanceof GamePane)) {
c = c.getParent(); 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(); FeedbackPanel.this.btnRight.doClick();
} }
} }
@ -181,8 +183,8 @@ public class FeedbackPanel extends javax.swing.JPanel {
private void handleOptions(Map<String, Serializable> options) { private void handleOptions(Map<String, Serializable> options) {
if (options != null) { if (options != null) {
if (options.containsKey("UI.right.btn.text")) { if (options.containsKey("UI.right.btn.text")) {
this.btnRight.setText((String)options.get("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.helper.setRight((String) options.get("UI.right.btn.text"), true);
} }
if (options.containsKey("dialog")) { if (options.containsKey("dialog")) {
connectedDialog = (MageDialog) options.get("dialog"); connectedDialog = (MageDialog) options.get("dialog");
@ -224,7 +226,7 @@ public class FeedbackPanel extends javax.swing.JPanel {
btnUndo = new javax.swing.JButton(); btnUndo = new javax.swing.JButton();
btnUndo.setVisible(true); 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.setText("Cancel");
btnRight.addActionListener(new java.awt.event.ActionListener() { btnRight.addActionListener(new java.awt.event.ActionListener() {

View file

@ -1,40 +1,43 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.client.game; package mage.client.game;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.GridBagLayout; import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import mage.client.components.MageTextArea; import mage.client.components.MageTextArea;
/** /**
@ -58,11 +61,15 @@ public class HelperPanel extends JPanel {
private javax.swing.JButton linkSpecial; private javax.swing.JButton linkSpecial;
private javax.swing.JButton linkUndo; private javax.swing.JButton linkUndo;
private final int defaultDismissTimeout = ToolTipManager.sharedInstance().getDismissDelay();
private final Object tooltipBackground = UIManager.get("info");
public HelperPanel() { public HelperPanel() {
initComponents(); initComponents();
} }
private void initComponents() { private void initComponents() {
setBackground(new Color(0, 0, 0, 100)); setBackground(new Color(0, 0, 0, 100));
//setLayout(new GridBagLayout()); //setLayout(new GridBagLayout());
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
@ -101,22 +108,24 @@ public class HelperPanel extends JPanel {
btnLeft.addActionListener(new java.awt.event.ActionListener() { btnLeft.addActionListener(new java.awt.event.ActionListener() {
@Override @Override
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkLeft != null) {{ if (linkLeft != null) {
Thread worker = new Thread(){ {
@Override Thread worker = new Thread() {
public void run(){ @Override
SwingUtilities.invokeLater(new Runnable(){ public void run() {
@Override SwingUtilities.invokeLater(new Runnable() {
public void run(){ @Override
setState("",false,"",false); public void run() {
setSpecial("", false); setState("", false, "", false);
linkLeft.doClick(); setSpecial("", false);
} linkLeft.doClick();
}); }
} });
}; }
worker.start(); };
}} worker.start();
}
}
} }
}); });
@ -124,13 +133,13 @@ public class HelperPanel extends JPanel {
@Override @Override
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkRight != null) { if (linkRight != null) {
Thread worker = new Thread(){ Thread worker = new Thread() {
@Override @Override
public void run(){ public void run() {
SwingUtilities.invokeLater(new Runnable(){ SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run(){ public void run() {
setState("",false,"",false); setState("", false, "", false);
setSpecial("", false); setSpecial("", false);
linkRight.doClick(); linkRight.doClick();
} }
@ -145,42 +154,61 @@ public class HelperPanel extends JPanel {
btnSpecial.addActionListener(new java.awt.event.ActionListener() { btnSpecial.addActionListener(new java.awt.event.ActionListener() {
@Override @Override
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkSpecial != null) {{ if (linkSpecial != null) {
Thread worker = new Thread(){ {
@Override Thread worker = new Thread() {
public void run(){ @Override
SwingUtilities.invokeLater(new Runnable(){ public void run() {
@Override SwingUtilities.invokeLater(new Runnable() {
public void run(){ @Override
setState("",false,"",false); public void run() {
setSpecial("", false); setState("", false, "", false);
linkSpecial.doClick(); setSpecial("", false);
} linkSpecial.doClick();
}); }
} });
}; }
worker.start(); };
}} worker.start();
}
}
} }
}); });
btnUndo.addActionListener(new java.awt.event.ActionListener() { btnUndo.addActionListener(new java.awt.event.ActionListener() {
@Override @Override
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
if (linkUndo != null) {{ if (linkUndo != null) {
Thread worker = new Thread(){ {
@Override Thread worker = new Thread() {
public void run(){ @Override
SwingUtilities.invokeLater(new Runnable(){ public void run() {
@Override SwingUtilities.invokeLater(new Runnable() {
public void run(){ @Override
linkUndo.doClick(); public void run() {
} linkUndo.doClick();
}); }
} });
}; }
worker.start(); };
}} 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);
} }
}); });
} }
@ -220,17 +248,18 @@ public class HelperPanel extends JPanel {
} }
public void setMessage(String message) { public void setMessage(String message) {
if (message.startsWith("Use alternative cost")) { // if (message.startsWith("Use alternative cost")) {
message = "Use alternative cost?"; // message = "Use alternative cost?";
} else if (message.contains("Use ")) { // } else if (message.contains("Use ")) {
if (message.length() < this.getWidth() / 10) { // if (message.length() < this.getWidth() / 10) {
message = getSmallText(message); // message = getSmallText(message);
} else { // } else {
message = "Use ability?" + getSmallText(message.substring(0, this.getWidth() / 10)); // message = "Use ability?" + getSmallText(message.substring(0, this.getWidth() / 10));
} // }
} // }
textArea.setText(message); textArea.setText(message, this.getWidth());
} }
protected String getSmallText(String text) { protected String getSmallText(String text) {
return "<div style='font-size:11pt'>" + text + "</div>"; return "<div style='font-size:11pt'>" + text + "</div>";
} }

View file

@ -328,8 +328,8 @@ public class PlayerPanelExt extends javax.swing.JPanel {
avatar.add(new JLabel()); avatar.add(new JLabel());
avatar.add(new JLabel()); avatar.add(new JLabel());
avatar.add(avatarFlag); avatar.add(avatarFlag);
avatar.setAlignmentY(CENTER_ALIGNMENT); avatar.setAlignTextLeft(true);
avatarFlag.setHorizontalAlignment(JLabel.CENTER); avatarFlag.setHorizontalAlignment(JLabel.LEFT);
avatarFlag.setVerticalAlignment(JLabel.BOTTOM); avatarFlag.setVerticalAlignment(JLabel.BOTTOM);
avatar.add(new JLabel()); avatar.add(new JLabel());
String showPlayerNamePermanently = MageFrame.getPreferences().get(PreferencesDialog.KEY_SHOW_PLAYER_NAMES_PERMANENTLY, "true"); String showPlayerNamePermanently = MageFrame.getPreferences().get(PreferencesDialog.KEY_SHOW_PLAYER_NAMES_PERMANENTLY, "true");

View file

@ -1286,7 +1286,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
} }
@Override @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()); log.debug("chooseUse: " + outcome.isGood());
// Be proactive! Always use abilities, the evaluation function will decide if it's good or not // 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 // Otherwise some abilities won't be used by AI like LoseTargetEffect that has "bad" outcome

View file

@ -27,13 +27,24 @@
*/ */
package mage.player.ai; package mage.player.ai;
import mage.constants.Outcome; import java.io.Serializable;
import mage.abilities.*; 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.common.PassAbility;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.Cards; import mage.cards.Cards;
import mage.choices.Choice; import mage.choices.Choice;
import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.game.combat.CombatGroup; import mage.game.combat.CombatGroup;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -44,9 +55,6 @@ import mage.target.TargetAmount;
import mage.target.TargetCard; import mage.target.TargetCard;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.io.Serializable;
import java.util.*;
/** /**
* *
* plays randomly * plays randomly
@ -58,7 +66,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
private boolean isSimulatedPlayer; private boolean isSimulatedPlayer;
private static Random rnd = new Random(); private static Random rnd = new Random();
private int actionCount = 0; 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) { public SimulatedPlayerMCTS(UUID id, boolean isSimulatedPlayer) {
super(id); super(id);
@ -83,14 +91,15 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
return actionCount; return actionCount;
} }
@Override @Override
public boolean priority(Game game) { public boolean priority(Game game) {
// logger.info("priority"); // logger.info("priority");
boolean didSomething = false; boolean didSomething = false;
Ability ability = getAction(game); Ability ability = getAction(game);
// logger.info("simulate " + ability.toString()); // logger.info("simulate " + ability.toString());
if (!(ability instanceof PassAbility)) if (!(ability instanceof PassAbility)) {
didSomething = true; didSomething = true;
}
activateAbility((ActivatedAbility) ability, game); activateAbility((ActivatedAbility) ability, game);
@ -102,16 +111,18 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
List<Ability> playables = getPlayableAbilities(game); List<Ability> playables = getPlayableAbilities(game);
Ability ability; Ability ability;
while (true) { while (true) {
if (playables.size() == 1) if (playables.size() == 1) {
ability = playables.get(0); ability = playables.get(0);
else } else {
ability = playables.get(rnd.nextInt(playables.size())); ability = playables.get(rnd.nextInt(playables.size()));
}
List<Ability> options = getPlayableOptions(ability, game); List<Ability> options = getPlayableOptions(ability, game);
if (!options.isEmpty()) { if (!options.isEmpty()) {
if (options.size() == 1) if (options.size() == 1) {
ability = options.get(0); ability = options.get(0);
else } else {
ability = options.get(rnd.nextInt(options.size())); ability = options.get(rnd.nextInt(options.size()));
}
} }
if (ability.getManaCosts().getVariableCosts().size() > 0) { if (ability.getManaCosts().getVariableCosts().size() > 0) {
int amount = getAvailableManaProducers(game).size() - ability.getManaCosts().convertedManaCost(); int amount = getAvailableManaProducers(game).size() - ability.getManaCosts().convertedManaCost();
@ -133,7 +144,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
// } // }
// } // }
// else { // else {
break; break;
// } // }
} }
return ability; return ability;
@ -147,12 +158,12 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
List<Ability> options = getPlayableOptions(source, game); List<Ability> options = getPlayableOptions(source, game);
if (options.isEmpty()) { if (options.isEmpty()) {
ability = source; ability = source;
} } else {
else { if (options.size() == 1) {
if (options.size() == 1)
ability = options.get(0); ability = options.get(0);
else } else {
ability = options.get(rnd.nextInt(options.size())); ability = options.get(rnd.nextInt(options.size()));
}
} }
if (ability.isUsesStack()) { if (ability.isUsesStack()) {
game.getStack().push(new StackAbility(ability, playerId)); game.getStack().push(new StackAbility(ability, playerId));
@ -205,7 +216,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
} }
List<Permanent> blockers = getAvailableBlockers(game); List<Permanent> blockers = getAvailableBlockers(game);
for (Permanent blocker: blockers) { for (Permanent blocker : blockers) {
int check = rnd.nextInt(numGroups + 1); int check = rnd.nextInt(numGroups + 1);
if (check < numGroups) { if (check < numGroups) {
CombatGroup group = game.getCombat().getGroups().get(check); 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) { protected boolean chooseRandomTarget(Target target, Ability source, Game game) {
Set<UUID> possibleTargets = target.possibleTargets(source==null?null:source.getSourceId(), playerId, game); Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game);
if (possibleTargets.isEmpty()) if (possibleTargets.isEmpty()) {
return false; return false;
}
if (!target.isRequired(source)) { if (!target.isRequired(source)) {
if (rnd.nextInt(possibleTargets.size() + 1) == 0) { if (rnd.nextInt(possibleTargets.size() + 1) == 0) {
return false; return false;
@ -266,8 +278,9 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
@Override @Override
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) { public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) {
if (this.isHuman()) if (this.isHuman()) {
return chooseRandom(target, game); return chooseRandom(target, game);
}
return super.choose(outcome, target, sourceId, game); return super.choose(outcome, target, sourceId, game);
} }
@ -318,7 +331,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
@Override @Override
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) { public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
Set<UUID> possibleTargets = target.possibleTargets(source==null?null:source.getSourceId(), playerId, game); Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game);
if (possibleTargets.isEmpty()) { if (possibleTargets.isEmpty()) {
return !target.isRequired(source); return !target.isRequired(source);
} }
@ -347,11 +360,11 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
} }
@Override @Override
public boolean chooseUse(Outcome outcome, String message, Game game) { public boolean chooseUse(Outcome outcome, String message, Ability source, Game game) {
if (this.isHuman()) { if (this.isHuman()) {
return rnd.nextBoolean(); return rnd.nextBoolean();
} }
return super.chooseUse(outcome, message, game); return super.chooseUse(outcome, message, source, game);
} }
@Override @Override
@ -436,8 +449,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
if (targets.size() == 1) { if (targets.size() == 1) {
targetId = targets.get(0); targetId = targets.get(0);
amount = remainingDamage; amount = remainingDamage;
} } else {
else {
targetId = targets.get(rnd.nextInt(targets.size())); targetId = targets.get(rnd.nextInt(targets.size()));
amount = rnd.nextInt(damage + 1); amount = rnd.nextInt(damage + 1);
} }
@ -445,8 +457,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
if (permanent != null) { if (permanent != null) {
permanent.damage(amount, sourceId, game, false, true); permanent.damage(amount, sourceId, game, false, true);
remainingDamage -= amount; remainingDamage -= amount;
} } else {
else {
Player player = game.getPlayer(targetId); Player player = game.getPlayer(targetId);
if (player != null) { if (player != null) {
player.damage(amount, sourceId, game, false, true); player.damage(amount, sourceId, game, false, true);
@ -455,8 +466,7 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
} }
targets.remove(targetId); targets.remove(targetId);
} }
} } else {
else {
super.assignDamage(damage, targets, singleTargetName, sourceId, game); super.assignDamage(damage, targets, singleTargetName, sourceId, game);
} }
} }

View file

@ -1,35 +1,50 @@
/* /*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR * 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 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 * 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 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.player.human; 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.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.VariableCost;
import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCost;
@ -42,7 +57,13 @@ import mage.cards.Cards;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.choices.Choice; import mage.choices.Choice;
import mage.choices.ChoiceImpl; 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.FilterAttackingCreature;
import mage.filter.common.FilterBlockingCreature; import mage.filter.common.FilterBlockingCreature;
import mage.filter.common.FilterCreatureForCombat; import mage.filter.common.FilterCreatureForCombat;
@ -63,13 +84,10 @@ import mage.target.TargetPermanent;
import mage.target.common.TargetAttackingCreature; import mage.target.common.TargetAttackingCreature;
import mage.target.common.TargetCreatureOrPlayer; import mage.target.common.TargetCreatureOrPlayer;
import mage.target.common.TargetDefender; import mage.target.common.TargetDefender;
import mage.util.GameLog;
import mage.util.ManaUtil; import mage.util.ManaUtil;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.io.Serializable;
import java.util.*;
import mage.util.GameLog;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -85,6 +103,7 @@ public class HumanPlayer extends PlayerImpl {
protected static final Choice replacementEffectChoice = new ChoiceImpl(true); protected static final Choice replacementEffectChoice = new ChoiceImpl(true);
private static final Logger log = Logger.getLogger(HumanPlayer.class); private static final Logger log = Logger.getLogger(HumanPlayer.class);
static { static {
replacementEffectChoice.setMessage("Choose replacement effect to resolve first"); replacementEffectChoice.setMessage("Choose replacement effect to resolve first");
} }
@ -104,7 +123,7 @@ public class HumanPlayer extends PlayerImpl {
response.clear(); response.clear();
log.debug("Waiting response from player: " + getId()); log.debug("Waiting response from player: " + getId());
game.resumeTimer(getTurnControlledBy()); game.resumeTimer(getTurnControlledBy());
synchronized(response) { synchronized (response) {
try { try {
response.wait(); response.wait();
log.debug("Got response from player: " + getId()); log.debug("Got response from player: " + getId());
@ -145,9 +164,9 @@ public class HumanPlayer extends PlayerImpl {
updateGameStatePriority("chooseMulligan", game); updateGameStatePriority("chooseMulligan", game);
int nextHandSize = game.mulliganDownTo(playerId); int nextHandSize = game.mulliganDownTo(playerId);
game.fireAskPlayerEvent(playerId, new StringBuilder("Mulligan ") 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)
.append(nextHandSize == 1?" card?":" cards?").toString()); .append(nextHandSize == 1 ? " card?" : " cards?").toString());
waitForBooleanResponse(game); waitForBooleanResponse(game);
if (!abort) { if (!abort) {
return response.getBoolean(); return response.getBoolean();
@ -156,9 +175,9 @@ public class HumanPlayer extends PlayerImpl {
} }
@Override @Override
public boolean chooseUse(Outcome outcome, String message, Game game) { public boolean chooseUse(Outcome outcome, String message, Ability source, Game game) {
updateGameStatePriority("chooseUse", game); updateGameStatePriority("chooseUse", game);
game.fireAskPlayerEvent(playerId, message); game.fireAskPlayerEvent(playerId, addSecondLineWithObjectName(message, source == null ? null : source.getSourceId(), game));
waitForBooleanResponse(game); waitForBooleanResponse(game);
if (!abort) { if (!abort) {
return response.getBoolean(); return response.getBoolean();
@ -166,6 +185,19 @@ public class HumanPlayer extends PlayerImpl {
return false; 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 += "<div style='font-size:11pt'>" + mageObject.getLogName() + "</div>";
}
}
return message;
}
@Override @Override
public int chooseReplacementEffect(Map<String, String> rEffects, Game game) { public int chooseReplacementEffect(Map<String, String> rEffects, Game game) {
updateGameStatePriority("chooseEffect", game); updateGameStatePriority("chooseEffect", game);
@ -173,7 +205,7 @@ public class HumanPlayer extends PlayerImpl {
return 0; return 0;
} }
if (!autoSelectReplacementEffects.isEmpty()) { if (!autoSelectReplacementEffects.isEmpty()) {
for (String autoKey :autoSelectReplacementEffects) { for (String autoKey : autoSelectReplacementEffects) {
int count = 0; int count = 0;
for (String effectKey : rEffects.keySet()) { for (String effectKey : rEffects.keySet()) {
if (effectKey.equals(autoKey)) { if (effectKey.equals(autoKey)) {
@ -230,7 +262,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game) { 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 @Override
@ -254,18 +286,18 @@ public class HumanPlayer extends PlayerImpl {
} }
List<UUID> chosen = target.getTargets(); List<UUID> 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); waitForResponse(game);
if (response.getUUID() != null) { if (response.getUUID() != null) {
if (!targetIds.contains(response.getUUID())) { if (!targetIds.contains(response.getUUID())) {
continue; continue;
} }
if (target instanceof TargetPermanent) { 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); target.add(response.getUUID(), game);
if(target.doneChosing()){ if (target.doneChosing()) {
return true; return true;
} }
} }
@ -276,8 +308,8 @@ public class HumanPlayer extends PlayerImpl {
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()); target.remove(response.getUUID());
} else { } else {
target.addTarget(response.getUUID(), (Ability)object, game); target.addTarget(response.getUUID(), (Ability) object, game);
if(target.doneChosing()){ if (target.doneChosing()) {
return true; return true;
} }
} }
@ -288,7 +320,7 @@ public class HumanPlayer extends PlayerImpl {
target.remove(response.getUUID()); target.remove(response.getUUID());
} else { } else {
target.addTarget(response.getUUID(), null, game); target.addTarget(response.getUUID(), null, game);
if(target.doneChosing()){ if (target.doneChosing()) {
return true; return true;
} }
} }
@ -316,12 +348,13 @@ public class HumanPlayer extends PlayerImpl {
abilityControllerId = target.getAbilityController(); abilityControllerId = target.getAbilityController();
} }
while (!abort) { while (!abort) {
Set<UUID> possibleTargets = target.possibleTargets(source==null?null:source.getSourceId(), abilityControllerId, game); Set<UUID> possibleTargets = target.possibleTargets(source == null ? null : source.getSourceId(), abilityControllerId, game);
boolean required = target.isRequired(source); boolean required = target.isRequired(source);
if (possibleTargets.isEmpty() || target.getTargets().size() >= target.getNumberOfTargets()) { if (possibleTargets.isEmpty() || target.getTargets().size() >= target.getNumberOfTargets()) {
required = false; 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); waitForResponse(game);
if (response.getUUID() != null) { if (response.getUUID() != null) {
if (target.getTargets().contains(response.getUUID())) { if (target.getTargets().contains(response.getUUID())) {
@ -331,7 +364,7 @@ public class HumanPlayer extends PlayerImpl {
if (possibleTargets.contains(response.getUUID())) { if (possibleTargets.contains(response.getUUID())) {
if (target.canTarget(abilityControllerId, response.getUUID(), source, game)) { if (target.canTarget(abilityControllerId, response.getUUID(), source, game)) {
target.addTarget(response.getUUID(), source, game); target.addTarget(response.getUUID(), source, game);
if(target.doneChosing()){ if (target.doneChosing()) {
return true; return true;
} }
} }
@ -348,7 +381,7 @@ public class HumanPlayer extends PlayerImpl {
return false; return false;
} }
private Map<String, Serializable> getOptions(Target target, Map<String, Serializable> options ) { private Map<String, Serializable> getOptions(Target target, Map<String, Serializable> options) {
if (options == null) { if (options == null) {
options = new HashMap<>(); options = new HashMap<>();
} }
@ -356,7 +389,7 @@ public class HumanPlayer extends PlayerImpl {
options.put("UI.right.btn.text", "Done"); options.put("UI.right.btn.text", "Done");
} }
options.put("targetZone", target.getZone()); options.put("targetZone", target.getZone());
return options; return options;
} }
@Override @Override
@ -378,7 +411,7 @@ public class HumanPlayer extends PlayerImpl {
} }
Map<String, Serializable> options = getOptions(target, null); Map<String, Serializable> options = getOptions(target, null);
List<UUID> chosen = target.getTargets(); List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable)chosen); options.put("chosen", (Serializable) chosen);
List<UUID> choosable = new ArrayList<>(); List<UUID> choosable = new ArrayList<>();
for (UUID cardId : cards) { for (UUID cardId : cards) {
if (target.canTarget(cardId, cards, game)) { if (target.canTarget(cardId, cards, game)) {
@ -432,7 +465,7 @@ public class HumanPlayer extends PlayerImpl {
} }
Map<String, Serializable> options = getOptions(target, null); Map<String, Serializable> options = getOptions(target, null);
List<UUID> chosen = target.getTargets(); List<UUID> chosen = target.getTargets();
options.put("chosen", (Serializable)chosen); options.put("chosen", (Serializable) chosen);
List<UUID> choosable = new ArrayList<>(); List<UUID> choosable = new ArrayList<>();
for (UUID cardId : cards) { for (UUID cardId : cards) {
if (target.canTarget(cardId, cards, game)) { if (target.canTarget(cardId, cards, game)) {
@ -442,7 +475,7 @@ public class HumanPlayer extends PlayerImpl {
if (!choosable.isEmpty()) { if (!choosable.isEmpty()) {
options.put("choosable", (Serializable) choosable); 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); waitForResponse(game);
if (response.getUUID() != null) { 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
@ -471,8 +504,8 @@ public class HumanPlayer extends PlayerImpl {
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) { public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
updateGameStatePriority("chooseTargetAmount", game); updateGameStatePriority("chooseTargetAmount", game);
while (!abort) { while (!abort) {
game.fireSelectTargetEvent(playerId, target.getMessage() + "\n Amount remaining:" + target.getAmountRemaining(), game.fireSelectTargetEvent(playerId, addSecondLineWithObjectName(target.getMessage() + "\n Amount remaining:" + target.getAmountRemaining(), source.getSourceId(), game),
target.possibleTargets(source==null?null:source.getSourceId(), playerId, game), target.possibleTargets(source == null ? null : source.getSourceId(), playerId, game),
target.isRequired(source), target.isRequired(source),
getOptions(target, null)); getOptions(target, null));
waitForResponse(game); waitForResponse(game);
@ -495,7 +528,7 @@ public class HumanPlayer extends PlayerImpl {
passed = false; passed = false;
if (!abort) { if (!abort) {
if (passedAllTurns) { if (passedAllTurns) {
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} }
@ -503,7 +536,7 @@ public class HumanPlayer extends PlayerImpl {
passedUntilStackResolved = false; passedUntilStackResolved = false;
boolean dontCheckPassStep = false; boolean dontCheckPassStep = false;
if (passedTurn) { if (passedTurn) {
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} }
@ -512,7 +545,7 @@ public class HumanPlayer extends PlayerImpl {
// it's a main phase // it's a main phase
if (!skippedAtLeastOnce || (!playerId.equals(game.getActivePlayerId()) && !this.getUserData().getUserSkipPrioritySteps().isStopOnAllMainPhases())) { if (!skippedAtLeastOnce || (!playerId.equals(game.getActivePlayerId()) && !this.getUserData().getUserSkipPrioritySteps().isStopOnAllMainPhases())) {
skippedAtLeastOnce = true; skippedAtLeastOnce = true;
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} else { } else {
@ -521,7 +554,7 @@ public class HumanPlayer extends PlayerImpl {
} }
} else { } else {
skippedAtLeastOnce = true; skippedAtLeastOnce = true;
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} }
@ -531,7 +564,7 @@ public class HumanPlayer extends PlayerImpl {
// It's end of turn phase // It's end of turn phase
if (!skippedAtLeastOnce || (playerId.equals(game.getActivePlayerId()) && !this.getUserData().getUserSkipPrioritySteps().isStopOnAllEndPhases())) { if (!skippedAtLeastOnce || (playerId.equals(game.getActivePlayerId()) && !this.getUserData().getUserSkipPrioritySteps().isStopOnAllEndPhases())) {
skippedAtLeastOnce = true; skippedAtLeastOnce = true;
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} else { } else {
@ -540,20 +573,20 @@ public class HumanPlayer extends PlayerImpl {
} }
} else { } else {
skippedAtLeastOnce = true; skippedAtLeastOnce = true;
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} }
} }
if (!dontCheckPassStep && checkPassStep(game)) { if (!dontCheckPassStep && checkPassStep(game)) {
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} }
} else if (passedUntilStackResolved) { } else if (passedUntilStackResolved) {
if (dateLastAddedToStack == game.getStack().getDateLastAdded()) { if (dateLastAddedToStack == game.getStack().getDateLastAdded()) {
dateLastAddedToStack = game.getStack().getDateLastAdded(); dateLastAddedToStack = game.getStack().getDateLastAdded();
if(passWithManaPoolCheck(game)) { if (passWithManaPoolCheck(game)) {
return false; return false;
} }
} else { } else {
@ -564,7 +597,7 @@ public class HumanPlayer extends PlayerImpl {
updateGameStatePriority("priority", game); updateGameStatePriority("priority", game);
game.firePriorityEvent(playerId); game.firePriorityEvent(playerId);
waitForResponse(game); waitForResponse(game);
if(game.executingRollback()) { if (game.executingRollback()) {
return true; return true;
} }
if (response.getBoolean() != null || response.getInteger() != null) { if (response.getBoolean() != null || response.getInteger() != null) {
@ -628,7 +661,7 @@ public class HumanPlayer extends PlayerImpl {
game.fireSelectTargetEvent(playerId, "Pick triggered ability (goes to the stack first)", abilities); game.fireSelectTargetEvent(playerId, "Pick triggered ability (goes to the stack first)", abilities);
waitForResponse(game); waitForResponse(game);
if (response.getUUID() != null) { if (response.getUUID() != null) {
for (TriggeredAbility ability: abilities) { for (TriggeredAbility ability : abilities) {
if (ability.getId().equals(response.getUUID())) { if (ability.getId().equals(response.getUUID())) {
return ability; return ability;
} }
@ -638,7 +671,6 @@ public class HumanPlayer extends PlayerImpl {
return null; return null;
} }
@Override @Override
public boolean playMana(ManaCost unpaid, String promptText, Game game) { public boolean playMana(ManaCost unpaid, String promptText, Game game) {
payManaMode = true; payManaMode = true;
@ -647,7 +679,6 @@ public class HumanPlayer extends PlayerImpl {
return result; return result;
} }
protected boolean playManaHandling(ManaCost unpaid, String promptText, Game game) { protected boolean playManaHandling(ManaCost unpaid, String promptText, Game game) {
updateGameStatePriority("playMana", game); updateGameStatePriority("playMana", game);
game.firePlayManaEvent(playerId, "Pay " + promptText); game.firePlayManaEvent(playerId, "Pay " + promptText);
@ -666,9 +697,9 @@ public class HumanPlayer extends PlayerImpl {
ManaCostsImpl<ManaCost> costs = (ManaCostsImpl<ManaCost>) unpaid; ManaCostsImpl<ManaCost> costs = (ManaCostsImpl<ManaCost>) unpaid;
for (ManaCost cost : costs.getUnpaid()) { for (ManaCost cost : costs.getUnpaid()) {
if (cost instanceof PhyrexianManaCost) { if (cost instanceof PhyrexianManaCost) {
PhyrexianManaCost ph = (PhyrexianManaCost)cost; PhyrexianManaCost ph = (PhyrexianManaCost) cost;
if (ph.canPay(null, null, playerId, game)) { if (ph.canPay(null, null, playerId, game)) {
((PhyrexianManaCost)cost).pay(null, game, null, playerId, false); ((PhyrexianManaCost) cost).pay(null, game, null, playerId, false);
} }
break; break;
} }
@ -686,6 +717,7 @@ public class HumanPlayer extends PlayerImpl {
/** /**
* Gets the amount of mana the player want to spent for a x spell * Gets the amount of mana the player want to spent for a x spell
*
* @param min * @param min
* @param max * @param max
* @param message * @param message
@ -700,7 +732,7 @@ public class HumanPlayer extends PlayerImpl {
game.fireGetAmountEvent(playerId, message, min, max); game.fireGetAmountEvent(playerId, message, min, max);
waitForIntegerResponse(game); waitForIntegerResponse(game);
if (response != null && response.getInteger() != null) { if (response != null && response.getInteger() != null) {
xValue = response.getInteger(); xValue = response.getInteger();
} }
return xValue; return xValue;
} }
@ -712,7 +744,7 @@ public class HumanPlayer extends PlayerImpl {
game.fireGetAmountEvent(playerId, message, min, max); game.fireGetAmountEvent(playerId, message, min, max);
waitForIntegerResponse(game); waitForIntegerResponse(game);
if (response != null && response.getInteger() != null) { if (response != null && response.getInteger() != null) {
xValue = response.getInteger(); xValue = response.getInteger();
} }
return xValue; return xValue;
} }
@ -739,8 +771,8 @@ public class HumanPlayer extends PlayerImpl {
FilterCreatureForCombat filter = filterCreatureForCombat.copy(); FilterCreatureForCombat filter = filterCreatureForCombat.copy();
filter.add(new ControllerIdPredicate(attackingPlayerId)); filter.add(new ControllerIdPredicate(attackingPlayerId));
while (!abort) { while (!abort) {
if (passedAllTurns || if (passedAllTurns
(!getUserData().getUserSkipPrioritySteps().isStopOnDeclareAttackersDuringSkipAction() && (passedTurn || passedUntilEndOfTurn || passedUntilNextMain) )) { || (!getUserData().getUserSkipPrioritySteps().isStopOnDeclareAttackersDuringSkipAction() && (passedTurn || passedUntilEndOfTurn || passedUntilNextMain))) {
return; return;
} }
Map<String, Serializable> options = new HashMap<>(); Map<String, Serializable> options = new HashMap<>();
@ -751,7 +783,7 @@ public class HumanPlayer extends PlayerImpl {
possibleAttackers.add(possibleAttacker.getId()); 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); game.fireSelectEvent(playerId, "Select attackers", options);
waitForResponse(game); waitForResponse(game);
@ -761,7 +793,7 @@ public class HumanPlayer extends PlayerImpl {
if (!game.getCombat().getAttackers().containsAll(game.getCombat().getCreaturesForcedToAttack().keySet())) { if (!game.getCombat().getAttackers().containsAll(game.getCombat().getCreaturesForcedToAttack().keySet())) {
int forcedAttackers = 0; int forcedAttackers = 0;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (UUID creatureId :game.getCombat().getCreaturesForcedToAttack().keySet()) { for (UUID creatureId : game.getCombat().getCreaturesForcedToAttack().keySet()) {
boolean validForcedAttacker = false; boolean validForcedAttacker = false;
if (game.getCombat().getAttackers().contains(creatureId)) { if (game.getCombat().getAttackers().contains(creatureId)) {
Set<UUID> possibleDefender = game.getCombat().getCreaturesForcedToAttack().get(creatureId); Set<UUID> possibleDefender = game.getCombat().getCreaturesForcedToAttack().get(creatureId);
@ -780,7 +812,7 @@ public class HumanPlayer extends PlayerImpl {
} }
if (game.getCombat().getMaxAttackers() > forcedAttackers) { 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, Math.min(game.getCombat().getMaxAttackers() - forcedAttackers, game.getCombat().getCreaturesForcedToAttack().size() - forcedAttackers))
.insert(0, "You have to attack with ").toString()); .insert(0, "You have to attack with ").toString());
continue; continue;
@ -799,18 +831,17 @@ public class HumanPlayer extends PlayerImpl {
if (attacker != null) { if (attacker != null) {
if (filterCreatureForCombat.match(attacker, null, playerId, game)) { if (filterCreatureForCombat.match(attacker, null, playerId, game)) {
selectDefender(game.getCombat().getDefenders(), attacker.getId(), 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); removeAttackerIfPossible(game, attacker);
} }
} }
} }
} }
} }
private void removeAttackerIfPossible(Game game, Permanent attacker) { private void removeAttackerIfPossible(Game game, Permanent attacker) {
for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(attacker, game).entrySet()) { for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(attacker, game).entrySet()) {
RequirementEffect effect = (RequirementEffect)entry.getKey(); RequirementEffect effect = (RequirementEffect) entry.getKey();
if (effect.mustAttack(game)) { if (effect.mustAttack(game)) {
if (game.getCombat().getMaxAttackers() >= game.getCombat().getCreaturesForcedToAttack().size() && game.getCombat().getDefenders().size() == 1) { 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 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) { if (possibleDefender.size() == 1) {
declareAttacker(attackerId, defenders.iterator().next(), game, true); declareAttacker(attackerId, defenders.iterator().next(), game, true);
return true; return true;
} } else {
else {
TargetDefender target = new TargetDefender(possibleDefender, attackerId); TargetDefender target = new TargetDefender(possibleDefender, attackerId);
target.setNotTarget(true); // player or planswalker hexproof does not prevent attacking a player target.setNotTarget(true); // player or planswalker hexproof does not prevent attacking a player
if (forcedToAttack) { if (forcedToAttack) {
@ -903,7 +933,7 @@ public class HumanPlayer extends PlayerImpl {
game.fireSelectTargetEvent(playerId, "Pick attacker", attackers, true); game.fireSelectTargetEvent(playerId, "Pick attacker", attackers, true);
waitForResponse(game); waitForResponse(game);
if (response.getUUID() != null) { if (response.getUUID() != null) {
for (Permanent perm: attackers) { for (Permanent perm : attackers) {
if (perm.getId().equals(response.getUUID())) { if (perm.getId().equals(response.getUUID())) {
return perm.getId(); return perm.getId();
} }
@ -913,7 +943,6 @@ public class HumanPlayer extends PlayerImpl {
return null; return null;
} }
@Override @Override
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) { public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
updateGameStatePriority("chooseBlockerOrder", game); updateGameStatePriority("chooseBlockerOrder", game);
@ -921,7 +950,7 @@ public class HumanPlayer extends PlayerImpl {
game.fireSelectTargetEvent(playerId, "Pick blocker", blockers, true); game.fireSelectTargetEvent(playerId, "Pick blocker", blockers, true);
waitForResponse(game); waitForResponse(game);
if (response.getUUID() != null) { if (response.getUUID() != null) {
for (Permanent perm: blockers) { for (Permanent perm : blockers) {
if (perm.getId().equals(response.getUUID())) { if (perm.getId().equals(response.getUUID())) {
return perm.getId(); return perm.getId();
} }
@ -967,8 +996,7 @@ public class HumanPlayer extends PlayerImpl {
if (permanent != null) { if (permanent != null) {
permanent.damage(damageAmount, sourceId, game, false, true); permanent.damage(damageAmount, sourceId, game, false, true);
remainingDamage -= damageAmount; remainingDamage -= damageAmount;
} } else {
else {
Player player = game.getPlayer(target.getFirstTarget()); Player player = game.getPlayer(target.getFirstTarget());
if (player != null) { if (player != null) {
player.damage(damageAmount, sourceId, game, false, true); player.damage(damageAmount, sourceId, game, false, true);
@ -1081,7 +1109,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana) { public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana) {
switch(ability.getSpellAbilityType()) { switch (ability.getSpellAbilityType()) {
case SPLIT: case SPLIT:
case SPLIT_FUSED: case SPLIT_FUSED:
MageObject object = game.getObject(ability.getSourceId()); MageObject object = game.getObject(ability.getSourceId());
@ -1111,7 +1139,7 @@ public class HumanPlayer extends PlayerImpl {
if (modes.size() > 1) { if (modes.size() > 1) {
MageObject obj = game.getObject(source.getSourceId()); MageObject obj = game.getObject(source.getSourceId());
Map<UUID, String> modeMap = new LinkedHashMap<>(); Map<UUID, String> 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 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 && mode.getTargets().canChoose(source.getSourceId(), source.getControllerId(), game)) { // and where targets are available
String modeText = mode.getEffects().getText(mode); String modeText = mode.getEffects().getText(mode);
@ -1125,7 +1153,7 @@ public class HumanPlayer extends PlayerImpl {
game.fireGetModeEvent(playerId, "Choose Mode", modeMap); game.fireGetModeEvent(playerId, "Choose Mode", modeMap);
waitForResponse(game); waitForResponse(game);
if (response.getUUID() != null) { if (response.getUUID() != null) {
for (Mode mode: modes.values()) { for (Mode mode : modes.values()) {
if (mode.getId().equals(response.getUUID())) { if (mode.getId().equals(response.getUUID())) {
return mode; return mode;
} }
@ -1150,7 +1178,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void setResponseString(String responseString) { public void setResponseString(String responseString) {
synchronized(response) { synchronized (response) {
response.setString(responseString); response.setString(responseString);
response.notify(); response.notify();
log.debug("Got response string from player: " + getId()); log.debug("Got response string from player: " + getId());
@ -1159,7 +1187,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void setResponseManaType(UUID manaTypePlayerId, ManaType manaType) { public void setResponseManaType(UUID manaTypePlayerId, ManaType manaType) {
synchronized(response) { synchronized (response) {
response.setManaType(manaType); response.setManaType(manaType);
response.setResponseManaTypePlayerId(manaTypePlayerId); response.setResponseManaTypePlayerId(manaTypePlayerId);
response.notify(); response.notify();
@ -1169,7 +1197,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void setResponseUUID(UUID responseUUID) { public void setResponseUUID(UUID responseUUID) {
synchronized(response) { synchronized (response) {
response.setUUID(responseUUID); response.setUUID(responseUUID);
response.notify(); response.notify();
log.debug("Got response UUID from player: " + getId()); log.debug("Got response UUID from player: " + getId());
@ -1178,7 +1206,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void setResponseBoolean(Boolean responseBoolean) { public void setResponseBoolean(Boolean responseBoolean) {
synchronized(response) { synchronized (response) {
response.setBoolean(responseBoolean); response.setBoolean(responseBoolean);
response.notify(); response.notify();
log.debug("Got response boolean from player: " + getId()); log.debug("Got response boolean from player: " + getId());
@ -1187,7 +1215,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void setResponseInteger(Integer responseInteger) { public void setResponseInteger(Integer responseInteger) {
synchronized(response) { synchronized (response) {
response.setInteger(responseInteger); response.setInteger(responseInteger);
response.notify(); response.notify();
log.debug("Got response integer from player: " + getId()); log.debug("Got response integer from player: " + getId());
@ -1197,7 +1225,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void abort() { public void abort() {
abort = true; abort = true;
synchronized(response) { synchronized (response) {
response.notify(); response.notify();
log.debug("Got cancel action from player: " + getId()); log.debug("Got cancel action from player: " + getId());
} }
@ -1205,7 +1233,7 @@ public class HumanPlayer extends PlayerImpl {
@Override @Override
public void skip() { public void skip() {
synchronized(response) { synchronized (response) {
response.setInteger(0); response.setInteger(0);
response.notify(); response.notify();
log.debug("Got skip action from player: " + getId()); log.debug("Got skip action from player: " + getId());
@ -1234,8 +1262,8 @@ public class HumanPlayer extends PlayerImpl {
} }
protected boolean passWithManaPoolCheck(Game game) { protected boolean passWithManaPoolCheck(Game game) {
if (userData.confirmEmptyManaPool() && if (userData.confirmEmptyManaPool()
game.getStack().isEmpty() && getManaPool().count() > 0) { && game.getStack().isEmpty() && getManaPool().count() > 0) {
String activePlayerText; String activePlayerText;
if (game.getActivePlayerId().equals(playerId)) { if (game.getActivePlayerId().equals(playerId)) {
activePlayerText = "Your turn"; activePlayerText = "Your turn";
@ -1247,7 +1275,7 @@ public class HumanPlayer extends PlayerImpl {
priorityPlayerText = " / priority " + game.getPlayer(game.getPriorityPlayerId()).getName(); priorityPlayerText = " / priority " + game.getPlayer(game.getPriorityPlayerId()).getName();
} }
if (!chooseUse(Outcome.Detriment, GameLog.getPlayerConfirmColoredText("You have still mana in your mana pool. Pass regardless?") 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); sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, game);
return false; return false;
} }

View file

@ -99,7 +99,7 @@ class ArsenalThresherEffect extends OneShotEffect {
Permanent arsenalThresher = game.getPermanent(source.getSourceId()); Permanent arsenalThresher = game.getPermanent(source.getSourceId());
FilterArtifactCard filter = new FilterArtifactCard(); FilterArtifactCard filter = new FilterArtifactCard();
filter.add(new AnotherCardPredicate()); 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(); Cards cards = new CardsImpl();
if (you.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) { if (you.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) {
TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter); TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter);

View file

@ -111,7 +111,7 @@ class EtherwroughtPageEffect extends OneShotEffect {
CardsImpl cards = new CardsImpl(); CardsImpl cards = new CardsImpl();
cards.add(card); cards.add(card);
controller.lookAtCards("Etherwrought Page", cards, game); 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 controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game);
} }
return true; return true;

View file

@ -139,7 +139,7 @@ class SovereignsOfLostAlaraEffect extends OneShotEffect {
FilterCard filter = new FilterCard("aura that could enchant the lone attacking creature"); FilterCard filter = new FilterCard("aura that could enchant the lone attacking creature");
filter.add(new SubtypePredicate("Aura")); filter.add(new SubtypePredicate("Aura"));
filter.add(new AuraCardCanAttachToPermanentId(attackingCreature.getId())); 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); TargetCardInLibrary target = new TargetCardInLibrary(filter);
target.setNotTarget(true); target.setNotTarget(true);
if (you.searchLibrary(target, game)) { if (you.searchLibrary(target, game)) {

View file

@ -104,7 +104,7 @@ class VectisDominatorEffect extends OneShotEffect {
if (player != null) { if (player != null) {
cost.clearPaid(); cost.clearPaid();
final StringBuilder sb = new StringBuilder("Pay 2 life? (Otherwise ").append(targetCreature.getName()).append(" will be tapped)"); 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); cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), true);
} }
if (!cost.isPaid()) { if (!cost.isPaid()) {

View file

@ -106,7 +106,7 @@ class PutLandOnBattlefieldEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); 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; return false;
} }

View file

@ -122,7 +122,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
return false; 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); Target targetAura = new TargetPermanent(filterAura);
if (player.choose(Outcome.Benefit, targetAura, source.getSourceId(), game)) { if (player.choose(Outcome.Benefit, targetAura, source.getSourceId(), game)) {
Permanent aura = game.getPermanent(targetAura.getFirstTarget()); Permanent aura = game.getPermanent(targetAura.getFirstTarget());
@ -137,7 +137,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
} }
int count = player.getHand().count(filterAuraCard, game); 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); TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard);
if (player.choose(Outcome.Benefit, player.getHand(), targetAura, game)) { if (player.choose(Outcome.Benefit, player.getHand(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget()); Card aura = game.getCard(targetAura.getFirstTarget());
@ -151,7 +151,7 @@ class BrunaLightOfAlabasterEffect extends OneShotEffect {
} }
count = player.getGraveyard().count(filterAuraCard, game); 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); TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard);
if (player.choose(Outcome.Benefit, player.getGraveyard(), targetAura, game)) { if (player.choose(Outcome.Benefit, player.getGraveyard(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget()); Card aura = game.getCard(targetAura.getFirstTarget());

View file

@ -110,7 +110,7 @@ class DescendantsPathEffect extends OneShotEffect {
} }
if (found) { if (found) {
game.informPlayers(sourceObject.getLogName() + ": Found a creature that shares a creature type with the revealed card."); 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); controller.cast(card.getSpellAbility(), game, true);
} else { } else {
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " canceled casting the card."); game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " canceled casting the card.");

View file

@ -105,7 +105,7 @@ class FettergeistUnlessPaysEffect extends OneShotEffect {
if (count == 0) { if (count == 0) {
return true; return true;
} }
if (player.chooseUse(Outcome.Benefit, "Pay " + count + "?", game)) { if (player.chooseUse(Outcome.Benefit, "Pay " + count + "?", source, game)) {
GenericManaCost cost = new GenericManaCost(count); GenericManaCost cost = new GenericManaCost(count);
if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) {
return true; return true;

View file

@ -106,7 +106,7 @@ class KillingWaveEffect extends OneShotEffect {
int playerLife = player.getLife(); int playerLife = player.getLife();
for (Permanent creature : creatures) { for (Permanent creature : creatures) {
String message = "Pay " + amount + " life? If you don't, " + creature.getName() + " will be sacrificed."; 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()); game.informPlayers(player.getLogName() + " pays " + amount + " life. He will not sacrifice " + creature.getName());
lifePaid += amount; lifePaid += amount;
} else { } else {

View file

@ -100,7 +100,7 @@ class PrimalSurgeEffect extends OneShotEffect {
if ((cardType.contains(CardType.ARTIFACT) || cardType.contains(CardType.CREATURE) if ((cardType.contains(CardType.ARTIFACT) || cardType.contains(CardType.CREATURE)
|| cardType.contains(CardType.ENCHANTMENT) || cardType.contains(CardType.LAND) || cardType.contains(CardType.ENCHANTMENT) || cardType.contains(CardType.LAND)
|| cardType.contains(CardType.PLANESWALKER)) || 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); card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
Permanent permanent = game.getPermanent(card.getId()); Permanent permanent = game.getPermanent(card.getId());

View file

@ -89,7 +89,7 @@ class VexingDevilEffect extends OneShotEffect {
if (controller != null && permanent != null) { if (controller != null && permanent != null) {
for (UUID opponentUuid : game.getOpponents(source.getControllerId())) { for (UUID opponentUuid : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentUuid); 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()); game.informPlayers(opponent.getLogName() + " has chosen to receive 4 damage from " + permanent.getLogName());
opponent.damage(4, permanent.getId(), game, false, true); opponent.damage(4, permanent.getId(), game, false, true);
permanent.sacrifice(source.getSourceId(), game); permanent.sacrifice(source.getSourceId(), game);

View file

@ -113,7 +113,7 @@ class IwamoriOfTheOpenFistEffect extends OneShotEffect {
Player opponent = game.getPlayer(playerId); Player opponent = game.getPlayer(playerId);
Target target = new TargetCardInHand(filter); Target target = new TargetCardInHand(filter);
if (opponent != null && target.canChoose(source.getSourceId(), opponent.getId(), game)) { 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)) { if (target.chooseTarget(Outcome.PutCreatureInPlay, opponent.getId(), source, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
if (card != null) { if (card != null) {

View file

@ -99,7 +99,7 @@ class OgreMarauderEffect extends OneShotEffect {
if (defender != null && sourceObject != null) { if (defender != null && sourceObject != null) {
Cost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent()); Cost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent());
if (cost.canPay(source, source.getSourceId(), defendingPlayerId, game) && 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)) { if (!cost.pay(source, game, source.getSourceId(), defendingPlayerId, false)) {
// cost was not payed - so source can't be blocked // cost was not payed - so source can't be blocked
ContinuousEffect effect = new CantBeBlockedSourceEffect(Duration.EndOfTurn); ContinuousEffect effect = new CantBeBlockedSourceEffect(Duration.EndOfTurn);

View file

@ -90,9 +90,9 @@ public class ToilsOfNightAndDay extends CardImpl {
for (UUID targetId : source.getTargets().get(0).getTargets()) { for (UUID targetId : source.getTargets().get(0).getTargets()) {
Permanent permanent = game.getPermanent(targetId); Permanent permanent = game.getPermanent(targetId);
if (permanent != null) { 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); 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); permanent.untap(game);
} }
} }

View file

@ -122,7 +122,7 @@ class ArbiterOfTheIdealEffect extends OneShotEffect {
player.revealCards("Arbiter of the Ideal", cards, game); player.revealCards("Arbiter of the Ideal", cards, game);
if (card != null) { 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()); card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId());
Permanent permanent = game.getPermanent(card.getId()); Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) { if (permanent != null) {

View file

@ -100,7 +100,7 @@ class FloodtideSerpentReplacementEffect extends ReplacementEffectImpl {
if ( player != null ) { if ( player != null ) {
ReturnToHandTargetPermanentCost attackCost = new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)); ReturnToHandTargetPermanentCost attackCost = new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter));
if ( attackCost.canPay(source, source.getSourceId(), event.getPlayerId(), game) && 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) ) { if (attackCost.pay(source, game, source.getSourceId(), event.getPlayerId(), true) ) {
return false; return false;

View file

@ -95,7 +95,7 @@ class HeroOfLeinaTowerEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId()); Player you = game.getPlayer(source.getControllerId());
ManaCosts cost = new ManaCostsImpl("{X}"); 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); int costX = you.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source);
cost.add(new GenericManaCost(costX)); cost.add(new GenericManaCost(costX));
if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) {

View file

@ -171,7 +171,7 @@ class HeroesPodiumEffect extends OneShotEffect {
player.lookAtCards("Heroes' Podium", cards, game); player.lookAtCards("Heroes' Podium", cards, game);
// You may reveal a legendary creature card from among them and put it into your hand. // 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) { if (cards.size() == 1) {
Card card = cards.getRandom(game); Card card = cards.getRandom(game);
cards.remove(card); cards.remove(card);

View file

@ -127,7 +127,7 @@ class DoUnlessTargetPaysCost extends OneShotEffect {
} }
message = CardUtil.replaceSourceName(message, mageObject.getLogName()); message = CardUtil.replaceSourceName(message, mageObject.getLogName());
cost.clearPaid(); 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); cost.pay(source, game, source.getSourceId(), player.getId(), false);
} }
if (!cost.isPaid()) { if (!cost.isPaid()) {

View file

@ -108,7 +108,7 @@ class OracleOfBonesCastEffect extends OneShotEffect {
if (controller != null) { if (controller != null) {
Target target = new TargetCardInHand(filter); Target target = new TargetCardInHand(filter);
if (target.canChoose(source.getSourceId(), controller.getId(), game) && if (target.canChoose(source.getSourceId(), controller.getId(), game) &&
controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", game)) { controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", source, game)) {
Card cardToCast = null; Card cardToCast = null;
boolean cancel = false; boolean cancel = false;
while (controller.isInGame() && !cancel) { while (controller.isInGame() && !cancel) {

View file

@ -104,7 +104,7 @@ class SatyrWayfinderEffect extends OneShotEffect {
controller.revealCards(sourceObject.getName(), cards, game); controller.revealCards(sourceObject.getName(), cards, game);
TargetCard target = new TargetCard(Zone.LIBRARY, filterPutInHand); TargetCard target = new TargetCard(Zone.LIBRARY, filterPutInHand);
if (properCardFound && 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)) { controller.choose(Outcome.DrawCard, cards, target, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
if (card != null) { if (card != null) {

View file

@ -96,7 +96,7 @@ class CutTheTethersEffect extends OneShotEffect {
Player player = game.getPlayer(creature.getControllerId()); Player player = game.getPlayer(creature.getControllerId());
if (player != null) { if (player != null) {
boolean paid = false; 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); Cost cost = new GenericManaCost(3);
if (!cost.pay(source, game, source.getSourceId(), creature.getControllerId(), false)) { if (!cost.pay(source, game, source.getSourceId(), creature.getControllerId(), false)) {
paid = true; paid = true;

View file

@ -103,7 +103,7 @@ class GhostlyPrisonReplacementEffect extends ReplacementEffectImpl {
if ( player != null && event.getTargetId().equals(source.getControllerId())) { if ( player != null && event.getTargetId().equals(source.getControllerId())) {
ManaCostsImpl attackTax = new ManaCostsImpl("{2}"); ManaCostsImpl attackTax = new ManaCostsImpl("{2}");
if (attackTax.canPay(source, source.getSourceId(), event.getPlayerId(), game) && 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())) { if (attackTax.payOrRollback(source, game, this.getId(), event.getPlayerId())) {
return false; return false;
} }

View file

@ -163,7 +163,7 @@ class HinderReplacementEffect extends ReplacementEffectImpl {
Card card = (Card) targetObject; Card card = (Card) targetObject;
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player != null) { 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())) { 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."); game.informPlayers(player.getLogName() + " has put " + card.getName() + " on " + (top ? "top" : "the bottom") + " of the library.");
} }

View file

@ -106,7 +106,7 @@ class InameLifeAspectEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId()); MageObject sourceObject = game.getObject(source.getSourceId());
if (controller != null && sourceObject != null) { 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); new ExileSourceEffect().apply(game, source);
return new ReturnToHandTargetEffect().apply(game, source); return new ReturnToHandTargetEffect().apply(game, source);
} }

View file

@ -102,7 +102,7 @@ class ThroughTheBreachEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
if (controller.chooseUse(Outcome.PutCreatureInPlay, choiceText, game)) { if (controller.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) {
TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard()); TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard());
if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());

View file

@ -115,7 +115,7 @@ class ArcumDagssonEffect extends OneShotEffect {
Player player = game.getPlayer(artifactCreature.getControllerId()); Player player = game.getPlayer(artifactCreature.getControllerId());
if (player != null) { if (player != null) {
artifactCreature.sacrifice(source.getSourceId(), game); 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); TargetCardInLibrary target = new TargetCardInLibrary(filter);
if (player.searchLibrary(target, game)) { if (player.searchLibrary(target, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());

View file

@ -100,7 +100,7 @@ class ScryingSheetsEffect extends OneShotEffect {
cards.add(card); cards.add(card);
player.lookAtCards("Scrying Sheets", cards, game); player.lookAtCards("Scrying Sheets", cards, game);
if (card.getSupertype().contains("Snow")) { 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); card = player.getLibrary().removeFromTop(game);
player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); player.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
player.revealCards("Scrying Sheets", cards, game); player.revealCards("Scrying Sheets", cards, game);

View file

@ -112,7 +112,7 @@ class ChorusOfTheConclaveReplacementEffect extends ReplacementEffectImpl {
int xCost = 0; int xCost = 0;
Player you = game.getPlayer(source.getControllerId()); Player you = game.getPlayer(source.getControllerId());
if (you != null) { 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); xCost += playerPaysXGenericMana(you, source, game);
// save the x value to be available for ETB replacement effect // save the x value to be available for ETB replacement effect
Object object = game.getState().getValue("spellX" + source.getSourceId()); Object object = game.getState().getValue("spellX" + source.getSourceId());

View file

@ -149,7 +149,7 @@ class KaaliaOfTheVastEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); 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; return false;
} }
TargetCardInHand target = new TargetCardInHand(filter); TargetCardInHand target = new TargetCardInHand(filter);

View file

@ -100,7 +100,7 @@ class TheMimeoplasmEffect extends OneShotEffect {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (controller != null && permanent != null) { if (controller != null && permanent != null) {
if (new CardsInAllGraveyardsCount(new FilterCreatureCard()).calculate(game, source, this) >= 2) { 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 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")); 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)) { if (controller.choose(Outcome.Copy, targetCopy, source.getSourceId(), game)) {

View file

@ -114,7 +114,7 @@ class VeteranExplorerEffect extends OneShotEffect {
} }
private void chooseAndSearchLibrary(List<Player> usingPlayers, Player player, Ability source, Game game) { private void chooseAndSearchLibrary(List<Player> usingPlayers, Player player, Ability source, Game game) {
if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for up to two basic land cards and put them onto the battlefield?", 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); usingPlayers.add(player);
TargetCardInLibrary target = new TargetCardInLibrary(0, 2, new FilterBasicLandCard()); TargetCardInLibrary target = new TargetCardInLibrary(0, 2, new FilterBasicLandCard());
if (player.searchLibrary(target, game)) { if (player.searchLibrary(target, game)) {

View file

@ -90,7 +90,7 @@ class WhirlpoolWhelmEffect extends OneShotEffect {
if (controller != null) { if (controller != null) {
boolean topOfLibrary = false; boolean topOfLibrary = false;
if (ClashEffect.getInstance().apply(game, source)) { 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) { if (topOfLibrary) {
controller.moveCardToHandWithInfo(creature, source.getSourceId(), game, Zone.BATTLEFIELD); controller.moveCardToHandWithInfo(creature, source.getSourceId(), game, Zone.BATTLEFIELD);

View file

@ -92,7 +92,7 @@ class WildRicochetEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Spell spell = game.getStack().getSpell(source.getFirstTarget()); Spell spell = game.getStack().getSpell(source.getFirstTarget());
Player you = game.getPlayer(source.getControllerId()); 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()); spell.chooseNewTargets(game, you.getId());
} }
if (spell != null) { if (spell != null) {
@ -100,7 +100,7 @@ class WildRicochetEffect extends OneShotEffect {
copy.setControllerId(source.getControllerId()); copy.setControllerId(source.getControllerId());
copy.setCopiedSpell(true); copy.setCopiedSpell(true);
game.getStack().push(copy); 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()); return copy.chooseNewTargets(game, you.getId());
} }
} }

View file

@ -141,7 +141,7 @@ class CurseOfChaosEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player attacker = game.getPlayer(this.getTargetPointer().getFirst(game, source)); Player attacker = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (attacker != null) { 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.discard(1, false, source, game);
attacker.drawCards(1, game); attacker.drawCards(1, game);
} }

View file

@ -141,11 +141,11 @@ class CurseOfInertiaTapOrUntapTargetEffect extends OneShotEffect {
Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (targetPermanent != null) { if (targetPermanent != null) {
if (targetPermanent.isTapped()) { 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); targetPermanent.untap(game);
} }
} else { } else {
if (player.chooseUse(Outcome.Tap, "Tap that permanent?", game)) { if (player.chooseUse(Outcome.Tap, "Tap that permanent?", source, game)) {
targetPermanent.tap(game); targetPermanent.tap(game);
} }
} }

View file

@ -152,7 +152,7 @@ class JelevaNephaliasCastEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { 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)); TargetCardInExile target = new TargetCardInExile(new FilterInstantOrSorceryCard(), CardUtil.getCardExileZoneId(game, source));
if (controller.choose(Outcome.PlayForFree, game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)), target, game)) { if (controller.choose(Outcome.PlayForFree, game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)), target, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());

View file

@ -105,7 +105,7 @@ class LimDulsVaultEffect extends OneShotEffect {
} }
} }
player.lookAtCards("Lim-Dul's Vault", cards, game); 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) { if (doAgain) {
player.loseLife(1, game); player.loseLife(1, game);
} else { } else {

View file

@ -101,7 +101,7 @@ class PlagueBoilerEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (controller != null && sourcePermanent != null) { 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); return new AddCountersSourceEffect(CounterType.PLAGUE.createInstance(), true).apply(game, source);
} else { } else {
return new RemoveCounterSourceEffect(CounterType.PLAGUE.createInstance()).apply(game, source); return new RemoveCounterSourceEffect(CounterType.PLAGUE.createInstance()).apply(game, source);

View file

@ -123,11 +123,11 @@ class MayTapOrUntapAttachedEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (equipedCreature != null && player != null) { if (equipedCreature != null && player != null) {
if (equipedCreature.isTapped()) { 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); equipedCreature.untap(game);
} }
} else { } else {
if (player.chooseUse(Outcome.Tap, "Tap equipped creature?", game)) { if (player.chooseUse(Outcome.Tap, "Tap equipped creature?", source, game)) {
equipedCreature.tap(game); equipedCreature.tap(game);
} }
} }

View file

@ -102,7 +102,7 @@ class TemptWithDiscoveryEffect extends OneShotEffect {
for (UUID playerId : game.getOpponents(controller.getId())) { for (UUID playerId : game.getOpponents(controller.getId())) {
Player opponent = game.getPlayer(playerId); Player opponent = game.getPlayer(playerId);
if (opponent != null) { 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(); target.clearChosen();
opponentsUsedSearch++; opponentsUsedSearch++;
if (opponent.searchLibrary(target, game)) { if (opponent.searchLibrary(target, game)) {

View file

@ -94,7 +94,7 @@ class TemptWithGloryEffect extends OneShotEffect {
for (UUID playerId : game.getOpponents(controller.getId())) { for (UUID playerId : game.getOpponents(controller.getId())) {
Player opponent = game.getPlayer(playerId); Player opponent = game.getPlayer(playerId);
if (opponent != null) { 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++; opponentsAddedCounters++;
addCounterToEachCreature(playerId, counter, game); addCounterToEachCreature(playerId, counter, game);
game.informPlayers(opponent.getLogName() + " added a +1/+1 counter on each of its creatures"); game.informPlayers(opponent.getLogName() + " added a +1/+1 counter on each of its creatures");

View file

@ -102,7 +102,7 @@ class TemptWithImmortalityEffect extends OneShotEffect {
Target targetOpponent = new TargetCardInGraveyard(filter); Target targetOpponent = new TargetCardInGraveyard(filter);
if (targetOpponent.canChoose(source.getSourceId(), opponent.getId(), game)) { 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)) { if (opponent.chooseTarget(outcome, targetOpponent, source, game)) {
Card card = game.getCard(targetOpponent.getFirstTarget()); Card card = game.getCard(targetOpponent.getFirstTarget());
if (card != null) { if (card != null) {

View file

@ -104,7 +104,7 @@ class TemptWithReflectionsEffect extends OneShotEffect {
do { do {
if (game.getOpponents(source.getControllerId()).contains(player.getId())) { if (game.getOpponents(source.getControllerId()).contains(player.getId())) {
String decision; 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()); playersSaidYes.add(player.getId());
decision = " chooses to copy "; decision = " chooses to copy ";
} else { } else {

View file

@ -94,7 +94,7 @@ class TemptWithVengeanceEffect extends OneShotEffect {
for (UUID playerId : game.getOpponents(controller.getId())) { for (UUID playerId : game.getOpponents(controller.getId())) {
Player opponent = game.getPlayer(playerId); Player opponent = game.getPlayer(playerId);
if (opponent != null) { 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; opponentsAddedTokens += xValue;
tokenCopy.putOntoBattlefield(xValue, game, source.getSourceId(), playerId, false, false); tokenCopy.putOntoBattlefield(xValue, game, source.getSourceId(), playerId, false, false);
} }

View file

@ -92,7 +92,7 @@ class WarCadenceReplacementEffect extends ReplacementEffectImpl {
String mana = new StringBuilder("{").append(amount).append("}").toString(); String mana = new StringBuilder("{").append(amount).append("}").toString();
ManaCostsImpl cost = new ManaCostsImpl(mana); ManaCostsImpl cost = new ManaCostsImpl(mana);
if ( cost.canPay(source, source.getSourceId(), event.getPlayerId(), game) && 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())) { if (cost.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) {
return false; return false;
} }

View file

@ -160,7 +160,7 @@ class AssaultSuitGainControlEffect extends OneShotEffect {
if (equipment.getAttachedTo() != null) { if (equipment.getAttachedTo() != null) {
Permanent equippedCreature = game.getPermanent(equipment.getAttachedTo()); Permanent equippedCreature = game.getPermanent(equipment.getAttachedTo());
if (equippedCreature != null && controller.chooseUse(outcome, 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); equippedCreature.untap(game);
ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfTurn, activePlayer.getId()); ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfTurn, activePlayer.getId());
effect.setTargetPointer(new FixedTarget(equipment.getAttachedTo())); effect.setTargetPointer(new FixedTarget(equipment.getAttachedTo()));

View file

@ -139,7 +139,7 @@ class NahiriTheLithomancerFirstAbilityEffect extends OneShotEffect {
//TODO: Make sure the Equipment can legally enchant the token, preferably on targetting. //TODO: Make sure the Equipment can legally enchant the token, preferably on targetting.
Target target = new TargetControlledPermanent(0, 1, filter, true); Target target = new TargetControlledPermanent(0, 1, filter, true);
if (target.canChoose(source.getSourceId(), controller.getId(), game) && 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)) { if (target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), game)) {
Permanent equipmentPermanent = game.getPermanent(target.getFirstTarget()); Permanent equipmentPermanent = game.getPermanent(target.getFirstTarget());
if (equipmentPermanent != null) { if (equipmentPermanent != null) {
@ -199,7 +199,7 @@ class NahiriTheLithomancerSecondAbilityEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { 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); Target target = new TargetCardInHand(0, 1, filter);
controller.choose(outcome, target, source.getSourceId(), game); controller.choose(outcome, target, source.getSourceId(), game);
Card card = controller.getHand().get(target.getFirstTarget(), game); Card card = controller.getHand().get(target.getFirstTarget(), game);

View file

@ -106,7 +106,7 @@ class ShaperParasiteEffect extends ContinuousEffectImpl {
super.init(source, game); super.init(source, game);
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
String message = "Should the target creature get -2/+2 instead of +2/-2?"; 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.power *= -1;
this.toughness *= -1; this.toughness *= -1;
} }

View file

@ -124,7 +124,7 @@ class WaveOfVitriolEffect extends OneShotEffect {
} }
game.getState().handleSimultaneousEvent(game); game.getState().handleSimultaneousEvent(game);
for(Map.Entry<Player, Integer> entry: sacrificedLands.entrySet()) { for(Map.Entry<Player, Integer> 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()); Target target = new TargetCardInLibrary(0, entry.getValue(), new FilterBasicLandCard());
entry.getKey().chooseTarget(outcome, target, source, game); entry.getKey().chooseTarget(outcome, target, source, game);
for(UUID targetId: target.getTargets()) { for(UUID targetId: target.getTargets()) {

View file

@ -101,7 +101,7 @@ class MaelstromArchangelCastEffect extends OneShotEffect {
if (controller != null) { if (controller != null) {
Target target = new TargetCardInHand(filter); Target target = new TargetCardInHand(filter);
if (target.canChoose(source.getSourceId(), controller.getId(), game) && 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; Card cardToCast = null;
boolean cancel = false; boolean cancel = false;
while (controller.isInGame() && !cancel) { while (controller.isInGame() && !cancel) {

View file

@ -104,7 +104,7 @@ class MasterTransmuterEffect extends OneShotEffect {
if (controller != null) { if (controller != null) {
Target target = new TargetCardInHand(new FilterArtifactCard("an artifact card from your hand")); Target target = new TargetCardInHand(new FilterArtifactCard("an artifact card from your hand"));
if (target.canChoose(source.getSourceId(), source.getControllerId(), game) 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)) { && controller.chooseTarget(outcome, target, source, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
if (card != null) { if (card != null) {

View file

@ -94,7 +94,7 @@ class PathToExileEffect extends OneShotEffect {
Player player = game.getPlayer(permanent.getControllerId()); 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 // 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); 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()); TargetCardInLibrary target = new TargetCardInLibrary(new FilterBasicLandCard());
if (player.searchLibrary(target, game)) { if (player.searchLibrary(target, game)) {
Card card = player.getLibrary().getCard(target.getFirstTarget(), game); Card card = player.getLibrary().getCard(target.getFirstTarget(), game);

View file

@ -92,7 +92,7 @@ class CoercivePortalEffect extends OneShotEffect {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null) { if (player != null) {
if (player.chooseUse(Outcome.DestroyPermanent, "Choose carnage?", game)) { if (player.chooseUse(Outcome.DestroyPermanent, "Choose carnage?", source, game)) {
carnageCount++; carnageCount++;
game.informPlayers(player.getLogName() + " has chosen: carnage"); game.informPlayers(player.getLogName() + " has chosen: carnage");
} }

View file

@ -88,7 +88,7 @@ class TyrantsChoiceEffect extends OneShotEffect {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player != null) { if (player != null) {
if (player.chooseUse(Outcome.Sacrifice, "Choose death?", game)) { if (player.chooseUse(Outcome.Sacrifice, "Choose death?", source, game)) {
deathCount++; deathCount++;
game.informPlayers(player.getLogName() + " has chosen: death"); game.informPlayers(player.getLogName() + " has chosen: death");
} }

View file

@ -141,7 +141,7 @@ class CallToTheKindredEffect extends OneShotEffect {
sb.delete(sb.length() - 2, sb.length()); sb.delete(sb.length() - 2, sb.length());
filter.setMessage(sb.toString()); 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); TargetCard target = new TargetCard(Zone.PICK, filter);
if (player.choose(Outcome.PutCreatureInPlay, cards, target, game)) { if (player.choose(Outcome.PutCreatureInPlay, cards, target, game)) {

View file

@ -96,7 +96,7 @@ class CounterlashEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (stackObject != null && player != null) { if (stackObject != null && player != null) {
game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game); 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(); FilterCard filter = new FilterCard();
ArrayList<Predicate<MageObject>> types = new ArrayList<Predicate<MageObject>>(); ArrayList<Predicate<MageObject>> types = new ArrayList<Predicate<MageObject>>();
for (CardType type: stackObject.getCardType()) { for (CardType type: stackObject.getCardType()) {

View file

@ -152,7 +152,7 @@ class CurseOfEchoesEffect extends OneShotEffect {
for (UUID playerId: game.getPlayerList()) { for (UUID playerId: game.getPlayerList()) {
if (!playerId.equals(spell.getControllerId())) { if (!playerId.equals(spell.getControllerId())) {
Player player = game.getPlayer(playerId); Player player = game.getPlayer(playerId);
if (player.chooseUse(Outcome.Copy, chooseMessage, game)) { if (player.chooseUse(Outcome.Copy, chooseMessage, source, game)) {
Spell copy = spell.copySpell(); Spell copy = spell.copySpell();
copy.setControllerId(playerId); copy.setControllerId(playerId);
copy.setCopiedSpell(true); copy.setCopiedSpell(true);

View file

@ -109,7 +109,7 @@ class AEtherVialEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player == null || player.getHand().count(filter, game) == 0 if (player == null || player.getHand().count(filter, game) == 0
|| !player.chooseUse(this.outcome, choiceText, game)) { || !player.chooseUse(this.outcome, choiceText, source, game)) {
return false; return false;
} }

View file

@ -109,7 +109,7 @@ class PanopticMirrorExileEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player == null || player.getHand().count(filter, game) == 0 if (player == null || player.getHand().count(filter, game) == 0
|| !player.chooseUse(this.outcome, choiceText, game)) { || !player.chooseUse(this.outcome, choiceText, source, game)) {
return false; return false;
} }
@ -177,7 +177,7 @@ class PanopticMirrorCastEffect extends OneShotEffect {
} }
if(cardToCopy != null){ if(cardToCopy != null){
Card copy = game.copyCard(cardToCopy, source, source.getControllerId()); 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); return controller.cast(copy.getSpellAbility(), game, true);
} }
} }

View file

@ -87,7 +87,7 @@ class SerumPowderReplaceEffect extends ReplacementEffectImpl {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Card sourceCard = game.getCard(source.getSourceId()); Card sourceCard = game.getCard(source.getSourceId());
if (controller != null && sourceCard != null) { 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; return false;
} }
int cardsHand = controller.getHand().size(); int cardsHand = controller.getHand().size();

View file

@ -172,7 +172,7 @@ class SwordOfLightAndShadowReturnToHandTargetEffect extends OneShotEffect {
return false; return false;
} }
if (!source.getTargets().isEmpty() && targetPointer.getFirst(game, source) != null) { 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)) { for (UUID targetId : targetPointer.getTargets(game, source)) {
switch (game.getState().getZone(targetId)) { switch (game.getState().getZone(targetId)) {
case GRAVEYARD: case GRAVEYARD:

View file

@ -102,7 +102,7 @@ class ResearchEffect extends OneShotEffect {
StringBuilder textToAsk = new StringBuilder(choiceText); StringBuilder textToAsk = new StringBuilder(choiceText);
textToAsk.append(" (0)"); textToAsk.append(" (0)");
int count = 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(); Cards cards = player.getSideboard();
if(cards.isEmpty()) { if(cards.isEmpty()) {
game.informPlayer(player, "You have no cards outside the game."); game.informPlayer(player, "You have no cards outside the game.");
@ -172,7 +172,7 @@ class DevelopmentEffect extends OneShotEffect {
for (UUID opponentUuid : opponents) { for (UUID opponentUuid : opponents) {
Player opponent = game.getPlayer(opponentUuid); Player opponent = game.getPlayer(opponentUuid);
if (opponent != null && opponent.chooseUse(Outcome.Detriment, 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."); game.informPlayers(opponent.getLogName() + " had chosen to let " + player.getLogName() + " draw a card.");
player.drawCards(1, game); player.drawCards(1, game);
putToken = false; putToken = false;

View file

@ -99,11 +99,11 @@ class HiddenStringsEffect extends OneShotEffect {
Permanent permanent = game.getPermanent(targetId); Permanent permanent = game.getPermanent(targetId);
if (permanent != null) { if (permanent != null) {
if (permanent.isTapped()) { 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); permanent.untap(game);
} }
} else { } 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); permanent.tap(game);
} }
} }

View file

@ -150,7 +150,7 @@ class PossibilityStormEffect extends OneShotEffect {
if (card != null && sharesType(card, spell.getCardType()) && if (card != null && sharesType(card, spell.getCardType()) &&
!card.getCardType().contains(CardType.LAND) && !card.getCardType().contains(CardType.LAND) &&
card.getSpellAbility().getTargets().canChoose(spellController.getId(), game)) { 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); spellController.cast(card.getSpellAbility(), game, true);
} }
} }

View file

@ -94,7 +94,7 @@ class ArashinSovereignEffect extends OneShotEffect {
Card sourceCard = game.getCard(source.getSourceId()); Card sourceCard = game.getCard(source.getSourceId());
if (controller != null && sourceCard != null) { if (controller != null && sourceCard != null) {
if (game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { 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); controller.moveCardToLibraryWithInfo(sourceCard, source.getSourceId(), game, Zone.GRAVEYARD, onTop, true);
} }
return true; return true;

View file

@ -102,7 +102,7 @@ class DeathmistRaptorEffect extends OneShotEffect {
MageObject sourceObject = source.getSourceObjectIfItStillExists(game); MageObject sourceObject = source.getSourceObjectIfItStillExists(game);
if (controller != null && (sourceObject instanceof Card)) { if (controller != null && (sourceObject instanceof Card)) {
controller.putOntoBattlefieldWithInfo((Card) sourceObject, game, Zone.GRAVEYARD, source.getSourceId(), false, 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 true;
} }
return false; return false;

View file

@ -92,7 +92,7 @@ class MysticMeditationEffect extends OneShotEffect {
filter.add(new CardTypePredicate(CardType.CREATURE)); filter.add(new CardTypePredicate(CardType.CREATURE));
if (controller != null if (controller != null
&& controller.getHand().count(filter, game) > 0 && 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)); Cost cost = new DiscardTargetCost(new TargetCardInHand(filter));
if (cost.canPay(source, source.getSourceId(), controller.getId(), game)) { if (cost.canPay(source, source.getSourceId(), controller.getId(), game)) {
if (cost.pay(source, game, source.getSourceId(), controller.getId(), false)) { if (cost.pay(source, game, source.getSourceId(), controller.getId(), false)) {

View file

@ -121,7 +121,7 @@ class NarsetTranscendentEffect1 extends OneShotEffect {
cards.add(card); cards.add(card);
controller.lookAtCards(sourceObject.getName(), cards, game); controller.lookAtCards(sourceObject.getName(), cards, game);
if (!card.getCardType().contains(CardType.CREATURE) && !card.getCardType().contains(CardType.LAND)) { 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.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
controller.revealCards(sourceObject.getName(), cards, game); controller.revealCards(sourceObject.getName(), cards, game);
} }

View file

@ -104,7 +104,7 @@ class QalSismaBehemothEffect extends ReplacementEffectImpl {
} }
ManaCostsImpl attackBlockTax = new ManaCostsImpl("{2}"); ManaCostsImpl attackBlockTax = new ManaCostsImpl("{2}");
if (attackBlockTax.canPay(source, source.getSourceId(), event.getPlayerId(), game) 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())) { if (attackBlockTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) {
return false; return false;
} }

View file

@ -101,7 +101,7 @@ class RevealingWindEffect extends OneShotEffect {
MageObject sourceObject = source.getSourceObject(game); MageObject sourceObject = source.getSourceObject(game);
if (controller != null && sourceObject != null) { if (controller != null && sourceObject != null) {
while (game.getBattlefield().count(filter, source.getOriginalId(), source.getControllerId(), game) > 0 && 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()) { if (!controller.isInGame()) {
return false; return false;
} }

View file

@ -132,7 +132,7 @@ class SilumgarsScornCounterEffect extends OneShotEffect {
if (condition) { if (condition) {
return game.getStack().counter(spell.getId(), source.getSourceId(), game); 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))) { new GenericManaCost(1).pay(source, game, spell.getSourceId(), spell.getControllerId(), false))) {
return game.getStack().counter(spell.getId(), source.getSourceId(), game); return game.getStack().counter(spell.getId(), source.getSourceId(), game);
} }

View file

@ -117,7 +117,7 @@ class SwiftWarkiteEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { 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); Target target = new TargetCardInHand(0, 1, filter);
controller.choose(outcome, target, source.getSourceId(), game); controller.choose(outcome, target, source.getSourceId(), game);
Card card = controller.getHand().get(target.getFirstTarget(), game); Card card = controller.getHand().get(target.getFirstTarget(), game);

View file

@ -122,7 +122,7 @@ class EvershrikeEffect extends OneShotEffect {
filterAuraCard.add(new AuraCardCanAttachToPermanentId(evershrikePermanent.getId())); filterAuraCard.add(new AuraCardCanAttachToPermanentId(evershrikePermanent.getId()));
filterAuraCard.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, xAmount)); filterAuraCard.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, xAmount));
int count = controller.getHand().count(filterAuraCard, game); 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); TargetCard targetAura = new TargetCard(Zone.PICK, filterAuraCard);
if (controller.choose(Outcome.Benefit, controller.getHand(), targetAura, game)) { if (controller.choose(Outcome.Benefit, controller.getHand(), targetAura, game)) {
Card aura = game.getCard(targetAura.getFirstTarget()); Card aura = game.getCard(targetAura.getFirstTarget());

View file

@ -128,7 +128,7 @@ class MindwrackLiegeEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); 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; return false;
} }

View file

@ -116,7 +116,7 @@ class RiseOfTheHobgoblinsEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId()); Player you = game.getPlayer(source.getControllerId());
ManaCosts<ManaCost> cost = new ManaCostsImpl<>("{X}"); ManaCosts<ManaCost> 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); int costX = you.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source);
cost.add(new GenericManaCost(costX)); cost.add(new GenericManaCost(costX));
if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) {

View file

@ -102,7 +102,7 @@ class ErraticPortalEffect extends OneShotEffect {
Player player = game.getPlayer(targetCreature.getControllerId()); Player player = game.getPlayer(targetCreature.getControllerId());
if (player != null) { if (player != null) {
cost.clearPaid(); 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); cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), false);
} }
if (!cost.isPaid()) { if (!cost.isPaid()) {

View file

@ -103,7 +103,7 @@ class ExaltedDragonReplacementEffect extends ReplacementEffectImpl {
if ( player != null ) { if ( player != null ) {
SacrificeTargetCost attackCost = new SacrificeTargetCost(new TargetControlledPermanent(filter)); SacrificeTargetCost attackCost = new SacrificeTargetCost(new TargetControlledPermanent(filter));
if ( attackCost.canPay(source, source.getSourceId(), event.getPlayerId(), game) && 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) ) { if (attackCost.pay(source, game, source.getSourceId(), event.getPlayerId(), false) ) {
return false; return false;

View file

@ -105,7 +105,7 @@ class TemurSabertoothEffect extends OneShotEffect {
if (controller != null) { if (controller != null) {
Target target = new TargetPermanent(1,1, filter, true); Target target = new TargetPermanent(1,1, filter, true);
if (target.canChoose(source.getSourceId(), controller.getId(), game)) { 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)) { controller.chooseTarget(outcome, target, source, game)) {
Permanent toHand = game.getPermanent(target.getFirstTarget()); Permanent toHand = game.getPermanent(target.getFirstTarget());
if (toHand != null) { if (toHand != null) {

View file

@ -112,7 +112,7 @@ class WriteIntoBeingEffect extends OneShotEffect {
if (controller.getLibrary().size() > 0) { if (controller.getLibrary().size() > 0) {
Card cardToPutBack = controller.getLibrary().getFromTop(game); Card cardToPutBack = controller.getLibrary().getFromTop(game);
String position = "on top"; 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); cardToPutBack.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
position = "on bottom"; position = "on bottom";
} }

View file

@ -110,7 +110,7 @@ class DisruptionAuraEffect extends OneShotEffect {
String message = CardUtil.replaceSourceName("Pay {this} mana cost ?", permanent.getLogName()); String message = CardUtil.replaceSourceName("Pay {this} mana cost ?", permanent.getLogName());
Cost cost = permanent.getManaCost().copy(); Cost cost = permanent.getManaCost().copy();
if (player.chooseUse(Outcome.Benefit, message, game)) { if (player.chooseUse(Outcome.Benefit, message, source, game)) {
cost.clearPaid(); cost.clearPaid();
if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) {
return true; return true;

View file

@ -95,7 +95,7 @@ class FoldIntoAEtherEffect extends OneShotEffect {
if (game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game)) { if (game.getStack().counter(source.getFirstTarget(), source.getSourceId(), game)) {
TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard()); TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard());
if (player != null 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)) { && player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
if (card != null) { if (card != null) {

View file

@ -106,7 +106,7 @@ class ReversalOfFortuneEffect extends OneShotEffect {
//If you do, you may cast the copy without paying its mana cost //If you do, you may cast the copy without paying its mana cost
if(card != null){ if(card != null){
Card copiedCard = game.copyCard(card, source, source.getControllerId()); 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); controller.cast(copiedCard.getSpellAbility(), game, true);
} }
} }

View file

@ -61,7 +61,6 @@ public class SylvanLibrary extends CardImpl {
super(ownerId, 191, "Sylvan Library", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); super(ownerId, 191, "Sylvan Library", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
this.expansionSetCode = "5ED"; 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. // 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()); this.addAbility(new BeginningOfDrawTriggeredAbility(new SylvanLibraryEffect(), TargetController.YOU, true), new CardsDrawnThisTurnWatcher());
@ -81,7 +80,7 @@ class SylvanLibraryEffect extends OneShotEffect {
public SylvanLibraryEffect() { public SylvanLibraryEffect() {
super(Outcome.LoseLife); 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) { public SylvanLibraryEffect(final SylvanLibraryEffect effect) {
@ -111,18 +110,18 @@ class SylvanLibraryEffect extends OneShotEffect {
} }
int numberOfTargets = Math.min(2, cards.size()); int numberOfTargets = Math.min(2, cards.size());
if (numberOfTargets > 0) { 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); controller.chooseTarget(outcome, cards, target, source, game);
Cards cardsPutBack = new CardsImpl(); Cards cardsPutBack = new CardsImpl();
for (UUID cardId :target.getTargets()) { for (UUID cardId : target.getTargets()) {
Card card = cards.get(cardId, game); Card card = cards.get(cardId, game);
if (card != null) { if (card != null) {
if (controller.canPayLifeCost() if (controller.canPayLifeCost()
&& controller.getLife() >= 4 && 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); 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 { } else {
cardsPutBack.add(card); cardsPutBack.add(card);
} }
@ -146,7 +145,7 @@ class SylvanLibraryEffect extends OneShotEffect {
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
} }
if (numberOfCardsToPutBack > 0) { 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<UUID> cardsDrawnThisTurn = new HashSet<UUID>(); private final Set<UUID> cardsDrawnThisTurn = new HashSet<UUID>();
public CardsDrawnThisTurnWatcher() { public CardsDrawnThisTurnWatcher() {
super("CardsDrawnThisTurnWatcher", WatcherScope.PLAYER); super("CardsDrawnThisTurnWatcher", WatcherScope.PLAYER);
} }

View file

@ -96,7 +96,7 @@ class ForceOfNatureEffect extends OneShotEffect {
if (controller != null) { if (controller != null) {
Cost cost = new ManaCostsImpl("{G}{G}{G}{G}"); 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}?"; 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))) { && cost.pay(source, game, source.getSourceId(), controller.getId(), false))) {
controller.damage(8, source.getSourceId(), game, false, true); controller.damage(8, source.getSourceId(), game, false, true);
} }

View file

@ -110,7 +110,7 @@ class GlitteringWishEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player != null) { if (player != null) {
while (player.chooseUse(Outcome.Benefit, choiceText, game)) { while (player.chooseUse(Outcome.Benefit, choiceText, source, game)) {
Cards cards = player.getSideboard(); Cards cards = player.getSideboard();
if(cards.isEmpty()) { if(cards.isEmpty()) {
game.informPlayer(player, "You have no cards outside the game."); game.informPlayer(player, "You have no cards outside the game.");

View file

@ -127,7 +127,7 @@ class DiluvianPrimordialEffect extends OneShotEffect {
if (target instanceof TargetCardInOpponentsGraveyard) { if (target instanceof TargetCardInOpponentsGraveyard) {
Card targetCard = game.getCard(target.getFirstTarget()); Card targetCard = game.getCard(target.getFirstTarget());
if (targetCard != null) { 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 // TODO: Handle the case if the cast is not possible, so the replacement effect shouldn't be active
ContinuousEffect effect = new DiluvianPrimordialReplacementEffect(); ContinuousEffect effect = new DiluvianPrimordialReplacementEffect();
effect.setTargetPointer(new FixedTarget(targetCard.getId())); effect.setTargetPointer(new FixedTarget(targetCard.getId()));

View file

@ -126,7 +126,7 @@ class DomriRadeEffect1 extends OneShotEffect {
cards.add(card); cards.add(card);
controller.lookAtCards(sourceObject.getName(), cards, game); controller.lookAtCards(sourceObject.getName(), cards, game);
if (card.getCardType().contains(CardType.CREATURE)) { 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.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
controller.revealCards(sourceObject.getName(), cards, game); controller.revealCards(sourceObject.getName(), cards, game);
} }

View file

@ -140,7 +140,7 @@ class CopyActivatedAbilityEffect extends OneShotEffect {
newAbility.newId(); newAbility.newId();
game.getStack().push(new StackAbility(newAbility, source.getControllerId())); game.getStack().push(new StackAbility(newAbility, source.getControllerId()));
if (newAbility.getTargets().size() > 0) { 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(); newAbility.getTargets().clearChosen();
if (newAbility.getTargets().chooseTargets(newAbility.getEffects().get(0).getOutcome(), source.getControllerId(), newAbility, game) == false) { if (newAbility.getTargets().chooseTargets(newAbility.getEffects().get(0).getOutcome(), source.getControllerId(), newAbility, game) == false) {
return false; return false;

Some files were not shown because too many files have changed in this diff Show more